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"; private const string LOCK = "Lock"; private const string WSHOLDPRESENT = "WSHoldPresent"; #endregion #region 内部变量 private TransporterData _transporterData = new TransporterData(); /// <summary> /// 状态 /// </summary> private RState _status; /// <summary> /// 当前操作 /// </summary> private TransporterCommonOperation _currentOperation; /// <summary> /// unlock后自动lock时长 /// </summary> private int _unlockTimerLockInterval = 20; /// <summary> /// unlock时间 /// </summary> private DateTime _unlockDateTime = DateTime.Now; #region Routine /// <summary> /// Retract Routine /// </summary> private TransporterRetractRoutine _retractRoutine; /// <summary> /// Extend Routine /// </summary> private TransporterExtendRoutine _extendRoutine; /// <summary> /// barcodeReaderName /// </summary> private string _barcodeReaderName; /// <summary> /// 条码读取器 /// </summary> private BarcodeReaderController _barcodeReader; #endregion #endregion #region 属性 /// <summary> /// 数据 /// </summary> public TransporterData TransporterData { get { return _transporterData; } } #endregion /// <summary> /// 构造函数 /// </summary> /// <param name="moduleName"></param> public TransporterCommon(string moduleName) : base(moduleName, "Common", "Common", "Common") { TransporterItem transporterItem = TransporterItemManager.Instance.GetTransporterItem(moduleName); if(transporterItem != null) { _barcodeReaderName =transporterItem.BarcodeReader; } } /// <summary> /// 初始化 /// </summary> /// <returns></returns> public bool Initialize() { InitializeData(); SubscribeValueAction(); InitializeRoutine(); InitializeOperation(); return true; } /// <summary> /// 初始化数据 /// </summary> 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); DATA.Subscribe($"{Module}.Locked", () => _transporterData.Lock, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.WSHoldPresent", () => _transporterData.WSHoldPresent, SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// <summary> /// 订阅变量数值发生变化 /// </summary> 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); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", LOCK, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", WSHOLDPRESENT, UpdateVariableValue); } /// <summary> /// 初始化操作 /// </summary> private void InitializeOperation() { OP.Subscribe($"{Module}.Lock", LockOperation); OP.Subscribe($"{Module}.Unlock", UnlockOperation); OP.Subscribe($"{Module}.Retract", RetractOperation); OP.Subscribe($"{Module}.Extend", ExtendOperation); } /// <summary> /// 更新变量数值 /// </summary> /// <param name="variable"></param> /// <param name="value"></param> 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; } } /// <summary> /// 初始化Routine /// </summary> private void InitializeRoutine() { _retractRoutine= new TransporterRetractRoutine(Module); _extendRoutine=new TransporterExtendRoutine(Module); } #region 指令 /// <summary> /// Lock 操作 /// </summary> /// <param name="cmd"></param> /// <param name="args"></param> /// <returns></returns> public bool LockOperation(string cmd, object[] args) { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{LOCK}"); if (!string.IsNullOrEmpty(ioName)) { return IOModuleManager.Instance.WriteIoValue(ioName, true); } else { return false; } } /// <summary> /// Unlock 操作 /// </summary> /// <param name="cmd"></param> /// <param name="args"></param> /// <returns></returns> public bool UnlockOperation(string cmd, object[] args) { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{LOCK}"); if (!string.IsNullOrEmpty(ioName)) { return IOModuleManager.Instance.WriteIoValue(ioName, false); } else { return false; } } /// <summary> /// Retract 操作 /// </summary> /// <param name="cmd"></param> /// <param name="args"></param> /// <returns></returns> private bool RetractOperation(string cmd , object[] args) { JetAxisBase elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{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); } /// <summary> /// Extend 操作 /// </summary> /// <param name="cmd"></param> /// <param name="args"></param> /// <returns></returns> private bool ExtendOperation(string cmd , object[] args) { JetAxisBase elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{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); } /// <summary> /// 启动Routine /// </summary> /// <param name="operation"></param> /// <param name="obj"></param> /// <returns></returns> private bool StartRoutine(TransporterCommonOperation operation,IRoutine routine,object obj) { if (!JudgeRunningState(operation)) { _currentOperation = operation; _status = routine.Start(obj); return true; } else { return false; } } /// <summary> /// 判定运行状态 /// </summary> /// <returns></returns> 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 /// <summary> /// 读取条码 /// </summary> /// <returns></returns> public string ReaderBarcode() { _barcodeReader = DEVICE.GetDevice<BarcodeReaderController>(_barcodeReaderName); if (_barcodeReader != null) { return _barcodeReader.ReadBarcode(); } return ""; } /// <summary> /// 定时器 /// </summary> /// <returns></returns> 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<int>($"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; } /// <summary> /// 获取当前操作对应的Routine /// </summary> /// <param name="currentOperation"></param> /// <returns></returns> private IRoutine GetCurrentRoutine(TransporterCommonOperation currentOperation) { switch (currentOperation) { case TransporterCommonOperation.Retract: return _retractRoutine; case TransporterCommonOperation.Extend: return _extendRoutine; default: return null; } } /// <summary> /// 检验Routine状态 /// </summary> /// <param name="routine"></param> /// <param name="currentOperation"></param> 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(); } } /// <summary> /// 结束操作 /// </summary> private void EndOperation() { _status = RState.End; _currentOperation = TransporterCommonOperation.None; } #region 设备接口 public void Monitor() { } public void Reset() { } public void Terminate() { } #endregion } }