using MainShell.Common; using MaxwellControl.Controls; using MaxwellFramework.Core.Attributes; using MwFramework.Controls.UIControl.Lighter; using MwFramework.Device; using MwFramework.Device.Delta; using MwFramework.Device.DeviceInterface; using MwFramework.Device.Drivers; using MwFramework.ManagerService; using StyletIoC; using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MainShell.Hardware { public static class AxisName { public const string Axis_SZ = "SZ"; //刺晶头 音圈电机 public const string Axis_PHS_X1 = "PHS-X1"; //PHS龙门 public const string Axis_PHS_X2 = "PHS-X2"; //PHS龙门 public const string Axis_PHS_Y1 = "PHS-Y1"; //PHS龙门Y轴 public const string Axis_WS_X3 = "WS-X3"; //WS龙门 public const string Axis_WS_R = "WS-R"; //WS旋转轴 public const string Axis_Stage_Y3 = "Stage-Y3"; //Stage平台Y3轴 public const string Axis_PHS_Z1 = "PHS-Z1"; //刺晶头Z轴 public const string Axis_PHS_Z3 = "PHS-Z3"; //相机Z轴 public const string Axis_PHS_Z4 = "PHS-Z4"; public const string Axis_PHS_Z5 = "PHS-Z5"; public const string Axis_PHS_Z6 = "PHS-Z6"; public const string Axis_Stage_Z7 = "Stage-Z7"; public const string Axis_Stage_Z8 = "Stage-Z8"; public const string Axis_Stage_Z9 = "Stage-Z9"; public const string Axis_Stage_Z10 = "Stage-Z10"; public const string Axis_Stage_CV_Y4 = "Stage-CV-Y4"; public const string Axis_Stage_CV_Y5 = "Stage-CV-Y5"; public const string Axis_WEU_Z11 = "WEU-Z11"; public const string Axis_WEU_Z12 = "WEU-Z12"; public const string Axis_WEU_Y6 = "WEU-Y6"; public const string Axis_CV_Z13 = "CV-Z13"; public const string Axis_CV_Y7 = "CV-Y7"; public const string Axis_CV_Y8 = "CV-Y8"; public const string Axis_CV_Y9 = "CV-Y9"; public const string Axis_CV_Y10 = "CV-Y10"; } [Singleton] public class HardwareManager { private const ushort DeltaDefaultNode = 0; private const ushort DeltaDefaultSlot = 0; private readonly List _ioPointDefinitions = new List(); private readonly Dictionary> _ioPointDefinitionsByModule = new Dictionary>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _simulatedIoStates = new Dictionary(StringComparer.OrdinalIgnoreCase); private const string DeviceIoConfigFileName = "DeviceIoPoints.csv"; public IReadOnlyList IoPointDefinitions => _ioPointDefinitions; public IReadOnlyDictionary> IoPointDefinitionsByModule => _ioPointDefinitionsByModule; #region//内部类 public class CameraAxisDevicesManager { //public List TopPositionCameraAxisDevices { get; set; } = new List(); //public List TopVirtualCameraAxisDevices { get; set; } = new List(); //public List MapCameraAxisDevices { get; set; } = new List(); //public List TopWideCameraAxisDevices { get; set; } = new List(); public List TopPositionAndWideCameraAxisDevices { get; set;} = new List(); //public List BottomCalibCameraAxisDevices { get; set; } = new List(); //public List WSCalibCameraAxisDevices { get; set; } = new List(); //public List PadCalibCameraAxisDevices { get; set; } = new List(); //public List WSCalibWideCameraAxisDevices { get; set; } = new List(); //public List PadCalibWideCameraAxisDevices { get; set; } = new List(); //上相机拍Pad,运动轴X1、Y2 public List TopCameraAxisDevices { get; set; } = new List(); //上相机拍WS,运动轴X2、Y1 public List TopCameraWsAxisDevices { get; set; } = new List(); //广角相机拍Pad、运动轴X1、Y2 public List WideCameraAxisDevices { get; set; } = new List(); //广角相机拍ws、运动轴X2、Y1 public List WideCameraWsAxisDevices { get; set; } = new List(); //下相机拍WS,运动轴X2、Y2 public List BottomCameraAxisDevices { get; set; } = new List(); } #endregion #region 单轴对象 public IAxis Axis_PHS_X1 => GetAxisInternal(AxisName.Axis_PHS_X1); public IAxis Axis_PHS_X2 => GetAxisInternal(AxisName.Axis_PHS_X2); public IAxis Axis_PHS_Y1 => GetAxisInternal(AxisName.Axis_PHS_Y1); //public IAxis Axis_PHS_Y2 => GetAxisInternal(AxisName.Axis_Stage_Y3); public IAxis Axis_WS_X3 => GetAxisInternal(AxisName.Axis_WS_X3); public IAxis Axis_WS_R => GetAxisInternal(AxisName.Axis_WS_R); public IAxis Axis_Stage_Y3 => GetAxisInternal(AxisName.Axis_Stage_Y3); public IAxis Axis_Stage_Z7 => GetAxisInternal(AxisName.Axis_Stage_Z7); public IAxis Axis_Stage_Z8 => GetAxisInternal(AxisName.Axis_Stage_Z8); public IAxis Axis_Stage_Z9 => GetAxisInternal(AxisName.Axis_Stage_Z9); public IAxis Axis_Stage_Z10 => GetAxisInternal(AxisName.Axis_Stage_Z10); public IAxis Axis_Stage_CV_Y4 => GetAxisInternal(AxisName.Axis_Stage_CV_Y4); public IAxis Axis_Stage_CV_Y5 => GetAxisInternal(AxisName.Axis_Stage_CV_Y5); public IAxis Axis_PHS_Z1 => GetAxisInternal(AxisName.Axis_PHS_Z1); public IAxis Axis_PHS_Z3 => GetAxisInternal(AxisName.Axis_PHS_Z3); public IAxis Axis_PHS_Z4 => GetAxisInternal(AxisName.Axis_PHS_Z4); public IAxis Axis_PHS_Z5 => GetAxisInternal(AxisName.Axis_PHS_Z5); public IAxis Axis_PHS_Z6 => GetAxisInternal(AxisName.Axis_PHS_Z6); public IAxis Axis_WEU_Z11 => GetAxisInternal(AxisName.Axis_WEU_Z11); public IAxis Axis_WEU_Z12 => GetAxisInternal(AxisName.Axis_WEU_Z12); public IAxis Axis_WEU_Y6 => GetAxisInternal(AxisName.Axis_WEU_Y6); public IAxis Axis_CV_Z13 => GetAxisInternal(AxisName.Axis_CV_Z13); public IAxis Axis_CV_Y7 => GetAxisInternal(AxisName.Axis_CV_Y7); public IAxis Axis_CV_Y8 => GetAxisInternal(AxisName.Axis_CV_Y8); public IAxis Axis_CV_Y9 => GetAxisInternal(AxisName.Axis_CV_Y9); public IAxis Axis_CV_Y10 => GetAxisInternal(AxisName.Axis_CV_Y10); public IAxis Axis_SZ => GetAxisInternal(AxisName.Axis_SZ); public IAxis Axis_X1 => Axis_PHS_X1; public IAxis Axis_X2 => Axis_PHS_X2; public IAxis Axis_Y1 => Axis_PHS_Y1; public IAxis Axis_Y2 => Axis_Stage_Y3; public IAxis Axis_Z1 => Axis_PHS_Z1; public IAxis Axis_Z3 => Axis_PHS_Z3; #endregion private readonly string _topCameraName = "TopPositionCamera"; private readonly string _topWsCameraName = "TopWsCamera"; private readonly string _topWideCameraName = "TopWideCamera"; private readonly string _topWideWsCameraName = "TopWideWsCamera"; private readonly string _bottomCameraName = "MapCamera"; //private readonly string _topVirtualCameraName = "TopVirtualCamera"; /// /// 相机轴参数对象 /// public CameraAxisDevicesManager CameraAxisManager { get; protected set; } = new CameraAxisDevicesManager(); /// /// 当前设备的所有轴 /// public Dictionary AxesDic { get; protected set; } = new Dictionary(StringComparer.Ordinal); /// /// Acs卡对象 /// public MwCard AcsCard { get; protected set; } /// /// 台达卡对象 /// public MwCard TdCard { get; protected set; } private MwCamera _topCamera; /// /// 上相机 /// public MwCameraExtend TopCameraExtend { get; protected set; } /// /// 虚拟相机(上相机) /// public MwCameraExtend TopVirtualCameraExtend { get; protected set; } /// /// 上相机(虚拟相机) /// public MwCameraExtend TopWsCameraExtend { get; protected set; } private MwCamera _bottomCamera; /// /// 下相机 /// public MwCameraExtend BottomCameraExtend { get; protected set; } private MwCamera _topWideCamera; /// /// 大视野上相机 /// public MwCameraExtend TopWideCameraExtend { get; protected set; } /// /// 大视野上相机(虚拟相机) /// public MwCameraExtend TopWideWsCameraExtend { get; protected set; } /// /// 光源控制器1 /// public MwLamp LightControl1 { get; protected set; } /// /// 光源控制器2 /// public MwLamp LightControl2 { get; protected set; } #region//光源通道 public MwLight Up_PointRedLight { get; protected set; } public MwLight Up_RingRedLight { get; protected set; } public MwLight Up_PointBlueLight { get; protected set; } public MwLight Up_RingBlueLight { get; protected set; } public MwLight Up_RedBackLight { get; protected set; } public MwLight Down_PointRedLight { get; protected set; } public MwLight Down_RingRedLight { get; protected set; } public MwLight Down_PointBlueLight { get; protected set; } public MwLight Down_RingBlueLight { get; protected set; } public MwLight Map_RedLight { get; protected set; } public MwLight Map_BlueLight { get; protected set; } #endregion /// /// 激光测距仪 /// public IDiastimeter Diastimeter { get; protected set; } public IFFU FFU { get; protected set; } [Inject] public IDeviceManager DeviceManager { get; set; } public HardwareManager() { } private IAxis GetAxisInternal(string axisName) { if (string.IsNullOrWhiteSpace(axisName) || AxesDic == null) { return null; } IAxis axis; return AxesDic.TryGetValue(axisName, out axis) ? axis : null; } public void Tesrt() { Debug.WriteLine("HardwareManager Test"); } public void Initialize() { if (DeviceManager is IDeviceList devices) { //初始化硬件设备 AcsCard=devices.GetDevice("AcsCard"); TdCard=devices.GetDevice("Delta"); _topCamera=devices.GetDevice("TopPositionCamera"); _bottomCamera = devices.GetDevice("MapCamera"); _topWideCamera= devices.GetDevice("TopWideCamera"); Diastimeter = devices.GetDevice("GPACON"); LightControl1= devices.GetDevice("LightControllor1"); LightControl2= devices.GetDevice("LightControllor2"); #region //光源通道初始化 Up_PointRedLight = new MwLight("点红光", LightControl1, 0); Up_PointBlueLight=new MwLight("点蓝光", LightControl1, 3); Up_RingRedLight=new MwLight("环红光", LightControl1, 1); Up_RingBlueLight=new MwLight("环蓝光", LightControl1, 2); Up_RedBackLight=new MwLight("红背光", LightControl1, 4); Down_PointRedLight=new MwLight("点红光", LightControl2, 0); Down_PointBlueLight=new MwLight("点蓝光", LightControl2, 3); Down_RingRedLight=new MwLight("环红光",LightControl2, 1); Down_RingBlueLight=new MwLight("环蓝光", LightControl2, 2); Map_RedLight=new MwLight("平面红光", LightControl2, 4); Map_BlueLight=new MwLight("平面蓝光", LightControl2, 5); #endregion TopCameraExtend = new MwCameraExtend(_topCamera, _topCameraName, _topCameraName); TopWsCameraExtend = new MwCameraExtend(_topCamera, _topWsCameraName, _topWsCameraName); TopWideCameraExtend = new MwCameraExtend(_topWideCamera, _topWideCameraName, _topWideCameraName); TopWideWsCameraExtend = new MwCameraExtend(_topWideCamera, _topWideWsCameraName, _topWideWsCameraName); BottomCameraExtend = new MwCameraExtend(_bottomCamera, _bottomCameraName, _bottomCameraName); //TopVirtualCameraExtend = new MwCameraExtend(_topCamera, _topVirtualCameraName, _topVirtualCameraName); AxesDic = GetAxes(); //初始化相机轴集合 //CameraAxisManager.TopPositionCameraAxisDevices.Add(new HardwareDevice //{ // AxisX = Axis_PHS_X1, // AxisY = Axis_Y1, // AxisZ = Axis_PHS_Z3, // Camera = TopCameraExtend, //}); //CameraAxisManager.TopVirtualCameraAxisDevices.Add(new HardwareDevice //{ // AxisX = Axis_PHS_X1, // AxisY = Axis_Y1, // AxisZ = Axis_PHS_Z3, // Camera = TopCameraExtend, //}); //标定用相机轴组集合 CameraAxisManager.TopCameraAxisDevices.Add(new HardwareDevice { AxisX = Axis_X1, AxisY = Axis_Y2, AxisZ = Axis_PHS_Z3, Camera = TopCameraExtend, }); CameraAxisManager.TopCameraWsAxisDevices.Add(new HardwareDevice { AxisX = Axis_X2, AxisY = Axis_Y1, AxisZ = Axis_PHS_Z3, Camera = TopWsCameraExtend, }); CameraAxisManager.WideCameraAxisDevices.Add(new HardwareDevice { AxisX = Axis_X2, AxisY = Axis_Y1, AxisZ = Axis_PHS_Z3, Camera = TopWideCameraExtend, }); CameraAxisManager.WideCameraWsAxisDevices.Add(new HardwareDevice { AxisX = Axis_X1, AxisY = Axis_Y2, AxisZ = Axis_PHS_Z3, Camera = TopWideWsCameraExtend, }); CameraAxisManager.BottomCameraAxisDevices.Add(new HardwareDevice { AxisX = Axis_X2, AxisY = Axis_Y2, AxisZ = Axis_PHS_Z3, Camera = BottomCameraExtend, }); CameraAxisManager.TopPositionAndWideCameraAxisDevices.Add(CameraAxisManager.TopCameraAxisDevices.FirstOrDefault()); CameraAxisManager.TopPositionAndWideCameraAxisDevices.Add(CameraAxisManager.WideCameraAxisDevices.FirstOrDefault()); } } private Dictionary GetAxes() { // 收集所有轴到列表,先做空检查以免抛出 null 引用 var allAxes = new List(); if (AcsCard?.Axises != null) { allAxes.AddRange(AcsCard.Axises); } if (TdCard?.Axises != null) { allAxes.AddRange(TdCard.Axises); } var dict = new Dictionary(allAxes.Count , StringComparer.Ordinal); foreach (var axis in allAxes) { if (axis == null) continue; var name = axis.Name; if (string.IsNullOrEmpty(name)) continue; dict[name] = axis; } return dict; } public IAxis GetAxisByName(string axisName) { return GetAxisInternal(axisName); } public bool TryGetDeltaIoExtend(out IDeltaIoExtend deltaIoExtend) { deltaIoExtend = TdCard.Controller as IDeltaIoExtend; return deltaIoExtend != null; } public bool TryReadLogisticsIoSnapshot(out DeviceIoSnapshot snapshot) { snapshot = new DeviceIoSnapshot { IsValid = false }; if (TdCard == null) { return false; } return false; } public IReadOnlyList GetIoDefinitionsByModule(string module) { if (string.IsNullOrWhiteSpace(module)) { return new List(); } List list; if (_ioPointDefinitionsByModule.TryGetValue(module, out list)) { return list; } return new List(); } private void LoadIoPointDefinitions() { _ioPointDefinitions.Clear(); _ioPointDefinitionsByModule.Clear(); var pointKeys = new HashSet(StringComparer.OrdinalIgnoreCase); var names = new HashSet(StringComparer.OrdinalIgnoreCase); var path = ResolveIoConfigPath(); if (string.IsNullOrWhiteSpace(path) || !File.Exists(path)) { return; } var lines = File.ReadAllLines(path, Encoding.UTF8); for (var i = 0; i < lines.Length; i++) { var raw = lines[i]; if (string.IsNullOrWhiteSpace(raw)) { continue; } var line = raw.Trim(); if (line.StartsWith("#")) { continue; } if (i == 0 && line.IndexOf("Id", StringComparison.OrdinalIgnoreCase) >= 0) { continue; } var cols = line.Split(','); if (cols.Length < 9) { continue; } int id; if (!int.TryParse(cols[0].Trim(), out id)) { continue; } var hasModuleColumn = cols.Length >= 10; var moduleIndex = hasModuleColumn ? 1 : -1; var nameIndex = hasModuleColumn ? 2 : 1; var typeIndex = hasModuleColumn ? 3 : 2; var cardIndex = hasModuleColumn ? 4 : 3; var stationIndex = hasModuleColumn ? 5 : -1; var lineNoIndex = hasModuleColumn ? 6 : -1; var enabledIndex = hasModuleColumn ? 7 : 4; var defaultValueIndex = hasModuleColumn ? 8 : 5; var isInverseIndex = hasModuleColumn && cols.Length >= 11 ? 9 : -1; var descriptionIndex = hasModuleColumn ? (isInverseIndex >= 0 ? 10 : 9) : 6; var name = cols[nameIndex].Trim(); if (string.IsNullOrWhiteSpace(name)) { continue; } var module = hasModuleColumn ? cols[moduleIndex].Trim() : ResolveModuleFromName(name); if (string.IsNullOrWhiteSpace(module)) { module = "Default"; } var type = ParseIoPointType(cols[typeIndex]); var card = ParseIoCardType(cols[cardIndex]); var stationNo = stationIndex >= 0 ? ParseInt(cols[stationIndex]) : 0; var lineNo = lineNoIndex >= 0 ? cols[lineNoIndex].Trim() : string.Empty; var pointKey = DeviceIoPointDefinition.BuildPointKey(type, card, stationNo, lineNo); if (!pointKeys.Add(pointKey)) { continue; } if (!names.Add(name)) { continue; } var definition = new DeviceIoPointDefinition { Id = id, PointKey = pointKey, Module = module, Name = name, Type = type, Card = card, StationNo = stationNo, LineNo = lineNo, Enabled = ParseBoolean(cols[enabledIndex], true), DefaultValue = ParseBoolean(cols[defaultValueIndex], false), IsInverse = isInverseIndex >= 0 && isInverseIndex < cols.Length && ParseBoolean(cols[isInverseIndex], false), Description = cols.Length > descriptionIndex ? string.Join(",", cols.Skip(descriptionIndex)).Trim() : string.Empty }; _ioPointDefinitions.Add(definition); List moduleDefinitions; if (!_ioPointDefinitionsByModule.TryGetValue(module, out moduleDefinitions)) { moduleDefinitions = new List(); _ioPointDefinitionsByModule[module] = moduleDefinitions; } moduleDefinitions.Add(definition); } } private static string ResolveModuleFromName(string name) { if (string.IsNullOrWhiteSpace(name)) { return "Default"; } var parts = name.Split('.'); if (parts.Length >= 2) { return parts[1]; } return "Default"; } private static IoPointType ParseIoPointType(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return IoPointType.Input; } var text = raw.Trim(); if (string.Equals(text, "Output", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "OUT", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "DO", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "O", StringComparison.OrdinalIgnoreCase)) { return IoPointType.Output; } return IoPointType.Input; } private static IoCardType ParseIoCardType(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return IoCardType.Td; } var text = raw.Trim(); if (string.Equals(text, "Acs", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "ACS", StringComparison.OrdinalIgnoreCase)) { return IoCardType.Acs; } return IoCardType.Td; } private static bool ParseBoolean(string raw, bool defaultValue) { if (string.IsNullOrWhiteSpace(raw)) { return defaultValue; } var text = raw.Trim(); if (string.Equals(text, "1", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "true", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "yes", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "y", StringComparison.OrdinalIgnoreCase)) { return true; } if (string.Equals(text, "0", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "false", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "no", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "n", StringComparison.OrdinalIgnoreCase)) { return false; } return defaultValue; } private static int ParseInt(string raw) { int value; return int.TryParse((raw ?? string.Empty).Trim(), out value) ? value : 0; } internal bool TryReadIoPointValues(IReadOnlyList definitions, out Dictionary values) { values = new Dictionary(StringComparer.OrdinalIgnoreCase); if (definitions == null || definitions.Count == 0) { return false; } bool hasAnyValue = false; IDeltaIoExtend deltaIoExtend; bool canReadDelta = TryGetDeltaIoExtend(out deltaIoExtend); List deltaDefinitions = new List(); foreach (DeviceIoPointDefinition definition in definitions) { if (definition == null) { continue; } bool simulatedValue; if (!string.IsNullOrWhiteSpace(definition.PointKey) && _simulatedIoStates.TryGetValue(definition.PointKey, out simulatedValue)) { values[definition.PointKey] = simulatedValue; hasAnyValue = true; continue; } if (definition.Card == IoCardType.Td && canReadDelta) { deltaDefinitions.Add(definition); continue; } bool singleValue; if (TryReadIoPointValue(definition, out singleValue)) { values[definition.PointKey] = singleValue; hasAnyValue = true; } } IEnumerable> groups = deltaDefinitions.GroupBy(BuildDeltaReadGroupKey); foreach (IGrouping group in groups) { if (TryReadDeltaIoPointGroup(group, deltaIoExtend, values)) { hasAnyValue = true; continue; } foreach (DeviceIoPointDefinition definition in group) { bool singleValue; if (TryReadDeltaIoPoint(definition, deltaIoExtend, out singleValue)) { values[definition.PointKey] = singleValue; hasAnyValue = true; } } } return hasAnyValue; } internal bool TryReadIoPointValue(DeviceIoPointDefinition definition, out bool value) { value = false; if (definition == null) { return false; } if (!string.IsNullOrWhiteSpace(definition.PointKey) && _simulatedIoStates.TryGetValue(definition.PointKey, out value)) { return true; } var card = definition.Card == IoCardType.Acs ? AcsCard : TdCard; if (card == null) { return false; } if (definition.Card == IoCardType.Td) { IDeltaIoExtend deltaIoExtend; if (!TryGetDeltaIoExtend(out deltaIoExtend)) { return false; } return TryReadDeltaIoPoint(definition, deltaIoExtend, out value); } return false; } private bool TryReadDeltaIoPoint(DeviceIoPointDefinition definition, IDeltaIoExtend deltaIoExtend, out bool value) { value = false; if (definition == null || deltaIoExtend == null) { return false; } ushort cardNo; ushort node; ushort slot; ushort index; ushort subIndex; byte bitNo; ushort ioType; if (!TryGetDeltaIoReadParameters(definition, out cardNo, out node, out slot, out index, out subIndex, out bitNo, out ioType)) { return false; } bool rawValue; ushort result = deltaIoExtend.ReadBit(cardNo, node, slot, index, subIndex, bitNo, out rawValue, ioType); if (result != 0) { return false; } value = definition.IsInverse ? !rawValue : rawValue; return true; } private bool TryReadDeltaIoPointGroup(IGrouping group, IDeltaIoExtend deltaIoExtend, IDictionary values) { if (group == null || deltaIoExtend == null || values == null) { return false; } DeviceIoPointDefinition firstDefinition = group.FirstOrDefault(); if (firstDefinition == null) { return false; } ushort cardNo; ushort node; ushort slot; ushort ioType; if (!TryGetDeltaGroupParameters(firstDefinition, out cardNo, out node, out slot, out ioType)) { return false; } List points = new List(); Dictionary definitionsByPointKey = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (DeviceIoPointDefinition definition in group) { ushort index; ushort subIndex; byte bitNo; if (!TryGetDeltaPointAddress(definition, out index, out subIndex, out bitNo)) { return false; } BitItem point = new BitItem(); point.Name = definition.PointKey; point.Index = index; point.SubIndex = subIndex; point.BitNo = bitNo; points.Add(point); definitionsByPointKey[definition.PointKey] = definition; } ushort result = deltaIoExtend.ReadBits(cardNo, node, slot, points, ioType); if (result != 0) { return false; } foreach (BitItem point in points) { DeviceIoPointDefinition definition; if (!definitionsByPointKey.TryGetValue(point.Name ?? string.Empty, out definition)) { continue; } values[definition.PointKey] = definition.IsInverse ? !point.Value : point.Value; } return true; } private bool TryGetDeltaIoReadParameters(DeviceIoPointDefinition definition, out ushort cardNo, out ushort node, out ushort slot, out ushort index, out ushort subIndex, out byte bitNo, out ushort ioType) { cardNo = 0; node = 0; slot = 0; index = 0; subIndex = 0; bitNo = 0; ioType = 0; if (!TryGetDeltaGroupParameters(definition, out cardNo, out node, out slot, out ioType)) { return false; } return TryGetDeltaPointAddress(definition, out index, out subIndex, out bitNo); } private bool TryGetDeltaIoWriteParameters(DeviceIoPointDefinition definition, out ushort cardNo, out ushort node, out ushort slot, out ushort index, out ushort subIndex, out byte bitNo, out ushort readIoType) { cardNo = 0; node = 0; slot = 0; index = 0; subIndex = 0; bitNo = 0; readIoType = 0; if (!TryGetDeltaGroupParameters(definition, out cardNo, out node, out slot, out readIoType)) { return false; } return TryGetDeltaPointAddress(definition, out index, out subIndex, out bitNo); } private bool TryGetDeltaGroupParameters(DeviceIoPointDefinition definition, out ushort cardNo, out ushort node, out ushort slot, out ushort ioType) { cardNo = 0; node = 0; slot = 0; ioType = 0; if (definition == null) { return false; } if (!TryConvertToUShort(definition.StationNo, out cardNo)) { return false; } node = DeltaDefaultNode; slot = DeltaDefaultSlot; ioType = definition.Type == IoPointType.Output ? (ushort)1 : (ushort)0; return true; } private bool TryGetDeltaPointAddress(DeviceIoPointDefinition definition, out ushort index, out ushort subIndex, out byte bitNo) { index = 0; subIndex = 0; bitNo = 0; if (definition == null) { return false; } if (!TryConvertHexIntToUShort(definition.Index, out index) || !TryConvertHexIntToUShort(definition.SubIndex, out subIndex) || !TryResolveBitNo(definition, out bitNo)) { return false; } return true; } private static bool TryConvertHexIntToUShort(int value, out ushort ushortValue) { ushortValue = 0; string hexText = value.ToString(CultureInfo.InvariantCulture); return ushort.TryParse(hexText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ushortValue); } private static bool TryResolveBitNo(DeviceIoPointDefinition definition, out byte bitNo) { bitNo = 0; if (definition == null) { return false; } int lineNoBitIndex; if (TryParseBitIndexFromLineNo(definition.LineNo, out lineNoBitIndex)) { bitNo = (byte)(lineNoBitIndex % 8); return true; } if (definition.Id < 0) { return false; } bitNo = (byte)(definition.Id % 8); return true; } private static bool TryParseBitIndexFromLineNo(string lineNo, out int bitIndex) { bitIndex = 0; if (string.IsNullOrWhiteSpace(lineNo)) { return false; } string text = lineNo.Trim(); if (text.Length < 2) { return false; } string suffix = text.Substring(text.Length - 2, 2); return int.TryParse(suffix, out bitIndex); } private static bool TryConvertToUShort(int value, out ushort ushortValue) { ushortValue = 0; if (value < ushort.MinValue || value > ushort.MaxValue) { return false; } ushortValue = (ushort)value; return true; } private static string BuildDeltaReadGroupKey(DeviceIoPointDefinition definition) { if (definition == null) { return string.Empty; } return string.Format( "{0}:{1}:{2}:{3}:{4}", definition.Card, definition.StationNo, definition.Type, definition.Index, definition.SubIndex); } internal bool TryWriteIoPointValue(DeviceIoPointDefinition definition, bool outputOn) { if (definition == null) { return false; } if (!string.IsNullOrWhiteSpace(definition.PointKey)) { _simulatedIoStates[definition.PointKey] = outputOn; } var card = definition.Card == IoCardType.Acs ? AcsCard : TdCard; if (card == null) { return true; } bool rawOutput = definition.IsInverse ? !outputOn : outputOn; if (definition.Card == IoCardType.Td) { IDeltaIoExtend deltaIoExtend; if (!TryGetDeltaIoExtend(out deltaIoExtend)) { return false; } ushort cardNo; ushort node; ushort slot; ushort index; ushort subIndex; byte bitNo; ushort readIoType; if (!TryGetDeltaIoWriteParameters(definition, out cardNo, out node, out slot, out index, out subIndex, out bitNo, out readIoType)) { return false; } ushort result = deltaIoExtend.WriteBit(cardNo, node, slot, index, subIndex, bitNo, rawOutput, readIoType); return result == 0; } return false; } private static string ResolveIoConfigPath() { var baseDir = AppDomain.CurrentDomain.BaseDirectory; var localPath = Path.Combine(baseDir, "Configuration", DeviceIoConfigFileName); var sourcePath = ResolveRootConfigPath(baseDir, DeviceIoConfigFileName); if (TrySyncConfigToLocal(sourcePath, localPath)) { return localPath; } return File.Exists(localPath) ? localPath : null; } private static string ResolveRootConfigPath(string baseDir, string fileName) { var current = new DirectoryInfo(baseDir); while (current != null) { var rootConfigDir = Path.Combine(current.FullName, "Configuration"); if (Directory.Exists(rootConfigDir) && Directory.Exists(Path.Combine(current.FullName, "MainShell"))) { var path = Path.Combine(rootConfigDir, fileName); if (File.Exists(path)) { return path; } } current = current.Parent; } return null; } private static bool TrySyncConfigToLocal(string sourcePath, string localPath) { if (string.IsNullOrWhiteSpace(sourcePath) || !File.Exists(sourcePath)) { return false; } if (!string.Equals(Path.GetFullPath(sourcePath), Path.GetFullPath(localPath), StringComparison.OrdinalIgnoreCase)) { var localDir = Path.GetDirectoryName(localPath); if (!string.IsNullOrWhiteSpace(localDir)) { Directory.CreateDirectory(localDir); } if (!File.Exists(localPath) || File.GetLastWriteTimeUtc(localPath) < File.GetLastWriteTimeUtc(sourcePath)) { File.Copy(sourcePath, localPath, true); } } return true; } #region // 获取相机 public MwCameraExtend GetCamera(CameraType cameraType) { switch (cameraType) { case CameraType.MapCamera: return BottomCameraExtend; case CameraType.TopWideCamera: return TopWideCameraExtend; case CameraType.TopPositionCamera: return TopCameraExtend; case CameraType.TopWideWsCamera: return TopWideWsCameraExtend; case CameraType.TopWsCamera: return TopWsCameraExtend; } throw new Exception("未知的相机类型,请检查相机类型参数"); } public string GetCameraName(CameraType cameraType) { var cameraExtend = GetCamera(cameraType); return cameraExtend != null ? cameraExtend.Name : throw new Exception("未知的相机类型,请检查相机类型参数"); } #endregion #region //设置光源强度 private void SetLightIntensity(MwLight light, int intensity) { if (light != null) { light.Intensity = intensity; } } private int GetLightIntensity(MwLight light) { if (light != null) { return light.Intensity; } return 0; } public void SetUpPointRedLightIntensity(int intensity) { SetLightIntensity(Up_PointRedLight, intensity); } public void SetUpRingRedLightIntensity(int intensity) { SetLightIntensity(Up_RingRedLight, intensity); } public void SetUpPointBlueLightIntensity(int intensity) { SetLightIntensity(Up_PointBlueLight, intensity); } public void SetUpRingBlueLightIntensity(int intensity) { SetLightIntensity(Up_RingBlueLight, intensity); } public void SetDownPointRedLightIntensity(int intensity) { SetLightIntensity(Down_PointRedLight, intensity); } public void SetDownRingRedLightIntensity(int intensity) { SetLightIntensity(Down_RingRedLight, intensity); } public void SetDownPointBlueLightIntensity(int intensity) { SetLightIntensity(Down_PointBlueLight, intensity); } public void SetDownRingBlueLightIntensity(int intensity) { SetLightIntensity(Down_RingBlueLight, intensity); } public void SetMapRedLightIntensity(int intensity) { SetLightIntensity(Map_RedLight, intensity); } public void SetMapBlueLightIntensity(int intensity) { SetLightIntensity(Map_BlueLight, intensity); } public void SetUpRedBackLightIntensity(int intensity) { SetLightIntensity(Up_RedBackLight, intensity); } public int GetUpPointRedLightIntensity() { return GetLightIntensity(Up_PointRedLight); } public int GetUpRingRedLightIntensity() { return GetLightIntensity(Up_RingRedLight); } public int GetUpPointBlueLightIntensity() { return GetLightIntensity(Up_PointBlueLight); } public int GetUpRingBlueLightIntensity() { return GetLightIntensity(Up_RingBlueLight); } public int GetDownPointRedLightIntensity() { return GetLightIntensity(Down_PointRedLight); } public int GetDownRingRedLightIntensity() { return GetLightIntensity(Down_RingRedLight); } public int GetDownPointBlueLightIntensity() { return GetLightIntensity(Down_PointBlueLight); } public int GetDownRingBlueLightIntensity() { return GetLightIntensity(Down_RingBlueLight); } public int GetMapRedLightIntensity() { return GetLightIntensity(Map_RedLight); } public int GetMapBlueLightIntensity() { return GetLightIntensity(Map_BlueLight); } public int GetUpRedBackLightIntensity() { return GetLightIntensity(Up_RedBackLight); } #endregion } }