2023-11-02 10:28:53 +08:00
|
|
|
|
using Aitex.Core.RT.DataCenter;
|
|
|
|
|
using Aitex.Core.RT.Device;
|
|
|
|
|
using Aitex.Core.RT.Event;
|
2023-11-02 17:46:03 +08:00
|
|
|
|
using Aitex.Core.RT.IOCore;
|
2023-11-02 10:28:53 +08:00
|
|
|
|
using Aitex.Core.RT.Log;
|
|
|
|
|
using Aitex.Core.RT.SCCore;
|
|
|
|
|
using Aitex.Core.Util;
|
|
|
|
|
using MECF.Framework.Common.Communications;
|
|
|
|
|
using RTOverEthernetDevelopmentKit;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2023-11-03 10:04:22 +08:00
|
|
|
|
using System.Data.Common;
|
2023-11-02 10:28:53 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Xml;
|
2023-11-02 17:46:03 +08:00
|
|
|
|
using System.Xml.Linq;
|
2023-11-02 10:28:53 +08:00
|
|
|
|
|
|
|
|
|
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps
|
|
|
|
|
{
|
2023-11-02 17:46:03 +08:00
|
|
|
|
public class SensorTemp : BaseDevice, IConnection, IDevice, ITempData
|
2023-11-02 10:28:53 +08:00
|
|
|
|
{
|
|
|
|
|
private SensorTempConnection _connection;
|
|
|
|
|
|
|
|
|
|
private TempBasFunction tempBasFunction;
|
2023-11-02 17:46:03 +08:00
|
|
|
|
|
2023-11-02 10:28:53 +08:00
|
|
|
|
private R_TRIG _trigCommunicationError = new R_TRIG();
|
2023-11-02 17:46:03 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 温度不发生变化
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly R_TRIG _trigTempNoChange = new R_TRIG();
|
|
|
|
|
private int TempInvariantCount;
|
|
|
|
|
private int TempInvariantCountMax = 5;
|
|
|
|
|
|
2023-11-02 10:28:53 +08:00
|
|
|
|
private PeriodicJob _thread;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
|
|
|
|
|
|
|
|
|
|
private object _locker = new object();
|
|
|
|
|
|
|
|
|
|
private string PMName;
|
|
|
|
|
|
|
|
|
|
private bool _enableLog = true;
|
|
|
|
|
|
|
|
|
|
public int TempMin { get; set; } = 600;
|
|
|
|
|
|
|
|
|
|
public int NumberOfChannels { get; set; } = 1;
|
|
|
|
|
|
|
|
|
|
public float[] TempDatasArray { get; set; }
|
|
|
|
|
|
|
|
|
|
|
2023-11-02 17:46:03 +08:00
|
|
|
|
|
2023-11-02 10:28:53 +08:00
|
|
|
|
public string Address
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsConnected
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return _connection != null && _connection.IsConnected;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Connect()
|
|
|
|
|
{
|
|
|
|
|
return _connection.Connect();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Disconnect()
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SensorTemp(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void QueryTemp()
|
|
|
|
|
{
|
|
|
|
|
SetQuery("QueryBup", "00mw0\r");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetQuery(string name, string strCmd)
|
|
|
|
|
{
|
|
|
|
|
lock (_locker)
|
|
|
|
|
{
|
|
|
|
|
if (_connection.IsBusy)
|
|
|
|
|
{
|
|
|
|
|
_connection.ForceClear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
byte[] bCmd = Encoding.Default.GetBytes(strCmd);
|
|
|
|
|
|
|
|
|
|
_lstHandler.AddLast(new SensorTempQueryHandler(this, name, bCmd));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public bool Initialize()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (!SC.GetValue<bool>($"{ScBasePath}.EnableDevice"))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
IniData();
|
|
|
|
|
|
|
|
|
|
IniTemp();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void IniData()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//添加参数设置
|
2023-11-02 17:46:03 +08:00
|
|
|
|
PMName = SC.GetStringValue($"{ScBasePath}.PMName");
|
2023-11-02 10:28:53 +08:00
|
|
|
|
|
2023-11-02 17:46:03 +08:00
|
|
|
|
tempBasFunction = new TempBasFunction(Name, TempMin, NumberOfChannels);
|
|
|
|
|
tempBasFunction.SetPmDoForInterlock(PMName, false);
|
2023-11-02 10:28:53 +08:00
|
|
|
|
|
|
|
|
|
Address = SC.GetStringValue($"{ScBasePath}.Address");
|
|
|
|
|
_enableLog = SC.GetValue<bool>($"{Name}.EnableLogMessage");
|
|
|
|
|
|
|
|
|
|
_connection = new SensorTempConnection(Address);
|
|
|
|
|
_connection.EnableLog(_enableLog);
|
2023-11-03 10:04:22 +08:00
|
|
|
|
|
2023-11-02 10:28:53 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var scOnTime = SC.GetValue<int>($"TempDevice.OnTimer");
|
|
|
|
|
_thread = new PeriodicJob(scOnTime, OnTimer, $"{Module}.{Name} MonitorHandler", true);
|
|
|
|
|
|
|
|
|
|
SC.RegisterValueChangedCallback($"TempDevice.OnTimer", (obj) => { _thread.ChangeInterval((int)obj); });
|
2023-11-07 09:45:04 +08:00
|
|
|
|
|
|
|
|
|
SC.RegisterValueChangedCallback($"{ScBasePath}.EnableLogMessage", (obj) => { _connection.EnableLog((bool)obj); });
|
2023-11-02 10:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void IniTemp()
|
|
|
|
|
{
|
|
|
|
|
TempDatasArray = new float[NumberOfChannels];
|
|
|
|
|
|
2023-11-02 17:46:03 +08:00
|
|
|
|
for (int i = 0; i < NumberOfChannels; i++)//初始化温度下限
|
2023-11-02 10:28:53 +08:00
|
|
|
|
{
|
2023-11-02 17:46:03 +08:00
|
|
|
|
int indexer = i;
|
|
|
|
|
TempDatasArray[indexer] = TempMin;
|
|
|
|
|
DATA.Subscribe($"{Name}.t{indexer + 1}", () => TempDatasArray[indexer]);
|
2023-11-02 10:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool OnTimer()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_connection.MonitorTimeout();
|
|
|
|
|
|
|
|
|
|
if (!_connection.IsConnected)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
_lstHandler.Clear();
|
|
|
|
|
|
|
|
|
|
//只要断开,就进行连接
|
|
|
|
|
if (!_connection.Connect())
|
|
|
|
|
{
|
|
|
|
|
_trigCommunicationError.CLK = !_connection.IsConnected;
|
|
|
|
|
if (_trigCommunicationError.Q)
|
|
|
|
|
{
|
2023-11-02 17:46:03 +08:00
|
|
|
|
Thread.Sleep(2000);//不加延时软件刚启动可能不打印
|
|
|
|
|
tempBasFunction.PMPostLog(PMName, $"Can not connect with {_connection.Address}, {Name}", EV.PostAlarmLog);
|
|
|
|
|
tempBasFunction.SetPmDoForInterlock(PMName, true);
|
2023-11-02 10:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else//已连接,自动复位断联信号
|
|
|
|
|
{
|
|
|
|
|
_trigCommunicationError.RST = true;
|
2023-11-02 17:46:03 +08:00
|
|
|
|
tempBasFunction.PMPostLog(PMName, $"{PMName} {Name} {Address} reconnected.", EV.PostInfoLog);
|
|
|
|
|
tempBasFunction.SetPmDoForInterlock(PMName, false);
|
2023-11-02 10:28:53 +08:00
|
|
|
|
}
|
2023-11-02 17:46:03 +08:00
|
|
|
|
Thread.Sleep(1000);//重连延时
|
2023-11-02 10:28:53 +08:00
|
|
|
|
_connection.ForceClear();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lock (_locker)
|
|
|
|
|
{
|
|
|
|
|
if (_lstHandler.Count == 0)
|
|
|
|
|
QueryTemp();
|
|
|
|
|
|
|
|
|
|
if (_lstHandler.Count > 0 && !_connection.IsBusy)
|
|
|
|
|
{
|
|
|
|
|
HandlerBase handler = _lstHandler.First.Value;
|
|
|
|
|
_lstHandler.RemoveFirst();
|
|
|
|
|
if (handler != null)
|
|
|
|
|
_connection.Execute(handler);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-03 10:04:22 +08:00
|
|
|
|
|
|
|
|
|
if (_connection.IsCommunicationError)
|
|
|
|
|
{
|
|
|
|
|
//ResponseError();
|
|
|
|
|
}
|
2023-11-02 10:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LOG.Write(ex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ResponseQuery(string name, byte[] data)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string sData = Encoding.Default.GetString(data);
|
|
|
|
|
if (name == "QueryBup")
|
|
|
|
|
{
|
|
|
|
|
string strTemp = sData;
|
|
|
|
|
if (!sData.Contains("\r"))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
int temp = Convert.ToInt32(strTemp.Replace("\r", ""), 16);
|
|
|
|
|
TempDatasArray[0] = (float)temp / 10;
|
2023-11-02 17:46:03 +08:00
|
|
|
|
TempInvariantCount = tempBasFunction.TempInvariantCount(TempDatasArray, out string tempInvariantData);
|
|
|
|
|
_trigTempNoChange.CLK = TempInvariantCount >= TempInvariantCountMax ? true : false;
|
|
|
|
|
if (_trigTempNoChange.Q)
|
|
|
|
|
{
|
|
|
|
|
tempBasFunction.PMPostLog(PMName, $"{PMName} {Name} {TempInvariantCount} temp no changeCount {tempInvariantData}", EV.PostWarningLog);
|
|
|
|
|
}
|
2023-11-02 10:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ResponseError()
|
|
|
|
|
{
|
2023-11-02 17:46:03 +08:00
|
|
|
|
_trigCommunicationError.CLK = true;
|
|
|
|
|
if (_trigCommunicationError.Q)
|
|
|
|
|
{
|
2023-11-03 10:04:22 +08:00
|
|
|
|
tempBasFunction.PMPostLog(PMName, $"{PMName} {Name} {Address} could not receive temp", EV.PostAlarmLog);
|
2023-11-02 17:46:03 +08:00
|
|
|
|
tempBasFunction.SetPmDoForInterlock(PMName, true);
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-02 10:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Reset()
|
|
|
|
|
{
|
|
|
|
|
_trigCommunicationError.RST = true;
|
2023-11-02 17:46:03 +08:00
|
|
|
|
_trigTempNoChange.RST = true;
|
2023-11-02 10:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Terminate()
|
|
|
|
|
{
|
|
|
|
|
_connection.Disconnect();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|