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.Text; using System.Threading; using System.Xml; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps { public class StrongTemp : TempSensorBase { private StrongTempConnection _connection; private readonly R_TRIG _trigCommunicationError = new (); private readonly R_TRIG _trigMonitorExcepted = new (); private readonly LinkedList _lstHandler = new(); private readonly object _locker = new (); private string PMName; private double[] _tempBuff; public override bool IsConnected => _connection is { IsConnected: true }; public StrongTemp(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule) { RTrigs.Add(_trigCommunicationError); RTrigs.Add(_trigMonitorExcepted); } private void QueryTemp() { SetQuery("QueryADT", "*ADT00000a"); } private void SetQuery(string name, string strCmd) { lock (_locker) { _lstHandler.Clear(); if (_connection.IsBusy) { _connection.ForceClear(); } var bCmd = Encoding.Default.GetBytes(strCmd); _lstHandler.AddLast(new StrongTempQueryHandler(this, name, bCmd)); } } protected override bool HandleInitialize() { InitController(); _tempBuff = new double[MaxChannels]; return true; } private void InitController() { //添加参数设置 PMName = SC.GetStringValue($"{ScBasePath}.{Name}.PMName"); Address = SC.GetStringValue($"{ScBasePath}.{Name}.Address"); _connection = new StrongTempConnection(Address); _connection.EnableLog(IsEnableLog); SC.RegisterValueChangedCallback($"TempSensors.EnableLogMessage", (obj) => { _connection.EnableLog((bool)obj); }); } protected override double[] HandleReadTemp() { return IsConnected ? _tempBuff : null; } protected override void HandleMonitor() { try { _connection.MonitorTimeout(); if (!_connection.IsConnected || _connection.IsCommunicationError) { lock (_locker) { _lstHandler.Clear(); } //只要断开,就进行连接 if (!_connection.Connect()) { _trigCommunicationError.CLK = !_connection.IsConnected; if (_trigCommunicationError.Q) { Thread.Sleep(2000);//不加延时软件刚启动可能不打印 TempBasFunction.PMPostLog(PMName, $"Can not connect with {_connection.Address}, {Name}", EV.PostAlarmLog); TempBasFunction.SetPmIoForInterlock(PMName, true); } } else//已连接,自动复位断联信号 { _trigCommunicationError.RST = true; TempBasFunction.PMPostLog(PMName, $"{PMName} {Name} {Address} reconnected.", EV.PostInfoLog); TempBasFunction.SetPmIoForInterlock(PMName, false); } Thread.Sleep(1000);//重连延时 _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 ResponseQuery(string name, byte[] data) { try { if (name == "QueryADT") { var sData = Encoding.Default.GetString(data); if (sData.Length < 9) return; if (sData.Contains("*A")) { string sT = sData.Substring(2, 6); _tempBuff[0] = Convert.ToSingle(sT); } } } catch (Exception ex) { // ignored } } public void ResponseError() { _trigCommunicationError.CLK = true; if (_trigCommunicationError.Q) { TempBasFunction.PMPostLog(PMName, $"{PMName} {Name} {Address} could not receive temp", EV.PostAlarmLog); TempBasFunction.SetPmIoForInterlock(PMName, true); } } public override void Terminate() { _connection.Disconnect(); } } }