MeterFile: - high speed file open
FrmLutUpdate, FrmFwUpdate, FrmLowLevelUpdate: - data base connection to connect task to have the progress bar active
This commit is contained in:
@@ -62,10 +62,6 @@
|
||||
/// </summary>
|
||||
PrepareUpdate,
|
||||
/// <summary>
|
||||
/// Read configuration file from meter
|
||||
/// </summary>
|
||||
UploadConfigFile,
|
||||
/// <summary>
|
||||
/// Delimiter for list
|
||||
/// </summary>
|
||||
FwUpdateStateListDelimiter
|
||||
|
||||
@@ -61,9 +61,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.Consts
|
||||
|
||||
StateInfos[(Int32)FwUpdateState.PrepareUpdate].State = FwUpdateState.PrepareUpdate;
|
||||
StateInfos[(Int32)FwUpdateState.PrepareUpdate].Message = Resources.StrFwUpdateStatePrepareUpdate;
|
||||
|
||||
StateInfos[(Int32)FwUpdateState.UploadConfigFile].State = FwUpdateState.UploadConfigFile;
|
||||
StateInfos[(Int32)FwUpdateState.UploadConfigFile].Message = Resources.StrUploadConfigFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -108,7 +108,6 @@
|
||||
<Compile Include="Consts\FwUpdateState.cs" />
|
||||
<Compile Include="Consts\FwUpdateStateInfo.cs" />
|
||||
<Compile Include="Consts\FwUpdateStateText.cs" />
|
||||
<Compile Include="MeterConfigFile.cs" />
|
||||
<Compile Include="MeterLutFile.cs" />
|
||||
<Compile Include="MeterFileRestore.cs" />
|
||||
<Compile Include="MeterFilesEraseRestore.cs" />
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
{
|
||||
/// <summary>
|
||||
/// File for meter configuration
|
||||
/// </summary>
|
||||
public class MeterConfigFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Data length
|
||||
/// </summary>
|
||||
public UInt32 DataLength;
|
||||
|
||||
/// <summary>
|
||||
/// Binary file content
|
||||
/// </summary>
|
||||
public List<Byte> BinData = new List<Byte>();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -38,12 +38,12 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
private const String StrOpenFileReadOnlyMode = "rb";
|
||||
//Open for both reading and writing in binary mode. If the file does not exist, FOpen returns NULL
|
||||
private const String StrOpenFileReadWriteMode = "rb+";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// FSeek for start of file
|
||||
/// </summary>
|
||||
public const Int32 FSeekStartOfFile = 0;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// FSeek for end of file
|
||||
/// </summary>
|
||||
@@ -281,7 +281,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
_currentGenesis.ReadRegister(Register.Configexchange.FileWrite));
|
||||
returnedFileOffset = ReadFilePointerOffset();
|
||||
}
|
||||
|
||||
|
||||
//set timeout back to default value
|
||||
_currentGenesis.TransmitProtocol.SetDefaultResponseTimeout();
|
||||
CommunicationConfig.RequestRetries = CommunicationConfig.DefaultRequestRetries;
|
||||
@@ -341,6 +341,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
/// <remarks date="2023-Jan-02" author="Thomas Wiedebusch">
|
||||
/// - Read data according to file size searched with FSeek.
|
||||
/// </remarks>
|
||||
/// <remarks date="2023-Jan-03" author="Thomas Wiedebusch">
|
||||
/// - Speed up FOpen as read is not so critical.
|
||||
/// </remarks>
|
||||
public Boolean ReadMeterFile(String fileName, out List<Byte> readBackData)
|
||||
{
|
||||
//set processing counter
|
||||
@@ -355,55 +358,58 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
// Get the current file size
|
||||
var returnValue = GetFileSize(fileName, out var readBackCount);
|
||||
|
||||
returnValue &= OpenMeterFile(fileName, StrOpenFileReadOnlyMode);
|
||||
|
||||
if (returnValue)
|
||||
{
|
||||
//set register write retries to 0 to avoid doubling of records
|
||||
CommunicationConfig.RequestRetries = 0;
|
||||
_currentGenesis.TransmitProtocol.SetResponseTimeout(ExtendedFileIoTimeoutMs);
|
||||
|
||||
//write size to 1
|
||||
_currentGenesis.WriteRegister(Register.Configexchange.FileRead, 1, false);
|
||||
//write counts to expected length
|
||||
_currentGenesis.WriteRegister(Register.Configexchange.FileRead, readBackCount, false);
|
||||
//write file pointer
|
||||
_currentGenesis.WriteRegister(Register.Configexchange.FileRead, _filePointer);
|
||||
//use high speed access
|
||||
returnValue &= OpenMeterFile(fileName, StrOpenFileReadOnlyMode, true);
|
||||
|
||||
//the preceding routine needs to wait for response, else this is always true!
|
||||
while (readBackCount > 0 && !_stopProcess)
|
||||
if (returnValue)
|
||||
{
|
||||
var remainingData = RegisterConverter.ConvertTo<Int32>(
|
||||
_currentGenesis.ReadRegister(Register.Configexchange.FileRead));
|
||||
//set register write retries to 0 to avoid doubling of records
|
||||
CommunicationConfig.RequestRetries = 0;
|
||||
_currentGenesis.TransmitProtocol.SetResponseTimeout(ExtendedFileIoTimeoutMs);
|
||||
|
||||
readBackCount = remainingData > 0 ? readBackCount - remainingData : 0;
|
||||
//write size to 1
|
||||
_currentGenesis.WriteRegister(Register.Configexchange.FileRead, 1, false);
|
||||
//write counts to expected length
|
||||
_currentGenesis.WriteRegister(Register.Configexchange.FileRead, readBackCount, false);
|
||||
//write file pointer
|
||||
_currentGenesis.WriteRegister(Register.Configexchange.FileRead, _filePointer);
|
||||
|
||||
while (remainingData > 0)
|
||||
//the preceding routine needs to wait for response, else this is always true!
|
||||
while (readBackCount > 0 && !_stopProcess)
|
||||
{
|
||||
var size = remainingData > MaxRawDataSize ? MaxRawDataSize : remainingData;
|
||||
readBackData.AddRange(_currentGenesis.ReadRegister(Register.Configexchange.FileRead, size));
|
||||
remainingData -= size;
|
||||
var remainingData = RegisterConverter.ConvertTo<Int32>(
|
||||
_currentGenesis.ReadRegister(Register.Configexchange.FileRead));
|
||||
|
||||
//set processed bytes for read loop
|
||||
ProcessedBytesCtr += size;
|
||||
readBackCount = remainingData > 0 ? readBackCount - remainingData : 0;
|
||||
|
||||
//inform the caller of changed statue
|
||||
var processCtrPercent = 100.0 * ProcessedBytesCtr / (_overallBytesCtr > 0 ? _overallBytesCtr : 1);
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs("", processCtrPercent));
|
||||
while (remainingData > 0)
|
||||
{
|
||||
var size = remainingData > MaxRawDataSize ? MaxRawDataSize : remainingData;
|
||||
readBackData.AddRange(_currentGenesis.ReadRegister(Register.Configexchange.FileRead, size));
|
||||
remainingData -= size;
|
||||
|
||||
//set processed bytes for read loop
|
||||
ProcessedBytesCtr += size;
|
||||
|
||||
//inform the caller of changed statue
|
||||
var processCtrPercent = 100.0 * ProcessedBytesCtr / (_overallBytesCtr > 0 ? _overallBytesCtr : 1);
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs("", processCtrPercent));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//set timeout back to default value
|
||||
_currentGenesis.TransmitProtocol.SetDefaultResponseTimeout();
|
||||
CommunicationConfig.RequestRetries = CommunicationConfig.DefaultRequestRetries;
|
||||
//set timeout back to default value
|
||||
_currentGenesis.TransmitProtocol.SetDefaultResponseTimeout();
|
||||
CommunicationConfig.RequestRetries = CommunicationConfig.DefaultRequestRetries;
|
||||
|
||||
}//file open succeeded
|
||||
}//file open succeeded
|
||||
|
||||
//dummy read to avoid 0x040B feedback from meter
|
||||
//_currentGenesis.ReadRegister(Register.Configexchange.FileRead, 1);
|
||||
returnValue &= CloseMeterFile();
|
||||
|
||||
returnValue &= CloseMeterFile();
|
||||
}// file size unequal to 0
|
||||
|
||||
//processed bytes not longer needed
|
||||
ProcessedBytesCtr = 0;
|
||||
@@ -562,16 +568,16 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
public Boolean GetFileSize(String fileName, out Int32 fileSize)
|
||||
{
|
||||
fileSize = 0;
|
||||
var returnValue = OpenMeterFile(fileName, StrOpenFileReadOnlyMode);
|
||||
|
||||
var returnValue = OpenMeterFile(fileName, StrOpenFileReadOnlyMode, true);
|
||||
|
||||
if (returnValue)
|
||||
{
|
||||
returnValue &= SetFilePointerOffset(fSeekPara: FSeekEndOfFile);
|
||||
returnValue &= SetFilePointerOffset(fSeekPara: FSeekEndOfFile);
|
||||
|
||||
if (returnValue)
|
||||
{
|
||||
fileSize = ReadFilePointerOffset();
|
||||
}
|
||||
if (returnValue)
|
||||
{
|
||||
fileSize = ReadFilePointerOffset();
|
||||
}
|
||||
}
|
||||
|
||||
returnValue &= CloseMeterFile();
|
||||
@@ -596,7 +602,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
{
|
||||
var returnValue = true;
|
||||
|
||||
if (!ReadMeterFile(fileName, out var binData)|| binData == null || binData.Count == 0)
|
||||
if (!ReadMeterFile(fileName, out var binData) || binData == null || binData.Count == 0)
|
||||
return false;
|
||||
|
||||
// compare the entire buffer which also includes the header of the file, remind the original
|
||||
@@ -609,11 +615,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
returnValue = false;
|
||||
}
|
||||
}
|
||||
//if (dataBytes.Where((t, ctr) => t != binData[ctr]).Any())
|
||||
//{
|
||||
// returnValue = false;
|
||||
//}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
@@ -704,7 +705,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
/// <remarks date="2023-Jan-02" author="Thomas Wiedebusch">
|
||||
/// - Extended FSeek for file end positioning.
|
||||
/// </remarks>
|
||||
private Boolean SetFilePointerOffset(Int32 filePointerOffset = 0, Int32 fSeekPara = FSeekStartOfFile)
|
||||
private Boolean SetFilePointerOffset(Int32 filePointerOffset = 0, Int32 fSeekPara = FSeekStartOfFile)
|
||||
{
|
||||
Boolean returnValue;
|
||||
var retryCtr = 0;
|
||||
@@ -802,7 +803,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
/// Open a file of the meter and sets the file pointer
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="accessMode"></param>
|
||||
/// <param name="accessMode">read, write eg,</param>
|
||||
/// <param name="highSpeed">disable high timeouts</param>
|
||||
/// <returns>true if filePointer higher than zero</returns>
|
||||
/// <remarks date="2019-Jun-20" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
@@ -815,7 +817,10 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
/// - Retries changed for and back,
|
||||
/// - Timeout changed for and back.
|
||||
/// </remarks>
|
||||
private Boolean OpenMeterFile(String fileName, String accessMode)
|
||||
/// <remarks date="2023-Jan-03" author="Thomas Wiedebusch">
|
||||
/// - Extended timings removed if high speed is active.
|
||||
/// </remarks>
|
||||
private Boolean OpenMeterFile(String fileName, String accessMode, Boolean highSpeed = false)
|
||||
{
|
||||
//check if logged on to meter and access level is as expected
|
||||
if (_currentGenesis == null || !_currentGenesis.IsLoggedOn)
|
||||
@@ -834,7 +839,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
}
|
||||
|
||||
//set extended timeout for file operations
|
||||
_currentGenesis.TransmitProtocol.SetResponseTimeout(ExtendedFileIoTimeoutMs);
|
||||
if (highSpeed)
|
||||
_currentGenesis.TransmitProtocol.SetResponseTimeout(ExtendedFileIoTimeoutMs);
|
||||
|
||||
CommunicationConfig.RequestRetries = 0;
|
||||
|
||||
//write file name to meter with meter open command, don't wait for response
|
||||
|
||||
@@ -25,9 +25,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
{
|
||||
#region Variables
|
||||
|
||||
// Look up table file
|
||||
public MeterConfigFile ConfigFile;
|
||||
|
||||
/// <summary>
|
||||
/// Port scan result event for message dispatcher to caller
|
||||
/// </summary>
|
||||
@@ -713,59 +710,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Upload the config file from meter
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2022-Apr-26" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public Boolean UploadConfigFile()
|
||||
{
|
||||
//counters for actual process information
|
||||
var retryCtr = 0;
|
||||
ConfigFile = new MeterConfigFile();
|
||||
|
||||
_processedBytesCtr = 0;
|
||||
_overallBytesCtr = 6;
|
||||
|
||||
_meterFile = new MeterFile(_genesisMeter);
|
||||
if (_meterFile != null)
|
||||
{
|
||||
_meterFile.OnProcessUpdate += ProcessUpdate_Event;
|
||||
}
|
||||
|
||||
_genesisMeter?.ReLogin();
|
||||
_genesisMeter?.SetProcessState(DisplayCodes.FwUpdateActive, webRequest: false);
|
||||
|
||||
if (_genesisMeter == null || !_genesisMeter.IsLoggedOn || _meterFile == null)
|
||||
return false;
|
||||
|
||||
var returnValue = true;
|
||||
|
||||
//read config file and retry if not successful
|
||||
do
|
||||
{
|
||||
_actualOperation = Resources.StrUploadConfigFile;
|
||||
|
||||
// logout and re-login to clear all ongoing processes and clear the Genesis buffers
|
||||
ReestablishMeterFileSystem();
|
||||
|
||||
if (!_meterFile.ReadMeterFile(StrConfigMeterFileName, out ConfigFile.BinData))
|
||||
{
|
||||
returnValue = false;
|
||||
}
|
||||
|
||||
if (!returnValue)
|
||||
{
|
||||
ReestablishMeterFileSystem();
|
||||
}
|
||||
} while (!returnValue && retryCtr++ < FileWriteRetries && !StopUpdateProcess);
|
||||
|
||||
_meterFile.OnProcessUpdate -= ProcessUpdate_Event;
|
||||
return !StopUpdateProcess && returnValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update meter firmware
|
||||
/// </summary>
|
||||
@@ -1170,6 +1114,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
/// - Prepare update added,
|
||||
/// - Upload config file added.
|
||||
/// </remarks>
|
||||
/// <remarks date="2023-Jan-02" author="Thomas Wiedebusch">
|
||||
/// - Upload config file removed.
|
||||
/// </remarks>
|
||||
private void FwUpdateStateMachine()
|
||||
{
|
||||
if (_fwBackupUpdateState == _fwUpdateState)
|
||||
@@ -1185,12 +1132,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
case FwUpdateState.Idle:
|
||||
break;
|
||||
|
||||
case FwUpdateState.UploadConfigFile:
|
||||
_fwUpdateState = UploadConfigFile()
|
||||
? FwUpdateState.Idle
|
||||
: FwUpdateState.StepFailed;
|
||||
break;
|
||||
|
||||
case FwUpdateState.StartInitial:
|
||||
_updateProcedureRetryCtr = 0;
|
||||
_fwUpdateState = FwUpdateState.BuildFileApps;
|
||||
|
||||
Reference in New Issue
Block a user