123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- using System;
- using System.Collections.Generic;
- 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.Util;
- namespace Aitex.Core.RT.Device.Unit
- {
- public class IoCylinder : BaseDevice, IDevice
- {
- private readonly DIAccessor _diON;
- private readonly DIAccessor _diOFF;
- private readonly DOAccessor _doON;
- private readonly DOAccessor _doOFF;
- private CylinderState _operation;
- private readonly DeviceTimer _timer = new DeviceTimer();
- private readonly R_TRIG _trigReset = new R_TRIG();
- private readonly R_TRIG _trigError = new R_TRIG();
- private readonly R_TRIG _trigCylinderStateError = new R_TRIG();
- private readonly R_TRIG _trigCylinderStateOpen = new R_TRIG();
- private readonly R_TRIG _trigCylinderStateClose = new R_TRIG();
- private readonly R_TRIG _trigCylinderStateUnknown = new R_TRIG();
- public bool EnableOpen { get; set; }
- public bool EnableClose { get; set; }
- private string _error = null;
- public int SetPoint
- {
- get
- {
- if (_doON.Value && _doOFF.Value) return (int)CylinderState.Error;
- if (_doON.Value && !_doOFF.Value) return (int)CylinderState.Open;
- if (!_doON.Value && _doOFF.Value) return (int)CylinderState.Close;
- if (!_doON.Value && !_doOFF.Value) return (int)CylinderState.Unknown;
- return (int)CylinderState.Unknown;
- }
- }
- private void SetOtherCylinderStateRst(R_TRIG curTrig)
- {
- List<R_TRIG> list = new List<R_TRIG>() { _trigCylinderStateError, _trigCylinderStateOpen, _trigCylinderStateClose, _trigCylinderStateUnknown };
- list.Remove(curTrig);
- list.ForEach(p => p.RST = true);
- }
- public CylinderState State
- {
- get
- {
- if (_diON != null && _diOFF != null)
- {
- if (ONFeedback && _diOFF.Value)
- {
- _trigCylinderStateError.CLK = ONFeedback && _diOFF.Value;
- if (_trigCylinderStateError.Q) LOG.Info($"{Module} {Name} cylinder state error");
- SetOtherCylinderStateRst(_trigCylinderStateError);
- return CylinderState.Error;
- }
- if (ONFeedback && !_diOFF.Value)
- {
- _trigCylinderStateOpen.CLK = ONFeedback && !_diOFF.Value;
- if (_trigCylinderStateOpen.Q) LOG.Info($"{Module} {Name} cylinder state open");
- SetOtherCylinderStateRst(_trigCylinderStateOpen);
- return CylinderState.Open;
- }
- if (!ONFeedback && _diOFF.Value)
- {
- _trigCylinderStateClose.CLK = !ONFeedback && _diOFF.Value;
- if (_trigCylinderStateClose.Q) LOG.Info($"{Module} {Name} cylinder state close");
- SetOtherCylinderStateRst(_trigCylinderStateClose);
- return CylinderState.Close;
- }
- if (!ONFeedback && !_diOFF.Value)
- {
- _trigCylinderStateUnknown.CLK = !ONFeedback && !_diOFF.Value;
- if (_trigCylinderStateUnknown.Q) LOG.Info($"{Module} {Name} cylinder state unknown");
- SetOtherCylinderStateRst(_trigCylinderStateUnknown);
- return CylinderState.Unknown;
- }
- }
- return CylinderState.Unknown;
- }
- }
- public bool ONFeedback
- {
- get { return _diON != null && _diON.Value; }
- }
- public bool OFFFeedback
- {
- get { return _diOFF != null && _diOFF.Value; }
- }
- public bool ONSetPoint
- {
- get
- {
- return _doON != null && _doON.Value;
- }
- private set
- {
- if (_doON != null && _doON.Check(value, out _error))
- {
- LOG.Write(_error);
- _doON.Value = value;
- }
- }
- }
- public bool OFFSetPoint
- {
- get
- {
- return _doOFF != null && _doOFF.Value;
- }
- private set
- {
- if (_doOFF != null && _doOFF.Check(value, out _error))
- {
- LOG.Write(_error);
- _doOFF.Value = value;
- }
- }
- }
- private AITCylinderData DeviceData
- {
- get
- {
- return new AITCylinderData
- {
- Module = Module,
- DeviceName = Name,
- DeviceSchematicId = DeviceID,
- DisplayName = Display,
- OpenFeedback = ONFeedback,
- CloseFeedback = OFFFeedback,
- OpenSetPoint = ONSetPoint,
- CloseSetPoint = OFFSetPoint
- };
- }
- }
- private object _locker = new object();
- public IoCylinder(string module, XmlElement node, string ioModule = "")
- {
- base.Module = module;
- base.Name = node.GetAttribute("id");
- base.Display = node.GetAttribute("display");
- base.DeviceID = node.GetAttribute("schematicId");
- _operation = CylinderState.Unknown;
- _diON = ParseDiNode("diON", node, ioModule);
- _diOFF = ParseDiNode("diOFF", node, ioModule);
- _doON = ParseDoNode("doON", node, ioModule);
- _doOFF = ParseDoNode("doOFF", node, ioModule);
- }
- public bool Initialize()
- {
- DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
- OP.Subscribe($"{Module}.{Name}.{AITCylinderOperation.Open}", (s, objects) => SetCylinder(true, out _));
- OP.Subscribe($"{Module}.{Name}.{AITCylinderOperation.Close}", (s, objects) => SetCylinder(false, out _));
- OP.Subscribe($"{Module}.{Name}.{AITCylinderOperation.SetState}", (out string reason, int time, object[] param) =>
- {
- bool isUp = (string)param[0] == "Up" ? true : false;
- SetCylinder(isUp, out reason);
- return true;
- });
- DEVICE.Register($"{Module}.{Name}.{AITCylinderOperation.Open}",
- (out string reason, int time, object[] param) => SetCylinder(true, out reason));
- DEVICE.Register($"{Module}.{Name}.{AITCylinderOperation.Close}",
- (out string reason, int time, object[] param) => SetCylinder(false, out reason));
- return true;
- }
- public void Terminate()
- {
- OFFSetPoint = false;
- ONSetPoint = false;
- }
- public bool SetCylinder(bool isOpen, out string reason)
- {
- reason = "";
- if (isOpen && State == CylinderState.Open)
- {
- LOG.Write($"检查到气缸 {Name} 已经开,该状态是当前信号下发之前的状态。");
- //EV.PostInfoLog(Module, $"检查到气缸 {Name} 已经开");
- //return true;
- }
- if (!isOpen && State == CylinderState.Close)
- {
- LOG.Write($"检查到气缸 {Name} 已经关,该状态是当前信号下发之前的状态。");
- //EV.PostInfoLog(Module, $"检查到气缸 {Name} 已经关");
- //return true;
- }
- lock (_locker)
- {
- _timer.Start(5 * 1000);
- ONSetPoint = isOpen;
- reason += _error;
- reason += " ";
- OFFSetPoint = !isOpen;
- reason += _error;
- _operation = isOpen ? CylinderState.Open : CylinderState.Close;
- }
- EV.PostInfoLog(Module, $"{(isOpen ? "打开" : "关闭")} 气缸 {Name}");
- if(Name== "LiftPin1")
- {
- }
- if (Name == "SlitDoor1")
- {
- }
- return true;
- }
- public void Monitor()
- {
- try
- {
- lock (_locker)
- {
- if (_timer.IsTimeout())
- {
- _timer.Stop();
- if (State != _operation)
- {
- if (_operation == CylinderState.Open)
- {
- if (!_doON.Check(true, out var reason))
- EV.PostAlarmLog(Module, $"{Name} 气缸信号无法打开, interlock, " + reason);
- else
- EV.PostAlarmLog(Module, $"{Name} 气缸信号仍然关闭");
- }
- else
- {
- if (!_doON.Check(false, out var reason))
- EV.PostAlarmLog(Module, $"{Name} 气缸信号无法关闭, interlock, " + reason);
- else
- EV.PostAlarmLog(Module, $"{Name} 气缸信号仍然打开");
- }
- }
- _operation = (CylinderState)SetPoint;
- }
- else if (_timer.IsIdle())
- {
- _trigReset.CLK = SetPoint != (int)_operation; // fire event only check at first, SetPoint set by interlock
- if (_trigReset.Q)
- {
- if (_operation == CylinderState.Open)
- {
- EV.PostAlarmLog(Module, !_doON.Check(true, out var reason)
- ? $"气缸信号 {Display} was Close,Reason:{reason}"
- : $"气缸信号 {Display} was Close,Reason PLC kept");
- }
- else
- {
- EV.PostAlarmLog(Module, !_doON.Check(false, out var reason)
- ? $"气缸信号 {Display} was Open,Reason:{reason}"
- : $"气缸信号 {Display} was Open,Reason PLC Kept");
- }
- _operation = (CylinderState)SetPoint;
- }
- }
- }
- _trigError.CLK = State == CylinderState.Error;
- if (_trigError.Q)
- {
- EV.PostAlarmLog(Module, $"{Name} 气缸状态错误");
- }
- //if ((SetPoint == (int)State) && (SetPoint == (int)CylinderState.Open || SetPoint == (int)CylinderState.Close))
- //{
- // OFFSetPoint = false;
- // ONSetPoint = false;
- //}
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- }
- }
- public void Reset()
- {
- _trigReset.RST = true;
- _trigError.RST = true;
- _trigCylinderStateError.RST = true;
- _trigCylinderStateOpen.RST = true;
- _trigCylinderStateClose.RST = true;
- _trigCylinderStateUnknown.RST = true;
- }
- }
- }
|