418 lines
19 KiB
C#
418 lines
19 KiB
C#
using Aurora.Api;
|
||
using Hermes;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace WeldingCommon.Devices
|
||
{
|
||
public class PLCMonitor
|
||
{
|
||
private static readonly Logger Log = new Logger("PLCMonitor");
|
||
//private static readonly Logger EventLog = new Logger(eMsg_TYPE.PLC.ToString(), "Event");
|
||
|
||
private const int SLEEP_TIME_MS = 50;
|
||
private const int SLEEP_TIME_FOR_CLOSE_MS = 200;
|
||
private const int SLEEP_TIME_FOR_RECONNECT_MS = 10000;
|
||
|
||
private const string SEQ_INIT = "Init";
|
||
private const string CHECK_ACTIVE = "Check PLC Activation";
|
||
|
||
private const string MONITOR_NETWORK = "Monitor PLC Network status";
|
||
|
||
private const string MONITOR_ALARM = "Monitor Alarm change";
|
||
private const string MONITOR_SETTING = "Monitor Setting change";
|
||
|
||
private const string RECONNECT_NETWORK = "Reconnect to PLC";
|
||
|
||
private const string GO_CHECK_ACTIVE = "Go to check active";
|
||
|
||
// ¸ð¾ÆÁÖ´Â ³ëµå
|
||
private const string GO_MONITOR_NETWORK = "Go to monitor network";
|
||
private const string PLC_IS_DEACTIVATING = "PLC is deactivating";
|
||
private const string GO_RECONNECT_NETWORK = "Reconnect PLC Phase";
|
||
|
||
private static PLCController _plc;
|
||
|
||
const int TIME_OUT = 2000; // 2 [s]
|
||
|
||
/*
|
||
public enum eMainSeqStep
|
||
{
|
||
INIT,
|
||
WORK,
|
||
WAIT_MANUAL_SELECT,
|
||
WAIT_MANUAL_SHOT_SELECT,
|
||
VISION_WAIT,
|
||
ACK_WAIT,
|
||
FAIL,
|
||
MAVIN_SEND_WAIT,
|
||
MAVIN_SEND,
|
||
MAVIN_RESULT_WAIT,
|
||
}
|
||
|
||
static eMainSeqStep Step_ALARM = new eMainSeqStep();
|
||
static eMainSeqStep Step_SETTING = new eMainSeqStep();
|
||
|
||
static Stopwatch swAlarm = new Stopwatch();
|
||
static Stopwatch swSetting = new Stopwatch();
|
||
*/
|
||
|
||
//static ulong _latchForWriteBitUpdate;
|
||
|
||
public static SequenceBuilder Builder()
|
||
{
|
||
SequenceBuilder sb = new SequenceBuilder(1000, true); // ¹«ÇÑ, ½ÃÄö½º Stop½Ã ÃÖ´ë ´ë±â½Ã°£.
|
||
|
||
sb.AddAction(SEQ_INIT, Init);
|
||
sb.AddDecision(CHECK_ACTIVE, CheckActive);
|
||
|
||
sb.AddDecision(MONITOR_NETWORK, MonitorNetworkStatus);
|
||
//-------------------- Setting/Alarm ·Î±ë ºÎºÐ
|
||
sb.AddDecision(MONITOR_ALARM, MonitorPLCAlarmStatus);
|
||
sb.AddDecision(MONITOR_SETTING, MonitorPLCSettingStatus);
|
||
//==================================================
|
||
sb.AddDecision(RECONNECT_NETWORK, ReconnectPLCNetwork);
|
||
|
||
sb.AddDecision(GO_CHECK_ACTIVE, GoToCheckActive);
|
||
|
||
// °æÀ¯¿ë ³ëµå (Ç÷οì Â÷Æ®¸¦ ÀÌ»Ú°Ô ¸¸µé±â À§ÇÑ ¸ñÀû)
|
||
sb.AddAction(GO_MONITOR_NETWORK, GoToMonitorNetwork);
|
||
sb.AddAction(PLC_IS_DEACTIVATING, PlcIsDeactivating);
|
||
sb.AddAction(GO_RECONNECT_NETWORK, GoToReconnectNetwork);
|
||
//===================================================
|
||
//----------------------------------------------------
|
||
//------ ½ºÄö½º Ç÷οì Â÷Æ®
|
||
sb.Flows(sb.Init > sb[SEQ_INIT] > sb[CHECK_ACTIVE]);
|
||
sb.Flows(sb[CHECK_ACTIVE] > sb[MONITOR_NETWORK]);
|
||
sb.Flows(sb[CHECK_ACTIVE] > sb.Final); // Á¾·á
|
||
//------------------- ÁÖ¿ä ·ÎÁ÷
|
||
// ·çÇÁ
|
||
sb.Flows(sb[MONITOR_NETWORK] > sb[MONITOR_ALARM] > sb[MONITOR_SETTING] > sb[GO_MONITOR_NETWORK] > sb[MONITOR_NETWORK]);
|
||
|
||
//------ Åë½Å À翬°á ·çÆ®
|
||
sb.Flows(sb[MONITOR_NETWORK] > sb[GO_RECONNECT_NETWORK]);
|
||
sb.Flows(sb[MONITOR_ALARM] > sb[GO_RECONNECT_NETWORK]);
|
||
sb.Flows(sb[MONITOR_SETTING] > sb[GO_RECONNECT_NETWORK]);
|
||
// ·çÇÁ
|
||
sb.Flows(sb[GO_RECONNECT_NETWORK] > sb[RECONNECT_NETWORK] > sb[GO_RECONNECT_NETWORK]);
|
||
sb.Flows(sb[RECONNECT_NETWORK] > sb[GO_CHECK_ACTIVE]);
|
||
|
||
//------ PLC ºñȰ¼ºÈ ·çÆ®
|
||
sb.Flows(sb[MONITOR_NETWORK] > sb[PLC_IS_DEACTIVATING]);
|
||
sb.Flows(sb[MONITOR_ALARM] > sb[PLC_IS_DEACTIVATING]);
|
||
sb.Flows(sb[MONITOR_SETTING] > sb[PLC_IS_DEACTIVATING]);
|
||
sb.Flows(sb[PLC_IS_DEACTIVATING] > sb[GO_CHECK_ACTIVE] > sb[CHECK_ACTIVE]);
|
||
//===================================================
|
||
sb.OnStopped(OnStopped);
|
||
sb.OnForceError(OnForceError);
|
||
|
||
//sb.Draw("PLCMonitoring.pdf");
|
||
|
||
return sb;
|
||
}
|
||
|
||
private static void OnForceError(SequenceContext arg1, string arg2)
|
||
{
|
||
Log.E("Enter Forced Error phase");
|
||
}
|
||
|
||
private static void OnStopped(SequenceContext obj)
|
||
{
|
||
Log.I("Enter Stopped phase");
|
||
}
|
||
|
||
private static string GoToCheckActive(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
||
{
|
||
//Log.I("GO_CHECK_ACTIVE: --> CHECK_ACTIVE");
|
||
#if DEBUG
|
||
//Debug.WriteLine($"GO_CHECK_ACTIVE: --> CHECK_ACTIVE");
|
||
#endif
|
||
return CHECK_ACTIVE;
|
||
}
|
||
|
||
private static string ReconnectPLCNetwork(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
||
{
|
||
if (_plc.IsActivated) {
|
||
//EventLog.W($"PLC Reconnection Phase due to connection error");
|
||
// ¿©±â´Â µ¶¸³ ½º·¹µåÀ̰í, PLC Åë½Å ¿¬°áÀÌ ½ÇÆÐÇϸé, ´Ù¸¥ ÀÛ¾÷ÀÌ ¹«ÀǹÌÇϹǷÎ, µô·¹ÀÌ·Î Sleep À» »ç¿ëÇÔ
|
||
if (_plc.ReconnectNetwork() != E1.OK) {
|
||
Log.E("PLC reconnection is failed. Retry after 10 [s]");
|
||
Thread.Sleep(SLEEP_TIME_FOR_RECONNECT_MS); // 10 ÃÊ
|
||
|
||
return GO_RECONNECT_NETWORK;
|
||
}
|
||
|
||
//_plc.WriteOffsetData(Data.UnitType.Max, null);
|
||
|
||
//EventLog.I($"PLC is reconnected");
|
||
return GO_CHECK_ACTIVE;
|
||
}
|
||
return GO_CHECK_ACTIVE;
|
||
}
|
||
|
||
private static SequenceActionResult GoToReconnectNetwork(SequenceContext context, string id, SequenceActionResult param)
|
||
{
|
||
return SequenceAction.Ok();
|
||
}
|
||
|
||
private static SequenceActionResult PlcIsDeactivating(SequenceContext context, string id, SequenceActionResult param)
|
||
{
|
||
// PLC ºñȰ¼ºÈ »óÅÂ
|
||
// IsActivated °¡ false °¡ µÉ¶§±îÁö ´ë±â½ÃŰÀÚ...
|
||
|
||
// Å×½ºÆ®: ¾à 1ÃÊ ½Ã°£ÀÇ Å¸ÀӾƿôÀ¸·Î üũ
|
||
var timeOutMS = 1000;
|
||
if (_plc.WaitUntilDeactivated(timeOutMS, out int elapsedMS)) {
|
||
Log.I($"PLC is deactivated: {elapsedMS} [ms] elapsed");
|
||
} else {
|
||
Log.W($"PLC is deactivating: {elapsedMS} [ms] elapsed");
|
||
Thread.Sleep(SLEEP_TIME_MS);
|
||
}
|
||
|
||
return SequenceAction.Ok();
|
||
}
|
||
|
||
private static SequenceActionResult GoToMonitorNetwork(SequenceContext context, string id, SequenceActionResult param)
|
||
{
|
||
|
||
#if DEBUG
|
||
//Debug.WriteLine($"GO_MONITOR_NETWORK: --> MONITOR_NETWORK");
|
||
#endif
|
||
Thread.Sleep(50);
|
||
return SequenceAction.Ok();
|
||
}
|
||
|
||
private static string MonitorPLCSettingStatus(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
||
{
|
||
/*
|
||
switch (Step_SETTING) {
|
||
case eMainSeqStep.INIT: {
|
||
Step_SETTING = eMainSeqStep.WORK;
|
||
_latchForWriteBitUpdate = _plc.LatchForWriteBitUpdate;
|
||
_plc.WriteBit((int)eBitOutput.EQP_SETTING_DATA_CHANGE_COMPLETE, false); //ST1_SETTING_COMPLETE
|
||
// ´ë±âÇÔ¼ö Ãß°¡..
|
||
if (_plc.WaitWriteBitUpdate(_latchForWriteBitUpdate, out _) == false) {
|
||
// ÇÔ¼ö¸íÀº ±âÁ¸ ·Î°Å¿¡¼ Áö¿øÇÏ´Ï, ¶óÀιøÈ£¸¸ ÂïÀÚ..
|
||
Log.W(_plc.WriteLogTag("WriteBit timed out"));
|
||
}
|
||
break;
|
||
}
|
||
case eMainSeqStep.WORK: {
|
||
var res2 = _plc.ReadBit((int)eBitInput.EQP_SETTING_DATA_CHANGE_REQ); //ST1_SETTING_REQ
|
||
// ºñȰ¼ºÈ¿Í ºñ¿¬°á ¿¹¿Ü¸¦ ±¸ºÐÇØ¾ß ÇÒ °Í °°Àºµ¥...»ý°¢ Á» ÇØº¸ÀÚ...
|
||
if (res2.err != E1.OK) {
|
||
Step_SETTING = eMainSeqStep.INIT;
|
||
swSetting.Stop();
|
||
Log.I($"Step_SETTING.eMainSeqStep.WORK 1: PLC is deactivating: {res2.err}");
|
||
return PLC_IS_DEACTIVATING;
|
||
} else {
|
||
if (res2.data) {
|
||
// ZR ÀåÄ¡ Àбâ
|
||
var res = _plc.ReadPLCSettingData();
|
||
if (res != E1.OK) {
|
||
// ºñȰ¼ºÈ¿¡ ÀÇÇÑ ½ÇÆÐÀÎÁö, Åë½Å ¿À·ù¿¡ ÀÇÇÑ ½ÇÆÐÀÎÁö ±¸ºÐ
|
||
if (_plc._dataUpdateTimer.IsRunning) {
|
||
Log.E("ReadPLCSettingData() is failed: --> reconnect");
|
||
// ¿øº»°ú ´Ù¸¥ ºÎºÐ, Åë½Å ½ÇÆÐ·Î À翬°áÀ» ½ÃµµÇÏ´Ï, óÀ½ºÎÅÍ ´Ù½ÃÇØ¾ß ÇÏÁö ¾ÊÀ»±î??
|
||
Step_SETTING = eMainSeqStep.INIT;
|
||
swSetting.Stop();
|
||
return GO_RECONNECT_NETWORK;
|
||
} else {
|
||
Log.E("ReadPLCSettingData() is failed: PLC is deactivating");
|
||
Step_SETTING = eMainSeqStep.INIT;
|
||
swSetting.Stop();
|
||
return PLC_IS_DEACTIVATING;
|
||
}
|
||
}
|
||
_plc.Check_SettingData();
|
||
_latchForWriteBitUpdate = _plc.LatchForWriteBitUpdate;
|
||
_plc.WriteBit((int)eBitOutput.EQP_SETTING_DATA_CHANGE_COMPLETE, true); //ST1_SETTING_COMPLETE
|
||
// ´ë±âÇÔ¼ö Ãß°¡..
|
||
if (_plc.WaitWriteBitUpdate(_latchForWriteBitUpdate, out _) == false) {
|
||
// ÇÔ¼ö¸íÀº ±âÁ¸ ·Î°Å¿¡¼ Áö¿øÇÏ´Ï, ¶óÀιøÈ£¸¸ ÂïÀÚ..
|
||
Log.W(_plc.WriteLogTag("WriteBit timed out"));
|
||
}
|
||
Step_SETTING = eMainSeqStep.ACK_WAIT;
|
||
swSetting.Restart();
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case eMainSeqStep.ACK_WAIT: {
|
||
var res2 = _plc.ReadBit((int)PLCController.eBitInput.EQP_SETTING_DATA_CHANGE_REQ); //ST1_SETTING_REQ
|
||
if (res2.err != E1.OK) {
|
||
Step_SETTING = eMainSeqStep.INIT;
|
||
swSetting.Stop();
|
||
Log.I("Step_SETTING.eMainSeqStep.ACK: PLC is deactivating");
|
||
return PLC_IS_DEACTIVATING;
|
||
} else {
|
||
if (!res2.data) {
|
||
Step_SETTING = eMainSeqStep.INIT;
|
||
swSetting.Stop();
|
||
} else if (swSetting.ElapsedMilliseconds > TIME_OUT) {
|
||
Step_SETTING = eMainSeqStep.INIT;
|
||
EventLog.W($"PLC Setting Change Bit Clear TimeOver");
|
||
swSetting.Stop();
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
*/
|
||
|
||
#if DEBUG
|
||
//Debug.WriteLine($"MONITOR_SETTING: --> GO_MONITOR_NETWORK");
|
||
#endif
|
||
return GO_MONITOR_NETWORK;
|
||
}
|
||
|
||
private static string MonitorPLCAlarmStatus(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
||
{
|
||
/*
|
||
switch (Step_ALARM) {
|
||
case eMainSeqStep.INIT: {
|
||
Step_ALARM = eMainSeqStep.WORK;
|
||
_latchForWriteBitUpdate = _plc.LatchForWriteBitUpdate;
|
||
_plc.WriteBit((int)eBitOutput.EQP_ALARM_STATUS_CHANGE_COMPLETE, false);
|
||
// ´ë±âÇÔ¼ö Ãß°¡..
|
||
if (_plc.WaitWriteBitUpdate(_latchForWriteBitUpdate, out _) == false) {
|
||
// ÇÔ¼ö¸íÀº ±âÁ¸ ·Î°Å¿¡¼ Áö¿øÇÏ´Ï, ¶óÀιøÈ£¸¸ ÂïÀÚ..
|
||
Log.W(_plc.WriteLogTag("WriteBit timed out"));
|
||
}
|
||
break;
|
||
}
|
||
case eMainSeqStep.WORK: {
|
||
var res2 = _plc.ReadBit((int)eBitInput.EQP_ALARM_STATUS_CHANGE_REQ);
|
||
if (res2.err != E1.OK) {
|
||
Step_ALARM = eMainSeqStep.INIT;
|
||
swAlarm.Stop();
|
||
Log.I("Step_ALARM.eMainSeqStep.WORK: PLC is deactivating");
|
||
return PLC_IS_DEACTIVATING;
|
||
} else {
|
||
if (res2.data) { // ¾Ë¶÷ ¿äû
|
||
// LUKAS: ²Ï ¸¹Àº M ÀåÄ¡¸¦ Àаí ÀÖÀ½
|
||
var res = _plc.ReadPLCAlarm();
|
||
if (res != E1.OK) {
|
||
// ºñȰ¼ºÈ¿¡ ÀÇÇÑ ½ÇÆÐÀÎÁö, Åë½Å ¿À·ù¿¡ ÀÇÇÑ ½ÇÆÐÀÎÁö ±¸ºÐ
|
||
if (_plc._dataUpdateTimer.IsRunning) {
|
||
Log.E("ReadPLCAlarm() is failed: --> reconnect");
|
||
// ¿øº»°ú ´Ù¸¥ ºÎºÐ, Åë½Å ½ÇÆÐ·Î À翬°áÀ» ½ÃµµÇÏ´Ï, óÀ½ºÎÅÍ ´Ù½ÃÇØ¾ß ÇÏÁö ¾ÊÀ»±î??
|
||
Step_ALARM = eMainSeqStep.INIT;
|
||
swAlarm.Stop();
|
||
return GO_RECONNECT_NETWORK;
|
||
} else {
|
||
Log.E("ReadPLCAlarm() is failed: PLC is deactivating");
|
||
Step_ALARM = eMainSeqStep.INIT;
|
||
swAlarm.Stop();
|
||
return PLC_IS_DEACTIVATING;
|
||
}
|
||
}
|
||
//Thread.Sleep(50);
|
||
// LUKAS: ¼øÈ¸¸¦ ÇÏ¸é¼ ·Î±×¸¦ ³²±â´Âµ¥...Èì...
|
||
_plc.CheckPLCAlarm();
|
||
|
||
_latchForWriteBitUpdate = _plc.LatchForWriteBitUpdate;
|
||
_plc.WriteBit((int)eBitOutput.EQP_ALARM_STATUS_CHANGE_COMPLETE, true);
|
||
// ´ë±âÇÔ¼ö Ãß°¡..
|
||
if (_plc.WaitWriteBitUpdate(_latchForWriteBitUpdate, out _) == false) {
|
||
// ÇÔ¼ö¸íÀº ±âÁ¸ ·Î°Å¿¡¼ Áö¿øÇÏ´Ï, ¶óÀιøÈ£¸¸ ÂïÀÚ..
|
||
Log.W(_plc.WriteLogTag("WriteBit timed out"));
|
||
}
|
||
Step_ALARM = eMainSeqStep.ACK_WAIT;
|
||
swAlarm.Restart();
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case eMainSeqStep.ACK_WAIT: {
|
||
// LUKAS: ¾Ë¶÷ ¿äûÀÌ ¾øÀ¸¸é, Init (óÀ½)À¸·Î À̵¿
|
||
var res2 = _plc.ReadBit((int)PLCController.eBitInput.EQP_ALARM_STATUS_CHANGE_REQ);
|
||
if (res2.err != E1.OK) {
|
||
Step_ALARM = eMainSeqStep.INIT;
|
||
swAlarm.Stop();
|
||
Log.I("Step_ALARM.eMainSeqStep.ACK: PLC is deactivating");
|
||
return PLC_IS_DEACTIVATING;
|
||
} else {
|
||
if (!res2.data) {
|
||
Step_ALARM = eMainSeqStep.INIT;
|
||
swAlarm.Stop();
|
||
} else if (swAlarm.ElapsedMilliseconds > TIME_OUT) { // LUKAS: PLC ¾Ë¶÷ ¸®¼Â ŸÀÔ¿À¹ö ??
|
||
Step_ALARM = eMainSeqStep.INIT;
|
||
EventLog.W($"PLC ALARM Change Bit Clear TimeOver");
|
||
swAlarm.Stop();
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
*/
|
||
#if DEBUG
|
||
//Debug.WriteLine($"MONITOR_ALARM: --> MONITOR_SETTING");
|
||
#endif
|
||
|
||
return MONITOR_SETTING;
|
||
}
|
||
|
||
private static string MonitorNetworkStatus(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
||
{
|
||
// Åë½Å ¿¬°á »óŸ¦ °Ë»çÇÑ´Ù.
|
||
// Åë½ÅÀÌ ²÷°åÀ» °æ¿ì´Â 1. PLC¸¦ ºñȰ¼ºÈÇßÀ» ¶§, 2. Åë½Å¿¡·¯·Î Á¾·áµÇ¾úÀ» °æ¿ì,
|
||
// => Check Active ·Î À̵¿ÇÑ´Ù...
|
||
|
||
// 1. => PLC ºñȰ¼ºÈ
|
||
// ==> Check Active ¿¡¼ 󸮵Ê...
|
||
// 2. => Åë½Å À翬°á ·ÎÁ÷ ¼öÇà
|
||
// ==> ¿©±â¼ 󸮵Ê...
|
||
|
||
if (_plc.IsConnected) {
|
||
#if DEBUG
|
||
/* // TEST CODE For TEST
|
||
_plc.ReadBit(1);
|
||
_plc.WriteBit(1, true);
|
||
_plc.ReadWord(1);
|
||
_plc.WriteWord(1, 1);
|
||
*/
|
||
//Debug.WriteLine($"MONITOR_NETWORK: --> CHECK_RUN_STATUS");
|
||
#endif
|
||
return MONITOR_ALARM;
|
||
} else { // Åë½ÅÀÌ Á¾·áµÇ¾ú´Ù...
|
||
if (_plc._dataUpdateTimer.IsRunning == false) { // ºñȰ¼ºÈ Æ®¸®°Å¸µ
|
||
Log.I("MonitorNetworkStatus(): PLC is deactivating");
|
||
return PLC_IS_DEACTIVATING;
|
||
}
|
||
|
||
// Åë½Å ÀÌ»ó...!!!
|
||
Log.I("Try to reconnect to PLC");
|
||
return GO_RECONNECT_NETWORK;
|
||
}
|
||
}
|
||
|
||
private static string CheckActive(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
||
{
|
||
while (!context.Stopped) {
|
||
if (_plc.IsActivated) {
|
||
// data ¾÷µ¥ÀÌÆ® ½º·¹µå´Â ºñµ¿±â·Î µ¿ÀÛÁßÀÌ´Ù..
|
||
Log.I("PLC is activated: --> Monitor PLC Network state");
|
||
return MONITOR_NETWORK;
|
||
}
|
||
|
||
// ÁÖ±âÀû µô·¹ÀÌ
|
||
Thread.Sleep(SLEEP_TIME_MS);
|
||
}
|
||
Log.W("Fatal error or Seq. Stop is occurred: --> Final");
|
||
return SeqNodeIds.FINAL;
|
||
}
|
||
|
||
private static SequenceActionResult Init(SequenceContext context, string id, SequenceActionResult param)
|
||
{
|
||
_plc = context.Devices[CommonDeviceIds.PLCDevice] as PLCController;
|
||
//Log.I("PLC Mon. Sequence starts");
|
||
return SequenceAction.Ok();
|
||
}
|
||
}
|
||
}
|