using Logic.ProductionToProductMapper.Cordonel; using Newtonsoft.Json; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Xylem.Common.CommonCore.Configuration; using Xylem.Common.Hardware.Interfaces.Protocols.ProtocolCore.EventArguments; using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.EventArguments; using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords; using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore; using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Consts; using Xylem.Common.Hardware.WaterMeter.Genesis.Registers; using Xylem.Common.Hardware.WaterMeter.WaterMeterCore; using Xylem.Common.Logic.ProductionOrderCore.OrderData; using Xylem.Common.Logic.SoftwareAccessHelper; using XylemCommonUiLegacyGenCtl.DataPackage; using XylemCommonUiLegacyGenCtl.Enums; namespace XylemCommonUiLegacyGenCtl { public partial class ctlMeterReady : UserControl { public event EventHandler OnStateChanged; private MeterReadyResults FlowState = MeterReadyResults.NotStarted; private MeterReadyResults Path1State = MeterReadyResults.NotStarted; private MeterReadyResults Path2State = MeterReadyResults.NotStarted; private MeterReadyResults Path3State = MeterReadyResults.NotStarted; private ConcurrentBag FlowRecords; private ConcurrentBag PathRecords; private Task MainTask; private enum TaskState { //allGrey Init, SetSlot, SetPcbId, LoginInProgress, LoginDone, LedInProgress, LedDone, MessurementInProgress, MessurementDone, MessurementDoneWithHint, LoginFailed, LedFailed, MessurementFailed, Fatal, } private bool isBusy; private TaskState currentState = TaskState.Init; public string PcbId = "-"; private GenesisMeter meter; public string OrderNumber { get; set; } public string RadioAdress { get; set; } public string CustomerSerialNr { get; set; } public string CalibrationRun { get; set; } public int LastTestBechState { get; set; } public MeterSize Metersize { get; set; } = MeterSize.NA; public ctlMeterReady() { InitializeComponent(); } private void changeCurrentSlotState(TaskState NewState) { if (NewState != currentState) { currentState = NewState; OnStateChanged?.Invoke(currentState, EventArgs.Empty); } if (NewState >= TaskState.SetPcbId) { Invoke(new Action(() => { setUi(PcbId, NewState, FlowState, Path1State, Path2State, Path3State); })); } } private Color NonColor = Color.LightGray; private Color CurrentColor = Color.FromArgb(0xff, 0xf5, 0x9d); private Color alterColor = Color.FromArgb(0xff, 0xf9, 0xc4); private Color ErrorColor = Color.FromArgb(0xef, 0x53, 0x50); private Color DoneColor = Color.FromArgb(0x81, 0xc7, 0x84); private void setUi(string pcbId, TaskState newState, MeterReadyResults flowState, MeterReadyResults path1State, MeterReadyResults path2State, MeterReadyResults path3State) { lblPcbId.Text = pcbId; lblLogin.BackColor = NonColor; lblLed.BackColor = NonColor; lblDataOverall.BackColor = NonColor; lblDataDisplay.BackColor = NonColor; lblDataP1.BackColor = NonColor; lblDataP2.BackColor = NonColor; lblDataP3.BackColor = NonColor; if (newState == TaskState.LoginInProgress) { lblLogin.BackColor = CurrentColor; return; } if (newState == TaskState.Fatal || newState == TaskState.LoginFailed) { lblLogin.BackColor = ErrorColor; return; } lblDataDisplay.BackColor = MeterStateToColor(flowState); lblDataP1.BackColor = MeterStateToColor(path1State); lblDataP2.BackColor = MeterStateToColor(path2State); lblDataP3.BackColor = MeterStateToColor(path3State); if (newState >= TaskState.LoginDone) { lblLogin.BackColor = DoneColor; if (newState == TaskState.LedInProgress) { lblLed.BackColor = CurrentColor; return; } if (newState == TaskState.Fatal || newState == TaskState.LedFailed) { lblLed.BackColor = ErrorColor; return; } if (newState >= TaskState.LedDone) { lblLed.BackColor = DoneColor; if (newState == TaskState.MessurementInProgress) { lblDataOverall.BackColor = CurrentColor; return; } if (newState == TaskState.Fatal || newState == TaskState.MessurementFailed) { lblDataOverall.BackColor = ErrorColor; return; } if (newState == TaskState.MessurementDone || newState == TaskState.MessurementDoneWithHint) { lblDataOverall.BackColor = DoneColor; } } } } internal void SetPreadjustmentValue(bool @checked) { cbxDoPreajdustment.Checked = @checked; } internal void SetFlowCalibration(bool @checked) { cbDoFlowCalibration.Checked = @checked; } internal void SetCalibrationTarget(decimal value) { nudCalibrationTarget.Value = value; } internal void SetSlot(int key, Xylem.Common.Hardware.WaterMeter.WaterMeterCore.MeterBatch meterBatch) { changeCurrentSlotState(TaskState.SetSlot); meterSlot = key; lblSlot.Text = key.ToString(); overallMeterBatch = meterBatch; } private Color MeterStateToColor(MeterReadyResults state) { switch (state) { case MeterReadyResults.NotStarted: return NonColor; case MeterReadyResults.NoRecords: return ErrorColor; case MeterReadyResults.OnlyInvalidRecords: return ErrorColor; case MeterReadyResults.MixedInvalidRecords: return Color.Orange; case MeterReadyResults.OnlyValidRecords: return DoneColor; } return ErrorColor; } private void setMeterInfo(string SerialNumber, bool? Preadjustment, bool? FlowTest) { Invoke(new Action(() => { setMeterInfoUi(SerialNumber, Preadjustment, FlowTest); })); } private void setMeterInfoUi(string SerialNumber, bool? Preadjustment, bool? FlowTest) { lblSerialNr.Text = SerialNumber; cbxDoTesting.Checked = false; if (!string.IsNullOrEmpty(SerialNumber) && SerialNumber != "-") { cbxDoTesting.Checked = true; } if (Preadjustment.HasValue) { if (Preadjustment.Value) { lblPreadjustment.BackColor = DoneColor; } else { lblPreadjustment.BackColor = ErrorColor; } } else { lblPreadjustment.BackColor = NonColor; } if (FlowTest.HasValue) { if (FlowTest.Value) { lblFlowTest.BackColor = DoneColor; } else { lblFlowTest.BackColor = ErrorColor; } } else { lblFlowTest.BackColor = NonColor; } } internal void StartGetMeterInfos(string PcbId) { var t = new Task(() => { var at = 0; if (int.TryParse(PcbId, out at)) { var responseJson = LocalWebRequest.GetRequest($"{ServiceUrls.MeterInfoForTestBench()}{PcbId}"); var a = JsonConvert.DeserializeObject(responseJson); var SerialNumber = a[0]; if (!String.IsNullOrEmpty(SerialNumber)) { OrderNumber = a[1]; RadioAdress = a[2]; CustomerSerialNr = a[3]; CalibrationRun = a[4]; LastTestBechState = 0; bool? HyState = null; bool? preState = null; if (!string.IsNullOrEmpty(a[5])) { var tmp = 0; int.TryParse(a[5], out tmp); LastTestBechState = tmp; } if (!string.IsNullOrEmpty(a[6])) { var tmp = 0; int.TryParse(a[6], out tmp); Metersize = MeterSizeConverter.ConvertToMeter(tmp); } if (!string.IsNullOrEmpty(a[7])) { var tmp = 0; int.TryParse(a[7], out tmp); Metersize = ((MeterSize)(tmp)); } if (LastTestBechState <= 20) { HyState = null; } else if (LastTestBechState <= 30) { HyState = true; } else { HyState = false; } if (!string.IsNullOrEmpty(CalibrationRun)) { preState = true; } setMeterInfo(SerialNumber, preState, HyState); } } else { setMeterInfo("-", false, false); } }); t.Start(); } private CancellationTokenSource CancellationTokenSource = new CancellationTokenSource(); internal void Start(CancellationToken ctlCancellationToken, bool forceDisplayClear = false, DefaultSettings settingsToUse = null) { if (!isBusy) { var t = new Task(() => { try { if (settingsToUse == null) { settingsToUse = new DefaultSettings(); } meter = new GenesisMeter(); meter.SetupFromConfigFile(meterSlot, false, true, true); overallMeterBatch.AddMeter(meter); changeCurrentSlotState(TaskState.SetPcbId); } catch (Exception) { changeCurrentSlotState(TaskState.Fatal); } isBusy = true; changeCurrentSlotState(TaskState.SetPcbId); setMeterInfo("-", null, null); if (ctlCancellationToken.IsCancellationRequested) { return; } try { if (currentState != TaskState.Fatal) { FlowState = MeterReadyResults.NotStarted; Path1State = MeterReadyResults.NotStarted; Path2State = MeterReadyResults.NotStarted; Path3State = MeterReadyResults.NotStarted; Thread.Sleep(meterSlot * 10); if (string.IsNullOrEmpty(meter.PcbId)) { PcbId = meter.GetPcbId(); } else { PcbId = meter.PcbId; } if (ctlCancellationToken.IsCancellationRequested) { return; } StartGetMeterInfos(PcbId); changeCurrentSlotState(TaskState.LoginInProgress); if (ctlCancellationToken.IsCancellationRequested) { return; } if (!string.IsNullOrEmpty(meter.PcbId) && meter.Login()) { changeCurrentSlotState(TaskState.LoginDone); if (ctlCancellationToken.IsCancellationRequested) { return; } if (forceDisplayClear) { meter.ResetAlarm(Alarm.ALL); meter.WriteRegister(Register.Genesisflow.TriggerIdle, 0, true, true); } meter.InitMeasurement(); FlowRecords = new ConcurrentBag(); PathRecords = new ConcurrentBag(); meter.StreamingProtocol.OnRecordIsDecoded += StreamingProtocol_OnRecordIsDecoded; meter.SyncStreamingBuffer(Xylem.Common.CommonCore.Consts.SyncMarkRecord.DecodeEveryPackage); changeCurrentSlotState(TaskState.LedInProgress); var nrOfChecksLeft = 50;//50 * 100ms = 5 Sekunden var startChnl = 1; while (nrOfChecksLeft > 0) { if (ctlCancellationToken.IsCancellationRequested) { return; } if (currentState == TaskState.LedInProgress) { if (PathRecords.Any() || FlowRecords.Any()) { changeCurrentSlotState(TaskState.MessurementInProgress); nrOfChecksLeft = 100; } } else { //check every path if (FlowRecords.Any() && FlowState != MeterReadyResults.MixedInvalidRecords) { if (FlowRecords.All(a => a.IsValid)) { FlowState = MeterReadyResults.OnlyValidRecords; } else if (FlowRecords.All(a => !a.IsValid)) { FlowState = MeterReadyResults.OnlyInvalidRecords; } else { FlowState = MeterReadyResults.MixedInvalidRecords; } } else { FlowState = MeterReadyResults.NoRecords; } if (PathRecords.Any()) { Path1State = NewMethod(Path1State, PathRecords.Where(c => c.Channel == 1).ToList()); Path2State = NewMethod(Path2State, PathRecords.Where(c => c.Channel == 2).ToList()); Path3State = NewMethod(Path3State, PathRecords.Where(c => c.Channel == 3).ToList()); } } nrOfChecksLeft = nrOfChecksLeft - 1; Thread.Sleep(100); } if (currentState == TaskState.LedInProgress) { changeCurrentSlotState(TaskState.LedFailed); } else { var aggregate = new List(); aggregate.Add(FlowState); aggregate.Add(Path1State); aggregate.Add(Path2State); aggregate.Add(Path3State); if (aggregate.All(a => a == MeterReadyResults.OnlyValidRecords)) { changeCurrentSlotState(TaskState.MessurementDone); } else if (aggregate.Any(a => a == MeterReadyResults.OnlyInvalidRecords)) { changeCurrentSlotState(TaskState.MessurementFailed); } else { changeCurrentSlotState(TaskState.MessurementDoneWithHint); } } } else { changeCurrentSlotState(TaskState.LoginFailed); } } } catch (Exception ex) { MessageBox.Show(ex.Message + ex.StackTrace, "Error on check meter is ready"); } finally { isBusy = false; overallMeterBatch.RemoveMeter(meter); meter?.Dispose(); } }); t.Start(); } } internal MeterTestSettings GetMeterTestSettings() { var ret = new MeterTestSettings(); ret.FlowTesting = cbxDoTesting.Checked; ret.FlowAdjustment = cbDoFlowCalibration.Checked; ret.PreAdjustment = cbxDoPreajdustment.Checked; ret.Slot = meterSlot; ret.SerialNr = lblSerialNr.Text; ret.FlowAdjustmentTarget = nudCalibrationTarget.Value; return ret; } private MeterReadyResults NewMethod(MeterReadyResults oldstate, List records) { if (records.Any()) { if (records.All(a => a.Validation == 0)) { return MeterReadyResults.OnlyValidRecords; } else if (records.All(a => a.Validation != 0)) { return MeterReadyResults.OnlyInvalidRecords; } else { return MeterReadyResults.MixedInvalidRecords; } } else { return MeterReadyResults.NoRecords; } } private void StreamingProtocol_OnRecordIsDecoded(object sender, BaseDataEventArgs e) { try { if (e is CalibDataEventArgs) { PathRecords.Add(((CalibDataEventArgs)e).CalibChl); } if (e is FlowDataEventArgs) { FlowRecords.Add(((FlowDataEventArgs)e).NewData); } } catch (Exception ex) { } } public new void Dispose() { CancellationTokenSource?.Cancel(); if (meter != null) { meter.Dispose(); } base.Dispose(); } private bool Light = false; private MeterBatch overallMeterBatch; private int meterSlot; private void tmrBusy_Tick(object sender, EventArgs e) { if (isBusy) { List