using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Beckhoff.ModuleIO; using MECF.Framework.Common.CommonData.Transporter; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.ToolLayout; using MECF.Framework.Common.TwinCat; using CyberX8_Core; using CyberX8_RT.Devices.AXIS; using CyberX8_RT.Devices.AXIS.CANOpen; using System; using System.Collections.Generic; using System.Linq; using System.Net.NetworkInformation; using System.Reflection; using System.Text; using System.Threading.Tasks; using CyberX8_RT.Devices.BarcodeReader; using MECF.Framework.Common.IOCore; namespace CyberX8_RT.Devices.TransPorter { public class TransporterCommon : BaseDevice, IDevice { private enum TransporterCommonOperation { None=0, Lock=1, Unlock=2, Retract=3, Extend=4 } #region 常量 private const string UNLOCK = "Unlock"; private const string LOCKED1 = "Locked1"; private const string LOCKED2 = "Locked2"; private const string UNLOCKED1 = "Unlocked1"; private const string UNLOCKED2 = "Unlocked2"; private const string IMMOBILIZE_ACTIVE = "ImmobilizeActive"; private const string IMMOBILIZE_ACTIVE2 = "ImmobilizeActive2"; private const string IMMOBILIZE_RETRACTED1 = "ImmobilizeRetracted1"; private const string IMMOBILIZE_RETRACTED2 = "ImmobilizeRetracted2"; private const string IMMOBILIZE_EXTEND1 = "ImmobilizeExtended1"; private const string IMMOBILIZE_EXTEND2= "ImmobilizeExtended2"; private const string READY_TO_LOCK1 = "ReadyToLock1"; private const string READY_TO_LOCK2 = "ReadyToLock2"; private const string WH_PRESENT1 = "WhPresent1"; private const string WH_PRESENT2 = "WhPresent2"; private const string TRANSPORTER_DATA = "TransporterData"; #endregion #region 内部变量 private TransporterData _transporterData = new TransporterData(); /// /// 状态 /// private RState _status; /// /// 当前操作 /// private TransporterCommonOperation _currentOperation; /// /// unlock后自动lock时长 /// private int _unlockTimerLockInterval = 20; /// /// unlock时间 /// private DateTime _unlockDateTime = DateTime.Now; #region Routine /// /// lock routine /// private TransporterLockRoutine _lockRoutine; /// /// Unlock Routine /// private TransporterUnlockRoutine _unlockRoutine; /// /// Retract Routine /// private TransporterRetractRoutine _retractRoutine; /// /// Extend Routine /// private TransporterExtendRoutine _extendRoutine; /// /// barcodeReaderName /// private string _barcodeReaderName; /// /// 条码读取器 /// private BarcodeReaderController _barcodeReader; #endregion #endregion #region 属性 /// /// 数据 /// public TransporterData TransporterData { get { return _transporterData; } } #endregion /// /// 构造函数 /// /// public TransporterCommon(string moduleName) : base(moduleName, "Common", "Common", "Common") { TransporterItem transporterItem = TransporterItemManager.Instance.GetTransporterItem(moduleName); if(transporterItem != null) { _barcodeReaderName =transporterItem.BarcodeReader; } } /// /// 初始化 /// /// public bool Initialize() { InitializeData(); SubscribeValueAction(); InitializeRoutine(); InitializeOperation(); return true; } /// /// 初始化数据 /// private void InitializeData() { DATA.Subscribe($"{Module}.{TRANSPORTER_DATA}", () => _transporterData, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.BarcodeReader", () => _barcodeReaderName, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.WSPresent1", ()=>_transporterData.WhPresent1, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.WSPresent2", () => _transporterData.WhPresent2, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.ImmobilizeActive1", () => _transporterData.ImmobilizeActive, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.ImmobilizeActive2", () => _transporterData.ImmobilizeActive2, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.ImmobilizeRetracted1", () => _transporterData.ImmobilizeRetracted1, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.ImmobilizeRetracted2", () => _transporterData.ImmobilizeRetracted2, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.ImmobilizeExtended1", () => _transporterData.ImmobilizeExtended1, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.ImmobilizeExtended2", () => _transporterData.ImmobilizeExtended2, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.Locked1", () => _transporterData.Locked1, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.Locked2", () => _transporterData.Locked2, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.ReadyToLock1", () => _transporterData.ReadyToLock1, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.ReadyToLock2", () => _transporterData.ReadyToLock2, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.Unlocked1", () => _transporterData.Unlocked1, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.Unlocked2", () => _transporterData.Unlocked2, SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 订阅变量数值发生变化 /// private void SubscribeValueAction() { IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", UNLOCK, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", LOCKED1, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", LOCKED2, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", UNLOCKED1, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", UNLOCKED2, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_ACTIVE, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_ACTIVE2, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_RETRACTED1, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_RETRACTED2, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_EXTEND1, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", IMMOBILIZE_EXTEND2, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", READY_TO_LOCK1, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", READY_TO_LOCK2, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", WH_PRESENT1, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", WH_PRESENT2, UpdateVariableValue); } /// /// 初始化操作 /// private void InitializeOperation() { OP.Subscribe($"{Module}.Lock", LockOperation); OP.Subscribe($"{Module}.Unlock", UnlockOperation); OP.Subscribe($"{Module}.Retract", RetractOperation); OP.Subscribe($"{Module}.Extend", ExtendOperation); } /// /// 更新变量数值 /// /// /// private void UpdateVariableValue(string variable, object value) { PropertyInfo property = TransporterData.GetType().GetProperty(variable); if (property != null) { property.SetValue(TransporterData, value); } if(TransporterData.Unlock) { _unlockDateTime = DateTime.Now; } } /// /// 初始化Routine /// private void InitializeRoutine() { _lockRoutine = new TransporterLockRoutine(Module); _unlockRoutine= new TransporterUnlockRoutine(Module); _retractRoutine= new TransporterRetractRoutine(Module); _extendRoutine=new TransporterExtendRoutine(Module); } #region 指令 /// /// Lock 操作 /// /// /// /// private bool LockOperation(string cmd, object[] args) { return StartRoutine(TransporterCommonOperation.Lock,_lockRoutine,null); } /// /// Unlock 操作 /// /// /// /// private bool UnlockOperation(string cmd, object[] args) { return StartRoutine(TransporterCommonOperation.Unlock, _unlockRoutine, null); } /// /// Retract 操作 /// /// /// /// private bool RetractOperation(string cmd , object[] args) { JetAxisBase elevatorAxis = DEVICE.GetDevice($"{Module}.Elevator"); if (elevatorAxis!=null && !elevatorAxis.CurrentStation.Contains("UP")) { LOG.WriteLog(eEvent.ERR_TRANSPORTER, Module, $"{Module}.Elevator is not in 'UP' Postion,Can not do Retract Action"); return false; } return StartRoutine(TransporterCommonOperation.Retract, _retractRoutine, null); } /// /// Extend 操作 /// /// /// /// private bool ExtendOperation(string cmd , object[] args) { JetAxisBase elevatorAxis = DEVICE.GetDevice($"{Module}.Elevator"); if (elevatorAxis != null && !elevatorAxis.CurrentStation.Contains("UP")) { LOG.WriteLog(eEvent.ERR_TRANSPORTER, Module, $"{Module}.Elevator is not in 'UP' Postion,Can not do Extend Action"); return false; } return StartRoutine(TransporterCommonOperation.Extend, _extendRoutine, null); } /// /// 启动Routine /// /// /// /// private bool StartRoutine(TransporterCommonOperation operation,IRoutine routine,object obj) { if (!JudgeRunningState(operation)) { _currentOperation = operation; _status = routine.Start(obj); return true; } else { return false; } } /// /// 判定运行状态 /// /// private bool JudgeRunningState(TransporterCommonOperation operation) { if (_status == RState.Running) { LOG.WriteLog(eEvent.ERR_TRANSPORTER,Module, $"{Module} current execute {_currentOperation},cannot {operation}"); return true; } return false; } #endregion /// /// 读取条码 /// /// public string ReaderBarcode() { _barcodeReader = DEVICE.GetDevice(_barcodeReaderName); if (_barcodeReader != null) { return _barcodeReader.ReadBarcode(); } return ""; } /// /// 定时器 /// /// public bool OnTimer() { if (_status == RState.Running) { if (_currentOperation != TransporterCommonOperation.None) { IRoutine routine = GetCurrentRoutine(_currentOperation); if (routine != null) { CheckRoutineState(routine, _currentOperation); } else { EndOperation(); } } } if (SC.ContainsItem($"Transporter.{Module}.UnlockTimerLock")) { _unlockTimerLockInterval = SC.GetValue($"Transporter.{Module}.UnlockTimerLock") * 1000; } if(TransporterData.Unlock) { if(DateTime.Now.Subtract(_unlockDateTime).TotalMilliseconds>=_unlockTimerLockInterval) { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{UNLOCK}"); if (!string.IsNullOrEmpty(ioName)) { IOModuleManager.Instance.WriteIoValue(ioName, false); } } } return true; } /// /// 获取当前操作对应的Routine /// /// /// private IRoutine GetCurrentRoutine(TransporterCommonOperation currentOperation) { switch (currentOperation) { case TransporterCommonOperation.Lock: return _lockRoutine; case TransporterCommonOperation.Unlock: return _unlockRoutine; case TransporterCommonOperation.Retract: return _retractRoutine; case TransporterCommonOperation.Extend: return _extendRoutine; default: return null; } } /// /// 检验Routine状态 /// /// /// private void CheckRoutineState(IRoutine routine, TransporterCommonOperation currentOperation) { RState state = routine.Monitor(); if (state == RState.End) { EndOperation(); } else if (state == RState.Failed || state == RState.Timeout) { LOG.WriteLog(eEvent.ERR_TRANSPORTER, $"{Module}.{Name}", $"{currentOperation} error"); EndOperation(); } } /// /// 结束操作 /// private void EndOperation() { _status = RState.End; _currentOperation = TransporterCommonOperation.None; } #region 设备接口 public void Monitor() { } public void Reset() { } public void Terminate() { } #endregion } }