Files
test_demo/MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/DeviceMaintance/ViewModel/CylinderViewModel.cs
Shi.Ji e31d3560bb 添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
2026-05-18 11:43:09 +08:00

306 lines
11 KiB
C#

using MainShell.DeviceMaintance.Model;
using MainShell.DeviceMaintance.ViewModel.State;
using MainShell.Hardware;
using MainShell.Manual.ViewModel.State;
using MaxwellFramework.Core.Interfaces;
using Stylet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MainShell.DeviceMaintance.ViewModel
{
public class CylinderViewModel : Screen, IPage
{
private readonly IDeviceIoMonitorService _ioMonitorService;
private readonly IDeviceCylinderService _cylinderService;
private readonly Dictionary<string, List<CylinderSignalState>> _signalMap = new Dictionary<string, List<CylinderSignalState>>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, DeviceIoPointDefinition> _ioDefinitionsByName;
private CylinderPageState _pageState;
public CylinderPageState PageState
{
get { return _pageState; }
set { SetAndNotify(ref _pageState, value); }
}
public CylinderViewModel(IDeviceIoMonitorService ioMonitorService, IDeviceCylinderService cylinderService)
{
_ioMonitorService = ioMonitorService;
_cylinderService = cylinderService;
_ioDefinitionsByName = _ioMonitorService.Definitions.ToDictionary(x => x.Name, x => x, StringComparer.OrdinalIgnoreCase);
PageState = BuildState();
_ioMonitorService.IoChanged += OnIoChanged;
_ioMonitorService.Start();
}
protected override void OnViewLoaded()
{
base.OnViewLoaded();
ApplyIoPoints(_ioMonitorService.LatestPoints.Values);
InitializePointsAsync();
}
protected override void OnDeactivate()
{
_ioMonitorService.IoChanged -= OnIoChanged;
base.OnDeactivate();
}
private CylinderPageState BuildState()
{
var state = new CylinderPageState();
_signalMap.Clear();
foreach (var definition in _cylinderService.Definitions)
{
var item = new CylinderItemState
{
Name = definition.Name,
Description = definition.Description,
Module = definition.Module,
ControlTypeText = GetControlTypeText(definition.ControlType)
};
item.ExtendCommand = new ActionCommand(() => ExecuteCylinderAction(definition, item, true), () => !item.IsBusy);
item.RetractCommand = new ActionCommand(() => ExecuteCylinderAction(definition, item, false), () => !item.IsBusy);
for (var i = 0; i < definition.ExtendOutputPoints.Count; i++)
{
AddOutputSignal(item, definition.ExtendOutputPoints[i], definition.ExtendOutputPoints.Count > 1 ? string.Format("{0}-伸出输出{1}", definition.Name, i + 1) : definition.Name + "-伸出输出");
}
for (var i = 0; i < definition.RetractOutputPoints.Count; i++)
{
AddOutputSignal(item, definition.RetractOutputPoints[i], definition.RetractOutputPoints.Count > 1 ? string.Format("{0}-缩回输出{1}", definition.Name, i + 1) : definition.Name + "-缩回输出");
}
foreach (var pointReference in definition.ExtendedFeedbackPoints)
{
AddFeedbackSignal(item, pointReference, definition.Name + "-伸出到位");
}
foreach (var pointReference in definition.RetractedFeedbackPoints)
{
AddFeedbackSignal(item, pointReference, definition.Name + "-缩回到位");
}
state.Cylinders.Add(item);
}
return state;
}
private void AddOutputSignal(CylinderItemState item, string pointReference, string fallbackName)
{
var definition = ResolveDefinition(pointReference);
var signal = new CylinderSignalState
{
PointReference = pointReference,
PointKey = definition?.PointKey,
Name = definition != null ? definition.Name : fallbackName,
LineNo = definition != null ? definition.LineNo : string.Empty,
IsOutput = true
};
item.OutputSignals.Add(signal);
MapSignal(signal, pointReference);
}
private void AddFeedbackSignal(CylinderItemState item, string pointReference, string fallbackName)
{
var definition = ResolveDefinition(pointReference);
var signal = new CylinderSignalState
{
PointReference = pointReference,
PointKey = definition?.PointKey,
Name = definition != null ? definition.Name : fallbackName,
LineNo = definition != null ? definition.LineNo : string.Empty,
IsOutput = false
};
item.FeedbackSignals.Add(signal);
MapSignal(signal, pointReference);
}
private DeviceIoPointDefinition ResolveDefinition(string pointReference)
{
if (string.IsNullOrWhiteSpace(pointReference))
{
return null;
}
DeviceIoPointDefinition definition;
if (_ioDefinitionsByName.TryGetValue(pointReference, out definition))
{
return definition;
}
int id;
if (!int.TryParse(pointReference, out id))
{
return null;
}
var matches = _ioMonitorService.Definitions.Where(x => x.Id == id).Take(2).ToList();
return matches.Count == 1 ? matches[0] : null;
}
private void MapSignal(CylinderSignalState signal, string pointReference)
{
var key = !string.IsNullOrWhiteSpace(signal.PointKey) ? signal.PointKey : pointReference;
if (string.IsNullOrWhiteSpace(key))
{
return;
}
List<CylinderSignalState> signals;
if (!_signalMap.TryGetValue(key, out signals))
{
signals = new List<CylinderSignalState>();
_signalMap[key] = signals;
}
signals.Add(signal);
}
private void OnIoChanged(object sender, EventArgs e)
{
var args = e as MainShell.EventArgsFolder.DeviceIoChangedEventArgs;
if (args == null)
{
return;
}
ApplyIoPoints(args.ChangedPoints);
}
private async void InitializePointsAsync()
{
_ioMonitorService.RequestRefresh();
await Task.Delay(150);
ApplyIoPoints(_ioMonitorService.LatestPoints.Values);
}
private void ApplyIoPoints(IEnumerable<DeviceIoPointState> points)
{
if (points == null)
{
return;
}
foreach (var point in points)
{
if (point == null)
{
continue;
}
List<CylinderSignalState> signals;
if (!_signalMap.TryGetValue(point.PointKey, out signals))
{
continue;
}
foreach (var signal in signals)
{
signal.IsOn = point.Value;
}
}
}
private void ExecuteCylinderAction(CylinderDefinition definition, CylinderItemState item, bool extend)
{
item.IsBusy = true;
RaiseCommands(item);
string failureReason;
var result = extend ? _cylinderService.TryExtend(definition.Name, out failureReason) : _cylinderService.TryRetract(definition.Name, out failureReason);
if (result)
{
SimulateCylinderFeedback(definition, extend);
PageState.LastActionMessage = definition.Name + (extend ? " 执行伸出成功。" : " 执行缩回成功。");
}
else
{
PageState.LastActionMessage = string.IsNullOrWhiteSpace(failureReason)
? definition.Name + (extend ? " 伸出失败。" : " 缩回失败。")
: failureReason;
}
PageState.LastActionTime = DateTime.Now;
item.IsBusy = false;
RaiseCommands(item);
}
private void SimulateCylinderFeedback(CylinderDefinition definition, bool extend)
{
foreach (var output in definition.ExtendOutputPoints.SelectMany(GetSignals))
{
output.IsOn = extend;
}
foreach (var output in definition.RetractOutputPoints.SelectMany(GetSignals))
{
output.IsOn = !extend;
}
foreach (var feedback in definition.ExtendedFeedbackPoints.SelectMany(GetSignals))
{
feedback.IsOn = extend;
}
foreach (var feedback in definition.RetractedFeedbackPoints.SelectMany(GetSignals))
{
feedback.IsOn = !extend;
}
}
private IEnumerable<CylinderSignalState> GetSignals(string pointReference)
{
var definition = ResolveDefinition(pointReference);
var key = definition != null ? definition.PointKey : pointReference;
if (string.IsNullOrWhiteSpace(key))
{
return Enumerable.Empty<CylinderSignalState>();
}
List<CylinderSignalState> signals;
if (_signalMap.TryGetValue(key, out signals))
{
return signals;
}
return Enumerable.Empty<CylinderSignalState>();
}
private static void RaiseCommands(CylinderItemState item)
{
var extend = item.ExtendCommand as ActionCommand;
if (extend != null)
{
extend.RaiseCanExecuteChanged();
}
var retract = item.RetractCommand as ActionCommand;
if (retract != null)
{
retract.RaiseCanExecuteChanged();
}
}
private static string GetControlTypeText(CylinderControlType controlType)
{
switch (controlType)
{
case CylinderControlType.DualOutput:
return "双输出控制";
case CylinderControlType.MultiOutput:
return "多输出单控";
default:
return "单输出控制";
}
}
}
}