History window for additional information

This commit is contained in:
Thomas Wiedebusch
2022-03-28 13:23:03 +02:00
parent c015b16f0a
commit 50f15842aa
15 changed files with 1096 additions and 454 deletions
File diff suppressed because it is too large Load Diff
@@ -40,7 +40,7 @@
/// <summary>
/// Download the CRC, the meter size and store calibration as preparation for the lookup table
/// </summary>
PrepareLutDownload,
FinalizeLutDownload,
/// <summary>
/// Erase lookup table file
/// </summary>
@@ -44,7 +44,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Consts
StateInfos[7].State = LutUpdateState.CompareLutFile;
StateInfos[7].Message = "Compare LUT file";
StateInfos[8].State = LutUpdateState.PrepareLutDownload;
StateInfos[8].State = LutUpdateState.FinalizeLutDownload;
StateInfos[8].Message = "Init meter size and LUT file CRC";
StateInfos[9].State = LutUpdateState.EraseLutFile;
@@ -152,6 +152,10 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
//the package file describes all files needed for a specific release
private String _packageDescriptionFile;
// manual stop of update process
private Boolean _stopUpdateProcess;
private Int32 _actualUpdateFileCtr;
/// <summary>
/// Enable partial file writes of single parts with gaps in between
/// </summary>
@@ -615,7 +619,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
return _actualOperation;
}
private Int32 _actualUpdateFileCtr;
/// <summary>
/// Returns the FW Update state
@@ -668,8 +671,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
_genesisMeter?.ReLogin();
}
private Boolean _stopUpdateProcess;
/// <summary>
/// Stop the update process
/// </summary>
@@ -104,6 +104,10 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
// 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>
@@ -166,7 +170,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
/// </remarks>
public MeterLutUpdate(GenesisMeter genesisMeter)
{
if (genesisMeter == null) return;
if (genesisMeter == null)
return;
AssignGenesis(genesisMeter);
if (genesisMeter.MeterAppListVersion.Any(f => f.AppName == "GENESISFLOW" && f.IsInstalled))
@@ -200,7 +205,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
/// </summary>
public void Dispose()
{
if (_meterFile == null) return;
if (_meterFile == null)
return;
_meterFile.OnProcessUpdate -= ProcessUpdate_Event;
_meterFile = null;
}
@@ -263,8 +269,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
_genesisMeter?.ReLogin();
}
private Boolean _stopUpdateProcess;
/// <summary>
/// Stop the update process
/// </summary>
@@ -364,7 +368,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
_lutUpdateState = LutUpdateState.Idle;
_meterFile = new MeterFile(_genesisMeter);
if (_meterFile != null) _meterFile.OnProcessUpdate += ProcessUpdate_Event;
if (_meterFile != null)
_meterFile.OnProcessUpdate += ProcessUpdate_Event;
_genesisMeter?.ReLogin();
_genesisMeter?.SetProcessState(DisplayCodes.FwUpdateActive, false);
@@ -398,7 +403,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
/// </remarks>
public Boolean ExitPreparation(Boolean returnValue)
{
if (_meterFile != null) _meterFile.OnProcessUpdate -= ProcessUpdate_Event;
if (_meterFile != null)
_meterFile.OnProcessUpdate -= ProcessUpdate_Event;
_meterFile = null;
ReestablishMeterFileSystem();
@@ -447,12 +453,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
case LutUpdateState.StartInitial:
_updateProcedureRetryCtr = 0;
_lutUpdateState = LutUpdateState.PrepareLutDownload;
break;
case LutUpdateState.PrepareLutDownload:
_lutUpdateState =
PrepareLutDownload() ? LutUpdateState.EraseLutFile : LutUpdateState.StepFailed;
//TODO THW Test only _lutUpdateState = LutUpdateState.EraseLutFile;
_lutUpdateState = LutUpdateState.DownloadLutFile;
break;
case LutUpdateState.EraseLutFile:
@@ -464,7 +466,12 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
break;
case LutUpdateState.UploadLutFile:
_lutUpdateState = UploadAndCompareLutFiles() ? LutUpdateState.Idle : LutUpdateState.StepFailed;
_lutUpdateState = UploadAndCompareLutFiles() ? LutUpdateState.FinalizeLutDownload : LutUpdateState.StepFailed;
break;
case LutUpdateState.FinalizeLutDownload:
_lutUpdateState =
FinalizeLutDownload() ? LutUpdateState.Idle : LutUpdateState.StepFailed;
break;
case LutUpdateState.CompareLutFile:
@@ -516,7 +523,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
// check if LUT file contains data
if (LutFile?.BinData == null || LutFile.BinData.Count < SizeLutFile)
{
ErrorMessage += "File size mismatch!";
ErrorMessage = "File size mismatch!";
return false;
}
@@ -524,7 +531,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
// extract the identifier and check, if this is a LUT file
LutFile.StrLutFileId =
Encoding.UTF8.GetString(LutFile.BinData.ToArray(), IndexLutFileId, IndexDataLength);
if (LutFile.StrLutFileId != StrLutFileId) return false;
if (LutFile.StrLutFileId != StrLutFileId)
return false;
LutFile.MeterSize = (MeterSize)LutFile.BinData[IndexMeterSize];
LutFile.FileCrc = (UInt16)(LutFile.BinData[IndexCrc] + (LutFile.BinData[IndexCrc + 1] << 8));
@@ -541,7 +549,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;
}
@@ -557,54 +565,96 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
/// <remarks date="2022-Feb-16" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private Boolean PrepareLutDownload()
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
if (LutFile == null || _genesisMeter == null || _meterFile == null)
return false;
// set extended timeout for trigger upgrade response delay
_genesisMeter.TransmitProtocol.SetResponseTimeout(5000);
do
{
_actualOperation = "Write Lut CRC to meter";
_operationCtr++;
if (!_genesisMeter.WriteRegister<UInt32>(Register.Genesisflow.LookupFileCrc, LutFile.FileCrc))
{
ErrorMessage += "Meter LUT CRC could not be set!\n";
_operationCtr--;
returnValue = false;
}
else
{
_operationCtr++;
_actualOperation = "Write meter size";
if (!_genesisMeter.WriteRegister(Register.Genesisflow.MeterSize, new[] { (Byte)LutFile.MeterSize }))
{
ErrorMessage = "Meter size could not be set!\n";
_operationCtr--;
returnValue = false;
}
else
{
_operationCtr++;
_actualOperation = "Store calibration to meter";
if (!_genesisMeter.WriteRegister(Register.Genesisflow.StoreCalibration, 1))
{
ErrorMessage += "Meter store calibration failed!\n";
_operationCtr--;
returnValue = false;
}
}
}
// 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!\n";
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!\n";
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!\n";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
_operationCtr--;
continue;
}
_operationCtr++;
_actualOperation = "Read LUT CRC";
var lutCrc = RegisterConverter.ConvertTo<UInt32>(
_genesisMeter.ReadRegister(Register.Genesisflow.LookupFileCrc));
if ((lutCrc & 0x80000000) != 0)
{
const String txt = "Meter LUT CRC could not be set!\n";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
_operationCtr--;
returnValue = false;
continue;
}
_operationCtr++;
_actualOperation = "Read meter size";
var meterSize = (MeterSize)RegisterConverter.ConvertTo<Byte>(
_genesisMeter.ReadRegister(Register.Genesisflow.MeterSize));
if (meterSize != LutFile.MeterSize)
{
const String txt = "Meter size could not be set!\n";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
_operationCtr--;
returnValue = false;
continue;
}
ErrorMessage = "";
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs("Meter size and LUT CRC correctly set!\n"));
} while (!returnValue && retryCtr++ < RegisterWriteRetries && !StopUpdateProcess);
//set timeout back to default value
// set timeout back to default value
_genesisMeter.TransmitProtocol.SetDefaultResponseTimeout();
return returnValue && !StopUpdateProcess;
@@ -628,10 +678,18 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
}
_meterFilesDrive1.Clear();
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs("\nRead meter files drive 1"));
if (!_meterFile.ReadMeterFileCatalog(out var meterFilesDrive1, MeterFile.StrMeterDrive1,
MeterFile.WildcardAll.ToString())) return false;
MeterFile.WildcardAll.ToString()))
return false;
_meterFilesDrive1.AddRange(meterFilesDrive1);
// inform overlay system of found files
foreach (var meterFile in _meterFilesDrive1)
{
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(meterFile));
}
return true;
}
@@ -644,20 +702,35 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
/// </remarks>
private Boolean EraseFile(String fileDriveName)
{
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($"\nErasing {fileDriveName}"));
var returnValue = _meterFile.UnlockEraseWriteMeterFile(fileDriveName);
//erase returns always TRUE, even if the erasure failed! Check with catalogue
// erase returns always TRUE, even if the erasure failed! Check with catalogue
_meterFile.EraseMeterFile(fileDriveName);
// give the meter a certain time to erase
Thread.Sleep(1000);
if (ReadMeterFilesDrive1())
{
if (_meterFilesDrive1.Contains(fileDriveName))
{
returnValue = false;
var txt = $"Failed to erase {fileDriveName}!";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
}
else
{
ErrorMessage = "";
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($"Successfully erased {fileDriveName}"));
}
}
else
{
returnValue = false;
const String txt = "Meter files read error!";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
}
return returnValue;
}
@@ -672,7 +745,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
{
//counters for actual process information
var retryCtr = 0;
if (LutFile == null) return false;
if (LutFile == null)
return false;
//set extended timeout for trigger upgrade response delay
_genesisMeter.TransmitProtocol.SetResponseTimeout(10000);
@@ -693,13 +767,22 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
{
foreach (var fileToErase in filesToErase)
{
if (!_meterFilesDrive1.Contains(fileToErase)) continue;
if (!_meterFilesDrive1.Contains(fileToErase))
continue;
_operationCtr++;
_actualOperation = $"Erase {fileToErase}";
if (EraseFile(fileToErase)) continue;
var txt = $"LUT file {fileToErase} erased!\n";
if (EraseFile(fileToErase))
{
ErrorMessage = "";
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
continue;
}
ErrorMessage += $"LUT file {fileToErase} not erased!\n";
txt = $"LUT file {fileToErase} not erased!\n";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
returnValue = false;
_operationCtr--;
}
@@ -728,7 +811,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
{
//counters for actual process information
var retryCtr = 0;
if (LutFile == null) return false;
if (LutFile == null)
return false;
//set extended timeout for trigger upgrade response delay
_genesisMeter.TransmitProtocol.SetResponseTimeout(10000);
@@ -744,14 +828,22 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
{
_operationCtr++;
_actualOperation = $"Write {fileToDownload}";
// logout and re-login to clear all ongoing processes and clear the Genesis buffers
ReestablishMeterFileSystem();
_meterFile.UnlockEraseWriteMeterFile(fileToDownload);
if (_meterFile.WriteMeterFile(fileToDownload, LutFile.BinData.ToArray())) continue;
var txt = $"{fileToDownload} successfully written\n";
if (_meterFile.WriteMeterFile(fileToDownload, LutFile.BinData.ToArray()))
{
ErrorMessage = "";
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
continue;
}
ErrorMessage += $"Writing of {fileToDownload} failed!\n";
txt = $"Writing of {fileToDownload} failed!\n";
ErrorMessage = txt;
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
returnValue = false;
_operationCtr--;
}
@@ -759,14 +851,20 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
// read all files on drive 1
_operationCtr++;
_actualOperation = "Read installed meter files drive 1";
if (ReadMeterFilesDrive1())
{
foreach (var checkInstalledFile in filesToDownload)
{
if (_meterFilesDrive1.Contains(checkInstalledFile)) continue;
if (_meterFilesDrive1.Contains(checkInstalledFile))
{
ErrorMessage = "";
var txt = $"{checkInstalledFile} found in meter\n";
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(txt));
continue;
}
ErrorMessage += $"LUT file {StrLutMeterFileName} not installed!\n";
ErrorMessage = $"LUT file {StrLutMeterFileName} not installed!\n";
returnValue = false;
}
}
@@ -798,7 +896,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
{
//counters for actual process information
var retryCtr = 0;
if (LutFile == null) return false;
if (LutFile == null)
return false;
//set extended timeout for trigger upgrade response delay
_genesisMeter.TransmitProtocol.SetResponseTimeout(10000);
@@ -814,7 +913,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
{
_operationCtr++;
_actualOperation = $"Read {fileToUpload}";
// logout and re-login to clear all ongoing processes and clear the Genesis buffers
ReestablishMeterFileSystem();
@@ -823,11 +922,17 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
// compare the entire buffer which also includes the header of the file
if (!binData.SequenceEqual(LutFile.BinData))
{
ErrorMessage += $"Meter LUT file is unequal to downloaded {fileToUpload}!\n";
ErrorMessage = $"Meter LUT file is unequal to downloaded {fileToUpload}!\n";
returnValue = false;
_operationCtr--;
}
else
{
OnProcessUpdate?.Invoke(this,
new ProcessExecEventArgs($"LUT file {fileToUpload} of meter successfully compared!\n"));
}
continue;
}