common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs
2026-04-23 17:50:07 +02:00

905 lines
32 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Consts;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Consts;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
using Xylem.Common.Utils.ProcessExec;
using Xylem.Common.Utils.ProcessExec.EventArguments;
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
{
/// <summary>
/// Meter lookup table for metrology update procedure
/// </summary>
public class MeterLutUpdate : IProcessState
{
#region Variables
/// <summary>
/// Port scan result event for message dispatcher to caller
/// </summary>
public event EventHandler<ProcessExecEventArgs> OnProcessUpdate;
//error mask for unsuccessfully written LUT CRC
private const UInt32 LutCrcErrorMask = 0x8000000;
/// <summary>
/// Threshold for power correction EMEA version
/// </summary>
public const UInt32 EmeaFwThresholdForLutFile= 0x1200;
/// <summary>
/// Threshold for power correction NA version
/// </summary>
public const UInt32 NaFwThresholdForLutFile = 0x2000;
//trigger update retries
private const Int32 RegisterWriteRetries = 0;
//update reties for files
private const Int32 FileWriteRetries = 1;
//retry of entire update procedure
private const Int32 UpdateProcedureRetries = 1;
//threshold to increase the file write timing
private const Int32 IncreaseTimeoutUpdateProcedureRetries = 4;
private Int32 _updateProcedureRetryCtr;
private IGenesisMeter _genesisMeter;
private MeterFile _meterFile;
// Text for caller to inform about actual process being carried out
private String _actualOperation;
private LutUpdateState _lutUpdateState;
private LutUpdateState _lutBackupUpdateState;
// Look up table file
public MeterLutFile LutFile;
// list of names of installed meter files on drive 1
private List<String> _meterFilesDrive1;
// number of operations for over all access
private const Int32 NumberOfOperations = 11;
private Int32 _operationCtr;
// error message for display of error reason
public String ErrorMessage;
// manual stop of update process
private Boolean _stopUpdateProcess;
/// <summary>
/// Register subset needed to adjust for update performance content before update
/// </summary>
private readonly Dictionary<String, Byte[]> _registersBeforeUpdate = new Dictionary<String, Byte[]>();
/// <summary>
/// Register to restore after update
/// </summary>
private Dictionary<String, Byte[]> _registersAfterUpdate = new Dictionary<String, Byte[]>();
#endregion
#region Events
/// <summary>
/// Process update event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks date="2020-Dec-10" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public virtual void ProcessUpdate_Event(Object sender, ProcessExecEventArgs e)
{
//// copy text from overall messages to actual, because this is from sub-routine
//OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(_overallOperation,
// OverallProcessCtrPercent, _actualOperation, e.OverallProcessPercent));
}
#endregion
#region Information
/// <summary>
/// Process counter in percent
/// </summary>
/// <remarks date="2022-Mar-03" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Double OverallProcessCtrPercent => 100.0 * _operationCtr / NumberOfOperations;
/// <summary>
/// Single file process counter in percent
/// </summary>
/// <remarks date="2019-Jun-24" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Double SingleFileProcessCtrPercent => _meterFile?.ProcessCtrPercent ?? 0;
#endregion
#region CtorAssignment
/// <summary>
/// Ctor
/// </summary>
/// <param name="genesisMeter"></param>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public MeterLutUpdate(IGenesisMeter genesisMeter)
{
if (genesisMeter == null)
return;
AssignGenesis(genesisMeter);
if (genesisMeter.MeterAppListVersion.Any(f => f.AppName == "GENESISFLOW" && f.IsInstalled))
{
_registersBeforeUpdate.Add(Register.Genesisflow.LedMode, new[] { (Byte)LedMode.Off });
_registersBeforeUpdate.Add(Register.Genesisflow.SampleRate, new Byte[] { 1 });
}
if (genesisMeter.MeterAppListVersion.Any(f => f.AppName == "METROLOGYASST" && f.IsInstalled))
_registersBeforeUpdate.Add(Register.Metrologyasst.PulseMode, new Byte[] { 0 });
//deny access if NA product, because this does not have the radio app installed
if (genesisMeter.MeterAppListVersion.Any(f => f.AppName == "SENSUSRADIO" && f.IsInstalled))
_registersBeforeUpdate.Add(Register.Sensusradio.WakeupInterval, new Byte[] { 6 });
}
/// <summary>
/// Assign new genesis
/// </summary>
/// <param name="genesisMeter"></param>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public void AssignGenesis(IGenesisMeter genesisMeter)
{
_genesisMeter = genesisMeter;
_actualOperation = "";
_lutUpdateState = LutUpdateState.Idle;
}
/// <summary>
/// Dispose
/// </summary>
public void Dispose()
{
if (_meterFile == null)
return;
_meterFile.OnProcessUpdate -= ProcessUpdate_Event;
_meterFile = null;
}
#endregion
#region ProcessInformation
/// <summary>
/// Returns the actual file in process for update
/// </summary>
/// <returns></returns>
/// <remarks date="2019-Jun-20" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public String GetActualOperation()
{
return _actualOperation;
}
/// <summary>
/// Returns the LUT Update state
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Feb-25" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public String GetLutUpdateStateOperation()
{
// search text assigned to current state
var text = LutUpdateStateInfo.GetTextFromState(_lutUpdateState);
if (_lutUpdateState == LutUpdateState.Idle)
{
return text;
}
text += _updateProcedureRetryCtr > 0 ? $"Retry {_updateProcedureRetryCtr}" : "";
return text;
}
#endregion
#region Actions
/// <summary>
/// Try to re-establish the file system, therefor logout to close all open files
/// and login again.
/// </summary>
/// <remarks date="2019-Jun-21" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2019-Jun-28" author="Thomas Wiedebusch">
/// - Enable auto-logon added
/// </remarks>
/// <remarks date="2019-Jul-03" author="Thomas Wiedebusch">
/// - Removed auto-logon
/// </remarks>
public void ReestablishMeterFileSystem()
{
_genesisMeter?.Logout();
_genesisMeter?.ReLogin();
}
/// <summary>
/// Stop the update process
/// </summary>
public Boolean StopUpdateProcess
{
get => _stopUpdateProcess;
set
{
_stopUpdateProcess = value;
if (_meterFile != null)
{
_meterFile.StopProcess = value;
}
_lutUpdateState = LutUpdateState.UpdateFailed;
}
}
/// <summary>
/// Update meter lookup table
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean UpdateMeterLut()
{
if (!UpdatePreparation())
{
return false;
}
_operationCtr = 0;
_actualOperation = "";
ErrorMessage = "";
_lutUpdateState = LutUpdateState.StartInitial;
_lutBackupUpdateState = LutUpdateState.Idle;
while (_lutUpdateState != LutUpdateState.Idle && !StopUpdateProcess)
{
LutUpdateStateMachine();
}
return ExitPreparation(true);
}
/// <summary>
/// Upload lookup table file and compare with the loaded from file system
/// </summary>
/// <remarks date="2019-Jun-29" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean VerifyLutFile()
{
if (!UpdatePreparation())
{
return false;
}
return ExitPreparation(true);
}
/// <summary>
/// Reset lookup table update process and all lists and counters
/// </summary>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public void ResetAll()
{
LutFile = null;
//remove the update stop action
StopUpdateProcess = false;
//reset all counters
_updateProcedureRetryCtr = 0;
//set state machine for automatic FW update
_lutUpdateState = LutUpdateState.Idle;
_lutBackupUpdateState = LutUpdateState.Idle;
_actualOperation = "";
_operationCtr = 0;
//logout/login/auto-login
ReestablishMeterFileSystem();
_genesisMeter?.Logout();
}
/// <summary>
/// Common update preparation and check
/// </summary>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean UpdatePreparation()
{
_actualOperation = "Update preparation";
_lutUpdateState = LutUpdateState.Idle;
_meterFile = new MeterFile(_genesisMeter);
if (_meterFile != null)
_meterFile.OnProcessUpdate += ProcessUpdate_Event;
_genesisMeter?.ReLogin();
_genesisMeter?.SetProcessState(DisplayCodes.FwUpdateActive, webRequest: false);
if (_genesisMeter == null || !_genesisMeter.IsLoggedOn)
{
return false;
}
//set default timeout for file write operation
_meterFile.SetDefaultFileWriteTimeout();
//switch LED off set sample rate to 1 -> 1Hz to slow down CPU load
_registersAfterUpdate = new Dictionary<String, Byte[]>();
foreach (var item in _registersBeforeUpdate)
{
var writeBackValue = _genesisMeter.ReadRegister(item.Key);
_registersAfterUpdate.Add(item.Key, writeBackValue);
_genesisMeter.WriteRegister(item.Key, item.Value);
}
//remove the update stop action
StopUpdateProcess = false;
return true;
}
/// <summary>
/// Common exit routine
/// </summary>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean ExitPreparation(Boolean returnValue)
{
if (_meterFile != null)
_meterFile.OnProcessUpdate -= ProcessUpdate_Event;
_meterFile = null;
ReestablishMeterFileSystem();
foreach (var item in _registersAfterUpdate)
{
_genesisMeter.WriteRegister(item.Key, item.Value);
}
_genesisMeter?.Logout();
if (!StopUpdateProcess)
{
return returnValue;
}
_actualOperation = "";
return false;
}
#endregion
#region StateMachine
/// <summary>
/// State machine for metrology lookup table update process
/// </summary>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2022-Mar-04" author="Thomas Wiedebusch">
/// - Introduced lock for repeated execution of state machine
/// </remarks>
/// <remarks date="2023-Jan-16" author="Thomas Wiedebusch">
/// - Started state machine with download of new mettbl.
/// </remarks>
private void LutUpdateStateMachine()
{
if (_lutBackupUpdateState == _lutUpdateState)
{
Thread.Sleep(1);
}
else
{
// remind backup state to avoid repeated execution and side effects
_lutBackupUpdateState = _lutUpdateState;
switch (_lutUpdateState)
{
case LutUpdateState.Idle:
break;
case LutUpdateState.StartInitial:
_updateProcedureRetryCtr = 0;
_lutUpdateState = LutUpdateState.DownloadLutFile;
break;
case LutUpdateState.EraseLutFile:
_lutUpdateState = EraseLutFiles() ? LutUpdateState.DownloadLutFile : LutUpdateState.StepFailed;
break;
case LutUpdateState.DownloadLutFile:
_lutUpdateState = DownloadLutFiles() ? LutUpdateState.UploadLutFile : LutUpdateState.StepFailed;
break;
case LutUpdateState.UploadLutFile:
_lutUpdateState = UploadAndCompareLutFiles() ? LutUpdateState.FinalizeLutDownload : LutUpdateState.StepFailed;
break;
case LutUpdateState.FinalizeLutDownload:
_lutUpdateState =
FinalizeLutDownload() ? LutUpdateState.Idle : LutUpdateState.StepFailed;
break;
case LutUpdateState.CompareLutFile:
break;
case LutUpdateState.StepFailed:
_lutUpdateState = _updateProcedureRetryCtr++ < UpdateProcedureRetries
? LutUpdateState.RepeatLutUpdate
: LutUpdateState.UpdateFailed;
break;
case LutUpdateState.RepeatLutUpdate:
_lutUpdateState = LutUpdateState.DownloadLutFile;
if (_updateProcedureRetryCtr >= IncreaseTimeoutUpdateProcedureRetries)
{
_meterFile?.SetExtremeFileWriteTimeout();
}
break;
case LutUpdateState.UpdateFailed:
StopUpdateProcess = true;
_lutUpdateState = LutUpdateState.Idle;
break;
case LutUpdateState.LutUpdateStateListDelimiter:
_lutUpdateState = LutUpdateState.Idle;
break;
default:
_lutUpdateState = LutUpdateState.Idle;
break;
}
}// lock for identical state
}
#endregion
#region LutFile
/// <summary>
/// Check the content of the metrology lookup table file
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Feb-25" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2023-Nov-13" author="Thomas Wiedebusch">
/// - LUT file validation exported to <see cref="MeterLutFile.ValidateLutFormat"/>
/// </remarks>
private Boolean ValidateLutFile()
{
// Take the file content to validate the format based
var lutFileFormatValid = LutFile.ValidateLutFormat();
if (LutFile.CrcError)
{
ErrorMessage = "CRC mismatch!";
return false;
}
// check if LUT file contains data
if (LutFile?.BinData == null || LutFile.BinData.Count != LutFile.SizeLutFile)
{
ErrorMessage = "File size mismatch!";
return false;
}
return lutFileFormatValid;
}
/// <summary>
/// Download the CRC, the meter size and store calibration as preparation for the lookup table
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2023-Jan-19" author="Thomas Wiedebusch">
/// - Used genesis meter lut crc, region and meter size read back procedure.
/// </remarks>
private Boolean FinalizeLutDownload()
{
var returnValue = true;
var retryCtr = 0;
if (LutFile == null || _genesisMeter == null || _meterFile == null)
return false;
// set extended timeout for trigger upgrade response delay
_genesisMeter.TransmitProtocol.SetResponseTimeout(5000);
do
{
// for repeated entry
if (!returnValue)
{
ReestablishMeterFileSystem();
}
_actualOperation = "Write Lut CRC to meter";
_operationCtr++;
returnValue = _genesisMeter.WriteRegister<UInt32>(Register.Genesisflow.LookupFileCrc, LutFile.FileCrc);
if (!returnValue)
{
const String txt = "Meter LUT CRC could not be set!";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
_operationCtr--;
continue;
}
_operationCtr++;
_actualOperation = "Write meter size";
returnValue =
_genesisMeter.WriteRegister(Register.Genesisflow.MeterSize, new[] { (Byte)LutFile.MeterSize });
if (!returnValue)
{
const String txt = "Meter size could not be set!";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
_operationCtr--;
continue;
}
_operationCtr++;
_actualOperation = "Store calibration to meter";
returnValue = _genesisMeter.WriteRegister(Register.Genesisflow.StoreCalibration, 1);
if (!returnValue)
{
const String txt = "Meter store calibration failed!";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
_operationCtr--;
continue;
}
// read back all values
_genesisMeter.CheckRegionSizeLutCrc();
var lutFileCrc = $"0x{LutFile.FileCrc:X4}";
if (!_genesisMeter.LutCrc.Equals(lutFileCrc))
{
const String txt = "Meter LUT CRC could not be set!";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
_operationCtr--;
returnValue = false;
continue;
}
OnProcessUpdate?.Invoke(this,
new ProcessExecEventArgs($"Read back and validated LUT CRC {_genesisMeter.LutCrc}"));
var lutMeterSize = MeterSizeConverter.ConvertMeterSizeEnumToSizeName(LutFile.MeterSize);
if (!_genesisMeter.MeterSize.Equals(lutMeterSize))
{
const String txt = "Meter size could not be set!";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
_operationCtr--;
returnValue = false;
continue;
}
ErrorMessage = "";
OnProcessUpdate?.Invoke(this,
new ProcessExecEventArgs($"Read back and validated meter size {lutMeterSize}"));
} while (!returnValue && retryCtr++ < RegisterWriteRetries && !StopUpdateProcess);
// set timeout back to default value
_genesisMeter.TransmitProtocol.SetDefaultResponseTimeout();
return returnValue && !StopUpdateProcess;
}
/// <summary>
/// Read meter files of drive 1
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Mar-04" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private Boolean ListMeterFilesDrive1()
{
// logout and re-login to clear all ongoing processes and clear the Genesis buffers
ReestablishMeterFileSystem();
if (_meterFilesDrive1 == null)
{
_meterFilesDrive1 = new List<String>();
}
_meterFilesDrive1.Clear();
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs("List meter files drive 1"));
if (!_meterFile.ReadMeterFileCatalog(out var meterFilesDrive1, MeterFile.StrMeterDrive1))
return false;
_meterFilesDrive1.AddRange(meterFilesDrive1);
// inform overlay system of found files
foreach (var meterFile in _meterFilesDrive1)
{
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(meterFile));
}
return true;
}
/// <summary>
/// Erase file!
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Mar-04" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private Boolean EraseFile(String fileDriveName)
{
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($"Erasing {fileDriveName}"));
var returnValue = _meterFile.UnlockEraseWriteMeterFile(fileDriveName);
// erase returns always TRUE, even if the erasure failed! Check with catalogue
_meterFile.EraseMeterFile(fileDriveName);
return returnValue;
}
/// <summary>
/// Erase old LUT files from meter
/// </summary>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean EraseLutFiles()
{
//counters for actual process information
var retryCtr = 0;
if (LutFile == null)
return false;
//set extended timeout for trigger upgrade response delay
_genesisMeter.TransmitProtocol.SetResponseTimeout(10000);
var returnValue = true;
//erase loop and retry if not successful
do
{
var filesToErase = new[] {
//"1\\upg00", "1\\upg01", "1\\upg04","1\\upg08","1\\upg09","1\\upg12","1\\upg14","1\\upg15",
MeterLutFile.StrLutMeterFileName, MeterLutFile.StrLutBackupMeterFileName };
// read all files which are already installed
_actualOperation = "Catalogue installed meter files drive 1";
_operationCtr++;
// read files on drive 1 to verify the LUT installation
if (ListMeterFilesDrive1())
{
foreach (var fileToErase in filesToErase)
{
if (!_meterFilesDrive1.Contains(fileToErase))
continue;
_operationCtr++;
_actualOperation = $"Erase {fileToErase}";
if (EraseFile(fileToErase))
{
ErrorMessage = "";
continue;
}
ErrorMessage = $"LUT file {fileToErase} not erased!";
returnValue = false;
_operationCtr--;
}
}
if (!returnValue)
{
ReestablishMeterFileSystem();
}
} while (!returnValue && retryCtr++ < FileWriteRetries && !StopUpdateProcess);
//set timeout back to default value
_genesisMeter.TransmitProtocol.SetDefaultResponseTimeout();
return !StopUpdateProcess && returnValue;
}
/// <summary>
/// Download the metrology lookup table files and read the catalog of drive 1
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2023-Jan-20" author="Thomas Wiedebusch">
/// - Removed list file drive 1 to speed up process. Files will be read back and binary compared!
/// </remarks>
private Boolean DownloadLutFiles()
{
//counters for actual process information
var retryCtr = 0;
if (LutFile == null)
return false;
//set extended timeout for trigger upgrade response delay
_genesisMeter.TransmitProtocol.SetResponseTimeout(1000);
var returnValue = true;
//write LUT files and retry if not successful
do
{
var filesToDownload = new[] { MeterLutFile.StrLutMeterFileName, MeterLutFile.StrLutBackupMeterFileName };
foreach (var fileToDownload in filesToDownload)
{
_operationCtr++;
_actualOperation = $"Write {fileToDownload}";
// logout and re-login to clear all ongoing processes and clear the Genesis buffers
ReestablishMeterFileSystem();
_meterFile.UnlockEraseWriteMeterFile(fileToDownload);
var txt = $"{fileToDownload} successfully written";
if (_meterFile.WriteMeterFile(fileToDownload, LutFile.BinData.ToArray()))
{
ErrorMessage = "";
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
continue;
}
txt = $"Writing of {fileToDownload} failed!";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
returnValue = false;
_operationCtr--;
}
// read all files on drive 1
_operationCtr++;
if (!returnValue)
{
ReestablishMeterFileSystem();
}
} while (!returnValue && retryCtr++ < FileWriteRetries && !StopUpdateProcess);
//set timeout back to default value
_genesisMeter.TransmitProtocol.SetDefaultResponseTimeout();
return !StopUpdateProcess && returnValue;
}
/// <summary>
/// Upload the metrology lookup table files and read the catalog of drive 1
/// </summary>
/// <returns></returns>
/// <remarks date="2022-Mar-04" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2022-Apr-01" author="Thomas Wiedebusch">
/// - Take the different size of original and receive buffer, which is an integer division by 4, into account.
/// </remarks>
/// <remarks date="2022-Apr-06" author="Thomas Wiedebusch">
/// - Exported file compare to <see cref="MeterFile"/>.
/// </remarks>
private Boolean UploadAndCompareLutFiles()
{
//counters for actual process information
var retryCtr = 0;
if (LutFile == null)
return false;
//set extended timeout for trigger upgrade response delay
_genesisMeter.TransmitProtocol.SetResponseTimeout(1000);
var returnValue = true;
//verify LUT files and retry if not successful
do
{
var filesToUpload = new[] { MeterLutFile.StrLutMeterFileName, MeterLutFile.StrLutBackupMeterFileName };
foreach (var fileToUpload in filesToUpload)
{
_operationCtr++;
_actualOperation = $"Read {fileToUpload}";
// logout and re-login to clear all ongoing processes and clear the Genesis buffers
ReestablishMeterFileSystem();
if (!_meterFile.VerifyMeterFile(fileToUpload, LutFile.BinData.ToArray()))
{
ErrorMessage = $"Meter LUT file is unequal to downloaded {fileToUpload}!";
returnValue = false;
_operationCtr--;
}
else
{
OnProcessUpdate?.Invoke(this,
new ProcessExecEventArgs($"LUT file {fileToUpload} of meter successfully compared!"));
}
}
if (!returnValue)
{
ReestablishMeterFileSystem();
}
} while (!returnValue && retryCtr++ < FileWriteRetries && !StopUpdateProcess);
//set timeout back to default value
_genesisMeter.TransmitProtocol.SetDefaultResponseTimeout();
return !StopUpdateProcess && returnValue;
}
/// <summary>
/// Load file from memory
/// </summary>
/// <param name="filePathName">to binary files</param>
/// <returns></returns>
/// <remarks date="2022-Feb-15" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean LoadLutFile(String filePathName)
{
if (!File.Exists(filePathName))
{
return false;
}
LutFile = null;
LutFile = new MeterLutFile(filePathName)
{
BinData = new List<Byte>(File.ReadAllBytes(filePathName))
};
// validate the file
return ValidateLutFile();
}
/// <summary>
/// Load file from memory
/// </summary>
/// <param name="name">origin Name</param>
/// <param name="streamData">list of bytes of the file strean</param>
/// <returns></returns>
/// <remarks date="2022-Feb-15" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public Boolean LoadLutFromStream(String name, List<Byte> streamData )
{
LutFile = null;
LutFile = new MeterLutFile(name)
{
BinData = streamData
};
// validate the file
return ValidateLutFile();
}
#endregion
}
}