ReSharper: RequestProtocol, MeterFwUpdate
This commit is contained in:
@@ -45,7 +45,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig
|
||||
/// <summary>
|
||||
/// Limit retries to this value.
|
||||
/// </summary>
|
||||
public const Int32 MaxRequestRetries = 6;
|
||||
private const Int32 MaxRequestRetries = 6;
|
||||
|
||||
/// <summary>
|
||||
/// Send delay between records in milliseconds before
|
||||
@@ -55,6 +55,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig
|
||||
/// response from meter.
|
||||
/// </summary>
|
||||
public const Int32 InterRecordSendDelayMs = 5;
|
||||
//public const Int32 InterRecordSendDelayMs = 50;
|
||||
|
||||
/// <summary>
|
||||
/// Timeout before retry will be initiated in milliseconds
|
||||
|
||||
@@ -1744,8 +1744,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
{
|
||||
var regDef = _configRegister.GetRegisterDefinitionByName(reg);
|
||||
var data = RegisterConverter.ConvertFrom(value);
|
||||
_logger.Info($"Slot:{Slot} - Write register({regDef.RegisterName}), " +
|
||||
$"record({BitConverter.ToString(data.ToArray())})");
|
||||
_logger.Info( $"Slot:{Slot} - Write register({regDef.RegisterName}), " +
|
||||
$"record({BitConverter.ToString(data.ToArray())})");
|
||||
|
||||
PreRegisterWrite(regDef, data);
|
||||
|
||||
var command = data.Length > RegisterDefinition.ChunkSize ?
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
//package file search string for applications including blank!!!!
|
||||
private const String StrPackageFileAppId = "Id ";
|
||||
private const String StrPackageFileAppCrc = "CRC ";
|
||||
private const String StrPackageFileAppCrc16 = "CRC16 ";
|
||||
private const String StrPackageFileAppVersion = "version ";
|
||||
|
||||
//binary file name is a combination of "binfile" application ID underline version
|
||||
@@ -102,7 +103,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
/// </summary>
|
||||
public Double? CoreRevisionMinimum
|
||||
{
|
||||
get; private set;
|
||||
get; set;
|
||||
}
|
||||
/// <summary>
|
||||
/// Core revision maximum as double for comparison
|
||||
@@ -2017,6 +2018,12 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
/// <remarks date="2020-Dec-02" author="Thomas Wiedebusch">
|
||||
/// - Extraction of valid core revisions min/max.
|
||||
/// </remarks>
|
||||
/// <remarks date="2022-Nov-07" author="Thomas Wiedebusch">
|
||||
/// - CRC16 added:
|
||||
/// old versions will contain CRC without a number,
|
||||
/// new versions starting with 2022-11-04_NA_B122B contain a CRC16 and CRC32 identifier.
|
||||
/// - File line check modified to be immune against multiple blanks behind the field identifier.
|
||||
/// </remarks>
|
||||
public Boolean ValidateFileAppsWithPackageFile()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_packageDescriptionFile) || FileApps.Count == 0 ||
|
||||
@@ -2031,9 +2038,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
{
|
||||
//find a line which contains all required information
|
||||
validAppsCtr += packageFileLines.Count(line =>
|
||||
line.Contains($"{StrPackageFileAppId}{ConvertAppIdToString(fileApp.AppId)}") &&
|
||||
line.Contains($"{StrPackageFileAppCrc}{ConvertCrcToString(fileApp.Crc)}") &&
|
||||
line.Contains($"{StrPackageFileAppVersion}{fileApp.StrVersion}"));
|
||||
line.Contains($"{StrPackageFileAppId}") &&
|
||||
line.Contains($"{ConvertAppIdToString(fileApp.AppId)}") &&
|
||||
(line.Contains($"{StrPackageFileAppCrc}") ||
|
||||
line.Contains($"{StrPackageFileAppCrc16}")) &&
|
||||
line.Contains($"{ConvertCrcToString(fileApp.Crc)}") &&
|
||||
line.Contains($"{StrPackageFileAppVersion}") &&
|
||||
line.Contains($"{fileApp.StrVersion}"));
|
||||
}
|
||||
|
||||
//extract the core revision fields
|
||||
|
||||
+8
@@ -5,6 +5,14 @@
|
||||
/// </summary>
|
||||
public enum RequestAcknowledgeState
|
||||
{
|
||||
/// <summary>
|
||||
/// Acknowledge code for unassigned command
|
||||
/// </summary>
|
||||
CommandNotAssigned,
|
||||
/// <summary>
|
||||
/// Acknowledge code not set, will be used initially
|
||||
/// </summary>
|
||||
NotDecoded,
|
||||
/// <summary>
|
||||
/// Response missing
|
||||
/// </summary>
|
||||
|
||||
@@ -166,24 +166,43 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
/// <remarks date="2021-Feb-02" author="T.Wiedebusch">
|
||||
/// - Avoid enqueue of _recordInProcess if retry counter is 0.
|
||||
/// </remarks>
|
||||
/// <remarks date="2022-Nov-04" author="T.Wiedebusch">
|
||||
/// - Additional DEBUG information included about FIFO and loops.
|
||||
/// </remarks>
|
||||
/// <remarks date="2022-Nov-07" author="T.Wiedebusch">
|
||||
/// - Command not assigned response for recordInProcess == null.
|
||||
/// </remarks>
|
||||
public RequestAcknowledgeState ProcessRecordList()
|
||||
{
|
||||
_logger.Trace(" 1 ProcessRecordList");
|
||||
_logger.Trace($" Enry to ProcessRecordList, FIFO contains ({_recordsSendFifo.Count}) records");
|
||||
|
||||
//The inter record send delay has to be hold before trying to communicate again
|
||||
const Int32 interRecordSendDelayMs = CommunicationConfig.InterRecordSendDelayMs;
|
||||
|
||||
//remind counter for FIFO and therefore execution loops
|
||||
var loopCounter = 0;
|
||||
|
||||
//check if FIFO is empty and get the actual record to process out of it
|
||||
while (_recordsSendFifo.TryDequeue(out var internalRecord))
|
||||
{
|
||||
_logger.Trace(" 1 TryDequeue ProcessRecordList");
|
||||
// Starting with record number 1
|
||||
loopCounter++;
|
||||
_logger.Trace($"Record({loopCounter}) - Dequeued from FIFO");
|
||||
|
||||
//pointer to new record
|
||||
_recordInProcess = internalRecord;
|
||||
if (_recordInProcess == null) return RequestAcknowledgeState.CommandNotAssigned;
|
||||
|
||||
//mark record as answer outstanding
|
||||
_recordInProcess.Acknowledge = RequestAcknowledgeState.NotDecoded;
|
||||
do
|
||||
{
|
||||
_logger.Trace(" 1 TryDequeue DO ProcessRecordList");
|
||||
_logger.Trace($"Record({loopCounter}) - Processing");
|
||||
//log retries
|
||||
if (_recordInProcess.RetryCtr > 0)
|
||||
{
|
||||
_logger.Debug($"{_ident} Retry({_recordInProcess.RetryCtr})");
|
||||
_logger.Trace($"Record({loopCounter}) - Retry({_recordInProcess.RetryCtr})");
|
||||
}
|
||||
|
||||
//log request protocol content
|
||||
@@ -216,6 +235,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
requestTimeUtc = DateTimeOffset.UtcNow;
|
||||
}
|
||||
responseTimeMs = (Int32)timeSpan.TotalMilliseconds;
|
||||
|
||||
} while (_recordInProcess.Acknowledge != RequestAcknowledgeState.Ok &&
|
||||
_recordInProcess.SkipRetryErrorCode != _recordInProcess.ResponseErrorCode &&
|
||||
_timeOutMs > responseTimeMs);
|
||||
@@ -249,6 +269,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
_recordInProcess.SkipRetryErrorCode != _recordInProcess.ResponseErrorCode);
|
||||
|
||||
}
|
||||
|
||||
return _recordInProcess.Acknowledge;
|
||||
}
|
||||
|
||||
@@ -371,8 +392,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
/// <remarks date="2022-Oct-02" author="T.Wiedebusch">
|
||||
/// - On wakeup message 5 retires are allowed to avoid an infinite loop.
|
||||
/// </remarks>
|
||||
/// <remarks date="2022-Oct-04" author="T.Wiedebusch">
|
||||
/// - On wakeup message exit this routine.
|
||||
/// </remarks>
|
||||
public override void DecodeRecord(IPortDataEventArgs data)
|
||||
{
|
||||
//new request has to be analyzed
|
||||
_recordInProcess.Acknowledge = RequestAcknowledgeState.NotDecoded;
|
||||
//the request response record covers the entire request protocol
|
||||
var responseRecord = GetTransmitProtocol().DecodeDataForLogicLayer((List<Byte>)data.GetData());
|
||||
|
||||
@@ -405,18 +431,24 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
{
|
||||
_recordInProcess.Acknowledge = RequestAcknowledgeState.WakeupMessage;
|
||||
//initiate a single retry on wakeup message response
|
||||
if ( _recordInProcess.WakeupMessageRetryCtr < 10)
|
||||
if ( _recordInProcess.WakeupMessageRetryCtr < 5)
|
||||
{
|
||||
_logger.Debug($"{_ident} Wakeup message received");
|
||||
_recordInProcess.WakeupMessageRetryCtr++;
|
||||
// reset retry counter to get all required retries
|
||||
_recordInProcess.RetryCtr = -1;
|
||||
//reset timeout to a normal value if timeout is extremely high but response received
|
||||
if (_timeOutMs > CommunicationConfig.BusyTimeoutMs)
|
||||
_timeOutMs = CommunicationConfig.BusyTimeoutMs;
|
||||
return;
|
||||
_logger.Debug($"{_ident} Wakeup message({_recordInProcess.WakeupMessageRetryCtr}) received");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//if it is not identified as valid wakeup message it is something unknown
|
||||
_recordInProcess.Acknowledge = RequestAcknowledgeState.DecodingError;
|
||||
_logger.Debug($"{_ident} Message decoding error.");
|
||||
}
|
||||
// reset retry counter to get all required retries
|
||||
_recordInProcess.RetryCtr = -1;
|
||||
//reset timeout to a normal value if timeout is extremely high but response received
|
||||
if (_timeOutMs > CommunicationConfig.BusyTimeoutMs)
|
||||
_timeOutMs = CommunicationConfig.BusyTimeoutMs;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -550,6 +582,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
if (command == Commands.MultipleReadData && meterRegister != null && meterRegister.DataType == typeof(String))
|
||||
{
|
||||
var completeResponse = new List<Byte>();
|
||||
//TODO THW check this including the recursive call CommandToMeter
|
||||
while (true)
|
||||
{
|
||||
var cRecord = CommandToMeter(Commands.ReadData, meterRegister, payload, expectedLength,
|
||||
@@ -668,7 +701,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
/// <summary>
|
||||
/// Analyzes the error code
|
||||
/// </summary>
|
||||
public void CheckErrorCode()
|
||||
private void CheckErrorCode()
|
||||
{
|
||||
if (_recordInProcess.ResponseErrorBase == (Byte)ConfigExErrors.Base)
|
||||
{
|
||||
@@ -709,7 +742,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
/// <returns></returns>
|
||||
public Boolean ContainsRegisterIdent(String registerName)
|
||||
{
|
||||
return _recordsSendFifo.Any(a => a.Register.GetIdent().ToLower() == registerName.ToLower());
|
||||
return _recordsSendFifo.Any(a => string.Equals(a.Register.GetIdent(),
|
||||
registerName, StringComparison.CurrentCultureIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
/// </summary>
|
||||
public class RequestRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates the base command <see cref="Commands" />
|
||||
/// </summary>
|
||||
public readonly Byte Command;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the base command <see cref="Commands" />
|
||||
/// </summary>
|
||||
@@ -65,12 +60,12 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
/// <summary>
|
||||
/// Data containing the request protocol
|
||||
/// </summary>
|
||||
public List<Byte> RequestProtocolData;
|
||||
public readonly List<Byte> RequestProtocolData;
|
||||
|
||||
/// <summary>
|
||||
/// Encoded with transmit protocol, ready to stream to port as is
|
||||
/// </summary>
|
||||
public List<Byte> EncodedRequestData { get; internal set; }
|
||||
public List<Byte> EncodedRequestData { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Extracted payload of response
|
||||
@@ -85,12 +80,12 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
/// <summary>
|
||||
/// avoid logging for e.g. password
|
||||
/// </summary>
|
||||
public Boolean HideDataInLog;
|
||||
public readonly Boolean HideDataInLog;
|
||||
|
||||
/// <summary>
|
||||
/// error mask to skip retries for functional errors <see cref="ResponseErrorCode"/>
|
||||
/// </summary>
|
||||
public UInt16 SkipRetryErrorCode;
|
||||
public readonly UInt16 SkipRetryErrorCode;
|
||||
|
||||
/// <summary>
|
||||
/// Ctor for an base command <see cref="Commands" />
|
||||
@@ -106,7 +101,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
Int32 responseTimeoutMs = 100, RegisterDefinition register = null, Boolean hideDataInLog = false,
|
||||
UInt16 skipRetryErrorCode = CommunicationConfig.SkipRetryErrorCode)
|
||||
{
|
||||
Command = command;
|
||||
ResponseCommand = (Byte)(command + 1);
|
||||
Register = register;
|
||||
RequestProtocolData = requestProtocolData;
|
||||
|
||||
Reference in New Issue
Block a user