diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/Consts/LutUpdateStateInfo.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/Consts/LutUpdateStateInfo.cs new file mode 100644 index 00000000..0ad537a2 --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/Consts/LutUpdateStateInfo.cs @@ -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 +{ + /// + /// Concatenation of state and string + /// + public static class LutUpdateStateInfo + { + /// + /// Build state information + /// + private static readonly LutUpdateStateText[] StateInfos; + + /// + /// Ctor + /// + 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"; + } + + /// + /// Get the current information + /// + /// state to search for information text + public static String GetTextFromState(LutUpdateState state) + { + return (from stateInfo in StateInfos + where stateInfo.State == state select stateInfo.Message).FirstOrDefault(); + } + /// + /// Get the state of the text + /// + /// information text to search if state is assigned + public static LutUpdateState GetStateFromText(String text) + { + return (from stateInfo in StateInfos + where stateInfo.Message == text select stateInfo.State).FirstOrDefault(); + } + } +} diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/Consts/LutUpdateStateText.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/Consts/LutUpdateStateText.cs new file mode 100644 index 00000000..88947bf6 --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/Consts/LutUpdateStateText.cs @@ -0,0 +1,19 @@ +using System; + +namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Consts +{ + /// + /// Concatenation between lokup table update state and text + /// + public struct LutUpdateStateText + { + /// + /// The state of the firmware update + /// + public LutUpdateState State; + /// + /// The message text of the lookup table update state + /// + public String Message; + } +} diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/GenesisFile.csproj b/Common/Hardware/WaterMeter/Genesis/GenesisFile/GenesisFile.csproj index 20c73c4d..89c08d2f 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/GenesisFile.csproj +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/GenesisFile.csproj @@ -66,6 +66,8 @@ Properties\SharedAssemblyInfo.cs + + diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs index 6088258e..f224d0f6 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterLutUpdate.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 _meterFilesDrive1; @@ -208,7 +205,15 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// 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; } + /// + /// Read meter files of drive 1 + /// + /// + /// + /// - Initial + /// + private Boolean ReadMeterFilesDrive1() + { + if (_meterFilesDrive1 == null) + { + _meterFilesDrive1 = new List(); + } + _meterFilesDrive1.Clear(); + + if (!_meterFile.ReadMeterFileCatalog(out var meterFilesDrive1, MeterFile.StrMeterDrive1, + MeterFile.WildcardAll.ToString())) return false; + + _meterFilesDrive1.AddRange(meterFilesDrive1); + return true; + } + /// /// Erase file and check if done! /// /// - /// + /// /// - Initial /// 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 } /// - /// Download the metrology lookup table files and read the catalog of drive 1 + /// Erase old LUT files from meter /// - /// /// /// - Initial /// - 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(); + 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; - } + /// + /// Download the metrology lookup table files and read the catalog of drive 1 + /// + /// + /// + /// - Initial + /// + 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; + } + + /// + /// Upload the metrology lookup table files and read the catalog of drive 1 + /// + /// + /// + /// - Initial + /// + 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) diff --git a/Common/Ui/GenesisToolBox/FrmFwUpdate.cs b/Common/Ui/GenesisToolBox/FrmFwUpdate.cs index a2cd2905..015616a0 100644 --- a/Common/Ui/GenesisToolBox/FrmFwUpdate.cs +++ b/Common/Ui/GenesisToolBox/FrmFwUpdate.cs @@ -668,6 +668,9 @@ namespace Xylem.Common.Ui.GenesisToolBox return; } + lblOverall.Text = @"Data base connection.."; + lblOverall.Visible = true; + Update(); _currentGenesis?.DisposeMeter(); //dispose old meter _meterBatch.RemoveAllMeters(); diff --git a/Common/Ui/GenesisToolBox/FrmLutUpdate.Designer.cs b/Common/Ui/GenesisToolBox/FrmLutUpdate.Designer.cs index 32c01bd5..8a2ef11c 100644 --- a/Common/Ui/GenesisToolBox/FrmLutUpdate.Designer.cs +++ b/Common/Ui/GenesisToolBox/FrmLutUpdate.Designer.cs @@ -64,6 +64,7 @@ this.btnOpenLutFile = new System.Windows.Forms.Button(); this.label9 = new System.Windows.Forms.Label(); this.lblUpdateTime = new System.Windows.Forms.Label(); + this.label7 = new System.Windows.Forms.Label(); this.grpSetup.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.groupBox1.SuspendLayout(); @@ -284,7 +285,7 @@ // this.lblFwUpdateInfo.AutoSize = true; this.lblFwUpdateInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblFwUpdateInfo.Location = new System.Drawing.Point(527, 6); + this.lblFwUpdateInfo.Location = new System.Drawing.Point(18, 32); this.lblFwUpdateInfo.Name = "lblFwUpdateInfo"; this.lblFwUpdateInfo.Size = new System.Drawing.Size(72, 13); this.lblFwUpdateInfo.TabIndex = 27; @@ -410,12 +411,23 @@ this.lblUpdateTime.TabIndex = 31; this.lblUpdateTime.Text = "0:00"; // + // label7 + // + this.label7.AutoSize = true; + this.label7.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label7.Location = new System.Drawing.Point(16, 9); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(159, 16); + this.label7.TabIndex = 32; + this.label7.Text = "Cordonel LUT Update"; + // // FrmLutUpdate // this.AccessibleRole = System.Windows.Forms.AccessibleRole.Sound; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(723, 364); + this.Controls.Add(this.label7); this.Controls.Add(this.lblUpdateTime); this.Controls.Add(this.label9); this.Controls.Add(this.groupBox1); @@ -478,5 +490,6 @@ private System.Windows.Forms.Label label6; private System.Windows.Forms.TextBox tbxMeterFw; private System.Windows.Forms.TextBox tbxPcbId; + private System.Windows.Forms.Label label7; } } \ No newline at end of file diff --git a/Common/Ui/GenesisToolBox/FrmLutUpdate.cs b/Common/Ui/GenesisToolBox/FrmLutUpdate.cs index dfa0a5dd..2cbf965a 100644 --- a/Common/Ui/GenesisToolBox/FrmLutUpdate.cs +++ b/Common/Ui/GenesisToolBox/FrmLutUpdate.cs @@ -148,6 +148,9 @@ namespace Xylem.Common.Ui.GenesisToolBox return; } + lblOverall.Text = @"Data base connection.."; + lblOverall.Visible = true; + Update(); _currentGenesis?.DisposeMeter(); //dispose old meter _meterBatch.RemoveAllMeters();