using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Global; using MECF.Framework.Common.Communications; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK; using RTOverEthernetDevelopmentKit; using SessionLayer; using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps { /// 昂坤Viper-RTC测温数据交互流程简介 /// 1:上位机连接昂坤软件启动的服务器,昂坤服务器启用 工控机的IP + 53888固定端口,上位机连接服务器获取温度数据 /// 2:昂坤软件通过USB线连接主机盒子获取温度,上位机不用干预 /// 3:昂坤通讯特性,上位机发送一条指令后,服务器会一直安装设定频率,一直发送数据,上位机只接受就可以了 /// 4:上位机读取数据,通过昂坤提供的库,调用连接和数据获取方法 /// 5:断联分为昂坤软件服务器、USB两种断联和重连判断,例如:昂坤软件未打开或UBS线松动 /// 6:继承ITempData接口,上层使用接口获取数据,方便以后扩展测温硬件 /// /// 昂坤Viper-RTC测温 /// public class AKunTemp : BaseDevice, IDevice, IConnection, ITempData { #region Variables private readonly IROverEthernet _ir; private PeriodicJob _thread;//工作线程 /// /// 连接昂坤软件服务器 /// private readonly R_TRIG _trigConnServiceError = new R_TRIG(); /// /// 机箱USB断联 /// private readonly R_TRIG _trigUSBDataError = new R_TRIG(); /// /// 机箱USB重连 /// private readonly R_TRIG _trigUSBDataOK = new R_TRIG(); private int _lastIntegTime; public double TempData1 { get; set; } public double TempData2 { get; set; } public double TempData3 { get; set; } public double TempData4 { get; set; } bool _enableLog; #endregion #region Constructors public AKunTemp(string module, string name) : base(module, name, name, name) { string[] data = SC.GetStringValue($"{Name}.Address").Split(':'); Address = data[0]; port = Convert.ToInt32(data[1]); _enableLog = SC.GetValue($"{Name}.EnableLogMessage"); _ir = new IROverEthernet(); _trigUSBDataOK.CLK = true;//初始化重连信号 DATA.Subscribe($"PM1.{Name}.Middle", () => TempData1); DATA.Subscribe($"PM1.{Name}.Outer", () => TempData2); DATA.Subscribe($"PM1.{Name}.Inner", () => TempData3); //DATA.Subscribe($"PM2.{Name}.Outer", () => TempData4); } ~AKunTemp() { Terminate(); } #endregion #region Properties public string Address { get; private set; } private int port { get; set; } public bool IsConnected => _ir.IsConnected; #endregion #region Methods /// /// 获取系统配置中的积分时间。 /// /// private int GetScIntegrationTime() { var integrationTime = SC.GetValue($"{Name}.IntegrationTime"); // the minimum value should be 10ms. if (integrationTime < 10) integrationTime = 10; return integrationTime; } public bool Connect() { try { _ir.Init(Address, port); _lastIntegTime = GetScIntegrationTime(); _ir.SetIntegrationTime(_lastIntegTime); _ir.StartIR(); return true; } catch (Exception ex) { return false; } } private void Reconnect() { try { _ir.Close(); } catch { } finally { Connect(); } } private bool OnTimer() { try { //判断昂坤软件服务器断联和重连逻辑 if (!_ir.IsConnected) { Reconnect(); if (!_ir.IsConnected)//昂坤软件的服务器未打开 { _trigConnServiceError.CLK = true; if (_trigConnServiceError.Q) { System.Threading.Thread.Sleep(2000);//不加延时软件刚启动可能不打印 ConnectError($"AKun Temp Software Maybe Not Open {Address} {Name}"); } } else//连接成功后不会再进入,只会提示一次 { _trigConnServiceError.RST = true; ConnectOK($"Connect OK with AKun Temp Software Form {Address} {Name}"); } System.Threading.Thread.Sleep(2000); return true; } //使用厂商提供的属性值判断是否断联,反映时间慢 //判断USB断联和重连 服务器未连接时不用判断USB //if(_ir.Current.Status == 0)//Current.Status昂坤提供的SUB断联属性,测试发现大约1分钟左右才会提示断联 //{ // _trigUSBDataOK.CLK = true;//USB连接提示,置起 // if (_trigUSBDataOK.Q) // { // ConnectOK($"{Module} Connect OK with {Name} From USB"); // } // _trigUSBDataError.RST = true; //} //else //{ // _trigUSBDataOK.RST = true;//复位USB重连信号,准备下次使用 // _trigUSBDataError.CLK = true;//置位USB断联信号,准备报警 // if (_trigUSBDataError.Q) // { // System.Threading.Thread.Sleep(2000); // ConnectError($"{Module} Can not connect with {Name} From USB"); // } // return true; //} //上面判断都没问题就可以读取温度了 GetValues(); return true; } catch (Exception ex) { if (_trigConnServiceError.Q) { EV.PostAlarmLog(Module, $"Unable to read data from viper RTC, {ex.Message}"); } return true; } } public bool Initialize() { try { _thread = new PeriodicJob(300, OnTimer, "AKunTemp", true); return true; } catch (Exception ex) { LOG.Error(ex.Message, ex); return false; } } public void Monitor() { } public void Terminate() { try { _ir.Close(); } catch (Exception ex) { LOG.Write(ex); } } public void Reset() { _trigConnServiceError.RST = true; _trigUSBDataError.RST = true; } int CountNum = 0;//接受数据失败次数 private void GetValues() { try { var all = _ir.GetAllChannel(); //USB线断联和重连逻辑 { //连接时使用次数报警,多次接收到空数据开始报警 ,此时发现正常连接时Count=0会出现,频率是几分钟出现一次 if ( (all[0].Count == 0 && all[1].Count == 0 && all[2].Count == 0 && all[3].Count == 0) || _ir.Current.Status != 0)//首次打开上位机时,测试昂坤软件打开且未连接USB时,Count一直大于0,所以此处添加厂商提供的属性值判断USB连接 { CountNum++; if (CountNum > 10) { _trigUSBDataOK.CLK = false;//复位USB重连信号, _trigUSBDataError.CLK = true; if (_trigUSBDataError.Q) ConnectError($"Can not connect with {Name} From USB"); CountNum = 0; return; } return; } _trigUSBDataOK.CLK = true; if (_trigUSBDataOK.Q) { ConnectOK($"Connect OK with {Name} From USB"); _trigUSBDataError.RST = true;//复位USB断联信号 } //有数据时必须复位 CountNum = 0; } //解析温度数值 for (var i = 0; i < all.Count; i++) { float _temp= all[i].Average(); if (_temp <= 400)//设置温度下限 _temp = 400; switch (i) { case 0: //PM1 Middle TempData1 = _temp; break; case 1: //PM1 Outer TempData2 = _temp; break; case 2: //PM1 Inner TempData3 = _temp; break; case 3: TempData4 = _temp; break; default: break; } } LOG.Write($"{Name} Middle{TempData1} Outer{TempData2} PM1 Inner{TempData3} TempData4 {TempData4}"); } catch (Exception ex) { LOG.Write($"{Name} AKunTemp GetValues Error {ex}"); } } #endregion #region Events private void ConnectError(string str) { if (SC.GetValue($"System.SetUp.IsPM1Installed")) EV.PostAlarmLog("PM1", str); if (SC.GetValue($"System.SetUp.IsPM2Installed")) EV.PostAlarmLog("PM2", str); } private void ConnectOK(string str) { if (SC.GetValue($"System.SetUp.IsPM1Installed")) EV.PostInfoLog("PM1", str); if (SC.GetValue($"System.SetUp.IsPM2Installed")) EV.PostInfoLog("PM2", str); } public bool Disconnect() { Terminate(); return true; } // #endregion } }