Verification of LUT files, upload and verify binary content
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Properties;
|
||||
|
||||
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Consts
|
||||
{
|
||||
/// <summary>
|
||||
/// Concatenation of state and string
|
||||
/// </summary>
|
||||
public static class LutUpdateStateInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Build state information
|
||||
/// </summary>
|
||||
private static readonly LutUpdateStateText[] StateInfos;
|
||||
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// </summary>
|
||||
static LutUpdateStateInfo()
|
||||
{
|
||||
StateInfos = new LutUpdateStateText[(Int32)LutUpdateState.LutUpdateStateListDelimiter];
|
||||
StateInfos[0].State = LutUpdateState.Idle;
|
||||
StateInfos[0].Message = "";
|
||||
|
||||
StateInfos[1].State = LutUpdateState.StepFailed;
|
||||
StateInfos[1].Message = "Processing Step Failed";
|
||||
|
||||
StateInfos[2].State = LutUpdateState.UpdateFailed;
|
||||
StateInfos[2].Message = "LUT Update Failed";
|
||||
|
||||
StateInfos[3].State = LutUpdateState.StartInitial;
|
||||
StateInfos[3].Message = "Initial start";
|
||||
|
||||
StateInfos[4].State = LutUpdateState.RepeatLutUpdate;
|
||||
StateInfos[4].Message = "Repeat update";
|
||||
|
||||
StateInfos[5].State = LutUpdateState.UploadLutFile;
|
||||
StateInfos[5].Message = "Upload LUT file from meter";
|
||||
|
||||
StateInfos[6].State = LutUpdateState.DownloadLutFile;
|
||||
StateInfos[6].Message = "Download LUT file to meter";
|
||||
|
||||
StateInfos[7].State = LutUpdateState.CompareLutFile;
|
||||
StateInfos[7].Message = "Compare LUT file";
|
||||
|
||||
StateInfos[8].State = LutUpdateState.PrepareLutDownload;
|
||||
StateInfos[8].Message = "Init meter size and LUT file CRC";
|
||||
|
||||
StateInfos[9].State = LutUpdateState.EraseLutFile;
|
||||
StateInfos[9].Message = "Erase LUT file in meter";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current information
|
||||
/// </summary>
|
||||
/// <param name="state">state to search for information text</param>
|
||||
public static String GetTextFromState(LutUpdateState state)
|
||||
{
|
||||
return (from stateInfo in StateInfos
|
||||
where stateInfo.State == state select stateInfo.Message).FirstOrDefault();
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the state of the text
|
||||
/// </summary>
|
||||
/// <param name="text">information text to search if state is assigned</param>
|
||||
public static LutUpdateState GetStateFromText(String text)
|
||||
{
|
||||
return (from stateInfo in StateInfos
|
||||
where stateInfo.Message == text select stateInfo.State).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Consts
|
||||
{
|
||||
/// <summary>
|
||||
/// Concatenation between lokup table update state and text
|
||||
/// </summary>
|
||||
public struct LutUpdateStateText
|
||||
{
|
||||
/// <summary>
|
||||
/// The state of the firmware update
|
||||
/// </summary>
|
||||
public LutUpdateState State;
|
||||
/// <summary>
|
||||
/// The message text of the lookup table update state
|
||||
/// </summary>
|
||||
public String Message;
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,8 @@
|
||||
<Compile Include="..\..\..\..\.shared\SharedAssemblyInfo.cs">
|
||||
<Link>Properties\SharedAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Consts\LutUpdateStateText.cs" />
|
||||
<Compile Include="Consts\LutUpdateStateInfo.cs" />
|
||||
<Compile Include="Consts\LutUpdateState.cs" />
|
||||
<Compile Include="Consts\FwUpdateState.cs" />
|
||||
<Compile Include="Consts\FwUpdateStateInfo.cs" />
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Text;
|
||||
using Logic.ProductionToProductMapper.Cordonel;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Properties;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
|
||||
using Xylem.Common.Utils.Crc16Ccitt;
|
||||
@@ -89,9 +88,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
|
||||
// Look up table file
|
||||
public MeterLutFile LutFile;
|
||||
|
||||
// actual processed file
|
||||
private String _actualFileName;
|
||||
public MeterLutFile LutFileReadBack;
|
||||
|
||||
// list of names of installed meter files on drive 1
|
||||
private List<String> _meterFilesDrive1;
|
||||
@@ -208,7 +205,15 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
/// </remarks>
|
||||
public String GetLutUpdateStateOperation()
|
||||
{
|
||||
return _lutUpdateState == LutUpdateState.Idle ? "" : "Processing...";
|
||||
// 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
|
||||
|
||||
@@ -366,7 +371,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
_actualOperation = Resources.StrWaiting;
|
||||
_actualOperation = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -393,18 +398,27 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
break;
|
||||
|
||||
case LutUpdateState.PrepareLutDownload:
|
||||
_lutUpdateState = PrepareLutDownload() ? LutUpdateState.DownloadLutFile : LutUpdateState.StepFailed;
|
||||
_lutUpdateState = PrepareLutDownload() ? LutUpdateState.EraseLutFile : LutUpdateState.StepFailed;
|
||||
break;
|
||||
|
||||
case LutUpdateState.EraseLutFile:
|
||||
_lutUpdateState = EraseLutFiles() ? LutUpdateState.DownloadLutFile : LutUpdateState.StepFailed;
|
||||
break;
|
||||
|
||||
case LutUpdateState.DownloadLutFile:
|
||||
_lutUpdateState = DownloadLutFile() ? LutUpdateState.Idle : LutUpdateState.StepFailed;
|
||||
_lutUpdateState = DownloadLutFiles() ? LutUpdateState.UploadLutFile : LutUpdateState.StepFailed;
|
||||
break;
|
||||
|
||||
case LutUpdateState.UploadLutFile:
|
||||
_lutUpdateState = UploadAndCompareLutFiles() ? LutUpdateState.Idle : LutUpdateState.StepFailed;
|
||||
break;
|
||||
|
||||
case LutUpdateState.CompareLutFile:
|
||||
break;
|
||||
|
||||
case LutUpdateState.StepFailed:
|
||||
|
||||
_lutUpdateState = _updateProcedureRetryCtr++ < UpdateProcedureRetries
|
||||
? LutUpdateState.RepeatLutUpdate
|
||||
: LutUpdateState.UpdateFailed;
|
||||
? LutUpdateState.RepeatLutUpdate : LutUpdateState.UpdateFailed;
|
||||
break;
|
||||
|
||||
case LutUpdateState.RepeatLutUpdate:
|
||||
@@ -421,19 +435,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
_lutUpdateState = LutUpdateState.Idle;
|
||||
break;
|
||||
|
||||
case LutUpdateState.UploadLutFile:
|
||||
break;
|
||||
|
||||
case LutUpdateState.CompareLutFile:
|
||||
break;
|
||||
|
||||
case LutUpdateState.EraseLutFile:
|
||||
case LutUpdateState.LutUpdateStateListDelimiter:
|
||||
_lutUpdateState = LutUpdateState.Idle;
|
||||
break;
|
||||
|
||||
default:
|
||||
_lutUpdateState = LutUpdateState.Idle;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,7 +485,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
var calculatedCrc = Crc16Ccitt.CalculateMsb1021(payload.ToArray());
|
||||
if (calculatedCrc != LutFile.FileCrc)
|
||||
{
|
||||
ErrorMessage += "CRC Mismatch!";
|
||||
ErrorMessage += "CRC mismatch!";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -496,7 +504,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
private Boolean PrepareLutDownload()
|
||||
{
|
||||
var returnValue = true;
|
||||
|
||||
|
||||
var retryCtr = 0;
|
||||
if (LutFile == null || _genesisMeter == null || _meterFile == null) return false;
|
||||
//set extended timeout for trigger upgrade response delay
|
||||
@@ -546,11 +554,33 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
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 ReadMeterFilesDrive1()
|
||||
{
|
||||
if (_meterFilesDrive1 == null)
|
||||
{
|
||||
_meterFilesDrive1 = new List<String>();
|
||||
}
|
||||
_meterFilesDrive1.Clear();
|
||||
|
||||
if (!_meterFile.ReadMeterFileCatalog(out var meterFilesDrive1, MeterFile.StrMeterDrive1,
|
||||
MeterFile.WildcardAll.ToString())) return false;
|
||||
|
||||
_meterFilesDrive1.AddRange(meterFilesDrive1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Erase file and check if done!
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2022-Mar-03" author="Thomas Wiedebusch">
|
||||
/// <remarks date="2022-Mar-04" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
private Boolean EraseFile(String fileDriveName)
|
||||
@@ -559,10 +589,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
//erase returns always TRUE, even if the erasure failed! Check with catalogue
|
||||
_meterFile.EraseMeterFile(fileDriveName);
|
||||
_meterFilesDrive1.Clear();
|
||||
if (_meterFile.ReadMeterFileCatalog(out var meterFilesDrive1, MeterFile.StrMeterDrive1,
|
||||
MeterFile.WildcardAll.ToString()))
|
||||
|
||||
if (ReadMeterFilesDrive1())
|
||||
{
|
||||
_meterFilesDrive1.AddRange(meterFilesDrive1);
|
||||
if (_meterFilesDrive1.Contains(fileDriveName))
|
||||
{
|
||||
returnValue = false;
|
||||
@@ -576,15 +605,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Download the metrology lookup table files and read the catalog of drive 1
|
||||
/// Erase old LUT files from meter
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
private Boolean DownloadLutFile()
|
||||
public Boolean EraseLutFiles()
|
||||
{
|
||||
|
||||
//counters for actual process information
|
||||
var retryCtr = 0;
|
||||
if (LutFile == null) return false;
|
||||
@@ -592,90 +619,152 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
//set extended timeout for trigger upgrade response delay
|
||||
_genesisMeter.TransmitProtocol.SetResponseTimeout(5000);
|
||||
var returnValue = true;
|
||||
//write file portion and retry if not successful
|
||||
|
||||
//erase loop and retry if not successful
|
||||
do
|
||||
{
|
||||
var filesToErase = new[] { StrLutMeterFileName, StrLutBackupMeterFileName};
|
||||
|
||||
// read all files which are already installed
|
||||
_actualOperation = "Read installed meter files drive 1";
|
||||
_operationCtr++;
|
||||
if (_meterFilesDrive1 == null)
|
||||
|
||||
// read files on drive 1 to verify the LUT installation
|
||||
if (ReadMeterFilesDrive1())
|
||||
{
|
||||
_meterFilesDrive1 = new List<String>();
|
||||
foreach (var fileToErase in filesToErase)
|
||||
{
|
||||
if (!_meterFilesDrive1.Contains(fileToErase)) continue;
|
||||
|
||||
_operationCtr++;
|
||||
_actualOperation = $"Erase {fileToErase}";
|
||||
if (EraseFile(fileToErase)) continue;
|
||||
|
||||
ErrorMessage += $"LUT file {fileToErase} not erased!\n";
|
||||
returnValue = false;
|
||||
_operationCtr--;
|
||||
}
|
||||
}
|
||||
_meterFilesDrive1.Clear();
|
||||
if (_meterFile.ReadMeterFileCatalog(out var meterFilesDrive1, MeterFile.StrMeterDrive1,
|
||||
MeterFile.WildcardAll.ToString()))
|
||||
|
||||
if (!returnValue)
|
||||
{
|
||||
_meterFilesDrive1.AddRange(meterFilesDrive1);
|
||||
ReestablishMeterFileSystem();
|
||||
}
|
||||
} while (!returnValue && retryCtr++ < FileWriteRetries && !StopUpdateProcess);
|
||||
|
||||
// erase file
|
||||
_operationCtr++;
|
||||
_actualFileName = StrLutMeterFileName;
|
||||
_actualOperation = $"Erase {_actualFileName}";
|
||||
if (!EraseFile(_actualFileName))
|
||||
{
|
||||
ErrorMessage += $"LUT file {_actualFileName} not erased!\n";
|
||||
returnValue = false;
|
||||
}
|
||||
//set timeout back to default value
|
||||
_genesisMeter.TransmitProtocol.SetDefaultResponseTimeout();
|
||||
|
||||
_operationCtr++;
|
||||
_actualOperation = $"Write {_actualFileName}";
|
||||
if (!_meterFile.WriteMeterFile(_actualFileName, LutFile.BinData.ToArray()))
|
||||
{
|
||||
ErrorMessage += $"Writing of {_actualFileName} failed!\n";
|
||||
returnValue = false;
|
||||
}
|
||||
|
||||
// erase file
|
||||
_operationCtr++;
|
||||
_actualFileName = StrLutBackupMeterFileName;
|
||||
_actualOperation = $"Erase {_actualFileName}";
|
||||
if (!EraseFile(_actualFileName))
|
||||
{
|
||||
ErrorMessage += $"LUT file {_actualFileName} not erased!\n";
|
||||
returnValue = false;
|
||||
}
|
||||
return !StopUpdateProcess && returnValue;
|
||||
}
|
||||
|
||||
_operationCtr++;
|
||||
_actualOperation = $"Write {_actualFileName}";
|
||||
if (!_meterFile.WriteMeterFile(_actualFileName, LutFile.BinData.ToArray()))
|
||||
{
|
||||
ErrorMessage += $"Writing of {_actualFileName} failed!\n";
|
||||
returnValue = false;
|
||||
}
|
||||
/// <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>
|
||||
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(5000);
|
||||
var returnValue = true;
|
||||
|
||||
//write LUT files and retry if not successful
|
||||
do
|
||||
{
|
||||
_actualOperation = "Download LUT files to meter";
|
||||
var filesToDownload = new[] { StrLutMeterFileName, StrLutBackupMeterFileName};
|
||||
|
||||
|
||||
_operationCtr++;
|
||||
_actualOperation = $"Write {_actualFileName}";
|
||||
if (!_meterFile.WriteMeterFile(_actualFileName, LutFile.BinData.ToArray()))
|
||||
foreach (var fileToDownload in filesToDownload)
|
||||
{
|
||||
ErrorMessage += $"Writing of {_actualFileName} failed!\n";
|
||||
_operationCtr++;
|
||||
_actualOperation = $"Write {fileToDownload}";
|
||||
if (_meterFile.WriteMeterFile(fileToDownload, LutFile.BinData.ToArray())) continue;
|
||||
|
||||
ErrorMessage += $"Writing of {fileToDownload} failed!\n";
|
||||
returnValue = false;
|
||||
_operationCtr--;
|
||||
}
|
||||
|
||||
// read all files on drive 1
|
||||
_operationCtr++;
|
||||
_actualOperation = "Read installed meter files drive 1";
|
||||
_meterFilesDrive1.Clear();
|
||||
if (!_meterFile.ReadMeterFileCatalog(out meterFilesDrive1, MeterFile.StrMeterDrive1,
|
||||
MeterFile.WildcardAll.ToString()))
|
||||
if (ReadMeterFilesDrive1())
|
||||
{
|
||||
returnValue = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_meterFilesDrive1.AddRange(meterFilesDrive1);
|
||||
if (!_meterFilesDrive1.Contains(StrLutMeterFileName))
|
||||
foreach (var checkInstalledFile in filesToDownload)
|
||||
{
|
||||
if (_meterFilesDrive1.Contains(checkInstalledFile)) continue;
|
||||
|
||||
ErrorMessage += $"LUT file {StrLutMeterFileName} not installed!\n";
|
||||
returnValue = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValue = false;
|
||||
}
|
||||
|
||||
if (!returnValue)
|
||||
{
|
||||
ReestablishMeterFileSystem();
|
||||
}
|
||||
} while (!returnValue && retryCtr++ < FileWriteRetries && !StopUpdateProcess);
|
||||
|
||||
if (!_meterFilesDrive1.Contains(StrLutBackupMeterFileName))
|
||||
//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>
|
||||
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(5000);
|
||||
var returnValue = true;
|
||||
|
||||
//write LUT files and retry if not successful
|
||||
do
|
||||
{
|
||||
_actualOperation = "Upload LUT files to meter";
|
||||
var filesToUpload = new[] { StrLutMeterFileName, StrLutBackupMeterFileName};
|
||||
|
||||
foreach (var fileToUpload in filesToUpload)
|
||||
{
|
||||
_operationCtr++;
|
||||
_actualOperation = $"Read {fileToUpload}";
|
||||
LutFileReadBack = new MeterLutFile(fileToUpload);
|
||||
if (_meterFile.ReadMeterFile(fileToUpload, out LutFileReadBack.BinData, LutFile.BinData.Count))
|
||||
{
|
||||
ErrorMessage += $"LUT file {StrLutBackupMeterFileName} not installed!\n";
|
||||
returnValue = false;
|
||||
if (LutFileReadBack.BinData != LutFile.BinData)
|
||||
{
|
||||
ErrorMessage += $"Verification of {fileToUpload} failed!\n";
|
||||
returnValue = false;
|
||||
_operationCtr--;
|
||||
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
ErrorMessage += $"Reading of {fileToUpload} failed!\n";
|
||||
returnValue = false;
|
||||
_operationCtr--;
|
||||
}
|
||||
|
||||
if (!returnValue)
|
||||
|
||||
Reference in New Issue
Block a user