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

395 lines
13 KiB
C#

using ByteArrayStyle;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Xylem.Common.CommonCore.Consts;
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
using Xylem.Common.Ui.GenesisToolBox.Ctls;
namespace Xylem.Common.Ui.GenesisToolBox
{
public partial class FrmFrozenMeter : Form
{
private MeterBatch _meterBatch = new MeterBatch();
private Boolean requestStop = false;
public FrmFrozenMeter()
{
InitializeComponent();
}
private void btnStart_Click(Object sender, EventArgs e)
{
if (btnStart.Text == "Stop")
{
btnStart.Text = "Stopping";
requestStop = true;
var r = new Task(() => { while (requestStop) { Thread.Sleep(10); } });
r.ContinueWith(delegate
{
Invoke(new Action(() =>
{
btnStart.Text = "Start";
}));
});
r.Start();
}
else if (btnStart.Text == "Start")
{
btnStart.Text = "Stop";
start();
}
}
private void start()
{
//ProductionUIFile
_meterBatch = new MeterBatch();
for (Int32 i = 0; i < clbSlots.Items.Count; i++)
{
if (clbSlots.GetItemChecked(i))
{
var _currentGenesis = new GenesisMeter();
_currentGenesis.SetupFromConfigFile((Int32)clbSlots.Items[i], false, true, cbxStreaming.Checked);
_meterBatch.AddMeter(_currentGenesis);
_currentGenesis.RequestProtocol.AdditionalRetryTimeoutMs = 100;
}
}
var rowsLoop = txtRegisterLoop.Text.Split(new String[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
var rowsPrep = txtRegister.Text.Split(new String[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
var reg = new Dictionary<String, Tuple<Byte[], String>>();
foreach (var item in rowsLoop)
{
reg.Add(item.Split('=')[0], new Tuple<Byte[], String>(ByteStyler.Parse(item.Split('=')[1].Split(':')[0], true), item.Split(':')[1]));
}
var regPrep = new Dictionary<String, Tuple<Byte[], String>>();
foreach (var item in rowsPrep)
{
reg.Add(item.Split('=')[0], new Tuple<Byte[], String>(ByteStyler.Parse(item.Split('=')[1].Split(':')[0], true), item.Split(':')[1]));
}
var MeterLoopList = new List<Task>();
var useStream = cbxStreaming.Checked;
groupBox2.Controls.Clear();
Int32 errorCount = (Int32)nudErros.Value;
//addProgressLoop(-1, (int)nudRep.Value);
foreach (GenesisMeter item in _meterBatch.ListOfMeters)
{
var updateCtls = addProgressLoop(item.Slot, (Int32)nudRep.Value);
var r = new Task(() =>
{
item.Login();
RunLoop(item, 1, 0, regPrep, false);
RunLoop(item, (Int32)nudRep.Value, (Int32)nudTesttime.Value, reg, useStream, errorCount, updateCtls);
});
MeterLoopList.Add(r);
r.Start();
}
var allTasksWait = new Task(() =>
{
Task.WaitAll(MeterLoopList.ToArray());
_meterBatch.Dispose();
});
allTasksWait.ContinueWith(delegate
{
Invoke(new Action(() =>
{
btnStart.Text = "Start";
}));
});
allTasksWait.Start();
}
public void RunLoop(GenesisMeter _currentGenesis, Int32 loopCount, Int32 testtime, Dictionary<String, Tuple<Byte[], String>> reg, Boolean useStreaming = true, Int32 errorCount = 20, TextProgressBar ctls = null)
{
var LoopCount = new List<Boolean>();
var meterIsGoneMarker = false;
var debugLoop = 1;
var errorOnLastXRos = 0;
for (Int32 i = loopCount; i > 0; i--)
{
var runWasGood = new List<Boolean>();
if (requestStop)
{
break;
}
foreach (var item in reg)
{
runWasGood.Add(_currentGenesis.WriteRegister(item.Key, item.Value.Item1, true, item.Value.Item2 == "WR"));
}
if (runWasGood.Any(a => a == false))
{
DebugM(_currentGenesis, loopCount, i, $"Error on communcication ");
}
try
{
if (useStreaming)
{
_meterBatch.MetersStartMeasurement();
new AutoResetEvent(false).WaitOne(testtime/2);
_meterBatch.MetersStopMeasurement();
new AutoResetEvent(false).WaitOne(testtime / 2);
var r = _currentGenesis.GetMeasurementState(0);
}
else
{
new AutoResetEvent(false).WaitOne(testtime);
}
}
catch (Exception)
{
DebugM(_currentGenesis, loopCount, i, $"Error on Testing ");
runWasGood.Add(false);
}
var thisrun = runWasGood.All(a => a == true);
LoopCount.AddRange(runWasGood);
if (LoopCount.Count > errorCount)
{
errorOnLastXRos = LoopCount.GetRange(LoopCount.Count - errorCount, errorCount).Count(a => !a);
if (errorOnLastXRos >= errorCount)
{
if (!meterIsGoneMarker)
{
DebugM(_currentGenesis, loopCount, i, $"looks like meter is gone", true);
}
meterIsGoneMarker = true;
}
else
{
if (meterIsGoneMarker)
{
DebugM(_currentGenesis, loopCount, i, $"meter is reachable again", true);
}
meterIsGoneMarker = false;
}
}
if (debugLoop <= 0)
{
debugLoop = 100;
DebugM(_currentGenesis, loopCount, i, $"End with {runWasGood.Count(a => !a)} errors");
if (ctls != null)
{
Invoke(new Action(() =>
{
ctls.CustomText = $"Loop { (loopCount - i) + 1}/{ loopCount}- Total Errors {LoopCount.Count(a => !a) }- Errors on the last {errorCount} rows:{errorOnLastXRos}";
if ((loopCount - i) + 1 == ctls.Maximum)
{
ctls.BackColor = System.Drawing.Color.Gray;
ctls.ProgressColor = System.Drawing.Color.Green;
}
if (meterIsGoneMarker)
{
ctls.BackColor = System.Drawing.Color.Orange;
ctls.ProgressColor = System.Drawing.Color.OrangeRed;
}
else
{
ctls.BackColor = System.Drawing.Color.Gray;
//ctls.ProgressColor = System.Drawing.Color.GreenYellow;
}
ctls.Value = (loopCount - i) + 1;
}));
}
}
debugLoop = debugLoop - 1;
}
if (ctls != null)
{
Invoke(new Action(() =>
{
ctls.CustomText = $"Loop { loopCount }/{ loopCount}- Total Errors {LoopCount.Count(a => !a) }- Errors on the last {errorCount} rows:{errorOnLastXRos}";
if ((loopCount) + 1 >= ctls.Maximum)
{
ctls.BackColor = System.Drawing.Color.Gray;
ctls.ProgressColor = System.Drawing.Color.Green;
}
if (meterIsGoneMarker)
{
ctls.BackColor = System.Drawing.Color.Orange;
ctls.ProgressColor = System.Drawing.Color.OrangeRed;
}
else
{
ctls.BackColor = System.Drawing.Color.Gray;
//ctls.ProgressColor = System.Drawing.Color.GreenYellow;
}
ctls.Value = loopCount;
}));
}
}
private void DebugM(GenesisMeter _currentGenesis, Int32 loopCount, Int32 currentLoop, String v, Boolean MBox = false)
{
//if (MBox)
//{
//}
//if (output)
//{
// Invoke(new Action(() =>
// {
// txtResult.Text = $"{v}{Environment.NewLine}{txtResult.Text}";
// }));
//}
v = $"{DateTime.Now.ToString("HH:mm:ss")} Slot{_currentGenesis.Slot} - Loop{(loopCount - currentLoop) + 1}/{loopCount} - {v}";
//Invoke(new Action(() =>
//{
// var t = textBox1.Text;
// if (t.Length > 50000)
// {
// t = t.Substring(0, 50000);
// }
// textBox1.Text = $"{v}{Environment.NewLine}{textBox1.Text}";
//}));
_currentGenesis.WriteLog(v);
}
private void timer1_Tick(Object sender, EventArgs e)
{
}
private void FrmFrozenMeter_Load(Object sender, EventArgs e)
{
var configfile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(Xylem.Common.Hardware.WaterMeter.Genesis), ProgramConfig.SerialConfigFileName);
if (!File.Exists(configfile))
{
throw new ApplicationException($"Configuration file {configfile} not found ");
}
var tr = new StreamReader(configfile);
var meterConfigList = JsonConvert.DeserializeObject<SlotConfig[]>(tr.ReadToEnd());
clbSlots.Items.Clear();
var listSlots = new List<Int32>();
foreach (var item in meterConfigList)
{
clbSlots.Items.Add(item.Slot, false);
}
}
private void calcEndDate()
{
var estTimeInMs = nudRep.Value * (nudTesttime.Value + 2000);
if (int.MaxValue <= estTimeInMs)
{
lblEstDate.Text = "-";
MessageBox.Show(@"you really think a software from roland can run that long without a fatal crash? No way!");
}
else
{
lblEstDate.Text = DateTime.Now.AddMilliseconds((Int32)estTimeInMs).ToString("dd.MM.yyyy HH:mm:ss");
}
}
private void nudRep_ValueChanged(Object sender, EventArgs e)
{
calcEndDate();
}
private void nudTesttime_ValueChanged(Object sender, EventArgs e)
{
calcEndDate();
}
private TextProgressBar addProgressLoop(Int32 slot = -1, Int32 LoopsTodo = 100)
{
var row = ((this.groupBox2.Controls.Count / 2) * 35) + 20;
TextProgressBar proTotal;
Label lblTotal;
proTotal = new TextProgressBar();
lblTotal = new System.Windows.Forms.Label();
proTotal.Location = new System.Drawing.Point(60, row);
proTotal.Name = "proTotal";
proTotal.Size = new System.Drawing.Size(450, 30);
proTotal.TabIndex = 1;
proTotal.Maximum = LoopsTodo;
proTotal.CustomText = "0/0";
proTotal.VisualMode = ProgressBarDisplayMode.CustomText;
lblTotal.AutoSize = true;
lblTotal.Location = new System.Drawing.Point(6, row + 8);
lblTotal.Name = "lblTotal";
lblTotal.Size = new System.Drawing.Size(31, 13);
lblTotal.TabIndex = 3;
lblTotal.Text = slot == -1 ? "Total" : $"Slot {slot}";
this.groupBox2.Controls.Add(lblTotal);
this.groupBox2.Controls.Add(proTotal);
return proTotal;
}
}
}