MoS2/Framework/MECF.Framework.RT.EquipmentLibrary/Devices/IoSensor.cs
2026-06-15 10:56:30 +08:00

257 lines
8.3 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.Common.DeviceData;
using Aitex.Core.RT.DataCenter;
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 System;
using System.Xml;
namespace Aitex.Core.RT.Device.Devices
{
public class IoSensor : BaseDevice, IDevice
{
private DIAccessor _di = null;
private DOAccessor _do = null;
public DIAccessor SensorDI => _di;
public DOAccessor SensorDO => _do;
private R_TRIG _trigTextOut = new R_TRIG();
private bool _textOutTrigValue;
public bool AlarmTrigValue
{
get { return _textOutTrigValue && !string.IsNullOrEmpty(_alarmText); }
}
private string _warningText;
private string _alarmText;
private string _infoText;
private bool _disabledInServiceMode = false;
private bool _disabledFromSc = false;
private readonly R_TRIG _rTrigDisabledInSc = new();
public Action WarningAction
{
get;
set;
}
public event Action<IoSensor, bool> OnSignalChanged;
public bool Value
{
get
{
if (_di != null)
return _di.Value;
if (_do != null)
return _do.Value;
return false;
}
}
private AITSensorData DeviceData
{
get
{
AITSensorData data = new AITSensorData()
{
DeviceName = Name,
DeviceSchematicId = DeviceID,
DisplayName = Display,
Value = Value,
};
return data;
}
}
private bool _previous;
public IoSensor(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
{
_di = ParseDiNode("di", node, ioModule);// IO.DI[node.GetAttribute("di")];
_do = ParseDoNode("do", node, ioModule);
_infoText = node.GetAttribute("infoText");
_warningText = node.GetAttribute("warningText");
_alarmText = node.GetAttribute("alarmText");
_disabledInServiceMode = (node.GetAttribute("DisInServiceMode") ?? "") == "true";
if(_disabledInServiceMode)
LOG.Warning($"{UniqueName} will be disabled in service mode");
if (Name == "SensorMFC07Offline" || Name == "SensorMFC08Offline")
{
if (!SC.GetValue<bool>($"PM.{Module}.TMAEnable"))
{
_alarmText = "";
}
}
_textOutTrigValue = Convert.ToBoolean(string.IsNullOrEmpty(node.GetAttribute("textOutTrigValue")) ? "false" : node.GetAttribute("textOutTrigValue"));
if (!string.IsNullOrEmpty(node.GetAttribute("scBasePath"))) //配置ScBasePath时使用配置信息
{
GetTextValue();
SC.RegisterValueChangedCallback($"{ScBasePath}.{Name}.AlarmType", (obj) => GetTextValue());
SC.RegisterValueChangedCallback($"{ScBasePath}.{Name}.Text", (obj) => GetTextValue());
SC.RegisterValueChangedCallback($"{ScBasePath}.{Name}.TrigValue", (obj) => GetTextValue());
SC.RegisterValueChangedCallback($"{ScBasePath}.{Name}.IsEnable", (obj) => GetTextValue());
// e.g. TM.IoSensor.{Name}.Disable
var scPath = $"{ScBasePath}.{Name}.Disable";
_disabledFromSc = SC.SafeGetValue(scPath, false);
SC.RegisterValueChangedCallback(scPath, (obj) =>
{
if (obj is bool isDisable)
_disabledFromSc = isDisable;
else
_disabledFromSc = false;
});
}
}
private string GetTrigValue(XmlElement node, string xmlNodeName, string scName)
{
var xmlNodeValue = node.GetAttribute(xmlNodeName);
return string.IsNullOrEmpty(xmlNodeValue) ? SC.GetStringValue($"{ScBasePath}.{Name}.{scName}") : xmlNodeValue;
}
private void GetTextValue()
{
var typ = SC.GetStringValue($"{ScBasePath}.{Name}.AlarmType");
var text = SC.GetStringValue($"{ScBasePath}.{Name}.Text");
_textOutTrigValue = SC.GetValue<bool>($"{ScBasePath}.{Name}.TrigValue");
if (!SC.SafeGetValue($"{ScBasePath}.{Name}.IsEnable", false))
text = "";
_ = typ switch
{
"Info" => _infoText = text,
"Warning" => _warningText = text,
"Alarm" => _alarmText = text,
_ => ""
};
}
public bool Initialize()
{
DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
DATA.Subscribe($"{Module}.{Name}.Value", () => Value);
return true;
}
public void Terminate()
{
}
protected override void HandleMonitor()
{
try
{
#region Sensor
if (_disabledFromSc)
{
_rTrigDisabledInSc.CLK = true;
if (_rTrigDisabledInSc.Q)
LOG.Warning($"{UniqueName} is disabled in system config, please check '{ScBasePath}.{Name}.Disabled'");
return; // 当前IoSenser设置为不侦测报警
}
else
{
_rTrigDisabledInSc.CLK = false;
}
#endregion
#region Service模式Bypass报警
if (_disabledInServiceMode)
{
// 检查{Module}.IsService数据是否不存在如果不存在跳过下面步骤
var dataPath = $"{Module}.IsService";
var isServiceMode = false;
lock (LockNonExistedServiceData)
{
if (!NonExistedServiceData.Contains(dataPath))
{
// 检查所属Module是否为Service模式如果是不报警
var objIsService = DATA.Poll(dataPath);
if (objIsService is not bool bValue)
{
NonExistedServiceData.Add(dataPath);
LOG.Warning(
$"{UniqueName} Unable to poll data '{Module}.IsService', service mode detection will be discontinued in future monitoring");
}
else
{
isServiceMode = bValue;
}
}
}
// 如果是Service模式不报警
if (isServiceMode)
{
return;
}
}
#endregion
_trigTextOut.CLK = (Value == _textOutTrigValue);
if (_trigTextOut.Q)
{
if (WarningAction != null)
{
WarningAction();
}
else if (!string.IsNullOrEmpty(_warningText.Trim()))
{
EV.PostWarningLog(Module, _warningText);
}
else if (!string.IsNullOrEmpty(_alarmText.Trim()))
{
EV.PostAlarmLog(Module, _alarmText);
}
else if (!string.IsNullOrEmpty(_infoText.Trim()))
{
EV.PostInfoLog(Module, _infoText);
}
}
if (_previous != Value)
{
if (OnSignalChanged != null)
OnSignalChanged(this, Value);
_previous = Value;
}
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
public void Reset()
{
_trigTextOut.RST = true;
}
}
}