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
}
}