GTB LowLevelTools: - Tidy files implemented

This commit is contained in:
Thomas Wiedebusch
2023-01-14 14:38:44 +01:00
parent b6655ae270
commit 18db1974e9
3 changed files with 282 additions and 136 deletions
@@ -69,6 +69,28 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
/// </summary>
public const String StrMeterEngLogIndexFile = "1\\logindex";
/// <summary>
/// EMEA log files which can be removed on NA installation
/// </summary>
public static readonly String[] EmeaLogs = { "1\\fdrdata", "1\\logdata", "1\\evtdata" };
/// <summary>
/// NA log files which can be removed on EMEA installation
/// </summary>
public static readonly String[] NaLogs =
{ "1\\NAalarm", "1\\NAconfig", "1\\NApress", "1\\NAstate", "1\\NAtempC", "1\\NAwater" };
/// <summary>
/// Essential files which have to be kept
/// </summary>
public static readonly String[] FilesToKeep =
{ "0\\password", StrMeterConfigFile, "1\\logindex", "1\\mettbl", "1\\mettbl_b" };
/// <summary>
/// Files which always can be removed to clean the file system up "tidy file"
/// </summary>
public static readonly String[] FilesToRemove = { "1\\upg", "1\\upgrade", StrMeterTstFile };
/// <summary>
/// Drive zero of meter.
/// </summary>
@@ -262,13 +284,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
var rpc = BuildRpcInt32(1, dataBytes.Length, _filePointer);
returnValue = _currentGenesis.WriteRegister(Register.Configexchange.FileWrite, rpc);
////write size to 1
//returnValue = _currentGenesis.WriteRegister(Register.Configexchange.FileWrite, 1, false);
////write counts to data size
//returnValue &= _currentGenesis.WriteRegister(Register.Configexchange.FileWrite, dataBytes.Length, false);
////write file pointer
//returnValue &= _currentGenesis.WriteRegister(Register.Configexchange.FileWrite, _filePointer);
//calculate records to send based on MaxRawDataSize
var chunkCounts = dataBytes.Length / MaxRawDataSize;
if (0 != dataBytes.Length % MaxRawDataSize)
@@ -439,13 +454,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
var rpc = BuildRpcInt32(1, fileSize, _filePointer);
_currentGenesis.WriteRegister(Register.Configexchange.FileRead, rpc);
////write size to 1
//_currentGenesis.WriteRegister(Register.Configexchange.FileRead, 1, false);
////write counts to expected length
//_currentGenesis.WriteRegister(Register.Configexchange.FileRead, fileSize, false);
////write file pointer
//_currentGenesis.WriteRegister(Register.Configexchange.FileRead, _filePointer);
//the preceding routine needs to wait for response, else this is always true!
while (fileSize > 0 && !_stopProcess)
{
@@ -605,12 +613,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
var rpc = BuildRpcInt32(1, 1, _filePointer);
returnValue = _currentGenesis.WriteRegister(Register.Configexchange.FileWrite, rpc);
////write size to 1
//returnValue = _currentGenesis.WriteRegister(Register.Configexchange.FileWrite, 1, false);
////write block of data to 1 as only one byte needed to be at the end of file
//returnValue &= _currentGenesis.WriteRegister(Register.Configexchange.FileWrite, 1, false);
////write file pointer
//returnValue &= _currentGenesis.WriteRegister(Register.Configexchange.FileWrite, _filePointer);
//write one byte at the end of file
returnValue &= _currentGenesis.WriteRegister(Register.Configexchange.FileWrite, 0xFF);
@@ -774,7 +776,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
//request retries on single write register access, needs to be zero to hold the sequence
CommunicationConfig.RequestRetries = 0;
//write "remove-command" to meter, wait for result and read back
//write "remove-command" to meter, return is always false!
//ATTENTION: read back returns FALSE because of unreadable content
_currentGenesis.WriteRegister(Register.Configexchange.FileRemove, fileName, true, true);
//set timeout back to default value
@@ -846,25 +848,12 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
do
{
//if (retryCtr > 0)
//{
// //read DUMMY to overcome FW malfunction
// _currentGenesis.ReadRegister(Register.System.MonotonicSeconds);
// Thread.Sleep(1000);
//}
//request retries on single write register access, needs to be zero to hold the sequence
CommunicationConfig.RequestRetries = 0;
var rpc = BuildRpcInt32(_filePointer, filePointerOffset, fSeekPara);
returnValue = _currentGenesis.WriteRegister(Register.Configexchange.SetFilePointerOffset, rpc);
//returnValue = _currentGenesis.WriteRegister(Register.Configexchange.SetFilePointerOffset,
// _filePointer, false);
//returnValue &= _currentGenesis.WriteRegister(Register.Configexchange.SetFilePointerOffset,
// filePointerOffset, false);
//returnValue &= _currentGenesis.WriteRegister(Register.Configexchange.SetFilePointerOffset,
// fSeekPara, false);
//function call returns 0 if FSeek successfully set
returnValue &= 0 == RegisterConverter.ConvertTo<UInt32>(_currentGenesis.ReadRegister(
Register.Configexchange.SetFilePointerOffset));
@@ -907,12 +896,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
do
{
//if (retryCtr > 0)
//{
// //read DUMMY to overcome FW malfunction
// _currentGenesis.ReadRegister(Register.System.MonotonicSeconds);
// Thread.Sleep(1000);
//}
//read file pointer offset
_currentGenesis.WriteRegister(Register.Configexchange.GetFilePointerOffset,
_filePointer, false);
@@ -988,13 +971,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
do
{
//if (retryCtr > 0)
//{
// //read DUMMY to overcome FW malfunction
// _currentGenesis.ReadRegister(Register.System.MonotonicSeconds);
// Thread.Sleep(1000);
//}
//write file name to meter with meter open command, don't wait for response
var rpcString = new String(rpc.ToArray());
rpcString += accessMode;
@@ -1002,11 +978,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
// wait for response!
retValue = _currentGenesis.WriteRegister(Register.Configexchange.FileOpen, rpcString, false);
////write file name to meter with meter open command, don't wait for response
//retValue = _currentGenesis.WriteRegister(Register.Configexchange.FileOpen, fileName, false);
////write access flag
//retValue &= _currentGenesis.WriteRegister(Register.Configexchange.FileOpen, accessMode, false);
if (retValue)
{
//get the file pointer
@@ -1068,13 +1039,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
do
{
//if (retryCtr > 0)
//{
// //read DUMMY to overcome FW malfunction
// _currentGenesis.ReadRegister(Register.System.MonotonicSeconds);
// Thread.Sleep(1000);
//}
retValue = _currentGenesis.WriteRegister(Register.Configexchange.FileClose, _filePointer);
//function call returns 0 if FClose successfully executed
+22 -9
View File
@@ -68,8 +68,9 @@
this.label7 = new System.Windows.Forms.Label();
this.saveConfigFile = new System.Windows.Forms.SaveFileDialog();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.btnReadLogFiles = new System.Windows.Forms.Button();
this.btnListFileDetails = new System.Windows.Forms.Button();
this.btnReadLogFiles = new System.Windows.Forms.Button();
this.btnTidyFile = new System.Windows.Forms.Button();
this.grpSetup.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.groupBox1.SuspendLayout();
@@ -348,6 +349,7 @@
//
// groupBox1
//
this.groupBox1.Controls.Add(this.btnTidyFile);
this.groupBox1.Controls.Add(this.btnGetDateTime);
this.groupBox1.Controls.Add(this.btnSetDateTime);
this.groupBox1.Controls.Add(this.btnRebootMeter);
@@ -465,6 +467,16 @@
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Log";
//
// btnListFileDetails
//
this.btnListFileDetails.Location = new System.Drawing.Point(10, 84);
this.btnListFileDetails.Name = "btnListFileDetails";
this.btnListFileDetails.Size = new System.Drawing.Size(116, 25);
this.btnListFileDetails.TabIndex = 39;
this.btnListFileDetails.Text = "List File Details";
this.btnListFileDetails.UseVisualStyleBackColor = true;
this.btnListFileDetails.Click += new System.EventHandler(this.btnListFileDetails_Click);
//
// btnReadLogFiles
//
this.btnReadLogFiles.Location = new System.Drawing.Point(10, 54);
@@ -475,15 +487,15 @@
this.btnReadLogFiles.UseVisualStyleBackColor = true;
this.btnReadLogFiles.Click += new System.EventHandler(this.btnReadLogFiles_Click);
//
// btnListFileDetails
// btnTidyFile
//
this.btnListFileDetails.Location = new System.Drawing.Point(10, 84);
this.btnListFileDetails.Name = "btnListFileDetails";
this.btnListFileDetails.Size = new System.Drawing.Size(116, 25);
this.btnListFileDetails.TabIndex = 39;
this.btnListFileDetails.Text = "List File Details";
this.btnListFileDetails.UseVisualStyleBackColor = true;
this.btnListFileDetails.Click += new System.EventHandler(this.btnListFileDetails_Click);
this.btnTidyFile.Location = new System.Drawing.Point(10, 174);
this.btnTidyFile.Name = "btnTidyFile";
this.btnTidyFile.Size = new System.Drawing.Size(116, 25);
this.btnTidyFile.TabIndex = 39;
this.btnTidyFile.Text = "Tidy File System";
this.btnTidyFile.UseVisualStyleBackColor = true;
this.btnTidyFile.Click += new System.EventHandler(this.btnTidyFile_Click);
//
// FrmLowLevelTools
//
@@ -568,5 +580,6 @@
private System.Windows.Forms.Button btnGetDateTime;
private System.Windows.Forms.Button btnReadLogFiles;
private System.Windows.Forms.Button btnListFileDetails;
private System.Windows.Forms.Button btnTidyFile;
}
}
+237 -68
View File
@@ -16,6 +16,7 @@ using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
using Xylem.Common.Utils.ProcessExec.EventArguments;
using String = System.String;
namespace Xylem.Common.Ui.GenesisToolBox
@@ -35,8 +36,8 @@ namespace Xylem.Common.Ui.GenesisToolBox
private MeterFile _meterFile;
private String _lastFwUpdateState;
private Int32 _lastSingleProgress;
//private String _lastFwUpdateState;
//private Int32 _lastSingleProgress;
private Boolean _progressBarOn;
private DateTimeOffset _startTime;
private Boolean _resetTimeMeasurement;
@@ -155,6 +156,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
btnUploadConfig.Enabled = false;
btnReadLogFiles.Enabled = false;
btnListFileDetails.Enabled = false;
btnTidyFile.Enabled = false;
}
/// <summary>
@@ -171,6 +173,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
btnUploadConfig.Enabled = true;
btnReadLogFiles.Enabled = true;
btnListFileDetails.Enabled = true;
btnTidyFile.Enabled = true;
}
/// <summary>
@@ -436,7 +439,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
lblOverall.Visible = true;
barOverallProgressUpdate.Visible = true;
barSingleProgressUpdate.Visible = true;
_lastFwUpdateState = "";
//_lastFwUpdateState = "";
tmrProgressUpdate.Enabled = true;
SetControlsLowLevelOpOngoing();
}
@@ -447,7 +450,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
barOverallProgressUpdate.Visible = false;
barSingleProgressUpdate.Visible = false;
tmrProgressUpdate.Enabled = false;
_lastFwUpdateState = "";
//_lastFwUpdateState = "";
lblWaitingForMeterResponse.Visible = false;
lblActualProcess.Text = "";
lblOverall.Text = "";
@@ -470,7 +473,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
{
Invoke(new Action(() =>
{
_lastFwUpdateState = "";
//_lastFwUpdateState = "";
ViewProcessControl(true);
tmrProgressUpdate.Enabled = true;
}));
@@ -635,7 +638,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
#endregion
#region Checks
#region Tools
private void CheckUpdateEnabled()
{
@@ -649,6 +652,111 @@ namespace Xylem.Common.Ui.GenesisToolBox
SetCordonelAccessLocked();
}
/// <summary>
/// List all meter files
/// </summary>
/// <remarks date="2023-Jan-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private List<String> ListMeterFiles()
{
SetActualProcessAndLog(@"List meter files drive 0");
_meterFile.ReadMeterFileCatalog(out var fileNamesDrive0, MeterFile.StrMeterDrive0);
if (fileNamesDrive0.Count == 0)
{
LogText(@"Could not read drive 0");
}
else
{
foreach (var fileName in fileNamesDrive0)
{
LogText(fileName);
}
}
SetActualProcessAndLog(@"List meter files drive 1");
_meterFile.ReadMeterFileCatalog(out var fileNamesDrive1, MeterFile.StrMeterDrive1);
if (fileNamesDrive1.Count == 0)
{
LogText(@"Could not read drive 1");
}
else
{
foreach (var fileName in fileNamesDrive1)
{
LogText(fileName);
}
}
var fileNames = new List<String>();
fileNames.AddRange(fileNamesDrive0);
fileNames.AddRange(fileNamesDrive1);
return fileNames;
}
/// <summary>
/// List all meter log files covered by the log index file
/// </summary>
/// <remarks date="2023-Jan-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private List<String> ListLogFiles()
{
SetActualProcessAndLog(@"Flushing the logger");
_currentGenesis.WriteRegister("LOGGER_TriggerLogFlush", 1);
CalculateMeterDateTime(RegisterConverter.ConvertTo<Int32>(
_currentGenesis.ReadRegister("SYSTEM_CalendarSeconds")));
SetActualProcessAndLog(@"Reading log index file");
_meterFile.ReadMeterFile(MeterFile.StrMeterEngLogIndexFile, out var data);
var fileNames = new List<String>();
var rawData = data.ToArray();
var sample = new Byte[4];
for (var ctr = 0; ctr < data.Count; ctr += 4)
{
for (var x = 0; x < 4; x++)
{
sample[x] = rawData[ctr + x];
}
var name = $"1\\{RegisterConverter.ConvertTo<Int32>(sample):X8}";
LogText($"Log file catalogue: {name}");
fileNames.Add(name);
}
fileNames.Sort();
return fileNames;
}
/// <summary>
/// Analyze all meter files
/// </summary>
/// <remarks date="2023-Jan-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private void AnalyzeMeterFiles(List<String> meterFiles)
{
if (meterFiles.Count == 0)
return;
LogText("Analyzing meter files");
foreach (var fileName in meterFiles)
{
Invoke(new Action(() => { lblActualProcess.Text = $@"Analyze file {fileName}"; }));
var success = _meterFile.GetFileSize(fileName, out var fileSize);
LogText(success
? $@"File name: {fileName}, File size: {fileSize} byte"
: $@"File name: {fileName} Unable to access file");
if (success)
continue;
_currentGenesis.Logout();
_currentGenesis.ReLogin();
}
}
#endregion
#region Events
@@ -690,7 +798,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
var singleProgress = (Int32)(_meterResetPsu?.SingleFileProcessCtrPercent ?? 0);
barSingleProgressUpdate.Value = singleProgress > 100 ? 100 : singleProgress;
_lastSingleProgress = singleProgress;
//_lastSingleProgress = singleProgress;
barSingleProgressUpdate.Update();
}
@@ -1019,7 +1127,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
}
/// <summary>
/// Read engineering log file from meter.
/// Read engineering log files from meter and analyzes the contents.
/// </summary>
/// <remarks date="2023-Jan-04" author="Roland Drabesch/Thomas Wiedebusch">
/// - Initial
@@ -1055,37 +1163,12 @@ namespace Xylem.Common.Ui.GenesisToolBox
{
_currentGenesis.ReLogin();
SetActualProcessAndLog(@"Flushing the logger");
_currentGenesis.WriteRegister("LOGGER_TriggerLogFlush", 1);
CalculateMeterDateTime(RegisterConverter.ConvertTo<Int32>(
_currentGenesis.ReadRegister("SYSTEM_CalendarSeconds")));
SetActualProcessAndLog(@"Reading log index file");
_meterFile.ReadMeterFile(MeterFile.StrMeterEngLogIndexFile, out var data);
var fileNames = new List<String>();
var rawData = data.ToArray();
var sample = new Byte[4];
for (var ctr = 0; ctr < data.Count; ctr += 4)
{
for (var x = 0; x < 4; x++)
{
sample[x] = rawData[ctr + x];
}
var name = RegisterConverter.ConvertTo<Int32>(sample).ToString("X8");
LogText(name);
fileNames.Add(name);
}
fileNames.Sort();
var fileNames = ListLogFiles();
foreach (var fileName in fileNames)
{
msg = $"1\\{fileName}";
SetActualProcessAndLog($@"Reading {msg}");
var success = _meterFile.ReadMeterFile(msg, out data);
SetActualProcessAndLog($@"Reading and analyzing {fileName}");
var success = _meterFile.ReadMeterFile(fileName, out var data);
if (!success)
{
@@ -1162,7 +1245,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
/// <summary>
/// List file details from meter.
/// </summary>
/// <remarks date="2023-Jan-04" author="Roland Drabesch/Thomas Wiedebusch">
/// <remarks date="2023-Jan-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private void btnListFileDetails_Click(Object sender, EventArgs e)
@@ -1177,42 +1260,15 @@ namespace Xylem.Common.Ui.GenesisToolBox
LowLevelActionControl(true);
var msg = @"List file details from meter";
var msg = @"List file details of meter";
LogText(msg);
lblOverall.Text = msg;
Task.Factory.StartNew(() =>
{
_currentGenesis.ReLogin();
var fileNames = new List<String>();
Invoke(new Action(() => { lblActualProcess.Text = @"List meter files drive 0"; }));
_meterFile.ReadMeterFileCatalog(out var fileNamesDrive0, MeterFile.StrMeterDrive0);
if (fileNamesDrive0.Count == 0)
{
LogText(@"Could not read drive 0");
}
Invoke(new Action(() => { lblActualProcess.Text = @"List meter files drive 1"; }));
_meterFile.ReadMeterFileCatalog(out var fileNamesDrive1, MeterFile.StrMeterDrive1);
if (fileNamesDrive1.Count == 0)
{
LogText(@"Could not read drive 1");
}
fileNames.AddRange(fileNamesDrive0);
fileNames.AddRange(fileNamesDrive1);
foreach (var fileName in fileNames)
{
Invoke(new Action(() => { lblActualProcess.Text = $@"Analyze file {fileName}"; }));
var success = _meterFile.GetFileSize(fileName, out var fileSize);
LogText(success ? $@"File name: {fileName}, File size: {fileSize} byte"
: $@"File name: {fileName} Unable to access file");
if (success) continue;
_currentGenesis.Logout();
_currentGenesis.ReLogin();
}
var fileNames = ListMeterFiles();
AnalyzeMeterFiles(fileNames);
}).ContinueWith(delegate
{
//add a blank line to separate next operation
@@ -1221,8 +1277,121 @@ namespace Xylem.Common.Ui.GenesisToolBox
LowLevelActionControl(false);
});
}
#endregion
/// <summary>
/// Tidy the file system:
/// - Erasing upgrade files left over from unsuccessfully FW update,
/// - Erase logging files for versions not covered by the actual region as
/// during development a reprogramming from EMEA to NA and vice versa will
/// leave the logs for thr other version in,
/// - Remove the test file for EMEA, as this is the placeholder for the FW
/// update over the air to keep the space reserved for this process (250 kB),
/// - Keep important files listed in the log index.
/// </summary>
/// <remarks date="2023-Jan-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
private void btnTidyFile_Click(Object sender, EventArgs e)
{
if (_currentGenesis == null)
return;
if (_meterFile == null)
_meterFile = new MeterFile(_currentGenesis);
//reset timer
_startTime = DateTimeOffset.UtcNow;
LowLevelActionControl(true);
var msg = @"Tidy file system";
LogText(msg);
lblOverall.Text = msg;
Task.Factory.StartNew(() =>
{
_currentGenesis.ReLogin();
// catalogue before cleaning
SetActualProcessAndLog(@"List meter files before cleaning");
// build file erase candidates for all releases
var fileEraseCandidates = new List<String>();
// put initially all files in as erase candidates
var meterFiles = ListMeterFiles();
AnalyzeMeterFiles(meterFiles);
fileEraseCandidates.AddRange(meterFiles);
// build list of files needed to keep
var filesToKeep = new List<String>();
filesToKeep.AddRange(MeterFile.FilesToKeep);
// for EMEA the NALogs are waste
if (_currentGenesis.Region.Contains("EMEA"))
{
LogText("EMEA version detected");
filesToKeep.AddRange(MeterFile.EmeaLogs);
}
// for EMEA the EMEALogs are waste
if (_currentGenesis.Region.Contains("NA"))
{
LogText("NA version detected");
filesToKeep.AddRange(MeterFile.NaLogs);
}
// red the log files and leave it in
var logFiles = ListLogFiles();
filesToKeep.AddRange(logFiles);
// remove files which should be kept in place
foreach (var meterFile in meterFiles)
{
foreach (var fileToKeep in filesToKeep)
{
if (meterFile.Contains(fileToKeep))
fileEraseCandidates.Remove(meterFile);
}
}
// check if something to clean
if (fileEraseCandidates.Count == 0)
{
LogText("File system is clean");
}
else
{
// erase files
foreach (var fileToErase in fileEraseCandidates)
{
Invoke(new Action(() => { lblActualProcess.Text = $@"Erase {fileToErase}"; }));
_meterFile.UnlockEraseWriteMeterFile(fileToErase);
var success = _meterFile.EraseMeterFile(fileToErase);
LogText(success
? $@"File {fileToErase} successfully erased"
: $@"File {fileToErase} erasure failed");
if (success) continue;
_currentGenesis.Logout();
_currentGenesis.ReLogin();
}
// catalogue after cleaning
SetActualProcessAndLog(@"List meter files after cleaning");
ListMeterFiles();
LogText("File system is cleaned up");
}
}).ContinueWith(delegate
{
//add a blank line to separate next operation
LogText("");
_currentGenesis.Logout();
LowLevelActionControl(false);
});
}
#endregion
}
}