Sic.Framework/MECF.Framework.RT.Equipment.../Unit/IoPump2.cs

290 lines
8.8 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
using System;
using System.Diagnostics;
using System.Xml;
using Aitex.Core.Common.DeviceData;
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.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Event;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Pumps;
namespace Aitex.Core.RT.Device.Unit
{
/// <summary>
/// 泵2对应的IO要求
/// diRunning 【如果未定义,默认泵为常开】
/// diOverloadAlarm【可以不定义】
///
/// doResetError【可以不定义】
/// doStartStop【可以不定义】
/// doPowerOn【可以不定义默认主电源常供】
/// </summary>
public class IoPump2 : BaseDevice, IDevice, IPump
{
public bool IsRunning
{
get
{
if (_diRunning != null)
return _diRunning.Value;
return true;
}
}
public bool IsPumpOverloadAlarm
{
get
{
return _diOverloadAlarm != null && _diOverloadAlarm.Value;
}
}
public bool ResetErrorSetPoint
{
get
{
return _doResetError != null && _doResetError.Value;
}
set
{
if (_doResetError!=null)
_doResetError.Value = value;
}
}
public bool StartSetPoint
{
get
{
return _doStart != null && _doStart.Value;
}
set
{
if (_doStart != null)
_doStart.Value = value;
}
}
public bool MainPowerOnSetPoint
{
get
{
return _doPowerOn != null && _doPowerOn.Value;
}
set
{
if (_doPowerOn != null)
_doPowerOn.Value = value;
}
}
private AITPumpData DeviceData
{
get
{
AITPumpData data = new AITPumpData()
{
DeviceName = Name,
DeviceSchematicId = DeviceID,
DisplayName = Display,
DeviceModule = Module,
Module = Module,
IsOn = IsRunning,
IsError = HasAlarm,
IsOverLoad = IsPumpOverloadAlarm,
};
return data;
}
}
private DIAccessor _diRunning = null;
private DIAccessor _diOverloadAlarm;
private DOAccessor _doStart;
private DOAccessor _doPowerOn;
private DOAccessor _doResetError;
private R_TRIG _trigOverload = new R_TRIG();
public AlarmEventItem AlarmOverload { get; set; }
public AlarmEventItem AlarmFailedStartStop { get; set; }
private Stopwatch _timerResetError = new Stopwatch();
private Stopwatch _timerStartStop = new Stopwatch();
private SCConfigItem _scStartTimeout;
private SCConfigItem _scResetErrorTimeout;
public IoPump2(string module, XmlElement node, string ioModule = "")
{
var attrModule = node.GetAttribute("module");
base.Module = string.IsNullOrEmpty(attrModule) ? module : attrModule;
base.Name = node.GetAttribute("id");
base.Display = node.GetAttribute("display");
base.DeviceID = node.GetAttribute("schematicId");
_diRunning = ParseDiNode("diRunning", node, ioModule);
_diOverloadAlarm = ParseDiNode("diOverloadAlarm", node, ioModule);
_doStart = ParseDoNode("doStartStop", node, ioModule);
_doPowerOn = ParseDoNode("doPowerOn", node, ioModule);
_doResetError = ParseDoNode("doReset", node, ioModule);
string scBasePath = node.GetAttribute("scBasePath");
if (string.IsNullOrEmpty(scBasePath))
scBasePath = $"{Module}.{Name}";
else
{
scBasePath = scBasePath.Replace("{module}", Module);
}
_scStartTimeout = ParseScNode("", node, ioModule, $"{scBasePath}.{Name}.StartTimeout");
_scResetErrorTimeout = ParseScNode("", node, ioModule, $"{scBasePath}.{Name}.ResetErrorTimeout");
System.Diagnostics.Debug.Assert(_scResetErrorTimeout != null, "SC not defined");
System.Diagnostics.Debug.Assert(_scStartTimeout != null, "SC not defined");
}
public bool Initialize()
{
DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
DATA.Subscribe($"{Module}.{Name}.IsOverload", () => IsPumpOverloadAlarm);
DATA.Subscribe($"{Module}.{Name}.IsRunning", () => IsRunning);
DATA.Subscribe($"{Module}.{Name}.StartSetPoint", () => StartSetPoint);
OP.Subscribe($"{Module}.{Name}.{AITPumpOperation.SetOnOff}" , SetPumpOnOff);
OP.Subscribe($"{Module}.{Name}.{AITPumpOperation.PumpOn}", SetPumpOn);
OP.Subscribe($"{Module}.{Name}.{AITPumpOperation.PumpOff}", SetPumpOff);
AlarmOverload = SubscribeAlarm($"{Module}.{Name}.OverloadAlarm", "", ResetOverload);
AlarmFailedStartStop = SubscribeAlarm($"{Module}.{Name}.FailedStartStopAlarm", "", null);
return true;
}
private bool SetPumpOn(out string reason, int time, object[] param)
{
return SetPump(out reason, time, true);
}
private bool SetPumpOff(out string reason, int time, object[] param)
{
return SetPump(out reason, time, false);
}
private bool SetPumpOnOff(out string reason, int time, object[] param)
{
return SetPump(out reason, time, Convert.ToBoolean((string)param[0]));
}
public bool SetMainPowerOnOff(bool isOn, out string reason)
{
MainPowerOnSetPoint = isOn;
reason = string.Empty;
return true;
}
public bool ResetOverload()
{
if (IsPumpOverloadAlarm)
{
if (!ResetErrorSetPoint)
{
_timerResetError.Restart();
ResetErrorSetPoint = true;
}
}
return !IsPumpOverloadAlarm;
}
public bool SetPump(out string reason, int time, bool isOn)
{
if (HasAlarm)
{
reason = $"{Display} Has active alarm, reset error first.";
return false;
}
reason = string.Empty;
_timerStartStop.Restart();
StartSetPoint = isOn;
return true;
}
public void Terminate()
{
}
public void Monitor()
{
try
{
if (StartSetPoint != IsRunning)
{
if (_timerStartStop.IsRunning &&
_timerStartStop.ElapsedMilliseconds > _scStartTimeout.IntValue * 1000)
{
var onoff = StartSetPoint ? "start up" : "shut down";
_timerStartStop.Stop();
AlarmFailedStartStop.Description =
$"{Display} can not {onoff} in {_scStartTimeout.IntValue} seconds";
AlarmFailedStartStop.Set();
StartSetPoint = IsRunning;
}
}
_trigOverload.CLK = IsPumpOverloadAlarm;
if (_trigOverload.Q)
{
AlarmOverload.Set("Pump Overload or Error");
StartSetPoint = false;
}
if (ResetErrorSetPoint)
{
if (!IsPumpOverloadAlarm)
{
AlarmOverload.Reset();
ResetErrorSetPoint = false;
_timerResetError.Stop();
}
if (IsPumpOverloadAlarm && _timerResetError.IsRunning &&
_timerResetError.ElapsedMilliseconds > _scResetErrorTimeout.IntValue * 1000)
{
_timerResetError.Stop();
EV.PostWarningLog(Module, $"Can not reset {Display} error in {_scResetErrorTimeout.IntValue} seconds");
ResetErrorSetPoint = false;
}
}
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
public void Reset()
{
AlarmFailedStartStop.Reset();
AlarmOverload.Reset();
}
}
}