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 System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; namespace SicPM.Devices { public enum ConfinementRingStateEnum { Unknown, Up, Down, Error, } public partial class IoConfinementRing : BaseDevice, IDevice { public ConfinementRingStateEnum State { get { if (_diRingUpFaceback.Value &&_diRingDownFaceback.Value) return ConfinementRingStateEnum.Error; if (_diRingUpFaceback.Value && !_diRingDownFaceback.Value) return ConfinementRingStateEnum.Up; if (!_diRingUpFaceback.Value && _diRingDownFaceback.Value) return ConfinementRingStateEnum.Down; return ConfinementRingStateEnum.Unknown; } } private DIAccessor _diRingDownFaceback = null; private DIAccessor _diRingUpFaceback = null; private DIAccessor _diRingResetFaceback = null; private DOAccessor _doRingResetSetpoint = null; enum DeviceState { Idle, MovingUp, MovingDown, Error, Reset, } #region DI public bool RingDownFaceback { get { if (_diRingDownFaceback != null) return _diRingDownFaceback.Value; return false; } } public bool RingUpFaceback { get { if (_diRingUpFaceback != null) return _diRingUpFaceback.Value; return false; } } public bool RingResetFaceback { get { if (_diRingResetFaceback != null) return _diRingResetFaceback.Value; return false; } } #endregion #region DO public bool RingResetSetpoint { get { if (_doRingResetSetpoint != null) return _doRingResetSetpoint.Value; return false; } } #endregion private DeviceState _state = DeviceState.Idle; private DeviceTimer _timer = new DeviceTimer(); private DeviceTimer _timerWarning = new DeviceTimer(); private R_TRIG _trigDown = new R_TRIG(); private R_TRIG _trigUp = new R_TRIG(); private SCConfigItem _scUpTimeout; private SCConfigItem _scDownTimeout; private SCConfigItem _scDownWarnTime; private R_TRIG _trigError = new R_TRIG(); public bool IsUp { get { return _diRingUpFaceback.Value; } } public bool IsDown { get { return _diRingDownFaceback.Value ; } } public bool IsReset { get { return _diRingResetFaceback.Value; } } public AITDeviceData DeviceData { get { AITDeviceData data = new AITDeviceData() { Module = Module, DeviceName = Name, DisplayName = Display, DeviceSchematicId = DeviceID, UniqueName = UniqueName, }; data.AttrValue["RingUpFaceback"] = _diRingUpFaceback.Value; data.AttrValue["RingDownFaceback"] = _diRingDownFaceback.Value; data.AttrValue["RingResetFaceback"] = _diRingResetFaceback.Value; data.AttrValue["RingResetSetpoint"] = _doRingResetSetpoint.Value; return data; } } public IoConfinementRing(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"); _diRingDownFaceback = ParseDiNode("diRingDownFaceback", node, ioModule); _diRingUpFaceback = ParseDiNode("diRingUpFaceback", node, ioModule); _diRingResetFaceback = ParseDiNode("diRingResetFaceback", node, ioModule); _doRingResetSetpoint = ParseDoNode("doRingResetSetpoint", node, ioModule); _scUpTimeout = ParseScNode("ConfinementRingUpTimeOut", node, "PM", "PM.Motion.ConfinementRingUpTimeOut"); _scDownTimeout = ParseScNode("ConfinementRingDownTimeOut", node,"PM", "PM.Motion.ConfinementRingDownTimeOut"); _scDownWarnTime = ParseScNode("ConfinementRingDownWarnTime", node, "PM", "PM.Motion.ConfinementRingDownWarnTime"); } public bool Initialize() { DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData); DATA.Subscribe($"{Module}.{Name}.RingDownFaceback", () => RingDownFaceback); DATA.Subscribe($"{Module}.{Name}.RingUpFaceback", () => RingUpFaceback); DATA.Subscribe($"{Module}.{Name}.RingResetSetpoint", () => RingResetSetpoint); DATA.Subscribe($"{Module}.{Name}.RingResetFaceback", () => RingResetFaceback); return false; } string reason = string.Empty; public bool Reset(out string reason) { if (!_doRingResetSetpoint.SetValue(true, out reason)) return false; _timer.Start(_scDownTimeout.IntValue * 1000); _state = DeviceState.Reset; return true; } public void Monitor() { _trigDown.CLK = _diRingDownFaceback.Value; if (_trigDown.Q) { _trigUp.RST = true; _timerWarning.Start(_scDownWarnTime.IntValue * 1000); } _trigUp.CLK = _diRingUpFaceback.Value; if (_trigUp.Q) { _timerWarning.Stop(); _trigDown.RST = true; } if (_timerWarning.IsTimeout()) { EV.PostAlarmLog(Module, $"Confinement in down position over {_scDownWarnTime.IntValue} s"); _timerWarning.Stop(); } switch (_state) { case DeviceState.Reset: { if (IsUp) { if (!_doRingResetSetpoint.SetValue(false, out string reason)) { LOG.Error($"{Module} reset DO failed, {reason}"); } _state = DeviceState.Idle; }else if (_timer.IsTimeout()) { _timer.Stop(); if (!_doRingResetSetpoint.SetValue(false, out string reason)) { LOG.Error($"{Module} reset DO failed, {reason}"); } EV.PostMessage(Module, EventEnum.DefaultWarning, $"{Module} {Name} Can not Rest Alarm in {_scDownTimeout.IntValue} seconds"); _state = DeviceState.Error; } } break; default: break; } } public void Reset() { _trigError.RST = true; _trigDown.RST = true; _trigUp.RST = true; } public void Terminate() { } } }