333 lines
14 KiB
C#
333 lines
14 KiB
C#
using Aurora.Api;
|
|
using HarfBuzzSharp;
|
|
using Hermes;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using WeldingCommon.Devices;
|
|
using WeldingCommon.Settings;
|
|
|
|
namespace WeldingCommon.Sequences.Main
|
|
{
|
|
public class SeqCheckWeldingComplete
|
|
{
|
|
static readonly Logger Log = new Logger("SeqExecutePlcBitInterface");
|
|
|
|
const string SEQ_ENTER = "[SeqCheckWeldingComplete] SEQ_ENTER"; // inputParam 으로 받자.
|
|
const string SEQ_CHECK_INIT_CONDITION = "[SeqCheckWeldingComplete] Check Init Condition"; // Check Init Condition
|
|
|
|
const string SEQ_SET_PC_WELD_COMPLETE_ON = "[SeqCheckWeldingComplete] Set PC Weld Complete On"; // PC 용접 완료 설정
|
|
const string SEQ_CHECK_PLC_WELDING_COMPLETE = "[SeqCheckWeldingComplete] Check Rewelding Request"; // 재용접 요청 확인
|
|
const string SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END = "[SeqCheckWeldingComplete] Set PC Weld Complete Off With End"; // 종료와 함께 PC 용접 완료 설정
|
|
const string SEQ_GET_PLC_WELD_COMPLETE_ACK_OFF = "[SeqCheckWeldingComplete] Set PLC Weld Complete Ack Off"; // PLC 용접 완료 확인 종료
|
|
const string SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY = "[SeqCheckWeldingComplete] Set PC Weld Complete Off With Retry"; // 재시도와 함께 PC 용접 완료 설정
|
|
const string SEQ_SET_PC_PAGE_CHANGE_COMPLETE_ON = "[SeqCheckWeldingComplete] Set PC Page Change Complete On"; // PC 페이지 변경 완료 설정
|
|
const string SEQ_GET_PLC_PAGE_REQ_OFF = "[SeqCheckWeldingComplete] Get PLC Page Request Off"; // PLC 페이지 요청 종료
|
|
const string SEQ_SET_PC_PAGE_CHANGE_COMPLETE_OFF = "[SeqCheckWeldingComplete] Set PC Page Change Complete Off"; // PC 페이지 변경 완료 종료
|
|
|
|
const string SEQ_COMPLETE = "[SeqCheckWeldingComplete] SEQ_COMPLETE"; // 완료
|
|
|
|
static class ContextKey
|
|
{
|
|
public const string KEY_SEQUENCE_IS_COMPLETE = "KEY_SEQUENCE_IS_COMPLETE_SeqCheckWeldingComplete";
|
|
public const string KEY_SEQUENCE_PAGE_NO = "KEY_SEQUENCE_PAGE_NO_SeqCheckWeldingComplete";
|
|
}
|
|
|
|
private PLCController _PLC;
|
|
|
|
private SeqCheckWeldingComplete_InitParam _InitParam;
|
|
private SeqCheckWeldingComplete_OutParam _OutParam;
|
|
private SystemParameter _SystemParameter;
|
|
|
|
const int timeoutSeconds = 10;
|
|
private bool _IsComplete = false;
|
|
|
|
public SequenceBuilder Builder()
|
|
{
|
|
var sb = new SequenceBuilder(1000, true);
|
|
////var sb = new SequenceBuilder(1000, false); // With log
|
|
|
|
sb.AddAction(SEQ_ENTER, Sequence_Enter);
|
|
sb.AddDecision(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); //분기
|
|
|
|
sb.AddAction(SEQ_SET_PC_WELD_COMPLETE_ON, SetPcWeldCompletOn);
|
|
sb.AddDecision(SEQ_CHECK_PLC_WELDING_COMPLETE, CheckPlcWeldingComplete); // 분기
|
|
|
|
sb.AddAction(SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END, SetPcWeldCompleteOffWithEnd);
|
|
sb.AddAction(SEQ_GET_PLC_WELD_COMPLETE_ACK_OFF, GetPlcWeldCompleteAckOff);
|
|
|
|
sb.AddAction(SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY, SetPcWeldCompleteOffWithRetry);
|
|
sb.AddAction(SEQ_SET_PC_PAGE_CHANGE_COMPLETE_ON, SetPcPageChangeCompleteOn);
|
|
sb.AddAction(SEQ_GET_PLC_PAGE_REQ_OFF, GetPlcPageRequestOff);
|
|
sb.AddAction(SEQ_SET_PC_PAGE_CHANGE_COMPLETE_OFF, SetPcPageChangeCompleteOff);
|
|
|
|
sb.AddAction(SEQ_COMPLETE, Complete);
|
|
|
|
|
|
sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION]
|
|
> sb[SEQ_SET_PC_WELD_COMPLETE_ON] > sb[SEQ_CHECK_PLC_WELDING_COMPLETE]
|
|
> sb[SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END] > sb[SEQ_GET_PLC_WELD_COMPLETE_ACK_OFF]
|
|
> sb[SEQ_COMPLETE]);
|
|
|
|
sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_COMPLETE] > sb.Final);
|
|
|
|
sb.Flows(sb[SEQ_CHECK_PLC_WELDING_COMPLETE] > sb[SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY]
|
|
> sb[SEQ_SET_PC_PAGE_CHANGE_COMPLETE_ON] > sb[SEQ_GET_PLC_PAGE_REQ_OFF]
|
|
> sb[SEQ_SET_PC_PAGE_CHANGE_COMPLETE_OFF] > sb[SEQ_COMPLETE]);
|
|
|
|
sb.OnForceError(OnForceError);
|
|
|
|
sb.OnStopped(OnStopped);
|
|
|
|
//sb.Draw("SeqCheckWeldingComplete.pdf");
|
|
|
|
return sb;
|
|
}
|
|
|
|
private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
Log.I("SeqCheckWeldingComplete Start");
|
|
|
|
_InitParam = param.Param as SeqCheckWeldingComplete_InitParam;
|
|
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
|
|
|
|
InitDev(context);
|
|
if (!CheckDeviceReady(context)) {
|
|
Log.E("The devices are not active.");
|
|
return null;
|
|
}
|
|
|
|
if (InitSequenceVariable(context) == false) {
|
|
return null;
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private string CheckInitCondition(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
if (!CheckCondition(context)) {
|
|
Log.E("Condition is not in state to start sequence.");
|
|
context.PutValue(ContextKey.KEY_SEQUENCE_IS_COMPLETE, false);
|
|
return SEQ_COMPLETE;
|
|
}
|
|
|
|
context.PutValue(ContextKey.KEY_SEQUENCE_PAGE_NO, (short)0);
|
|
return SEQ_SET_PC_WELD_COMPLETE_ON;
|
|
}
|
|
|
|
private SequenceActionResult SetPcWeldCompletOn(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
int setAddress = _InitParam.WeldingCompleteAddress;
|
|
|
|
_PLC.WriteBit(setAddress, true);
|
|
|
|
Log.I(string.Format("Set PC Welding Complete On"));
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private string CheckPlcWeldingComplete(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
int completeAckAddress = _InitParam.WeldingCompleteAckAddress;
|
|
int pageChangeRequestAddress = _InitParam.PageChangeRequestAddress;
|
|
|
|
// Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess
|
|
Func<bool> plcResponse = () => _PLC.ReadBit(completeAckAddress).data
|
|
|| _PLC.ReadBit(pageChangeRequestAddress).data;
|
|
|
|
var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE("Get PLC Welding Complete or Page Change Request Timeout !");
|
|
return null;
|
|
} else {
|
|
if (_PLC.ReadBit(completeAckAddress).data) {
|
|
Log.I(string.Format("Get PLC Weld Complete Ack On"));
|
|
return SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END;
|
|
} else if (_PLC.ReadBit(pageChangeRequestAddress).data) {
|
|
Log.I(string.Format("Get PLC Page Change Request On"));
|
|
return SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY;
|
|
} else {
|
|
Log.I(string.Format("Unexpected Situation."));
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
private SequenceActionResult SetPcWeldCompleteOffWithEnd(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
int setAddress = _InitParam.WeldingCompleteAddress;
|
|
_PLC.WriteBit(setAddress, false);
|
|
Log.I(string.Format("Set PC Weld Complete Off For End"));
|
|
context.PutValue(ContextKey.KEY_SEQUENCE_IS_COMPLETE, true);
|
|
|
|
// 완료하였음.
|
|
_IsComplete = true;
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult GetPlcWeldCompleteAckOff(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
int getAddress = _InitParam.WeldingCompleteAckAddress;
|
|
// Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess
|
|
Func<bool> plcResponse = () => !_PLC.ReadBit(getAddress).data;
|
|
|
|
var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE("Get PLC Welding Complete ACK Off Timeout !");
|
|
return null;
|
|
} else {
|
|
Log.I(string.Format("Get PLC Weld Complete Ack Off"));
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult SetPcWeldCompleteOffWithRetry(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
int setAddress = _InitParam.WeldingCompleteAddress;
|
|
_PLC.WriteBit(setAddress, false);
|
|
Log.I(string.Format("Set PC Weld Complete Off For End"));
|
|
context.PutValue(ContextKey.KEY_SEQUENCE_IS_COMPLETE, false);
|
|
// Retry 해야함.
|
|
_IsComplete = false;
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult SetPcPageChangeCompleteOn(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
int wordNo = _InitParam.PageNoAddress;
|
|
short pageNo = _PLC.ReadWord(wordNo).data;
|
|
|
|
context.PutValue(ContextKey.KEY_SEQUENCE_PAGE_NO, (short)pageNo);
|
|
|
|
Log.I(string.Format("Write Page No & _IsComplete !"));
|
|
|
|
int setAddress = _InitParam.PageChangeCompleteAddress;
|
|
_PLC.WriteBit(setAddress, true);
|
|
Log.I(string.Format("Set PC Page Change Complete On"));
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult GetPlcPageRequestOff(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
int getAddress = _InitParam.PageChangeRequestAddress;
|
|
// Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess
|
|
Func<bool> plcResponse = () => !_PLC.ReadBit(getAddress).data;
|
|
|
|
var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE("Get PLC Page Change Request Off Timeout !");
|
|
return null;
|
|
} else {
|
|
Log.I(string.Format("Get PLC Page Change Request Off"));
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult SetPcPageChangeCompleteOff(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
int setAddress = _InitParam.PageChangeCompleteAddress;
|
|
_PLC.WriteBit(setAddress, false);
|
|
Log.I(string.Format("Set PC Page Change Complete Off"));
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
context.TryGetValue(ContextKey.KEY_SEQUENCE_IS_COMPLETE, out bool isComplete);
|
|
context.TryGetValue(ContextKey.KEY_SEQUENCE_PAGE_NO, out short pageNo);
|
|
|
|
SeqCheckWeldingComplete_OutParam result = new SeqCheckWeldingComplete_OutParam()
|
|
{ Success = true, IsComplete = _IsComplete, PageNo = pageNo };
|
|
|
|
Log.D("CheckWeldingComplete Sequence Complete");
|
|
|
|
return SequenceAction.Ok(result);
|
|
}
|
|
|
|
private void OnStopped(SequenceContext context)
|
|
{
|
|
Log.I("SequenceAction Ok : OnStopped");
|
|
}
|
|
|
|
private void OnForceError(SequenceContext context, string arg2)
|
|
{
|
|
Log.I("SequenceAction Ok : OnForceError");
|
|
}
|
|
|
|
#region Device 및 상태 확인 함수 (시퀸스 공용)
|
|
private bool InitSequenceVariable(SequenceContext context)
|
|
{
|
|
// TODO: [장비구현필요] Initialize Variable 추가
|
|
_IsComplete = false;
|
|
return true;
|
|
}
|
|
|
|
private void InitDev(SequenceContext context)
|
|
{
|
|
//Device Init
|
|
_PLC = context.GetPLC();
|
|
}
|
|
|
|
private bool CheckDeviceReady(SequenceContext context)
|
|
{
|
|
List<string> deviceListToCheck = new List<string>() { CommonDeviceIds.PLCDevice };
|
|
bool isAllDeviceActivated = true;
|
|
foreach (string item in deviceListToCheck) {
|
|
if (!context.Devices[item].IsActivated) {
|
|
isAllDeviceActivated = isAllDeviceActivated && false;
|
|
}
|
|
}
|
|
|
|
return isAllDeviceActivated;
|
|
}
|
|
|
|
private bool CheckCondition(SequenceContext context)
|
|
{
|
|
if (CheckCondition_Interlock()) {
|
|
if (InitializeDeviceStatus(context)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool InitializeDeviceStatus(SequenceContext context)
|
|
{
|
|
// format 유지, ReceiveCellInfo 없음
|
|
return true;
|
|
}
|
|
|
|
private bool CheckCondition_Interlock()
|
|
{
|
|
// PLC, Data, IO 등 Interlock checking
|
|
|
|
return true;
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
public class SeqCheckWeldingComplete_InitParam : InitParam
|
|
{
|
|
public int WeldingCompleteAddress { get; set; }
|
|
public int WeldingCompleteAckAddress { get; set; }
|
|
public int PageChangeRequestAddress { get; set; }
|
|
public int PageChangeCompleteAddress { get; set; }
|
|
public int PageNoAddress { get; set; }
|
|
}
|
|
public class SeqCheckWeldingComplete_OutParam : OutParam
|
|
{
|
|
public bool IsComplete { get; set; }
|
|
public short PageNo { get; set; }
|
|
}
|
|
}
|