195 lines
6.3 KiB
C#
195 lines
6.3 KiB
C#
using MainShell.EventArgsFolder;
|
|
using MainShell.Hardware;
|
|
using MainShell.Manual.Model;
|
|
using MainShell.DeviceMaintance.ViewModel.State;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace MainShell.DeviceMaintance.ViewModel
|
|
{
|
|
public class DeviceIoViewModel : OperateViewModelBase
|
|
{
|
|
private readonly IDeviceIoMonitorService _ioMonitorService;
|
|
private readonly Dictionary<string, DeviceIoPointItemState> _pointStateMap = new Dictionary<string, DeviceIoPointItemState>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
private DeviceIoPageState _pageState;
|
|
public DeviceIoPageState PageState
|
|
{
|
|
get { return _pageState; }
|
|
set { SetAndNotify(ref _pageState, value); }
|
|
}
|
|
|
|
public DeviceIoViewModel(IDeviceIoMonitorService ioMonitorService)
|
|
{
|
|
_ioMonitorService = ioMonitorService;
|
|
PageState = BuildState();
|
|
_ioMonitorService.IoChanged += OnIoChanged;
|
|
_ioMonitorService.Start();
|
|
}
|
|
|
|
protected override void OnViewLoaded()
|
|
{
|
|
base.OnViewLoaded();
|
|
RefreshFromCurrentPoints();
|
|
InitializeLatestPointsAsync();
|
|
}
|
|
|
|
protected override void OnDeactivate()
|
|
{
|
|
_ioMonitorService.IoChanged -= OnIoChanged;
|
|
base.OnDeactivate();
|
|
}
|
|
|
|
private DeviceIoPageState BuildState()
|
|
{
|
|
var state = new DeviceIoPageState();
|
|
_pointStateMap.Clear();
|
|
|
|
foreach (var moduleGroup in _ioMonitorService.Definitions.GroupBy(x => string.IsNullOrWhiteSpace(x.Module) ? "Default" : x.Module))
|
|
{
|
|
var moduleState = new DeviceIoModuleState
|
|
{
|
|
Name = moduleGroup.Key
|
|
};
|
|
|
|
foreach (var definition in moduleGroup.OrderBy(x => x.StationNo).ThenBy(x => x.Id).ThenBy(x => x.LineNo))
|
|
{
|
|
var item = new DeviceIoPointItemState
|
|
{
|
|
Id = definition.Id,
|
|
PointKey = definition.PointKey,
|
|
Module = definition.Module,
|
|
Name = definition.Name,
|
|
StationNo = definition.StationNo,
|
|
LineNo = definition.LineNo,
|
|
Description = definition.Description,
|
|
IsOutput = definition.Type == IoPointType.Output,
|
|
IsOn = definition.DefaultValue,
|
|
IsInverse = definition.IsInverse,
|
|
CanWrite = definition.Type == IoPointType.Output && definition.Enabled,
|
|
};
|
|
|
|
if (item.IsOutput)
|
|
{
|
|
var command = new ActionCommand(() => ToggleOutput(item), () => item.CanWrite);
|
|
item.ToggleCommand = command;
|
|
}
|
|
|
|
_pointStateMap[item.PointKey] = item;
|
|
|
|
if (item.IsOutput)
|
|
{
|
|
moduleState.OutputPoints.Add(item);
|
|
}
|
|
else
|
|
{
|
|
moduleState.InputPoints.Add(item);
|
|
}
|
|
}
|
|
|
|
state.Modules.Add(moduleState);
|
|
}
|
|
|
|
state.IsOnline = _ioMonitorService.IsOnline;
|
|
return state;
|
|
}
|
|
|
|
private async void InitializeLatestPointsAsync()
|
|
{
|
|
_ioMonitorService.RequestRefresh();
|
|
await Task.Delay(150);
|
|
RefreshFromCurrentPoints();
|
|
}
|
|
|
|
private void RefreshFromCurrentPoints()
|
|
{
|
|
var points = _ioMonitorService.LatestPoints.Values.ToList();
|
|
ApplyPoints(points);
|
|
}
|
|
|
|
private void OnIoChanged(object sender, EventArgs e)
|
|
{
|
|
var args = e as DeviceIoChangedEventArgs;
|
|
if (args == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ApplyPoints(args.ChangedPoints);
|
|
PageState.LastRefreshTime = DateTime.Now;
|
|
}
|
|
|
|
private void ApplyPoints(IEnumerable<DeviceIoPointState> points)
|
|
{
|
|
if (points == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var hasPoint = false;
|
|
foreach (var point in points)
|
|
{
|
|
if (point == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
hasPoint = true;
|
|
DeviceIoPointItemState item;
|
|
if (!_pointStateMap.TryGetValue(point.PointKey, out item))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
item.IsOn = point.Value;
|
|
|
|
var outputPoint = point as DeviceOutputPointState;
|
|
item.CanWrite = outputPoint != null && outputPoint.CanWrite;
|
|
|
|
var command = item.ToggleCommand as ActionCommand;
|
|
if (command != null)
|
|
{
|
|
command.RaiseCanExecuteChanged();
|
|
}
|
|
}
|
|
|
|
if (hasPoint)
|
|
{
|
|
PageState.LastRefreshTime = DateTime.Now;
|
|
}
|
|
|
|
PageState.IsOnline = hasPoint && _ioMonitorService.IsOnline;
|
|
}
|
|
|
|
private void ToggleOutput(DeviceIoPointItemState item)
|
|
{
|
|
DeviceIoPointState point;
|
|
if (!_ioMonitorService.TryGetPoint(item.PointKey, out point))
|
|
{
|
|
UpdateWriteResult(item.Name + " 写入失败:未找到输出点。", false);
|
|
return;
|
|
}
|
|
|
|
var outputPoint = point as DeviceOutputPointState;
|
|
if (outputPoint == null || !outputPoint.CanWrite)
|
|
{
|
|
UpdateWriteResult(item.Name + " 写入失败:输出点不可写。", false);
|
|
return;
|
|
}
|
|
|
|
var targetState = !item.IsOn;
|
|
var result = outputPoint.TrySetOutput(targetState);
|
|
UpdateWriteResult(item.Name + (result ? (targetState ? " 已切换为 ON。" : " 已切换为 OFF。") : " 写入失败。"), result);
|
|
}
|
|
|
|
private void UpdateWriteResult(string message, bool success)
|
|
{
|
|
PageState.LastWriteMessage = message;
|
|
PageState.IsWriteSuccess = success;
|
|
PageState.LastWriteTime = DateTime.Now;
|
|
}
|
|
}
|
|
}
|