using System;
using System.Threading;
using System.Xml;
using Aitex.Core.RT.DataCenter;
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 MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Flipper.FlipperBase;
namespace Aitex.Core.RT.Device.Unit
{
///
///
///
public class IoTurnOverGona : FlipperBaseDevice
{
private readonly DIAccessor _diM0;
private readonly DIAccessor _di0Degree;
private readonly DIAccessor _di180Degree;
private readonly DIAccessor _diReady;
private readonly DIAccessor _diBusy;
private readonly DIAccessor _diAlarm;
private readonly DIAccessor _diHomePos;
private readonly DIAccessor _diGrip;
private readonly DIAccessor _diUngrip;
private readonly DIAccessor _diPlacement;
private readonly DIAccessor _diPressureError;
private readonly DOAccessor _doStart;
private readonly DOAccessor _doRequest0Degree;
private readonly DOAccessor _doRequest180Degree;
private readonly DOAccessor _doRequestHome;
private readonly DOAccessor _doRelease;
private readonly DOAccessor _doStop;
private readonly DOAccessor _doResetError;
private readonly DOAccessor _doGrip;
private readonly DOAccessor _doUngrip;
private DateTime _dtActionStart;
public string Display, DeviceID;
private PeriodicJob _thread;
public IoTurnOverGona(string module, XmlElement node, string ioModule = ""):base(node.GetAttribute("module"), node.GetAttribute("id"))
{
Module = node.GetAttribute("module");
Name = node.GetAttribute("id");
Display = node.GetAttribute("display");
DeviceID = node.GetAttribute("schematicId");
_di0Degree = ParseDiNode("DI_TurnOver0Degree", node, ioModule);
_di180Degree = ParseDiNode("DI_TurnOver180Degree", node, ioModule);
_diReady = ParseDiNode("DI_TurnOverReady", node, ioModule);
_diBusy = ParseDiNode("DI_TurnOverBusy", node, ioModule);
_diAlarm = ParseDiNode("DI_TurnOverAlarm", node, ioModule);
_diHomePos = ParseDiNode("DI_TurnOverHomePos", node, ioModule);
_diGrip = ParseDiNode("DI_TurnOverGrip", node, ioModule);
_diUngrip = ParseDiNode("DI_TurnOverUngrip", node, ioModule);
_diPlacement = ParseDiNode("DI_TurnOverPlacement", node, ioModule);
_diPressureError = ParseDiNode("DI_TurnOverPressureError", node, ioModule);
_doStart = ParseDoNode("DO_TurnOverStart", node, ioModule);
_doRequest0Degree = ParseDoNode("DO_TurnOverRequest0", node, ioModule);
_doRequest180Degree = ParseDoNode("DO_TurnOverRequest180", node, ioModule);
_doRequestHome = ParseDoNode("DO_TurnOverOrigin", node, ioModule);
_doRelease = ParseDoNode("DO_TurnOverRelease", node, ioModule);
_doStop = ParseDoNode("DO_TurnOverStop", node, ioModule);
_doResetError = ParseDoNode("DO_TurnOverResetError", node, ioModule);
_doGrip = ParseDoNode("DO_TurnOverGrip", node, ioModule);
_doUngrip = ParseDoNode("DO_TurnOverUngrip", node, ioModule);
InitializeIoTurnover();
}
public override bool IsPlacement
{
get
{
if(_diPlacement !=null) return _diPlacement.Value;
return WaferManager.Instance.CheckHasWafer(ModuleName.TurnOverStation, 0);
}
}
public bool IsAlarm => !_diAlarm.Value;
public bool IsPressureError => _diPressureError ==null? false: !_diPressureError.Value;
public override FlipperPosEnum CurrentFlipperPosition
{
get
{
if (_di0Degree.Value && !_di180Degree.Value) return FlipperPosEnum.FrontSide;
if (!_di0Degree.Value && _di180Degree.Value) return FlipperPosEnum.BackSide;
return FlipperPosEnum.Unknow;
}
}
public override GripPosEnum CurrentGripperPositon
{
get
{
if (_diGrip.Value && !_diUngrip.Value) return GripPosEnum.Close;
if (!_diGrip.Value && _diUngrip.Value) return GripPosEnum.Open;
return GripPosEnum.Unknow;
}
}
public bool InitializeIoTurnover()
{
DATA.Subscribe($"{Module}.{Name}.IsHomed", () => _diHomePos.Value);
DATA.Subscribe($"{Module}.{Name}.IsBusy", () => _diBusy.Value);
DATA.Subscribe($"{Module}.{Name}.IsGrip", () => _diGrip.Value);
DATA.Subscribe($"{Module}.{Name}.IsUnGrip", () => _diUngrip.Value);
DATA.Subscribe($"{Module}.{Name}.Is0Degree", () => _di0Degree.Value);
DATA.Subscribe($"{Module}.{Name}.Is180Degree", () => _di180Degree.Value);
DATA.Subscribe($"{Module}.{Name}.IsPlacement", () => IsPlacement);
DATA.Subscribe($"{Module}.{Name}.IsAlarm", () => _diAlarm.Value);
DATA.Subscribe($"{Module}.{Name}.IsPressureError", () => IsPressureError);
DATA.Subscribe($"{Module}.{Name}.GripCmd", () => _doGrip.Value);
DATA.Subscribe($"{Module}.{Name}.TurnTo0Cmd", () => _doRequest0Degree.Value);
DATA.Subscribe($"{Module}.{Name}.TurnTo180Cmd", () => _doRequest180Degree.Value);
DATA.Subscribe($"{Module}.{Name}.HomeCmd", () => _doRequestHome.Value);
DATA.Subscribe($"{Module}.{Name}.ResetCmd", () => _doResetError.Value);
DATA.Subscribe($"{Module}.{Name}.StopCmd", () => _doStop.Value);
DATA.Subscribe($"{Module}.{Name}.UnGripCmd", () => _doUngrip.Value);
_trigError = new R_TRIG();
_trigError.CLK = (_diAlarm != null && !_diAlarm.Value) || (_diPressureError != null && !_diPressureError.Value);
_thread = new PeriodicJob(50, OnTimerMonitor, $"{Module}.{Name} MonitorHandler", true);
return true;
}
private R_TRIG _trigError;
private bool OnTimerMonitor()
{
_trigError.CLK = (_diAlarm != null && !_diAlarm.Value) || (_diPressureError != null && !_diPressureError.Value);
if(_trigError.Q)
{
Thread.Sleep(500);
if((_diAlarm != null && !_diAlarm.Value) || (_diPressureError != null && !_diPressureError.Value))
OnError($"{FlipperModuleName}Error");
}
return true;
}
public override void Terminate()
{
}
public DOAccessor ParseDoNode(string name, XmlElement node, string ioModule = "")
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
return IO.DO[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"];
return null;
}
public DIAccessor ParseDiNode(string name, XmlElement node, string ioModule = "")
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
return IO.DI[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"];
return null;
}
protected override bool fStartGrip(object[] param)
{
_doGrip.SetValue(true, out _);
_doUngrip.SetValue(false, out _);
_dtActionStart = DateTime.Now;
return true;
}
protected override bool fMonitorGrip(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
{
OnError("Grip timeout");
return false;
}
if (_diGrip.Value && !_diUngrip.Value)
{
EV.PostInfoLog("Flipper", $"{FlipperModuleName} grip completed");
return true;
}
return false;
}
protected override bool fStartUnGrip(object[] param)
{
_doGrip.SetValue(false, out _);
_doUngrip.SetValue(true, out _);
_dtActionStart = DateTime.Now;
return true;
}
protected override bool fMonitorUnGrip(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
{
OnError("UnGrip timeout");
return false;
}
if (!_diGrip.Value && _diUngrip.Value)
{
EV.PostInfoLog("Flipper", $"{FlipperModuleName} ungrip completed");
return true;
}
return false;
}
protected override bool fStartHome(object[] param)
{
_doRequest0Degree.SetValue(false, out _);
_doRequest180Degree.SetValue(false, out _);
_doRequestHome.SetValue(true, out _);
_dtActionStart = DateTime.Now;
_dtActionStart = DateTime.Now;
return true;
}
protected override bool fMonitorHome(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
{
OnError("Home timeout");
_doRequestHome.SetValue(false, out _);
return false;
}
if (_diHomePos.Value)// && _diReady.Value)
{
_doRequestHome.SetValue(false, out _);
EV.PostInfoLog("Flipper", $"{FlipperModuleName} home completed");
return true;
}
return false;
}
protected override bool fStartTurnTo0(object[] param)
{
_doRequestHome.SetValue(false, out _);
_doStop.SetValue(false, out _);
_doRequest0Degree.SetValue(true, out _);
_doRequest180Degree.SetValue(false, out _);
Thread.Sleep(500);
_doStart.SetValue(true, out _);
Thread.Sleep(100);
_dtActionStart = DateTime.Now;
var wafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
if (!wafer.IsEmpty)
{
var dvid = new SerializableDictionary()
{
{"LOT_ID", wafer.LotId},
{"WAFER_ID", wafer.WaferID},
{"ARRIVE_POS_NAME", FlipperModuleName.ToString()}
};
EV.Notify(EventWaferTurnOverStart, dvid);
}
return true;
}
protected override bool fMonitorTurnTo0(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
{
OnError("Turn to 0 timeout");
_doStart.SetValue(false, out _);
_doRequest0Degree.SetValue(false, out _);
_doRequest180Degree.SetValue(false, out _);
return false;
}
if (_di0Degree.Value && !_di180Degree.Value && !_diBusy.Value) //&& _diReady.Value
{
_doStart.SetValue(false, out _);
_doRequest0Degree.SetValue(false, out _);
_doRequest180Degree.SetValue(false, out _);
EV.PostInfoLog("Flipper", $"{FlipperModuleName} turn to 0 degree completed");
var wafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
if (!wafer.IsEmpty)
{
var dvid = new SerializableDictionary()
{
{"LOT_ID", wafer.LotId},
{"WAFER_ID", wafer.WaferID},
{"ARRIVE_POS_NAME", FlipperModuleName.ToString()}
};
EV.Notify(EventWaferTurnOverEnd, dvid);
}
return true;
}
return false;
}
protected override bool fStartTurnTo180(object[] param)
{
_doRequestHome.SetValue(false, out _);
_doStop.SetValue(false, out _);
_doRequest0Degree.SetValue(false, out _);
_doRequest180Degree.SetValue(true, out _);
Thread.Sleep(500);
_doStart.SetValue(true, out _);
Thread.Sleep(100);
_dtActionStart = DateTime.Now;
var wafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
if (!wafer.IsEmpty)
{
var dvid = new SerializableDictionary()
{
{"LOT_ID", wafer.LotId},
{"WAFER_ID", wafer.WaferID},
{"ARRIVE_POS_NAME", "TRN1"}
};
EV.Notify(EventWaferTurnOverStart, dvid);
}
return true;
}
protected override bool fMonitorTurnTo180(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
{
OnError("Turn to 180 timeout");
_doStart.SetValue(false, out _);
_doRequest0Degree.SetValue(false, out _);
_doRequest180Degree.SetValue(false, out _);
return false;
}
if (!_di0Degree.Value && _di180Degree.Value && !_diBusy.Value)//&& _diReady.Value
{
_doStart.SetValue(false, out _);
_doRequest0Degree.SetValue(false, out _);
_doRequest180Degree.SetValue(false, out _);
EV.PostInfoLog("Flipper", $"{FlipperModuleName} turn to 180 degree completed");
var wafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
if (!wafer.IsEmpty)
{
var dvid = new SerializableDictionary()
{
{"LOT_ID", wafer.LotId},
{"WAFER_ID", wafer.WaferID},
{"ARRIVE_POS_NAME", FlipperModuleName.ToString()}
};
EV.Notify(EventWaferTurnOverEnd, dvid);
}
return true;
}
return false;
}
protected override bool fStartAbort(object[] param)
{
_doRequestHome.SetValue(false, out _);
_doStart.SetValue(false, out _);
_doStop.SetValue(true, out _);
_doResetError.SetValue(false, out _);
_doRequest0Degree.SetValue(false, out _);
_doRequest180Degree.SetValue(false, out _);
IsBusy = false;
return true;
}
protected override bool fStartReset(object[] param)
{
_doRequestHome.SetValue(false, out _);
_doStart.SetValue(false, out _);
_doRequest0Degree.SetValue(false, out _);
_doRequest180Degree.SetValue(false, out _);
_doStop.SetValue(false, out _);
_doResetError.SetValue(true, out _);
_dtActionStart = DateTime.Now;
return true;
}
protected override bool fMonitorReset(object[] param)
{
IsBusy = false;
if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
{
OnError("Reset timeout");
_doResetError.SetValue(false, out _);
return false;
}
if (_diAlarm != null && !_diAlarm.Value)
return false;
if (_diPressureError != null && !_diPressureError.Value)
return false;
EV.PostInfoLog("Flipper", $"{FlipperModuleName} reset completed");
_doResetError.SetValue(false, out _);
return true;
}
}
}