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.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>(); foreach (var item in rowsLoop) { reg.Add(item.Split('=')[0], new Tuple(ByteStyler.Parse(item.Split('=')[1].Split(':')[0], true), item.Split(':')[1])); } var regPrep = new Dictionary>(); foreach (var item in rowsPrep) { reg.Add(item.Split('=')[0], new Tuple(ByteStyler.Parse(item.Split('=')[1].Split(':')[0], true), item.Split(':')[1])); } var MeterLoopList = new List(); 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> reg, Boolean useStreaming = true, Int32 errorCount = 20, TextProgressBar ctls = null) { var LoopCount = new List(); var meterIsGoneMarker = false; var debugLoop = 1; var errorOnLastXRos = 0; for (Int32 i = loopCount; i > 0; i--) { var runWasGood = new List(); 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(tr.ReadToEnd()); clbSlots.Items.Clear(); var listSlots = new List(); 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; } } }