using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; 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.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps { public class StrongTemp : BaseDevice, IConnection, IDevice, ITempData { private StrongTempConnection _connection; private TempBasFunction tempBasFunction; private R_TRIG _trigCommunicationError = new R_TRIG(); private PeriodicJob _thread; private LinkedList _lstHandler = new LinkedList(); private object _locker = new object(); private bool _enableLog = false; private string PMName; public int TempMin { get; set; } = 600; public int NumberOfChannels { get; set; } = 1; public float[] TempDatasArray { get; set; } public string Address { get; set; } public bool IsConnected { get { return _connection != null && _connection.IsConnected; } } public bool Connect() { return true; } public bool Disconnect() { return true; } public StrongTemp(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule) { } public void QueryTemp() { SetQuery("QueryADT", "*ADT00000a"); } public void SetQuery(string name, string strCmd) { lock (_locker) { _lstHandler.Clear(); if (_connection.IsBusy) { _connection.ForceClear(); } byte[] bCmd = Encoding.Default.GetBytes(strCmd); _lstHandler.AddLast(new StrongTempQueryHandler(this, name, bCmd)); } } public bool Initialize() { if (!SC.GetValue($"{ScBasePath}.EnableDevice")) return true; IniData(); IniTemp(); return true; } private void IniData() { //添加参数设置 PMName = SC.GetStringValue($"{ScBasePath}.PMName"); tempBasFunction = new TempBasFunction(Name, TempMin, NumberOfChannels); tempBasFunction.SetPmIoForInterlock(PMName, false); Address = SC.GetStringValue($"{ScBasePath}.Address"); _enableLog = SC.GetValue($"TempDevice.EnableLogMessage"); _connection = new StrongTempConnection(Address); _connection.EnableLog(_enableLog); var scOnTime = SC.GetValue($"TempDevice.OnTimer"); _thread = new PeriodicJob(scOnTime, OnTimer, $"{Module}.{Name} MonitorHandler", true); SC.RegisterValueChangedCallback($"TempDevice.OnTimer", (obj) => { _thread.ChangeInterval((int)obj); }); SC.RegisterValueChangedCallback($"TempDevice.EnableLogMessage", (obj) => { _connection.EnableLog((bool)obj); }); } private void IniTemp() { TempDatasArray = new float[NumberOfChannels]; for (int i = 0; i < NumberOfChannels; i++)//初始化温度下限 { int indexer = i; TempDatasArray[indexer] = TempMin; DATA.Subscribe($"Temp.{Name}.t{indexer + 1}", () => TempDatasArray[indexer]); } } private bool OnTimer() { 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(); return true; } HandlerBase handler = null; lock (_locker) { if (_lstHandler.Count == 0) QueryTemp(); if (_lstHandler.Count > 0 && !_connection.IsBusy) { handler = _lstHandler.First.Value; _lstHandler.RemoveFirst(); if (handler != null) { _connection.Execute(handler); } } } } catch (Exception ex) { LOG.Write(ex); } return true; } public void Reset() { _trigCommunicationError.RST = true; } public void ResponseQuery(string name, byte[] data) { try { if (name == "QueryADT") { string sData = Encoding.Default.GetString(data); if (sData.Length < 9) return; if (sData.Contains("*A")) { string sT = sData.Substring(2, 6); TempDatasArray[0] = Convert.ToSingle(sT); } } } catch (Exception ex) { } } 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 void Terminate() { _connection.Disconnect(); } } }