720 lines
23 KiB
C#
720 lines
23 KiB
C#
using Logic.ProductionToProductMapper.Cordonel;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using Xylem.Common.CommonCore.Configuration;
|
|
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.Registers;
|
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
|
using Xylem.Common.Logic.SoftwareAccessHelper;
|
|
using XylemCommonUiLegacyGenCtl.DataPackage;
|
|
using XylemCommonUiLegacyGenCtl.Enums;
|
|
|
|
namespace XylemCommonUiLegacyGenCtl
|
|
{
|
|
|
|
[Guid("532F05D1-3317-4f00-B5D9-6CBB208B6B58")]
|
|
[ComSourceInterfaces(typeof(IEasyMeterRdy))]
|
|
[ComVisible(true)]
|
|
public partial class ctlEasyMeterRdy : UserControl, IEasyMeterRdy
|
|
{
|
|
public event OnPop Expand;
|
|
public event OnStateChange StateChange;
|
|
|
|
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.NAN;
|
|
public ctlEasyMeterRdy(int v)
|
|
{
|
|
SetSlot(v);
|
|
InitializeComponent();
|
|
button1.Text = "►";
|
|
this.Width = 140;
|
|
var vis = false;
|
|
|
|
|
|
|
|
|
|
lblPreadjustment.Visible = vis;
|
|
lblFlowTest.Visible = vis;
|
|
lblLogin.Visible = vis;
|
|
lblLed.Visible = vis;
|
|
lblDataOverall.Visible = vis;
|
|
lblDataDisplay.Visible = vis;
|
|
lblDataP1.Visible = vis;
|
|
lblDataP2.Visible = vis;
|
|
lblDataP3.Visible = vis;
|
|
}
|
|
|
|
|
|
|
|
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 SetSlot(int key)
|
|
{
|
|
changeCurrentSlotState(TaskState.SetSlot);
|
|
meterSlot = key;
|
|
overallMeterBatch = new 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)
|
|
{
|
|
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 (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();
|
|
|
|
|
|
|
|
public void Start(bool forceDisplayClear = false)
|
|
{
|
|
|
|
if (!isBusy)
|
|
{
|
|
|
|
var t = new Task(() =>
|
|
{
|
|
var ctlCancellationToken = CancellationTokenSource.Token;
|
|
|
|
try
|
|
{
|
|
|
|
var 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;
|
|
|
|
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.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.Slot = meterSlot;
|
|
|
|
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 ctlMeterReady_Load(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void lblSerialNr_Click(object sender, EventArgs e)
|
|
{
|
|
Start();
|
|
}
|
|
|
|
private void lblSlot_Click(object sender, EventArgs e)
|
|
{
|
|
Start();
|
|
}
|
|
private void lblPcbId_Click(object sender, EventArgs e)
|
|
{
|
|
Start();
|
|
}
|
|
|
|
private void lblDataDisplay_Click(object sender, EventArgs e)
|
|
{
|
|
Start(true);
|
|
}
|
|
|
|
|
|
|
|
private void lblPcbId_MouseLeave(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void ctlEasyMeterRdy_MouseLeave(object sender, EventArgs e)
|
|
{
|
|
// Expand?.Invoke(sender, new PopEventArgs() { Show = false });
|
|
}
|
|
|
|
public void OneStateChange()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void OnPop(object sender, PopEventArgs e)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
private void ctlEasyMeterRdy_MouseEnter(object sender, EventArgs e)
|
|
{
|
|
//
|
|
}
|
|
|
|
private void button1_Click(object sender, EventArgs e)
|
|
{
|
|
var vis = false;
|
|
//"◄►"
|
|
if (button1.Text == "►")
|
|
{
|
|
this.Width = 450;
|
|
Expand?.Invoke(sender, new PopEventArgs() { Show = true });
|
|
button1.Text = "◄";
|
|
vis = true;
|
|
}
|
|
else
|
|
{
|
|
this.Width = 140;
|
|
Expand?.Invoke(sender, new PopEventArgs() { Show = false });
|
|
button1.Text = "►";
|
|
this.Width = 140;
|
|
vis = false;
|
|
|
|
}
|
|
|
|
|
|
lblPreadjustment.Visible = vis;
|
|
lblFlowTest.Visible = vis;
|
|
lblLogin.Visible = vis;
|
|
lblLed.Visible = vis;
|
|
lblDataOverall.Visible = vis;
|
|
lblDataDisplay.Visible = vis;
|
|
lblDataP1.Visible = vis;
|
|
lblDataP2.Visible = vis;
|
|
lblDataP3.Visible = vis;
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|
|
}
|