275 lines
8.9 KiB
C#
275 lines
8.9 KiB
C#
|
|
using Aitex.Core.RT.Event;
|
|||
|
|
using Aitex.Core.RT.Log;
|
|||
|
|
using Aitex.Core.RT.SCCore;
|
|||
|
|
using Aitex.Core.Util;
|
|||
|
|
using System;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Xml;
|
|||
|
|
using RTOverEthernetDevelopmentKit;
|
|||
|
|
|
|||
|
|
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}.ControllerAverageTime"); // 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
|
|||
|
|
}
|
|||
|
|
}
|