common/Ui/LegacyGenesisControl/ctlMeterReady.cs
2026-04-23 17:50:07 +02:00

726 lines
24 KiB
C#

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<FlowTestRecord> FlowRecords;
private ConcurrentBag<CalibrationRecord> 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<string[]>(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<FlowTestRecord>();
PathRecords = new ConcurrentBag<CalibrationRecord>();
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<MeterReadyResults>();
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<CalibrationRecord> 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<Label> lblList = new List<Label>()
{
lblLogin,
lblLed,
lblDataOverall,
lblDataDisplay,
lblDataP1,
lblDataP2,
lblDataP3
};
if (Light)
{
lblList.Where(a => a.BackColor == CurrentColor).ToList().ForEach(a => a.BackColor = alterColor);
Light = false;
}
else
{
lblList.Where(a => a.BackColor == alterColor).ToList().ForEach(a => a.BackColor = CurrentColor);
Light = true;
}
}
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
}
private void label4_Click(object sender, EventArgs e)
{
}
private void lblDoPreajustment_Click(object sender, EventArgs e)
{
cbxDoPreajdustment.Checked = !cbxDoPreajdustment.Checked;
}
private void duFlowCalibration_Click(object sender, EventArgs e)
{
cbDoFlowCalibration.Checked = !cbDoFlowCalibration.Checked;
}
private void cbxDoPreajdustment_CheckedChanged(object sender, EventArgs e)
{
if (cbxDoPreajdustment.Checked)
{
cbxDoPreajdustment.Text = "V";
}
else
{
cbxDoPreajdustment.Text = "-";
}
}
private void cbDoFlowCalibration_CheckedChanged(object sender, EventArgs e)
{
if (cbDoFlowCalibration.Checked)
{
cbDoFlowCalibration.Text = "V";
}
else
{
cbDoFlowCalibration.Text = "-";
}
}
private void cbxDoTesting_CheckedChanged(object sender, EventArgs e)
{
if (cbxDoTesting.Checked)
{
cbxDoTesting.Text = "V";
}
else
{
cbxDoTesting.Text = "-";
}
}
private void ctlMeterReady_Load(object sender, EventArgs e)
{
}
private void lblSerialNr_Click(object sender, EventArgs e)
{
Start(CancellationTokenSource.Token);
}
private void lblSlot_Click(object sender, EventArgs e)
{
Start(CancellationTokenSource.Token);
}
private void lblPcbId_Click(object sender, EventArgs e)
{
Start(CancellationTokenSource.Token);
}
private void lblFlowTest_Click(object sender, EventArgs e)
{
if (lblSerialNr.Text.Length > 5)
{
ProcessStartInfo sInfo = new ProcessStartInfo($"http://sla12iis01:4442/Meter/Detail?SerialNr={lblSerialNr.Text}");
Process.Start(sInfo);
}
}
private void lblDataDisplay_Click(object sender, EventArgs e)
{
Start(CancellationTokenSource.Token, true);
}
}
}