Sic.Framework/MECF.Framework.RT.Equipment.../HardwareUnits/Temps/AKunTemp/AKunTemp.cs

365 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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接口上层使用接口获取数据方便以后扩展测温硬件
/// <summary>
/// 昂坤Viper-RTC测温
/// </summary>
public class AKunTemp : BaseDevice, IDevice, IConnection, ITempData
{
#region Variables
private readonly IROverEthernet _ir;
private PeriodicJob _thread;//工作线程
/// <summary>
/// 连接昂坤软件服务器
/// </summary>
private readonly R_TRIG _trigConnServiceError = new R_TRIG();
/// <summary>
/// 机箱USB断联
/// </summary>
private readonly R_TRIG _trigUSBDataError = new R_TRIG();
/// <summary>
/// 机箱USB重连
/// </summary>
private readonly R_TRIG _trigUSBDataOK = new R_TRIG();
private int _lastIntegTime;
public double TempData1 { get; set; } = 600;
public double TempData2 { get; set; } = 600;
public double TempData3 { get; set; } = 600;
public double TempData4 { get; set; } = 600;
public bool IsThreePoint { get; set; } = false;
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<bool>($"{Name}.EnableLogMessage");
_ir = new IROverEthernet();
_trigUSBDataOK.CLK = true;//初始化重连信号
if (SC.GetConfigItem($"{Name}.IsThreePoint").BoolValue)
{
DATA.Subscribe($"PM1.{Name}.Middle", () => TempData1);
DATA.Subscribe($"PM1.{Name}.Outer", () => TempData2);
DATA.Subscribe($"PM1.{Name}.Inner", () => TempData3);
IsThreePoint = true;
}
else
{
DATA.Subscribe($"PM1.{Name}.Middle", () => TempData1);
DATA.Subscribe($"PM1.{Name}.Outer", () => TempData2);
DATA.Subscribe($"PM2.{Name}.Middle", () => TempData3);
DATA.Subscribe($"PM2.{Name}.Outer", () => TempData4);
IsThreePoint = false;
}
}
~AKunTemp()
{
Terminate();
}
#endregion
#region Properties
public string Address
{
get;
private set;
}
private int port { get; set; }
public bool IsConnected => _ir.IsConnected;
/// <summary>
/// 获取系统配置中的积分时间。
/// </summary>
/// <returns></returns>
private int GetScIntegrationTime()
{
var integrationTime = SC.GetValue<int>($"{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}");
IO.DO[$"PM1.DO_PyroCommunicationError"].Value = true;//新增断联后置位DO_220
IO.DO[$"PM2.DO_PyroCommunicationError"].Value = true;
}
}
else//连接成功后不会再进入,只会提示一次
{
_trigConnServiceError.RST = true;
ConnectOK($"Connect OK with AKun Temp Software Form {Address} {Name}");
IO.DO[$"PM1.DO_PyroCommunicationError"].Value = false;//新增连接后复位DO_220
IO.DO[$"PM2.DO_PyroCommunicationError"].Value = false;
}
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;
IO.DO[$"PM1.DO_PyroCommunicationError"].Value = true;//新增断联后置位DO_220
IO.DO[$"PM2.DO_PyroCommunicationError"].Value = true;
return;
}
return;
}
_trigUSBDataOK.CLK = true;
if (_trigUSBDataOK.Q)
{
ConnectOK($"Connect OK with {Name} From USB");
_trigUSBDataError.RST = true;//复位USB断联信号
IO.DO[$"PM1.DO_PyroCommunicationError"].Value = false;//新增连接后复位DO_220
IO.DO[$"PM2.DO_PyroCommunicationError"].Value = false;
}
//有数据时必须复位
CountNum = 0;
}
//解析温度数值
for (var i = 0; i < all.Count; i++)
{
float _temp = all[i].Average();
if (_temp <= 600)//设置温度下限
_temp = 600;
switch (i)
{
case 0: //PM1 Middle
TempData1 = _temp;
break;
case 1: //PM1 Outer
TempData2 = _temp;
break;
case 2: //PM2 Middle
TempData3 = _temp;
break;
case 3: //PM2 Outer
TempData4 = _temp;
break;
default:
break;
}
}
}
catch (Exception ex)
{
LOG.Write($"{Name} AKunTemp GetValues Error {ex}");
}
}
#endregion
#region Events
private void ConnectError(string str)
{
if (SC.GetValue<bool>($"System.SetUp.IsPM1Installed"))
EV.PostAlarmLog("PM1", str);
if (SC.GetValue<bool>($"System.SetUp.IsPM2Installed"))
EV.PostAlarmLog("PM2", str);
}
private void ConnectOK(string str)
{
if (SC.GetValue<bool>($"System.SetUp.IsPM1Installed"))
EV.PostInfoLog("PM1", str);
if (SC.GetValue<bool>($"System.SetUp.IsPM2Installed"))
EV.PostInfoLog("PM2", str);
}
public bool Disconnect()
{
Terminate();
return true;
}
//
#endregion
}
}