laatzen/Common/Ui/GenesisToolBox/FrmLutUpdate.cs
2022-03-02 14:24:47 +01:00

465 lines
15 KiB
C#

using System;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
namespace Xylem.Common.Ui.GenesisToolBox
{
/// <summary>
/// FW update form
/// </summary>
public partial class FrmLutUpdate : Form
{
#region Variables
private readonly MeterBatch _meterBatch = new MeterBatch();
private GenesisMeter _currentGenesis;
private const String StrConnecting = "Connecting to PCB";
private const String StrNotConnected = "NOT CONNECTED";
private const String StrCoreRevision = "System Core Revision: ";
private const String StrPartPcbConnected = "Connected to PCB ID: ";
private const String StrOverallProcess = "Overall Process";
private MeterLutUpdate _meterLutUpdate;
private String _lastFwUpdateState;
private Int32 _lastSingleProgress;
private DateTimeOffset _startTime;
private Boolean _resetTimeMeasurement;
private readonly Boolean _updateGui = true;
private Boolean _lutFileValid;
private Boolean _tryConnectPcb;
private Boolean _lutFileSuccessfulWritten;
private const String StrUpdateErrorMessage = "METROLOGY LOOKUP TABLE UPDATE FAILED!\n\n";
private const String StrUpdateSuccessMessage = "Metrology lookup table successfulley written!\n\n";
private const String StrLutFileInvalid = "LUT FILE INVALID";
private const String StrLutFileValid = "LUT file loaded";
#endregion
#region FormControls
/// <summary>
/// Ctor FW update
/// </summary>
public FrmLutUpdate()
{
InitializeComponent();
var cultureInfo = new CultureInfo("en-GB");
Thread.CurrentThread.CurrentUICulture = cultureInfo;
Thread.CurrentThread.CurrentCulture = cultureInfo;
}
/// <summary>
/// Clear data table and set genesis to not connected
/// </summary>
private void Init()
{
ProcessViewControl(false);
lblConnectPcb.Text = StrNotConnected;
lblCoreRevision.Text = "";
lblConnectPcb.ForeColor = Color.Red;
lblWaitingForMeterResponse.Visible = false;
btnConnect.Enabled = true;
btnDownloadLutFile.ForeColor = Color.DarkGreen;
btnStopFwUpdate.ForeColor = Color.Red;
SetControlDownloadsLocked();
btnStopFwUpdate.Enabled = false;
btnOpenLutFile.Enabled = true;
}
private void FrmLutUpdate_Load(Object sender, EventArgs e)
{
var version = Assembly.GetExecutingAssembly().GetName().Version;
lblFwUpdateInfo.Text = $@"Version: {version.Major}.{version.Minor}.{version.Build}";
_resetTimeMeasurement = true;
Init();
}
private void FrmLutUpdate_FormClosing(Object sender, FormClosingEventArgs e)
{
_currentGenesis?.Logout();
_meterBatch?.RemoveAllMeters();
_meterBatch?.Dispose();
_meterLutUpdate?.Dispose();
_meterLutUpdate = null;
Dispose();
}
private void cbComSlot_SelectedIndexChanged(Object sender, EventArgs e)
{
_resetTimeMeasurement = true;
Init();
}
#endregion
#region ActivationControls
private void SetControlDownloadsLocked()
{
btnDownloadLutFile.Enabled = false;
btnStopFwUpdate.Enabled = false;
btnConnect.Enabled = true;
}
private void SetControlsDownloadIsOngoing()
{
btnConnect.Enabled = false;
btnOpenLutFile.Enabled = false;
btnDownloadLutFile.Enabled = false;
btnStopFwUpdate.Enabled = true;
}
private void SetControlsDownloadIsFinished()
{
_currentGenesis.RequestProtocol.AdditionalRetryTimeoutMs = 0;
btnConnect.Enabled = true;
btnOpenLutFile.Enabled = true;
btnDownloadLutFile.Enabled = true;
btnStopFwUpdate.Enabled = false;
}
#endregion
#region BoardControls
private void Connect()
{
try
{
Init();
Int32 slotNr;
if (string.IsNullOrEmpty(cbComSlot.SelectedItem.ToString()) ||
!int.TryParse(cbComSlot.SelectedItem.ToString(), out slotNr))
{
return;
}
_currentGenesis?.DisposeMeter();
//dispose old meter
_meterBatch.RemoveAllMeters();
_currentGenesis = null;
Thread.Sleep(200);
//assign new meter and assign meter to FW update file if this exists
_currentGenesis = new GenesisMeter();
_currentGenesis.SetupFromConfigFile(slotNr);
_meterBatch.AddMeter(_currentGenesis);
_currentGenesis._configuration.UseRegisterWatchService = false;
_currentGenesis._configuration.UseMinMaxCheck = false;
Task.Factory.StartNew(() =>
{
ViewProgressPcb(true);
_meterBatch.MetersLogin();
if (!_currentGenesis.IsLoggedOn)
{
Thread.Sleep(2000);
_meterBatch.MetersLogin();
}
if (!_currentGenesis.IsLoggedOn)
{
return;
}
_meterLutUpdate?.AssignGenesis(_currentGenesis);
Invoke(new Action(() =>
{
lblConnectPcb.Text = StrPartPcbConnected + _currentGenesis.PcbId;
lblCoreRevision.Text = StrCoreRevision + _currentGenesis.CoreRevision;
lblConnectPcb.ForeColor = Color.Green;
CheckUpdateEnabled();
_currentGenesis.Logout();
}));
}).ContinueWith(delegate { ViewProgressPcb(false); });
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion
#region ProcessControls
private void ViewProgressPcb(Boolean isActive)
{
if (_updateGui)
{
if (isActive)
{
Invoke(new Action(() =>
{
_tryConnectPcb = true;
ProcessViewControl(true);
lblActualProcess.Text = StrConnecting;
lblOverall.Text = StrOverallProcess;
}));
}
else
{
Invoke(new Action(() =>
{
_tryConnectPcb = false;
ProcessViewControl(false);
}));
}
}
}
/// <summary>
/// View all process bars and labels
/// </summary>
private void ProcessViewControl(Boolean view)
{
if (view)
{
lblActualProcess.Visible = true;
lblOverall.Visible = true;
barOverallProgressUpdate.Visible = true;
barSingleProgressUpdate.Visible = true;
_lastFwUpdateState = "";
tmrProgressUpdate.Enabled = true;
}
else
{
lblActualProcess.Visible = false;
lblOverall.Visible = false;
barOverallProgressUpdate.Visible = false;
barSingleProgressUpdate.Visible = false;
tmrProgressUpdate.Enabled = false;
_lastFwUpdateState = "";
lblWaitingForMeterResponse.Visible = false;
lblActualProcess.Text = "";
lblOverall.Text = "";
}
//common actions and settings
lblActualProcess.Update();
lblOverall.Update();
barOverallProgressUpdate.Value = 0;
barOverallProgressUpdate.Update();
barSingleProgressUpdate.Value = 0;
barSingleProgressUpdate.Update();
Update();
}
private void StartStopDownload(Boolean isActive)
{
if (isActive)
{
Invoke(new Action(() =>
{
_lastFwUpdateState = "";
ProcessViewControl(true);
tmrProgressUpdate.Enabled = true;
}));
}
else
{
Invoke(new Action(() =>
{
ProcessViewControl(false);
SetControlsDownloadIsFinished();
if (_lutFileSuccessfulWritten)
{
MessageBoxShow(StrUpdateErrorMessage, @"FAILED",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBoxShow(StrUpdateSuccessMessage, @"SUCCESS",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}));
}
}
#endregion
#region Checks
private void CheckUpdateEnabled()
{
//this check has been placed here to force display update
if (_meterLutUpdate != null && _currentGenesis != null && _lutFileValid)
{
SetControlDownloadsLocked();
return;
}
SetControlDownloadsLocked();
}
#endregion
#region TimerControls
private void tmrProgressUpdate_Tick(Object sender, EventArgs e)
{
//cbxManualControl.Visible = true;
if (_tryConnectPcb)
{
barOverallProgressUpdate.Value = barOverallProgressUpdate.Value + 1 > 100 ? 0 :
barOverallProgressUpdate.Value + 1;
barSingleProgressUpdate.Value = barSingleProgressUpdate.Value + 4 > 100 ? 0 :
barSingleProgressUpdate.Value + 4;
lblOverall.Text = StrOverallProcess;
}
else
{
lblOverall.Text = _meterLutUpdate?.GetLutUpdateStateOperation();
lblActualProcess.Text = _meterLutUpdate?.GetActualOperation();
var overallProgress = (Int32)(_meterLutUpdate?.OverallProcessCtrPercent ?? 0);
barOverallProgressUpdate.Value = overallProgress > 100 ? 100 : overallProgress;
barOverallProgressUpdate.Update();
var singleProgress = (Int32)(_meterLutUpdate?.SingleFileProcessCtrPercent ?? 0);
if (_meterLutUpdate?.GetLutUpdateStateOperation() != _lastFwUpdateState)
{
_lastFwUpdateState = _meterLutUpdate?.GetLutUpdateStateOperation();
lblWaitingForMeterResponse.Visible = false;
}
else
{
//if the communication gets frozen
lblWaitingForMeterResponse.Visible = _lastSingleProgress == singleProgress;
}
barSingleProgressUpdate.Value = singleProgress > 100 ? 100 : singleProgress;
_lastSingleProgress = singleProgress;
barSingleProgressUpdate.Update();
}
SetTimeDisplay();
Update();
}
private void SetTimeDisplay()
{
var time = DateTimeOffset.UtcNow;
var timeSpan = time - _startTime;
lblUpdateTime.Text = $@"{(UInt32)timeSpan.TotalMinutes}:{timeSpan.Seconds:00}";
}
#endregion
#region Buttons
private void btnConnect_Click(Object sender, EventArgs e)
{
if (_resetTimeMeasurement)
{
_startTime = DateTimeOffset.UtcNow;
_resetTimeMeasurement = false;
}
Connect();
}
private void btnOpenLutFile_Click(Object sender, EventArgs e)
{
if (dlgOpenLuFile.ShowDialog() != DialogResult.OK)
{
return;
}
var lutFilePathName = dlgOpenLuFile.FileName;
tbxLutFilePathName.Text = lutFilePathName;
if (_meterLutUpdate == null)
{
_meterLutUpdate = new MeterLutUpdate(_currentGenesis);
}
if (_meterLutUpdate == null)
{
return;
}
if (_meterLutUpdate.LoadLutFile(lutFilePathName))
{
lblLutFileLoadedInfo.ForeColor = Color.Green;
lblLutFileLoadedInfo.Text = StrLutFileValid;
_lutFileValid = true;
}
else
{
lblLutFileLoadedInfo.ForeColor = Color.Red;
lblLutFileLoadedInfo.Text = StrLutFileInvalid;
_lutFileValid = false;
}
CheckUpdateEnabled();
_resetTimeMeasurement = true;
}
/// <summary>
/// Download LUT file
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnDownloadLutFile_Click(Object sender, EventArgs e)
{
if (_currentGenesis == null || _meterLutUpdate?.LutFile == null)
{
return;
}
SetControlsDownloadIsOngoing();
StartStopDownload(true);
_startTime = DateTimeOffset.UtcNow;
_resetTimeMeasurement = false;
Task.Factory.StartNew(() =>
{
_lutFileSuccessfulWritten = _meterLutUpdate.UpdateMeterLut();
Thread.Sleep(1000);
}).ContinueWith(delegate { StartStopDownload(false); });
}
private void btnStopFwUpdate_Click(Object sender, EventArgs e)
{
if (_meterLutUpdate != null)
{
_meterLutUpdate.StopUpdateProcess = true;
}
}
#endregion
#region ExternalCalls
public MsgEventArgs LastMsgEvent;
public class MsgEventArgs : EventArgs
{
public String Text;
public String Caption;
public MessageBoxButtons Buttons;
public MessageBoxIcon Icon;
}
public event EventHandler<MsgEventArgs> OnMsgPopUp;
private void MessageBoxShow(String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon)
{
if (_updateGui)
{
MessageBox.Show(text, caption, buttons, icon);
}
else
{
LastMsgEvent = new MsgEventArgs() { Text = text, Caption = caption, Buttons = buttons, Icon = icon };
OnMsgPopUp?.Invoke(this, LastMsgEvent);
}
}
#endregion
}
}