using CordonelPreadjustmentUi.Helper; using CordonelPreadjustmentUi.Processes.Itinerary; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Xylem.Common.Ui.CordonelPreadjustmentUi; using static CordonelPreadjustmentUi.PreAdjustmentControl; namespace CordonelPreadjustmentUi.Processes { public abstract class BaseProcess : IProcess { public ProcessProgress CurrentProcessProgress; internal List MeterStateCtls = new List(); internal List TempMeterStateCtls = new List(); internal readonly string ProcessName; public readonly StatusPanelItems PanelState; public readonly string FailedMessage; public readonly string PerformMessage; public readonly int ExpectedTimeS; public DateTimeOffset StartTime; public BaseProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS = null) { ProcessName = processName; PanelState = panelState; FailedMessage = failedMessage; PerformMessage = performMessage; StartTime = DateTimeOffset.UtcNow; ExpectedTimeS = expectedTimeS.HasValue ? expectedTimeS.Value : 0; } internal List AllMeterStateCtrls() { var r = new List(); r.AddRange(MeterStateCtls); r.AddRange(TempMeterStateCtls); return r; } public ProcessProgress StartProcess(ProcessProgress pp, List MeterCtsl, List TempMeterCtls) { var listOfProcessTasks = new List(); try { StartTime = DateTimeOffset.UtcNow; MeterStateCtls = MeterCtsl; TempMeterStateCtls = TempMeterCtls; CurrentProcessProgress = pp; //SetUi //Check meters pp.Bubbles = true; pp.StatusLabel = PerformMessage; pp.DebugMessage($"{ProcessName} procedure started"); try { listOfProcessTasks = StartWork(); } catch (Exception innerEX) { pp.DebugMessage($"Error on Start Work ex:{innerEX}"); } listOfProcessTasks.ForEach(t => t.Start()); } catch (Exception ex) { throw new ApplicationException("Error on prepare process start", ex); } var completTasks = new Task(() => { try { while (!listOfProcessTasks.All(t => t.IsCompleted)) { if (pp.CancellationSource != null && pp.CancellationSource.IsCancellationRequested) { return; } Thread.Sleep(5); } GetSequenceResult($"{ProcessName} sequence"); pp.IsBusy = false; } catch (Exception ex) { throw new ApplicationException("Error on waiting for completition", ex); } }); completTasks.Start(); //todo for all task failed offer a retry //SetUi //Check meters and remove meters return pp; } public abstract List StartWork(); public bool ActivityCheck(ProcessProgress pp, ActivityCheckMultiPathDataLogContainer> listOfTotalTimeOfFlightSPerPath, int seconds) { //no update or last update was more AmpTestActivityCheckInverval ago if (listOfTotalTimeOfFlightSPerPath.GetSecondsSinceLastUpdate() < 0 || listOfTotalTimeOfFlightSPerPath.GetSecondsSinceLastUpdate() > pp.Setting.AmpTestActivityCheckInverval) { return false; } return true; } public void GetSequenceResult(String name) { #region Definitions and initializations CurrentProcessProgress.Aborted = false; Boolean NoDeviceEnabled = true; Boolean AtLeastOneMeterEnabled = false; Boolean AtLeastOneThermometerEnabled = false; Boolean AllDevicesFailed = true; Boolean AllMetersOk = true; Boolean AllMetersFailed = true; Boolean AllThermometersFailed = true; Boolean AllThermometersOk = true; String MeterSeqSucceeded = String.Empty; String MeterSeqFailed = String.Empty; String ThermoSeqSucceeded = String.Empty; String ThermoSeqFailed = String.Empty; #endregion #region No device enabled NoDeviceEnabled = !MeterStateCtls.Any(m => m.IsEnabled); AtLeastOneMeterEnabled = MeterStateCtls.Any(m => m.IsEnabled); AllDevicesFailed = AllMeterStateCtrls().Where(e => e.Enabled).All(f => f.Failed); AllMetersOk = !AllDevicesFailed; AllMetersFailed = MeterStateCtls.Where(e => e.Enabled).All(f => f.Failed); AllThermometersFailed = TempMeterStateCtls.Where(e => e.Enabled).All(f => f.Failed); AtLeastOneThermometerEnabled = TempMeterStateCtls.Any(e => e.Enabled); AllThermometersOk = !AllThermometersFailed; if (NoDeviceEnabled) { CurrentProcessProgress.DebugMessage($"\tAPPLICATION:\t\t No device enabled"); CurrentProcessProgress.DebugMessage($"\tAPPLICATION:\t\t ZEROFLOW CALIBRATION sequence failed"); CurrentProcessProgress.Aborted = true; return; } #endregion #region At least one METER/ THERMOMETER enabled AtLeastOneMeterEnabled = MeterStateCtls.Any(m => m.IsEnabled); AtLeastOneThermometerEnabled = TempMeterStateCtls.Any(m => m.IsEnabled); #endregion #region All Devices failed if (AtLeastOneMeterEnabled | AtLeastOneThermometerEnabled) { AllDevicesFailed = MeterStateCtls.Where(m => m.IsEnabled).All(m => m.Failed); if (AllDevicesFailed) { #region All devices failed CurrentProcessProgress.Aborted = true; CurrentProcessProgress.DebugMessage($"{name} failed!"); CurrentProcessProgress.DebugMessage($"ZEROFLOW CALIBRATION sequence failed"); CurrentProcessProgress.ForceFailedMessage(); return; #endregion } } #endregion #region Meter string if (!AtLeastOneMeterEnabled) { CurrentProcessProgress.Aborted = true; CurrentProcessProgress.DebugMessage($"No METER enabled"); CurrentProcessProgress.DebugMessage($"ZEROFLOW CALIBRATION sequence failed"); return; } foreach (var checkMeter in MeterStateCtls) { if (checkMeter.IsEnabled & !checkMeter.Failed) { MeterSeqSucceeded = $"{MeterSeqSucceeded} Meter {checkMeter.Slot} {Environment.NewLine}"; } if (checkMeter.IsEnabled & checkMeter.Failed) { MeterSeqFailed = $"{MeterSeqFailed} Meter {checkMeter.Slot} {Environment.NewLine}"; } } #endregion #region AllMetersOk/ Failed AllMetersOk = !MeterStateCtls.Any(m => m.IsEnabled && m.Failed); AllMetersFailed = !MeterStateCtls.Where(m => m.IsEnabled).All(m => !m.Failed); #endregion #region Summary METER if (AtLeastOneMeterEnabled) { #region All METERS FAILED if (AllMetersFailed) { CurrentProcessProgress.Aborted = true; CurrentProcessProgress.DebugMessage($"{name} failed at all METERS"); } #endregion #region All METERS ok if (AllMetersOk) { CurrentProcessProgress.DebugMessage($"SUMMARY: "); CurrentProcessProgress.DebugMessage($"{name} {name} successful at all {MeterStateCtls.Count(a => a.IsEnabled)} Meters"); } #endregion if (!AllMetersOk && !AllMetersFailed) { if (AtLeastOneMeterEnabled) { CurrentProcessProgress.DebugMessage($"SUMMARY:"); if (String.IsNullOrEmpty(MeterSeqFailed)) { MeterSeqFailed = "None"; } CurrentProcessProgress.DebugMessage($"{name} failed at {MeterSeqFailed}"); if (String.IsNullOrEmpty(MeterSeqSucceeded)) { MeterSeqSucceeded = "None"; } CurrentProcessProgress.DebugMessage($"{name} successful at {MeterSeqSucceeded}"); } } } #endregion #region Summary THERMOMETER if (AtLeastOneThermometerEnabled) { CurrentProcessProgress.DebugMessage($"SUMMARY: "); if (AllThermometersFailed) { CurrentProcessProgress.Aborted = true; CurrentProcessProgress.DebugMessage($"{name} failed at all THERMOMETERS"); } if (AllThermometersOk) { CurrentProcessProgress.DebugMessage($"{name} successful at all THERMOMETERS"); } if (!AllThermometersOk && !AllThermometersFailed) { if (AtLeastOneThermometerEnabled) { if (String.IsNullOrEmpty(ThermoSeqFailed)) { ThermoSeqFailed = "None"; } CurrentProcessProgress.DebugMessage($"{name} failed at {ThermoSeqFailed}"); if (String.IsNullOrEmpty(ThermoSeqSucceeded)) { ThermoSeqSucceeded = "None"; } CurrentProcessProgress.DebugMessage($"{name} successful at {ThermoSeqSucceeded}"); } } } #endregion if (CurrentProcessProgress.Aborted) { CurrentProcessProgress.DebugMessage($"{name} finished"); CurrentProcessProgress.DebugMessage($"ZEROFLOW CALIBRATION sequence failed"); } return; } public bool CheckAbort(bool resultFromAction, MeterStateControl ctl = null) { if (!resultFromAction || CurrentProcessProgress.CancellationSource.Token.IsCancellationRequested) { if (ctl != null) { ctl.Failed = true; } else { AllMeterStateCtrls().Where(e => e.IsEnabled).ToList().ForEach(f => f.Failed = true); } return true; } return false; } public bool ReadRegisterRetry(ZeroFlowGenesisMeter m, string displayName, string registerName, out byte[] ret) { var retRet = ReadRegister(m, displayName, registerName, out byte[] rr); if (!retRet) { retRet = ReadRegister(m, displayName, registerName, out rr); } ret = rr; return retRet; } public bool ReadRegister(ZeroFlowGenesisMeter m, string displayName, string registerName, out byte[] ret) { Thread.Sleep(100); CurrentProcessProgress.StatusLabel = PredefinedMessages.WaitUntilRegisterReadFinished(CurrentProcessProgress.Setting.Culture); var Ok = false; CurrentProcessProgress.DebugMessage($"Reading '{displayName}'-register", m.Slot, "CC", m.PcbId); try { ret = m.ReadRegister(registerName); CurrentProcessProgress.DebugMessage($"Reading '{displayName}'-register successful", m.Slot, "CC", m.PcbId); Ok = true; } catch (Exception e) { ret = null; CurrentProcessProgress.DebugMessage($"Reading '{displayName}'-register failed", m.Slot, "CC", m.PcbId); Ok = false; } return Ok; } public bool WriteRegisterSafe(ZeroFlowGenesisMeter m, string displayName, string registerName, T Value, bool CheckResult = true) { Thread.Sleep(100); CurrentProcessProgress.DebugMessage($"Writing {Value} to '{displayName}'-register", m.Slot, "CC", m.PcbId); var Ok = false; if (CheckResult) { Ok = m.WriteRegisterSafe(registerName, Value); } else { Ok = m.WriteRegisterUnsafe(registerName, Value); } if (Ok) { CurrentProcessProgress.DebugMessage($"Writing {Value} to '{displayName}'-register successful", m.Slot, "CC", m.PcbId); } else { CurrentProcessProgress.DebugMessage($"Writing {Value} to '{displayName}'-register failed", m.Slot, "CC", m.PcbId); } if (displayName == "WorkAround TriggerIdle") { Ok = m.WriteRegisterUnsafe("GENESISFLOW_LedMode", 6); } return Ok; } } }