278 lines
18 KiB
C#
278 lines
18 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.Api.Devices;
|
|
using Aurora.View;
|
|
using AuroraLaser;
|
|
using CoreUnit.Control.UserControl.Canvas;
|
|
using CoreUnit.Scanner.UserControl.ScannerCanvas;
|
|
using DB.Recipe;
|
|
using Hermes;
|
|
using ILSOS_PrismaticGun.Alarm;
|
|
using ILSOS_PrismaticGun.Device;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Linq;
|
|
using System.Reactive.Linq;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Markup;
|
|
using System.Windows.Media;
|
|
using VisionCommon;
|
|
using WeldingCommon;
|
|
using WeldingCommon.Alarm;
|
|
using WeldingCommon.Data;
|
|
using WeldingCommon.Devices;
|
|
using WeldingCommon.RMS;
|
|
using WeldingCommon.Settings;
|
|
using WeldingCommon.Utils;
|
|
using WeldingCommon.Utils.Diff;
|
|
using static AuroraPLC.PLCBase;
|
|
using static ILSOS_PrismaticGun.Device.PLCControllerPrismaticGun;
|
|
using static WeldingCommon.Devices.PLCController;
|
|
|
|
namespace ILSOS_PrismaticGun.Recipes
|
|
{
|
|
public class RMSHandlerForMainWelder : RMSHandler
|
|
{
|
|
private const string AStageLaserWeldingRecipeNo = "AStageLaserWeldingRecipeNo";
|
|
private const string AStageLaserWeldingN2PurgeFlow = "AStageLaserWeldingN2PurgeFlow";
|
|
private const string AStageLaserWeldingPosition = "AStageLaserWeldingPosition";
|
|
private const string AStageLaserLineSpeed = "AStageLaserLineSpeed";
|
|
private const string AStageLaserCornerSpeed = "AStageLaserCornerSpeed";
|
|
private const string AStageLaserLinePowerCore = "AStageLaserLinePowerCore";
|
|
private const string AStageLaserLinePowerRing = "AStageLaserLinePowerRing";
|
|
private const string AStageLaserCornerPowerCore = "AStageLaserCornerPowerCore";
|
|
private const string AStageLaserCornerPowerRing = "AStageLaserCornerPowerRing";
|
|
private const string AStageLaserRampingPowerStarting = "AStageLaserRampingPowerStarting";
|
|
private const string AStageLaserRampingLengthStarting = "AStageLaserRampingLengthStarting";
|
|
private const string AStageLaserRampingPowerOverpath = "AStageLaserRampingPowerOverpath";
|
|
private const string AStageLaserRampingLengthOverpath = "AStageLaserRampingLengthOverpath";
|
|
|
|
private const string BStageLaserWeldingRecipeNo = "BStageLaserWeldingRecipeNo";
|
|
private const string BStageLaserWeldingN2PurgeFlow = "BStageLaserWeldingN2PurgeFlow";
|
|
private const string BStageLaserWeldingPosition = "BStageLaserWeldingPosition";
|
|
private const string BStageLaserLineSpeed = "BStageLaserLineSpeed";
|
|
private const string BStageLaserCornerSpeed = "BStageLaserCornerSpeed";
|
|
private const string BStageLaserLinePowerCore = "BStageLaserLinePowerCore";
|
|
private const string BStageLaserLinePowerRing = "BStageLaserLinePowerRing";
|
|
private const string BStageLaserCornerPowerCore = "BStageLaserCornerPowerCore";
|
|
private const string BStageLaserCornerPowerRing = "BStageLaserCornerPowerRing";
|
|
private const string BStageLaserRampingPowerStarting = "BStageLaserRampingPowerStarting";
|
|
private const string BStageLaserRampingLengthStarting = "BStageLaserRampingLengthStarting";
|
|
private const string BStageLaserRampingPowerOverpath = "BStageLaserRampingPowerOverpath";
|
|
private const string BStageLaserRampingLengthOverpath = "BStageLaserRampingLengthOverpath";
|
|
|
|
private PLCControllerPrismaticGun _plc;
|
|
private SettingRmsDataList _RmsSetting;
|
|
|
|
public override void RegistryDeviceHandler(IAuroraEnvironment aurora)
|
|
{
|
|
base.RegistryDeviceHandler(aurora);
|
|
_plc = aurora.DeviceManager[CommonDeviceIds.PLCDevice] as PLCControllerPrismaticGun;
|
|
_RmsSetting = aurora.SettingEntry[CommonSettingIds.RmsDatas] as SettingRmsDataList;
|
|
|
|
aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_RECIPE_ACTIVATED)
|
|
.ObserveOnDispatcher()
|
|
.Select(param => (RecipeInfo)param.Param)
|
|
.Subscribe(t => UploadRecipeParameter(t.Id));
|
|
|
|
aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_RECIPE_ITEM_CHANGED)
|
|
.ObserveOnDispatcher()
|
|
.Subscribe(UploadActivatedRecipeParameter);
|
|
|
|
}
|
|
|
|
private void UploadActivatedRecipeParameter(EventMessage message)
|
|
{
|
|
var id = _aurora.RecipeManager.ActivatedRecipe().Id;
|
|
UploadRecipeParameter(id);
|
|
}
|
|
|
|
private bool TrySetReportData(string key, double value)
|
|
{
|
|
var data = getReportData(key);
|
|
if (data == null) {
|
|
Log.E($"RMS 데이터 항목을 찾을 수 없음: {key}");
|
|
_aurora.AlarmService.SetAlarm(AlarmCode.RMS_PAGE_SETTING_NULL);
|
|
return false;
|
|
}
|
|
data.Value = value;
|
|
return true;
|
|
}
|
|
|
|
private void UploadRecipeParameter(int id)
|
|
{
|
|
try {
|
|
var RecipeStageA = _recipeEntry.RecipeItem(id, RecipeIds.StageAMainRecipe) as MainRecipe;
|
|
var RecipeStageB = _recipeEntry.RecipeItem(id, RecipeIds.StageBMainRecipe) as MainRecipe;
|
|
|
|
if (RecipeStageA == null || RecipeStageB == null) {
|
|
Log.E($"레시피 항목 로드 실패: id={id}, StageA={RecipeStageA != null}, StageB={RecipeStageB != null}");
|
|
MessageUtil.ShowToast($"RMS 레시피 항목 로드 실패 (id={id})", Log);
|
|
_aurora.AlarmService.SetAlarm(AlarmCode.RMS_PAGE_SETTING_NULL);
|
|
return;
|
|
}
|
|
|
|
if (!TrySetReportData(AStageLaserWeldingRecipeNo, id)) return;
|
|
if (!TrySetReportData(AStageLaserWeldingN2PurgeFlow, RecipeStageA.N2PressMFC)) return;
|
|
if (!TrySetReportData(AStageLaserWeldingPosition, RecipeStageA.AxisZPosition)) return;
|
|
if (!TrySetReportData(AStageLaserLineSpeed, RecipeStageA.StraightParam.Velocity)) return;
|
|
if (!TrySetReportData(AStageLaserCornerSpeed, RecipeStageA.CurveParam.Velocity)) return;
|
|
if (!TrySetReportData(AStageLaserLinePowerCore, RecipeStageA.StraightParam.CorePowerW)) return;
|
|
if (!TrySetReportData(AStageLaserLinePowerRing, RecipeStageA.StraightParam.RingPowerW)) return;
|
|
if (!TrySetReportData(AStageLaserCornerPowerCore, RecipeStageA.CurveParam.CorePowerW)) return;
|
|
if (!TrySetReportData(AStageLaserCornerPowerRing, RecipeStageA.CurveParam.RingPowerW)) return;
|
|
if (!TrySetReportData(AStageLaserRampingPowerStarting, RecipeStageA.RampingOnStartPower)) return;
|
|
if (!TrySetReportData(AStageLaserRampingLengthStarting, RecipeStageA.RampingOnOverlapDist)) return;
|
|
if (!TrySetReportData(AStageLaserRampingPowerOverpath, RecipeStageA.RampingOffEndPower)) return;
|
|
if (!TrySetReportData(AStageLaserRampingLengthOverpath, RecipeStageA.RampingOffOverlapDist)) return;
|
|
|
|
if (!TrySetReportData(BStageLaserWeldingRecipeNo, id)) return;
|
|
if (!TrySetReportData(BStageLaserWeldingN2PurgeFlow, RecipeStageB.N2PressMFC)) return;
|
|
if (!TrySetReportData(BStageLaserWeldingPosition, RecipeStageB.AxisZPosition)) return;
|
|
if (!TrySetReportData(BStageLaserLineSpeed, RecipeStageB.StraightParam.Velocity)) return;
|
|
if (!TrySetReportData(BStageLaserCornerSpeed, RecipeStageB.CurveParam.Velocity)) return;
|
|
if (!TrySetReportData(BStageLaserLinePowerCore, RecipeStageB.StraightParam.CorePowerW)) return;
|
|
if (!TrySetReportData(BStageLaserLinePowerRing, RecipeStageB.StraightParam.RingPowerW)) return;
|
|
if (!TrySetReportData(BStageLaserCornerPowerCore, RecipeStageB.CurveParam.CorePowerW)) return;
|
|
if (!TrySetReportData(BStageLaserCornerPowerRing, RecipeStageB.CurveParam.RingPowerW)) return;
|
|
if (!TrySetReportData(BStageLaserRampingPowerStarting, RecipeStageB.RampingOnStartPower)) return;
|
|
if (!TrySetReportData(BStageLaserRampingLengthStarting, RecipeStageB.RampingOnOverlapDist)) return;
|
|
if (!TrySetReportData(BStageLaserRampingPowerOverpath, RecipeStageB.RampingOffEndPower)) return;
|
|
if (!TrySetReportData(BStageLaserRampingLengthOverpath, RecipeStageB.RampingOffOverlapDist)) return;
|
|
|
|
//Write Parameter
|
|
UploadRmsParameter();
|
|
}
|
|
catch (Exception ex) {
|
|
Log.E($"UploadRecipeParameter 예외: {ex.Message}");
|
|
MessageUtil.ShowToast($"RMS 파라미터 업로드 중 오류 발생", Log);
|
|
_aurora.AlarmService.SetAlarm(AlarmCode.RMS_PAGE_SETTING_NULL);
|
|
}
|
|
}
|
|
|
|
// Server(PLC) => Client(Local PC)
|
|
public override void OnParameterReadRequest(EventMessage message)
|
|
{
|
|
Task.Run(() => {
|
|
if (_setting.IgnoreRMS) {
|
|
MessageUtil.ShowToast($"Not Used RMS Recipe", Log);
|
|
_aurora.AlarmService.SetAlarm(AlarmCode.RMS_NOT_USED_OPTION);
|
|
return;
|
|
}
|
|
|
|
// Read Parameter
|
|
if (UpdateRmsParameter() != E1.OK) {
|
|
MessageUtil.ShowToast($"RMS Parameter Read Fail", Log);
|
|
_aurora.AlarmService.SetAlarm(AlarmCode.RMS_RECIPE_EDIT_REQUEST_RESPONSE_TIMEOUT);
|
|
return;
|
|
}
|
|
|
|
// RMS Recipe Check
|
|
var recipeId = getReportData(AStageLaserWeldingRecipeNo).readValue(-1);
|
|
var recipe = _recipeEntry.Recipes().FirstOrDefault(x => x.Id == recipeId);
|
|
if (recipe == null) {
|
|
MessageUtil.ShowToast($"{recipeId}번 레시피 없음", Log);
|
|
_aurora.AlarmService.SetAlarm(AlarmCode.RMS_RECIPE_EDIT_REQUEST_RESPONSE_TIMEOUT);
|
|
return;
|
|
}
|
|
var RecipeStageA = _recipeEntry.RecipeItem(recipeId, RecipeIds.StageAMainRecipe) as MainRecipe;
|
|
var RecipeStageB = _recipeEntry.RecipeItem(recipeId, RecipeIds.StageBMainRecipe) as MainRecipe;
|
|
|
|
var RecipeBeforeChangedStageA = RecipeStageA.Clone() as MainRecipe;
|
|
var RecipeBeforeChangedStageB = RecipeStageB.Clone() as MainRecipe;
|
|
|
|
RecipeStageA.N2PressMFC = getReportData(AStageLaserWeldingN2PurgeFlow).readValue(RecipeStageA.N2PressMFC);
|
|
RecipeStageA.AxisZPosition = getReportData(AStageLaserWeldingPosition).readValue(RecipeStageA.AxisZPosition);
|
|
RecipeStageA.StraightParam.Velocity = getReportData(AStageLaserLineSpeed).readValue(RecipeStageA.StraightParam.Velocity);
|
|
RecipeStageA.CurveParam.Velocity = getReportData(AStageLaserCornerSpeed).readValue(RecipeStageA.CurveParam.Velocity);
|
|
RecipeStageA.StraightParam.CorePowerW = getReportData(AStageLaserLinePowerCore).readValue(RecipeStageA.StraightParam.CorePowerW);
|
|
RecipeStageA.StraightParam.RingPowerW = getReportData(AStageLaserLinePowerRing).readValue(RecipeStageA.StraightParam.RingPowerW);
|
|
RecipeStageA.CurveParam.CorePowerW = getReportData(AStageLaserCornerPowerCore).readValue(RecipeStageA.CurveParam.CorePowerW);
|
|
var CurvRingPowerStageA = getReportData(AStageLaserCornerPowerRing).readValue(RecipeStageA.CurveParam.RingPowerW);
|
|
RecipeStageA.RampingOnStartPower = getReportData(AStageLaserRampingPowerStarting).readValue(RecipeStageA.RampingOnStartPower);
|
|
RecipeStageA.RampingOnOverlapDist = getReportData(AStageLaserRampingLengthStarting).readValue(RecipeStageA.RampingOnOverlapDist);
|
|
RecipeStageA.RampingOffEndPower = getReportData(AStageLaserRampingPowerOverpath).readValue(RecipeStageA.RampingOffEndPower);
|
|
RecipeStageA.RampingOffOverlapDist = getReportData(AStageLaserRampingLengthOverpath).readValue(RecipeStageA.RampingOffOverlapDist);
|
|
|
|
RecipeStageB.N2PressMFC = getReportData(BStageLaserWeldingN2PurgeFlow).readValue(RecipeStageB.N2PressMFC);
|
|
RecipeStageB.AxisZPosition = getReportData(BStageLaserWeldingPosition).readValue(RecipeStageB.AxisZPosition);
|
|
RecipeStageB.StraightParam.Velocity = getReportData(BStageLaserLineSpeed).readValue(RecipeStageB.StraightParam.Velocity);
|
|
RecipeStageB.CurveParam.Velocity = getReportData(BStageLaserCornerSpeed).readValue(RecipeStageB.CurveParam.Velocity);
|
|
RecipeStageB.StraightParam.CorePowerW = getReportData(BStageLaserLinePowerCore).readValue(RecipeStageB.StraightParam.CorePowerW);
|
|
RecipeStageB.StraightParam.RingPowerW = getReportData(BStageLaserLinePowerRing).readValue(RecipeStageB.StraightParam.RingPowerW);
|
|
RecipeStageB.CurveParam.CorePowerW = getReportData(BStageLaserCornerPowerCore).readValue(RecipeStageB.CurveParam.CorePowerW);
|
|
var CurvRingPowerStageB = getReportData(BStageLaserCornerPowerRing).readValue(RecipeStageB.CurveParam.RingPowerW);
|
|
RecipeStageB.RampingOnStartPower = getReportData(BStageLaserRampingPowerStarting).readValue(RecipeStageB.RampingOnStartPower);
|
|
RecipeStageB.RampingOnOverlapDist = getReportData(BStageLaserRampingLengthStarting).readValue(RecipeStageB.RampingOnOverlapDist);
|
|
RecipeStageB.RampingOffEndPower = getReportData(BStageLaserRampingPowerOverpath).readValue(RecipeStageB.RampingOffEndPower);
|
|
RecipeStageB.RampingOffOverlapDist = getReportData(BStageLaserRampingLengthOverpath).readValue(RecipeStageB.RampingOffOverlapDist);
|
|
|
|
// Recipe Save
|
|
var editRequestRecipe = _recipeEntry.Recipes().FirstOrDefault(x => x.Id == recipeId);
|
|
_aurora.RecipeManager.SaveRecipeItem(editRequestRecipe, RecipeIds.StageAMainRecipe, RecipeStageA);
|
|
_aurora.RecipeManager.SaveRecipeItem(editRequestRecipe, RecipeIds.StageBMainRecipe, RecipeStageB);
|
|
|
|
//Compare 추가
|
|
var diffs = new ObservableCollection<PropertyDiff>();
|
|
CompareHelper.Fill(RecipeBeforeChangedStageA, RecipeStageA, diffs,
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.N2PressMFC), x => x.N2PressMFC),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.AxisZPosition), x => x.AxisZPosition),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.StraightParam.Velocity), x => x.StraightParam.Velocity),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.CurveParam.Velocity), x => x.CurveParam.Velocity),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.StraightParam.CorePowerW), x => x.StraightParam.CorePowerW),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.StraightParam.RingPowerW), x => x.StraightParam.RingPowerW),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.CurveParam.CorePowerW), x => x.CurveParam.CorePowerW),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.RampingOnStartPower), x => x.RampingOnStartPower),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.RampingOnOverlapDist), x => x.RampingOnOverlapDist),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.RampingOffEndPower), x => x.RampingOffEndPower),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.RampingOffOverlapDist), x => x.RampingOffOverlapDist)
|
|
);
|
|
if(diffs.Count > 0) {
|
|
Log.FuncI("StageA Recipe Changed");
|
|
_aurora.RecipeManager.RchHandler().AppendChangedItem(recipe.Name + "-StageA", diffs);
|
|
foreach (var diff in diffs)
|
|
Log.V($"{diff.ToString()}");
|
|
}
|
|
|
|
CompareHelper.Fill(RecipeBeforeChangedStageB, RecipeStageB, diffs,
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.N2PressMFC), x => x.N2PressMFC),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.AxisZPosition), x => x.AxisZPosition),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.StraightParam.Velocity), x => x.StraightParam.Velocity),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.CurveParam.Velocity), x => x.CurveParam.Velocity),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.StraightParam.CorePowerW), x => x.StraightParam.CorePowerW),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.StraightParam.RingPowerW), x => x.StraightParam.RingPowerW),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.CurveParam.CorePowerW), x => x.CurveParam.CorePowerW),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.RampingOnStartPower), x => x.RampingOnStartPower),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.RampingOnOverlapDist), x => x.RampingOnOverlapDist),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.RampingOffEndPower), x => x.RampingOffEndPower),
|
|
new CompareHelper.FieldSpec<MainRecipe>(nameof(MainRecipe.RampingOffOverlapDist), x => x.RampingOffOverlapDist)
|
|
);
|
|
if (diffs.Count > 0) {
|
|
Log.FuncI("StageB Recipe Changed");
|
|
_aurora.RecipeManager.RchHandler().AppendChangedItem(recipe.Name + "-StageB", diffs);
|
|
foreach (var diff in diffs)
|
|
Log.V($"{diff.ToString()}");
|
|
}
|
|
|
|
// Activated Recipe를 자동으로 변경 >> ActivedRecipe Change Event를 통해서 써주기까지 함
|
|
var preActivatedRecipe = _aurora.RecipeManager.ActivatedRecipe();
|
|
_aurora.RecipeManager.ActivateRecipe(recipe.Id, "RMS Request");
|
|
MessageUtil.ShowToast($"RMS Change Recipe Parameter & Activated Recipe ( {preActivatedRecipe.Id} -> {recipe.Id} )", Log);
|
|
|
|
// Complete
|
|
if (!ReportChangeConfirm()) {
|
|
MessageUtil.ShowToast($"RMS Change Recipe Ack Timeout", Log);
|
|
_aurora.AlarmService.SetAlarm(AlarmCode.RMS_RECIPE_EDIT_REQUEST_RESPONSE_TIMEOUT);
|
|
return;
|
|
}
|
|
|
|
MessageUtil.ShowToast($"Complete OnParameterReadRequest", Log);
|
|
});
|
|
}
|
|
}
|
|
}
|