using MainShell.Common; using MainShell.DeviceMaintance.Model; using MainShell.EventArgsFolder; using MainShell.Hardware; using MainShell.Models; using MainShell.Motion; using MainShell.Parameter; using MainShell.Process; using MainShell.Recipe.Models; using MaxwellControl.Tools; using MaxwellFramework.Core.Interfaces; using MW.WorkFlow; using MwFramework.Device; using MwFramework.ManagerService; using MXJM.Parameter.Maintance; using Stylet; using StyletIoC; using System; using System.Collections.ObjectModel; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; namespace MainShell.DeviceMaintance.ViewModel { public class NeedleCaliViewModel : DeviceMaintanceBaseViewModel, IPage, IHandle { private const string CalibrationWorkflowName = "NeedleZCalibration"; private readonly IParameterManager _parameterManager; private readonly IParamList _paramList; private readonly SafeAxisMotion _safeAxisMotion; private readonly StagePlatformMotionService _stagePlatformMotionService; private readonly HardwareManager _hardwareManager; private readonly IDeviceIoMonitorService _deviceIoMonitorService; private readonly IEventAggregator _eventAggregator; private readonly WorkflowRunner _workflowRunner; private readonly NeedleZCalibrationService _needleZCalibrationService; private ParameterHelper _parameterHelper = new ParameterHelper(); private NeedleCalibrationSetting _needleCalibrationSetting; private NeedleZCalibrationItem _needleZCalibrationItem; private CancellationTokenSource _cancellationTokenSource; private bool _uiEnable = true; private bool _autoRaiseZ1 = true; private bool _isEnabledNeedleCalibrationControl = true; private NeedleTouchRecord _selectedRecord; public NeedleCaliViewModel(IParameterManager parameterManager, SafeAxisMotion safeAxisMotion, StagePlatformMotionService stagePlatformMotionService, HardwareManager hardwareManager, IDeviceIoMonitorService deviceIoMonitorService, IEventAggregator eventAggregator, WorkflowRunner workflowRunner, NeedleZCalibrationService needleZCalibrationService) { _parameterManager = parameterManager; _paramList = parameterManager as IParamList; _safeAxisMotion = safeAxisMotion; _stagePlatformMotionService = stagePlatformMotionService; _hardwareManager = hardwareManager; _deviceIoMonitorService = deviceIoMonitorService; _eventAggregator = eventAggregator; _workflowRunner = workflowRunner; _needleZCalibrationService = needleZCalibrationService; _eventAggregator?.Subscribe(this); } public string Name { get; set; } = "NeedleCaliMaint"; public ParameterHelper ParameterHelper { get => _parameterHelper; set => SetAndNotify(ref _parameterHelper, value); } public NeedleCalibrationSetting NeedleCalibrationSetting { get => _needleCalibrationSetting; set => SetAndNotify(ref _needleCalibrationSetting, value); } public NeedleZCalibrationItem NeedleZCalibrationItem { get => _needleZCalibrationItem; set => SetAndNotify(ref _needleZCalibrationItem, value); } public bool UiEnable { get => _uiEnable; set { if (SetAndNotify(ref _uiEnable, value)) { OnUiStateChanged(value); } } } public bool AutoRaiseZ1 { get => _autoRaiseZ1; set => SetAndNotify(ref _autoRaiseZ1, value); } public bool IsEnabledNeedleCalibrationControl { get => _isEnabledNeedleCalibrationControl; set => SetAndNotify(ref _isEnabledNeedleCalibrationControl, value); } public NeedleTouchRecord SelectedRecord { get => _selectedRecord; set => SetAndNotify(ref _selectedRecord, value); } protected override void OnViewLoaded() { base.OnViewLoaded(); LoadParameters(); } protected override void OnClose() { _eventAggregator?.Unsubscribe(this); base.OnClose(); } public void Handle(NeedleZCalibrationResultEventArgs message) { if (message == null || NeedleZCalibrationItem == null) { return; } CommonUti.RunOnUi(() => { EnsureRecordCollection(); int index = NeedleZCalibrationItem.NeedleTouchRecords.Count + 1; NeedleZCalibrationItem.NeedleTouchHeight = message.Result; NeedleZCalibrationItem.NeedleTouchRecords.Add(new NeedleTouchRecord { CurrentCount = index, Height = message.Result, }); SelectedRecord = NeedleZCalibrationItem.NeedleTouchRecords.LastOrDefault(); RefreshStatistics(); }); } public void MoveCzCurrentLocation() { ExecuteMotion(() => { if (NeedleZCalibrationItem == null) { return; } _safeAxisMotion.MoveAbs(_hardwareManager.Axis_SZ, NeedleZCalibrationItem.CZHeight); _stagePlatformMotionService.MoveFlat(NeedleZCalibrationItem.StageHeight); }); } public void ReadGantry2CurrentLocation() { CommonUti.RunOnUi(() => { if (NeedleZCalibrationItem == null) { return; } NeedleZCalibrationItem.Gantry2AvoidPositionX = GetAxisPosition(_hardwareManager.Axis_X2); NeedleZCalibrationItem.Gantry2AvoidPositionY = GetAxisPosition(_hardwareManager.Axis_Y2); }); } public void MoveGantry2ToCurrentLocation() { ExecuteMotion(() => { if (NeedleZCalibrationItem == null) { return; } _safeAxisMotion.MoveAbs(_hardwareManager.Axis_X2, NeedleZCalibrationItem.Gantry2AvoidPositionX); _safeAxisMotion.MoveAbs(_hardwareManager.Axis_Y2, NeedleZCalibrationItem.Gantry2AvoidPositionY); }); } public void ReadSupportPinCurrentLocation() { CommonUti.RunOnUi(() => { if (NeedleZCalibrationItem == null) { return; } NeedleZCalibrationItem.SupportPinPositionX = GetAxisPosition(_hardwareManager.Axis_X1); NeedleZCalibrationItem.SupportPinPositionY = GetAxisPosition(_hardwareManager.Axis_Y1); }); } public void MoveSupportPinToCurrentLocation() { ExecuteMotion(() => { if (NeedleZCalibrationItem == null) { return; } _safeAxisMotion.MoveAbs(_hardwareManager.Axis_X1, NeedleZCalibrationItem.SupportPinPositionX); _safeAxisMotion.MoveAbs(_hardwareManager.Axis_Y1, NeedleZCalibrationItem.SupportPinPositionY); }); } public void SetBaseHeight() { CommonUti.RunOnUi(() => { if (NeedleZCalibrationItem == null) { return; } NeedleZCalibrationItem.NeedleTouchHeightBase = NeedleZCalibrationItem.CurrentNeedleTouchHeight; RefreshStatistics(); }); } public async void StartSingleZ1CalibrationAsync() { await ExecuteCalibrationAsync(1, false); } public void UseCurrentZ1Height() { CommonUti.RunOnUi(() => { if (NeedleZCalibrationItem == null) { return; } NeedleZCalibrationItem.CurrentNeedleTouchHeight = NeedleZCalibrationItem.NeedleTouchHeightAve + NeedleZCalibrationItem.KnifeOffset; RefreshStatistics(); SaveParameterInternal(true); }); } public async void StartCalibrationAsync() { await ExecuteCalibrationAsync(Math.Max(1, NeedleZCalibrationItem != null ? NeedleZCalibrationItem.NeedleTouchCount : 1), true); } public async void StopCalibrationAsync() { _cancellationTokenSource?.Cancel(); if (_workflowRunner != null && _workflowRunner.IsRunning) { await _workflowRunner.StopAsync(); } _safeAxisMotion.Stop( _hardwareManager.Axis_X1, _hardwareManager.Axis_X2, _hardwareManager.Axis_Y1, _hardwareManager.Axis_Y2, _hardwareManager.Axis_Z1, _hardwareManager.Axis_SZ, _hardwareManager.Axis_Stage_Z7, _hardwareManager.Axis_Stage_Z8, _hardwareManager.Axis_Stage_Z9); UiEnable = true; } public void SaveCalibration() { CommonUti.RunOnUi(() => SaveParameterInternal(true)); } private async Task ExecuteCalibrationAsync(int touchCount, bool clearRecords) { if (NeedleZCalibrationItem == null) { LoadParameters(); } if (NeedleZCalibrationItem == null) { LocalizedMessageBox.Show(MessageKey.NeedleCalibrationLoadFailed, MessageKey.TitleError); return; } if (touchCount <= 0) { LocalizedMessageBox.Show(MessageKey.NeedleCalibrationTouchCountMustGreaterThanZero, MessageKey.TitleWarning); return; } InitCancelToken(); if (clearRecords) { CommonUti.RunOnUi(() => { EnsureRecordCollection(); NeedleZCalibrationItem.NeedleTouchRecords.Clear(); NeedleZCalibrationItem.NeedleTouchHeight = 0; NeedleZCalibrationItem.NeedleTouchHeightAve = 0; NeedleZCalibrationItem.CurrentNeedleTouchHeight = 0; NeedleZCalibrationItem.NeedleTouchOffset = 0; }); } UiEnable = false; try { WorkflowContext context = new WorkflowContext(); NeedleZCalibrationWorkflowData workflowData = new NeedleZCalibrationWorkflowData( CalibrationWorkflowName, touchCount, AutoRaiseZ1, _cancellationTokenSource.Token, _eventAggregator, _hardwareManager, _safeAxisMotion, _parameterManager, _deviceIoMonitorService); context.SetData(WorkflowContextKeys.WorkflowName, workflowData.WorkflowName); context.SetData(WorkflowContextKeys.NeedleZCalibrationWorkflowData, workflowData); NeedleZCalibrationActivity activity = new NeedleZCalibrationActivity(_needleZCalibrationService); WorkflowRunCompletedEventArgs result = await _workflowRunner.RunActivityWithResultAsync(activity, context); switch (result != null ? result.FinalState : WorkflowState.Faulted) { case WorkflowState.Completed: RefreshStatistics(); LocalizedMessageBox.Show(MessageKey.NeedleCalibrationCompleted, MessageKey.TitleInfo); break; case WorkflowState.Canceled: LocalizedMessageBox.Show(MessageKey.NeedleCalibrationStopped, MessageKey.TitleWarning); break; case WorkflowState.Faulted: string failureMessage = string.IsNullOrWhiteSpace(result != null ? result.FailureMessage : null) ? (result != null ? result.Error : null) : result.FailureMessage; if (string.IsNullOrWhiteSpace(failureMessage)) { LocalizedMessageBox.Show(MessageKey.ProcessFailed, MessageKey.TitleError); } else { LocalizedMessageBox.ShowFormat(MessageKey.ProcessFailedWithReason, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error, failureMessage); } break; } } catch (OperationCanceledException) { LocalizedMessageBox.Show(MessageKey.NeedleCalibrationCanceled, MessageKey.TitleWarning); } catch (Exception ex) { LocalizedMessageBox.ShowFormat(MessageKey.ProcessFailedWithReason, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error, ex.Message); } finally { UiEnable = true; } } private void RefreshStatistics() { if (NeedleZCalibrationItem == null) { return; } ObservableCollection records = NeedleZCalibrationItem.NeedleTouchRecords; if (records == null || records.Count == 0) { NeedleZCalibrationItem.NeedleTouchHeightAve = 0; NeedleZCalibrationItem.CurrentNeedleTouchHeight = 0; NeedleZCalibrationItem.NeedleTouchOffset = 0; return; } NeedleZCalibrationItem.NeedleTouchHeightAve = records.Average(x => x.Height); NeedleZCalibrationItem.CurrentNeedleTouchHeight = NeedleZCalibrationItem.NeedleTouchHeightAve + NeedleZCalibrationItem.KnifeOffset; NeedleZCalibrationItem.NeedleTouchOffset = NeedleZCalibrationItem.CurrentNeedleTouchHeight - NeedleZCalibrationItem.NeedleTouchHeightBase; } private void SaveParameterInternal(bool showSuccessMessage) { NeedleCalibrationSetting?.Write(); ParameterHelper?.RaiseValueAccept(); if (showSuccessMessage) { LocalizedMessageBox.Show(MessageKey.CommonSaveSucceeded, MessageKey.TitleInfo); } } private void LoadParameters() { NeedleCalibrationSetting = _paramList?.GetParameter(); NeedleZCalibrationItem = NeedleCalibrationSetting != null ? NeedleCalibrationSetting.NeedleZCalibrationItem : null; EnsureRecordCollection(); } private void EnsureRecordCollection() { if (NeedleZCalibrationItem != null && NeedleZCalibrationItem.NeedleTouchRecords == null) { NeedleZCalibrationItem.NeedleTouchRecords = new ObservableCollection(); } } private void InitCancelToken() { _cancellationTokenSource?.Cancel(); _cancellationTokenSource?.Dispose(); _cancellationTokenSource = new CancellationTokenSource(); } private double GetAxisPosition(IAxis axis) { if (axis == null) { return 0; } return axis.State != null ? axis.State.ActualPos : axis.GetPositionImmediate(); } private void ExecuteMotion(Action action) { CommonUti.RunOnUi(() => { try { action?.Invoke(); } catch (Exception ex) { LocalizedMessageBox.ShowFormat(MessageKey.ProcessFailedWithReason, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error, ex.Message); } }); } } }