Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../HardwareUnits/Temps/AKunTemp/AKunTemp.cs

275 lines
8.8 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.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using RTOverEthernetDevelopmentKit;
using System;
using System.Linq;
using System.Threading;
using System.Xml;
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 : TempSensorBase
{
#region Variables
private IROverEthernet _ir;
/// <summary>
/// 连接昂坤软件服务器
/// </summary>
private readonly R_TRIG _trigConnServiceError = new();
/// <summary>
/// 机箱USB断联
/// </summary>
private readonly R_TRIG _trigUSBDataError = new();
/// <summary>
/// 机箱USB重连
/// </summary>
private readonly R_TRIG _trigUSBDataOK = new();
private int _lastIntegTime;
#endregion Variables
#region Constructors
public AKunTemp(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
{
RTrigs.Add(_trigConnServiceError);
RTrigs.Add(_trigUSBDataError);
RTrigs.Add(_trigUSBDataOK);
}
#endregion
#region Properties
private int Port { get; set; }
public override bool IsConnected => _ir.IsConnected;
#endregion
#region Methods
/// <summary>
/// 获取系统配置中的积分时间。
/// </summary>
/// <returns></returns>
private int GetScIntegrationTime()
{
var integrationTime = SC.GetValue<int>($"{ScBasePath}.{Name}.AverageTime"); // the minimum value should be 10ms.
if (integrationTime < 10)
integrationTime = 10;
return integrationTime;
}
public override bool Connect()
{
try
{
if (IsSimMode)
return true;
_ir.Init(Address, Port);
_ir.StopIR();
_lastIntegTime = GetScIntegrationTime();
_ir.SetIntegrationTime(_lastIntegTime);
_ir.StartIR();
return true;
}
catch (Exception ex)
{
return false;
}
}
private void Reconnect()
{
try
{
if (IsSimMode)
return;
_ir.Close();
}
catch
{
// ignored
}
finally
{
Connect();
}
}
protected override bool HandleInitialize()
{
InitAKunController();
return true;
}
private void InitAKunController()
{
if (IsSimMode)
return;
var data = SC.GetStringValue($"{ScBasePath}.{Name}.Address").Split(':');
Address = data[0];
Port = Convert.ToInt32(data[1]);
_ir = new IROverEthernet();
_trigUSBDataOK.CLK = true;//初始化重连信号
SC.RegisterValueChangedCallback($"{ScBasePath}.{Name}.ControllerAverageTime",
SetControllerAverageTime);
}
private void SetControllerAverageTime(object time)
{
if (IsSimMode)
return;
if (time != null && int.TryParse(time.ToString(), out var avt))
{
_ir.StopIR();
_ir.SetIntegrationTime(avt);
_ir.StartIR();
}
else
{
LOG.Error($"Unable to set {Name} controller average time, the parameter {time} is not a integer.");
}
}
private int _usbReConnCnt = 0;//接受数据失败次数
private double[] ReadTemp()
{
try
{
if (IsSimMode)
return null;
var allChannel = _ir.GetAllChannel();
//USB线断联和重连逻辑
{
//连接时使用次数报警,多次接收到空数据开始报警 此时发现正常连接时Count=0会出现频率是几分钟出现一次
if (allChannel.FirstOrDefault(ch => ch == null || !ch.Any()) != null || // 某个通道没有数据
_ir.Current.Status != 0) //首次打开上位机时测试昂坤软件打开且未连接USB时Count一直大于0所以此处添加厂商提供的属性值判断USB连接
{
_usbReConnCnt++;
if (_usbReConnCnt <= 10)
return null;
_trigUSBDataOK.CLK = false; //复位USB重连信号
_trigUSBDataError.CLK = true;
if (_trigUSBDataError.Q)
TempBasFunction.PM1PM2PostLog(
$"Can not connect with {Name} From USB,Status:{_ir.Current.Status}",
EV.PostAlarmLog);
_usbReConnCnt = 0;
TempBasFunction.SetPm1Pm2IoForInterlock(true);
return null;
}
_trigUSBDataOK.CLK = true;
if (_trigUSBDataOK.Q)
{
TempBasFunction.PM1PM2PostLog($"Connect OK with {Name} From USB", EV.PostInfoLog);
_trigUSBDataError.RST = true;//复位USB断联信号
TempBasFunction.SetPm1Pm2IoForInterlock(false);
}
//有数据时必须复位
_usbReConnCnt = 0;
}
return allChannel.Select(ch => (double)ch.Average()).ToArray();
}
catch (Exception ex)
{
LOG.Write($"{Name} Read controller error, {ex}");
return null;
}
}
protected override double[] HandleReadTemp()
{
try
{
//判断昂坤软件服务器断联和重连逻辑
if (_ir.IsConnected)
return ReadTemp();
Reconnect();
if (!_ir.IsConnected)//昂坤软件的服务器未打开
{
_trigConnServiceError.CLK = true;
if (_trigConnServiceError.Q)
{
Thread.Sleep(2000);//不加延时软件刚启动可能不打印
TempBasFunction.PM1PM2PostLog($"AKun Temp Software Maybe Not Open {Address} {Name}", EV.PostAlarmLog);
TempBasFunction.SetPm1Pm2IoForInterlock(true);
}
}
else//连接成功后不会再进入,只会提示一次
{
_trigConnServiceError.RST = true;
TempBasFunction.PM1PM2PostLog($"Connect OK with AKun Temp Software Form {Address} {Name}", EV.PostInfoLog);
TempBasFunction.SetPm1Pm2IoForInterlock(false);
}
Thread.Sleep(1000);
return null;
}
catch (Exception ex)
{
if (_trigConnServiceError.Q)
{
TempBasFunction.PM1PM2PostLog($"{this} Unable to read data from viper RTC, {ex.Message}", EV.PostAlarmLog);
}
return null;
}
}
public override void Terminate()
{
try
{
if (IsSimMode)
return;
_ir.Close();
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
public override bool Disconnect()
{
Terminate();
return true;
}
#endregion
}
}