395 lines
13 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|