188 lines
9.1 KiB
C#
188 lines
9.1 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.Api.Devices;
|
|
using Aurora.Util.HislogPlus;
|
|
using Aurora.View;
|
|
using AuroraLaser;
|
|
using CoreUnit.Control.UserControl.Canvas;
|
|
using CoreUnit.Scanner.UserControl.ScannerCanvas;
|
|
using DB.Recipe;
|
|
using GUI;
|
|
using Hermes;
|
|
using ILSOS_PrismaticScanner.Alarm;
|
|
using ILSOS_PrismaticScanner.Device;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Reactive.Linq;
|
|
using System.Reflection;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
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_PrismaticScanner.Device.PLCControllerPrismaticScanner;
|
|
|
|
namespace ILSOS_PrismaticScanner.Recipes
|
|
{
|
|
public class RMSHandlerForScanner : RMSHandler
|
|
{
|
|
private const string RecipeNo = "RecipeNo";
|
|
//$"{nameof(param.MarkSpeed)}_{parameterNo}"
|
|
|
|
private PLCControllerPrismaticScanner _plc;
|
|
private SettingRmsDataList _RmsSetting;
|
|
public override void RegistryDeviceHandler(IAuroraEnvironment aurora)
|
|
{
|
|
base.RegistryDeviceHandler(aurora);
|
|
_plc = aurora.DeviceManager[CommonDeviceIds.PLCDevice] as PLCControllerPrismaticScanner;
|
|
_RmsSetting = aurora.SettingEntry[CommonSettingIds.RmsDatas] as SettingRmsDataList;
|
|
|
|
// Aurora에서 제공하는 이벤트를 체인으로 사용하면 동작(Aurora가 저장 후 LASA가 저장하는)에 대한 우선순위가 보장이 안되기 때문에
|
|
aurora.EventObservable.AsObservable(CommonEventIds.EVENT_CHANGE_RECIPE_INFO)
|
|
.ObserveOnDispatcher()
|
|
.Select(param => (RecipeInfo)param.Param)
|
|
.Subscribe(OnUpdateCurrentActivatedRecipe);
|
|
}
|
|
|
|
private void OnUpdateCurrentActivatedRecipe(RecipeInfo info)
|
|
{
|
|
RecipeHelper.ReloadRecipe(info.Name);
|
|
UploadActivatedRecipeParameter();
|
|
}
|
|
|
|
private void UploadActivatedRecipeParameter()
|
|
{
|
|
// PC에 저장된 데이터를 PLC에 전달
|
|
for (int i = 0; i < 3; i++) {
|
|
ApplyParamToReport(ScannerCanvasUserCtrl.ScannerParams[i], i);
|
|
}
|
|
|
|
//Write Parameter
|
|
UploadRmsParameter();
|
|
}
|
|
|
|
// 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
|
|
int recipeId = getReportData(RecipeNo).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 RecipeBeforeChanged = RecipeHelper.getRecipeInfo(recipe.Name);
|
|
|
|
// Recipe Load
|
|
Application.Current.Dispatcher.Invoke(() => {
|
|
RecipeHelper.ReloadRecipe(recipe.Name);
|
|
});
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
ApplyReportToParam(ScannerCanvasUserCtrl.ScannerParams[i], i);
|
|
}
|
|
|
|
// PLC에서 받은 데이터를 저장 후 다시 로드
|
|
Application.Current.Dispatcher.Invoke(() => {
|
|
RecipeHelper.SaveRecipe(recipe.Name);
|
|
});
|
|
|
|
var ChangedRecipe = RecipeHelper.getRecipeInfo(recipe.Name);
|
|
|
|
var diffs = new ObservableCollection<PropertyDiff>();
|
|
for (int i = 0; i < 3; i++) {
|
|
CompareHelper.Fill(RecipeBeforeChanged.ReadOnlyScanParams[i], ChangedRecipe.ReadOnlyScanParams[i], diffs,
|
|
new CompareHelper.FieldSpec<ScannerParam>("Draw Speed", x => x.MarkSpeed),
|
|
new CompareHelper.FieldSpec<ScannerParam>("Jump Speed", x => x.JumpSpeed),
|
|
new CompareHelper.FieldSpec<ScannerParam>("Power#1", x => x.LaserPower1),
|
|
new CompareHelper.FieldSpec<ScannerParam>("Power#2", x => x.LaserPower2),
|
|
new CompareHelper.FieldSpec<ScannerParam>(nameof(ScannerParam.RampingStartPower), x => x.RampingStartPower),
|
|
new CompareHelper.FieldSpec<ScannerParam>(nameof(ScannerParam.RampingStartDist), x => x.RampingStartDist),
|
|
new CompareHelper.FieldSpec<ScannerParam>(nameof(ScannerParam.RampingEndPower), x => x.RampingEndPower),
|
|
new CompareHelper.FieldSpec<ScannerParam>(nameof(ScannerParam.RampingEndDist), x => x.RampingEndDist)
|
|
);
|
|
if (diffs.Count > 0) {
|
|
Log.FuncI($"ScanParameter{i + 1} Recipe Changed");
|
|
_aurora.RecipeManager.RchHandler().AppendChangedItem(recipe.Name + $"-ScanParam{i + 1}", diffs);
|
|
foreach (var diff in diffs)
|
|
Log.V($"{diff.ToString()}");
|
|
}
|
|
}
|
|
// Activated Recipe를 자동으로 변경 >> ActivedRecipe Change Event를 통해서 써주기까지 함
|
|
/// <Method 참조 cref="WeldingCommon.Views.UCScannerObjectTeachingViewModel.OnActivatedRecipe"/>
|
|
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);
|
|
});
|
|
}
|
|
|
|
private void ApplyReportToParam(ScannerParam param, int parameterNo)
|
|
{
|
|
// Report -> 모델 (readValue)
|
|
param.MarkSpeed = getReportData($"{nameof(param.MarkSpeed)}_{parameterNo}").readValue(param.MarkSpeed);
|
|
param.JumpSpeed = getReportData($"{nameof(param.JumpSpeed)}_{parameterNo}").readValue(param.JumpSpeed);
|
|
param.LaserPower1 = getReportData($"{nameof(param.LaserPower1)}_{parameterNo}").readValue(param.LaserPower1);
|
|
param.LaserPower2 = getReportData($"{nameof(param.LaserPower2)}_{parameterNo}").readValue(param.LaserPower2);
|
|
param.RampingStartPower = getReportData($"{nameof(param.RampingStartPower)}_{parameterNo}").readValue(param.RampingStartPower);
|
|
param.RampingStartDist = getReportData($"{nameof(param.RampingStartDist)}_{parameterNo}").readValue(param.RampingStartDist);
|
|
param.RampingEndPower = getReportData($"{nameof(param.RampingEndPower)}_{parameterNo}").readValue(param.RampingEndPower);
|
|
param.RampingEndDist = getReportData($"{nameof(param.RampingEndDist)}_{parameterNo}").readValue(param.RampingEndDist);
|
|
}
|
|
|
|
private void ApplyParamToReport(ScannerParam param, int parameterNo)
|
|
{
|
|
// 26.04.14 확인용
|
|
// 모델 -> Report (Value = )
|
|
getReportData($"RecipeNo").Value = _aurora.RecipeManager.ActivatedRecipe().Id;
|
|
getReportData($"{nameof(param.MarkSpeed)}_{parameterNo}").Value = param.MarkSpeed;
|
|
getReportData($"{nameof(param.JumpSpeed)}_{parameterNo}").Value = param.JumpSpeed;
|
|
getReportData($"{nameof(param.LaserPower1)}_{parameterNo}").Value = param.LaserPower1;
|
|
getReportData($"{nameof(param.LaserPower2)}_{parameterNo}").Value = param.LaserPower2;
|
|
getReportData($"{nameof(param.RampingStartPower)}_{parameterNo}").Value = param.RampingStartPower;
|
|
getReportData($"{nameof(param.RampingStartDist)}_{parameterNo}").Value = param.RampingStartDist;
|
|
getReportData($"{nameof(param.RampingEndPower)}_{parameterNo}").Value = param.RampingEndPower;
|
|
getReportData($"{nameof(param.RampingEndDist)}_{parameterNo}").Value = param.RampingEndDist;
|
|
}
|
|
}
|
|
}
|