505 lines
18 KiB
C#
505 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using Newtonsoft.Json;
|
|
using NLog;
|
|
using Xylem.Common.CommonCore.Consts;
|
|
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
|
|
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.Utils.Logging;
|
|
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeterStreamingQuality;
|
|
|
|
namespace Xylem.Common.Ui.GenesisToolBox
|
|
{
|
|
/// <summary>
|
|
/// Streaming quality display
|
|
/// </summary>
|
|
public partial class FrmStreamingQuality : Form
|
|
{
|
|
private GenesisMeterStreamingQuality _currentGenesis;
|
|
private MeterBatch _meterBatch = new MeterBatch();
|
|
private readonly ILogger _logger;
|
|
private const Int32 SampleRateHz = 16;
|
|
private Int32 _channels;
|
|
private const String StrStartLiveCheck = "Start Live Check";
|
|
private const String StrStopLiveCheck = "Stop Live Check";
|
|
private const String StrStartContinuousCheck = "Start Logging";
|
|
private const String StrStopContinuousCheck = "Stop Logging";
|
|
private const String StrConnecting = "Connecting";
|
|
private const String StrNotConnected = "NOT CONNECTED";
|
|
private const String StrPartPcbConnected = "Connected to PCBID:";
|
|
private const String StrUpdate = "Update";
|
|
private const String StrUnknown = "---";
|
|
private Boolean _isLiveUpdate;
|
|
private Byte[] _readout = new Byte[4];
|
|
|
|
/// <summary>
|
|
/// Ctor
|
|
/// </summary>
|
|
public FrmStreamingQuality()
|
|
{
|
|
InitializeComponent();
|
|
tmrCheck.Tick += TmrCheck_Tick;
|
|
tmrProgress.Tick += TmrProgress_Tick;
|
|
_logger = NLogHelper.CreateOrGetLogger("StreamingQuality");
|
|
|
|
StopLiveUpdate();
|
|
StopLoggingUpdate();
|
|
|
|
lblPcbConnect.Text = StrNotConnected;
|
|
lblPcbConnect.ForeColor = Color.Red;
|
|
InitStreamingQualityCheck();
|
|
}
|
|
|
|
private void StopLoggingUpdate()
|
|
{
|
|
tmrCheck.Enabled = false;
|
|
btnStartStop.Text = StrStartContinuousCheck;
|
|
lblLoggingUpdate.Text = @"STOPPED";
|
|
lblLoggingUpdate.Visible = true;
|
|
}
|
|
|
|
private void StopLiveUpdate()
|
|
{
|
|
tmrCheck.Enabled = false;
|
|
btnStartStopLive.Text = StrStartLiveCheck;
|
|
lblLiveUpdate.Text = @"STOPPED";
|
|
lblLiveUpdate.Visible = true;
|
|
_isLiveUpdate = false;
|
|
}
|
|
|
|
private void cbComSlot_SelectedIndexChanged(Object sender, EventArgs e)
|
|
{
|
|
// switch LED off to safe energy
|
|
WriteValue(Register.Genesisflow.LedMode, (Byte)LedMode.Off);
|
|
StopLiveUpdate();
|
|
StopLoggingUpdate();
|
|
btnStartStop.Text = StrStartContinuousCheck;
|
|
lblPcbConnect.Text = StrNotConnected;
|
|
lblPcbConnect.ForeColor = Color.Red;
|
|
InitStreamingQualityCheck();
|
|
}
|
|
|
|
private void FrmStreamingQuality_FormClosing(Object sender, FormClosingEventArgs e)
|
|
{
|
|
Dispose();
|
|
}
|
|
|
|
private new void Dispose()
|
|
{
|
|
// switch LED off to safe energy
|
|
WriteValue(Register.Genesisflow.LedMode, (Byte)LedMode.Off);
|
|
_currentGenesis?.DisposeMeter();
|
|
_meterBatch?.Dispose();
|
|
base.Dispose();
|
|
}
|
|
|
|
/// <remarks date="2025-Oct-02" author="Thomas Wiedebusch">
|
|
/// - Catch error message on unknown data type and kill meter.
|
|
/// </remarks>
|
|
private void Connect()
|
|
{
|
|
Int32 slotNr;
|
|
lblPcbConnect.Text = StrNotConnected;
|
|
lblPcbConnect.ForeColor = Color.Red;
|
|
if (!string.IsNullOrEmpty(cbComSlot.SelectedItem.ToString()) &&
|
|
int.TryParse(cbComSlot.SelectedItem.ToString(), out slotNr))
|
|
{
|
|
try
|
|
{
|
|
_currentGenesis?.DisposeMeter();
|
|
_currentGenesis = null;
|
|
ViewProgress(true);
|
|
_currentGenesis = new GenesisMeterStreamingQuality();
|
|
_currentGenesis.SetupFromConfigFile(slotNr);
|
|
_meterBatch.AddMeter(_currentGenesis);
|
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
{
|
|
_meterBatch.MetersLogin();
|
|
|
|
WriteValue(Register.Genesisflow.TriggerIdle, 0);
|
|
WriteValue(Register.Genesisflow.SampleRate, SampleRateHz);
|
|
|
|
_channels = 4;
|
|
WriteValue(Register.Genesisflow.LedMode, (Byte)LedMode.FlowTestAndCalibDataAndBendCorrect);
|
|
|
|
if (_currentGenesis.IsLoggedOn)
|
|
{
|
|
_currentGenesis.EnableAutoLogon();
|
|
Invoke(new Action(() =>
|
|
{
|
|
lblPcbConnect.Text = StrPartPcbConnected + $@" {_currentGenesis.PcbId}";
|
|
lblPcbConnect.ForeColor = Color.Green;
|
|
EnableCheckButtons();
|
|
}));
|
|
}
|
|
}).ContinueWith(delegate { ViewProgress(false); });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, @"FAILED", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
// Dispose meter
|
|
_meterBatch.RemoveAllMeters();
|
|
// If meter is not already assigned to batch as the config reader may fail
|
|
_currentGenesis?.DisposeMeter();
|
|
}
|
|
}
|
|
}
|
|
|
|
// write value avoids access if genesis is not assigned and logged in
|
|
private Boolean WriteValue<T>(String reg, T value)
|
|
{
|
|
if (_currentGenesis == null || !_currentGenesis.IsLoggedOn) return false;
|
|
_currentGenesis.WriteRegister(reg, value, checkRegister: true);
|
|
return true;
|
|
|
|
}
|
|
private void btnRawMode_Click(Object sender, EventArgs e)
|
|
{
|
|
// stop timer for synchronization
|
|
tmrCheck.Enabled = false;
|
|
_currentGenesis.StopStreamingQualityCheck(SampleRateHz * _channels);
|
|
if (WriteValue(Register.Genesisflow.LedMode, (Byte)LedMode.CalibData))
|
|
{
|
|
_readout = _currentGenesis.ReadRegister(Register.Genesisflow.LedMode);
|
|
if (null != _readout && _readout[0] == (Byte)LedMode.CalibData)
|
|
{
|
|
_channels = 3;
|
|
}
|
|
|
|
_currentGenesis.StartStreamingQualityCheck();
|
|
tmrCheck.Enabled = true;
|
|
}
|
|
}
|
|
|
|
private void btnMixMode_Click(Object sender, EventArgs e)
|
|
{
|
|
// stop timer for synchronization
|
|
tmrCheck.Enabled = false;
|
|
_currentGenesis.StopStreamingQualityCheck(SampleRateHz * _channels);
|
|
if (WriteValue(Register.Genesisflow.LedMode, (Byte)LedMode.FlowTestAndCalibData))
|
|
{
|
|
_readout = _currentGenesis.ReadRegister(Register.Genesisflow.LedMode);
|
|
if (null != _readout && _readout[0] == (Byte)LedMode.FlowTestAndCalibData)
|
|
{
|
|
_channels = 4;
|
|
}
|
|
|
|
_currentGenesis.StartStreamingQualityCheck();
|
|
tmrCheck.Enabled = true;
|
|
}
|
|
}
|
|
|
|
private void btnRawOnly_Click(Object sender, EventArgs e)
|
|
{
|
|
// stop timer for synchronization
|
|
tmrCheck.Enabled = false;
|
|
_currentGenesis.StopStreamingQualityCheck(SampleRateHz * _channels);
|
|
if (WriteValue(Register.Genesisflow.LedMode, (Byte)LedMode.FlowTestData))
|
|
{
|
|
_readout = _currentGenesis.ReadRegister(Register.Genesisflow.LedMode);
|
|
if (null != _readout && _readout[0] == (Byte)LedMode.FlowTestData)
|
|
{
|
|
_channels = 1;
|
|
}
|
|
|
|
_currentGenesis.StartStreamingQualityCheck();
|
|
tmrCheck.Enabled = true;
|
|
}
|
|
}
|
|
|
|
private void btnStartStop_Click(Object sender, EventArgs e)
|
|
{
|
|
// start logging
|
|
if (btnStartStop.Text == StrStartContinuousCheck)
|
|
{
|
|
StopLiveUpdate();
|
|
|
|
lblLoggingUpdate.Text = StrUpdate;
|
|
btnStartStop.Text = StrStopContinuousCheck;
|
|
_logger.Info($"StartCheck for {txtFlowText.Text}");
|
|
_currentGenesis.StartStreamingQualityCheck();
|
|
tmrCheck.Enabled = true;
|
|
}
|
|
|
|
// stop logging and display result
|
|
else
|
|
{
|
|
var result = _currentGenesis.StopStreamingQualityCheck(SampleRateHz * _channels);
|
|
var sb = new StringBuilder();
|
|
|
|
StopLoggingUpdate();
|
|
|
|
_logger.Info($"Logging comment: {txtFlowText.Text}");
|
|
|
|
_logger.Info($"TotalTime={result.TotalTime}");
|
|
sb.AppendLine($"TotalTime={result.TotalTime}");
|
|
|
|
_logger.Info($"ExpectedRecords={result.ExpectedLinesCount}");
|
|
sb.AppendLine($"ExpectedRecords={result.ExpectedLinesCount}");
|
|
|
|
_logger.Info($"ReceivedRecords={result.TotalLinesCount}");
|
|
sb.AppendLine($"ReceivedRecords={result.TotalLinesCount}");
|
|
|
|
_logger.Info($"ValidRecords={result.TotalDecodedCount}");
|
|
sb.AppendLine($"ValidRecords={result.TotalDecodedCount}");
|
|
|
|
_logger.Info($"InvalidRecords={result.TotalTransportErrorCount}");
|
|
sb.AppendLine($"InvalidRecords={result.TotalTransportErrorCount}");
|
|
|
|
_logger.Info($"DifferentMeterErrorCodes={result.ErrorOccurredCounter.Count}");
|
|
sb.AppendLine($"DifferentMeterErrorCodes={result.ErrorOccurredCounter.Count}");
|
|
|
|
foreach (var errorCount in result.ErrorOccurredCounter)
|
|
{
|
|
_logger.Info($"MeterErrorCode 0x{errorCount.Key:X4} counted {errorCount.Value} times");
|
|
sb.AppendLine($"MeterErrorCode 0x{errorCount.Key:X4} counted {errorCount.Value} times");
|
|
}
|
|
|
|
_logger.Info("################################");
|
|
|
|
|
|
MessageBox.Show(sb.ToString());
|
|
}
|
|
}
|
|
|
|
private void btnStartStopLive_Click(Object sender, EventArgs e)
|
|
{
|
|
// start live update
|
|
if (btnStartStopLive.Text == StrStartLiveCheck)
|
|
{
|
|
StopLoggingUpdate();
|
|
|
|
lblLiveUpdate.Text = StrUpdate;
|
|
btnStartStopLive.Text = StrStopLiveCheck;
|
|
_currentGenesis.StartStreamingQualityCheck();
|
|
tmrCheck.Enabled = true;
|
|
|
|
_isLiveUpdate = true;
|
|
}
|
|
|
|
// stop live update
|
|
else
|
|
{
|
|
StopLiveUpdate();
|
|
}
|
|
}
|
|
|
|
private void TmrProgress_Tick(Object sender, EventArgs e)
|
|
{
|
|
if (barProgress.Value == 100)
|
|
{
|
|
barProgress.Value = 0;
|
|
}
|
|
|
|
barProgress.Value += 1;
|
|
}
|
|
|
|
private void TmrCheck_Tick(Object sender, EventArgs e)
|
|
{
|
|
if (_currentGenesis != null && _currentGenesis.IsRunning)
|
|
{
|
|
// stop timer for synchronization
|
|
tmrCheck.Enabled = false;
|
|
|
|
if (_isLiveUpdate)
|
|
{
|
|
lblLiveUpdate.Visible = !lblLiveUpdate.Visible;
|
|
var result = _currentGenesis.StopStreamingQualityCheck(SampleRateHz * _channels);
|
|
var percentHit = Math.Round(result.TotalDecodedCount / (Double)result.ExpectedLinesCount * 100.0, 0);
|
|
if (percentHit > 85.0)
|
|
{
|
|
lblHitRate.ForeColor = Color.Green;
|
|
lblHitRateTxt.ForeColor = Color.Green;
|
|
}
|
|
else
|
|
{
|
|
lblHitRate.ForeColor = Color.Red;
|
|
lblHitRateTxt.ForeColor = Color.Red;
|
|
}
|
|
|
|
lblHitRate.Text = percentHit.ToString(CultureInfo.InvariantCulture);
|
|
lblExpectedRecords.Text = result.ExpectedLinesCount.ToString();
|
|
lblDecodingFailed.Text = result.TotalTransportErrorCount.ToString();
|
|
lblDecodingValid.Text = result.TotalDecodedCount.ToString();
|
|
lblReceivedRecords.Text = result.TotalLinesCount.ToString();
|
|
_currentGenesis.StartStreamingQualityCheck();
|
|
}
|
|
else
|
|
{
|
|
lblLoggingUpdate.Visible = !lblLoggingUpdate.Visible;
|
|
}
|
|
|
|
tmrCheck.Enabled = true;
|
|
}
|
|
}
|
|
|
|
private void InitStreamingQualityCheck()
|
|
{
|
|
btnStartStopLive.Enabled = false;
|
|
btnMixMode.Enabled = false;
|
|
btnStartStop.Enabled = false;
|
|
btnRawOnly.Enabled = false;
|
|
btnConnect.Enabled = true;
|
|
lblHitRate.Text = StrUnknown;
|
|
lblHitRate.ForeColor = Color.Black;
|
|
lblHitRateTxt.ForeColor = Color.Black;
|
|
lblDecodingFailed.Text = StrUnknown;
|
|
lblExpectedRecords.Text = StrUnknown;
|
|
lblDecodingValid.Text = StrUnknown;
|
|
lblReceivedRecords.Text = StrUnknown;
|
|
}
|
|
|
|
private void EnableCheckButtons()
|
|
{
|
|
btnStartStopLive.Enabled = true;
|
|
btnMixMode.Enabled = true;
|
|
btnStartStop.Enabled = true;
|
|
btnRawOnly.Enabled = true;
|
|
//btnConnect.Enabled = false;
|
|
}
|
|
|
|
private void ViewProgress(Boolean isActive)
|
|
{
|
|
if (isActive)
|
|
{
|
|
Invoke(new Action(() =>
|
|
{
|
|
lblProgress.Text = StrConnecting;
|
|
barProgress.Value = 0;
|
|
lblProgress.Visible = true;
|
|
barProgress.Visible = true;
|
|
tmrProgress.Enabled = true;
|
|
lblPcbConnect.Visible = false;
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
Invoke(new Action(() =>
|
|
{
|
|
tmrProgress.Enabled = false;
|
|
lblProgress.Visible = false;
|
|
barProgress.Visible = false;
|
|
lblPcbConnect.Visible = true;
|
|
}));
|
|
}
|
|
}
|
|
|
|
private void btnConnect_Click(Object sender, EventArgs e)
|
|
{
|
|
Connect();
|
|
}
|
|
|
|
private void btnSetSampleRate_Click(Object sender, EventArgs e)
|
|
{
|
|
if (int.TryParse(cobSr.SelectedItem.ToString(), out var intTemp))
|
|
{
|
|
_currentGenesis.WriteRegister(Register.Genesisflow.SampleRate, intTemp);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
private void btnTestAll_Click(Object sender, EventArgs e)
|
|
{
|
|
_currentGenesis?.DisposeMeter();
|
|
_currentGenesis = null;
|
|
|
|
|
|
SlotConfig[] meterConfigList;
|
|
using (var tr = new StreamReader(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Genesis", ProgramConfig.SerialConfigFileName)))
|
|
{
|
|
meterConfigList = JsonConvert.DeserializeObject<SlotConfig[]>(tr.ReadToEnd());
|
|
}
|
|
|
|
_meterBatch = new MeterBatch();
|
|
foreach (var item in meterConfigList)
|
|
{
|
|
|
|
var meter = new GenesisMeterStreamingQuality();
|
|
meter.SetupFromConfigFile(item.Slot);
|
|
_meterBatch.AddMeter(meter);
|
|
|
|
|
|
}
|
|
|
|
_meterBatch.MetersLogin();
|
|
|
|
|
|
Int32 intTemp;
|
|
|
|
if (int.TryParse(cobSr.SelectedItem.ToString(), out intTemp))
|
|
{
|
|
|
|
}
|
|
|
|
|
|
foreach (var item in _meterBatch.ListOfMeters)
|
|
{
|
|
if (item is GenesisMeterStreamingQuality meter)
|
|
{
|
|
meter.WriteRegister(Register.Genesisflow.SampleRate, intTemp);
|
|
meter.WriteRegister(Register.Genesisflow.LedMode, (Byte)LedMode.CalibData);
|
|
meter.SetLcdText(true, null);
|
|
}
|
|
|
|
}
|
|
var start = DateTimeOffset.UtcNow;
|
|
var taskList = new List<Task>();
|
|
|
|
foreach (var item in _meterBatch.ListOfMeters)
|
|
{
|
|
if (item is GenesisMeterStreamingQuality meter)
|
|
{
|
|
taskList.Add(new Task<QualityResult>(() =>
|
|
{
|
|
meter.IsRunning = false;
|
|
meter.StartStreamingQualityCheck(900 * 3);
|
|
|
|
while (meter.IsRunning)
|
|
{
|
|
Thread.Sleep(20);
|
|
}
|
|
return meter.LastQualityResult;
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
taskList.ForEach(t => t.Start());
|
|
while (!taskList.All(t => t.IsCompleted))
|
|
{
|
|
Thread.Sleep(20);
|
|
}
|
|
|
|
|
|
|
|
var ts = DateTimeOffset.UtcNow - start;
|
|
|
|
|
|
MessageBox.Show(ts.TotalSeconds.ToString(CultureInfo.InvariantCulture));
|
|
|
|
}
|
|
|
|
private void btnDispose_Click(Object sender, EventArgs e)
|
|
{
|
|
_currentGenesis.CurrentActionText = "StreamingQuality";
|
|
|
|
}
|
|
}
|
|
}
|