using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Communications; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Xml; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps { public sealed class AETemp : TempSensorBase { private AETempConnection _connection; private readonly R_TRIG _trigCommunicationError = new (); private readonly R_TRIG _trigFewChannels = new (); private readonly R_TRIG _trigMonitorExcepted = new (); private readonly LinkedList _lstHandler = new (); private readonly object _locker = new (); private double[] _tempBuff; /// /// 设备通道启用 /// private bool[] _channelInstalled; public override bool IsConnected => _connection is { IsConnected: true }; public AETemp(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule) { RTrigs.Add(_trigCommunicationError); RTrigs.Add(_trigFewChannels); RTrigs.Add(_trigMonitorExcepted); } private void QueryTemp() { lock (_locker) { _lstHandler.AddLast(new AETempReadCommandHandler(this, "OUT", "1")); } } protected override bool HandleInitialize() { InitController(); _channelInstalled=new bool[MaxChannels]; for (int i = 0; i < _channelInstalled.Length; i++) _channelInstalled[i] = SC.GetValue($"{ScBasePath}.{Name}.Channel{i+1}"); _tempBuff = new double[MaxChannels]; return true; } private void InitController() { Address = SC.GetStringValue($"{ScBasePath}.{Name}.Address"); _connection = new AETempConnection(Address); _connection.EnableLog(IsEnableLog); SC.RegisterValueChangedCallback($"TempSensors.EnableLogMessage", (obj) => { _connection.EnableLog((bool)obj); }); } protected override double[] HandleReadTemp() { OnTimeQueryTemp(); return IsConnected ? _tempBuff : null; } protected void OnTimeQueryTemp() { try { _connection.MonitorTimeout(); if (!_connection.IsConnected || _connection.IsCommunicationError) { lock (_locker) { _lstHandler.Clear(); } //只要断开,就进行连接 if (!_connection.Connect()) { _trigCommunicationError.CLK = !_connection.IsConnected; if (_trigCommunicationError.Q) { TempBasFunction.PM1PM2PostLog($"Can not connect with {_connection.Address}, {Module}.{Name}",EV.PostAlarmLog); TempBasFunction.SetPm1Pm2IoForInterlock(true); } _connection.ForceClear(); Thread.Sleep(1000);//重连延时 } else { //连接成功后不会再进入,所以也只是写入一次LOG LOG.Write($"{Module} {Name} Connected"); EV.PostInfoLog(Module, $"{Name} Connected"); TempBasFunction.PM1PM2PostLog($"{Name} Connected", EV.PostInfoLog); TempBasFunction.SetPm1Pm2IoForInterlock(false); } _trigCommunicationError.CLK = !_connection.IsConnected; _connection.ForceClear(); } else { lock (_locker) { if (_lstHandler.Count == 0) QueryTemp(); if (_lstHandler.Count > 0 && !_connection.IsBusy) { var handler = _lstHandler.First.Value; _lstHandler.RemoveFirst(); if (handler != null) { _connection.Execute(handler); } } } } } catch (Exception ex) { _trigMonitorExcepted.CLK = true; if(_trigMonitorExcepted.Q) LOG.Write(ex); } } public void ParseCommandInfo(string command, string message) { try { switch (command) { case "OUT": { if (message != null) { if (message.Contains(" ")) { var strs = message.Split(' '); if (strs.Length > 0 ) { //判断AE温度通道启用,和上位机设定通道启用,是否相同 if (strs.Length != _channelInstalled.Count(c => c == true)) { _trigFewChannels.CLK = true; if (_trigFewChannels.Q) { TempBasFunction.PM1PM2PostLog("AE Error: Too few channels.", EV.PostAlarmLog); } return; } //温度数组,根据通道是否屏蔽来赋值, _trigFewChannels.RST = true; for (int i = 0; i < strs.Length; i++) { if (_channelInstalled[i] == true) { _tempBuff[i] = float.Parse(strs[i]); } } //温度连续多次不变化侦测 //TempInvariantCount = TempBasFunction.TempInvariantCount(TempDatasArray, out string tempInvariantData); //_trigTempNoChange.CLK = TempInvariantCount >= TempInvariantCountMax ? true : false; //if (_trigTempNoChange.Q) //{ // TempBasFunction.PM1PM2PostLog($"{Name} {TempInvariantCount} temp no changeCount {tempInvariantData}", EV.PostWarningLog); //} } } } } break; } } catch (Exception ex) { // ignored } } public override void Reset() { _connection?.SetCommunicationError(false, ""); base.Reset(); } public override void Terminate() { _connection.Disconnect(); } } }