GenesisMeter: - Removed retries on "ReadMeterFwAndAssignRegisters" as the reties will be handled by the RequestProtocol
This commit is contained in:
@@ -155,7 +155,7 @@
|
||||
</site>
|
||||
<site name="MeterProcessState" id="2">
|
||||
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
||||
<virtualDirectory path="/" physicalPath="C:\Users\drabesch_ro\Repo\lab\la_operations\laa_production\Common\Service\MeterProcessState" />
|
||||
<virtualDirectory path="/" physicalPath="D:\Projekte\SENSUS_GitLab\laa_production\Common\Service\MeterProcessState" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:56011:localhost" />
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<s:Boolean x:Key="/Default/Environment/ExcludedFiles/FilesAndFoldersToSkip/=1057AD21_002DBA22_002D4CAB_002DB3FE_002D88C5C9980E6A_002Fd_003AScripts_002Ff_003Ajquery_002D1_002E10_002E2_002Eintellisense_002Ejs/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/Environment/Hierarchy/Build/SolBuilderDuo/UseMsbuildSolutionBuilder/@EntryValue">NewVersion</s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/Hierarchy/EntityFrameworkOptions/IsAlreadyNotifiedAboutEntityFramework/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/Environment/Highlighting/HighlightingSourceSnapshotLocation/@EntryValue">C:\Users\Thomas\AppData\Local\Temp\JetBrains\ReSharperPlatformVs15\vAny_33007af5\CoverageData\_Common.-1885154465\Snapshot\snapshot.utdcvr</s:String>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1263,7 +1263,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
try
|
||||
{
|
||||
var radioFrequencyRaw = ReadRegister(Register.Sensusradio.FrequencyIndicator);
|
||||
if (radioFrequencyRaw != null )
|
||||
if (radioFrequencyRaw != null)
|
||||
{
|
||||
Region = "EMEA";
|
||||
RadioFrequencyMhz = RegisterConverter.ConvertTo<Int32>(radioFrequencyRaw);
|
||||
@@ -1283,7 +1283,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
LutCrc = "?";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reading all applications which can be found in the configuration.json and have been stored
|
||||
/// to the meter register dictionary in advance.
|
||||
@@ -1313,6 +1313,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <remarks date="2023-Jan-16" author="Thomas Wiedebusch">
|
||||
/// - Checked meter size string for "DN", than it cannot be an EMEA version.
|
||||
/// </remarks>
|
||||
/// <remarks date="2023-Feb-13" author="Thomas Wiedebusch">
|
||||
/// - Removed retry as this will be handled by the <see cref="RequestProtocol"/>.
|
||||
/// </remarks>
|
||||
private void ReadMeterFirmwareAndAssignRegisters()
|
||||
{
|
||||
//avoid overwriting of list if this already exits
|
||||
@@ -1329,39 +1332,32 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
UInt16 readFwCrc = 0;
|
||||
var isInstalled = false;
|
||||
var versionString = "";
|
||||
var recount = 4;
|
||||
while (recount > 0)
|
||||
if (WriteRegister(Register.System.CheckFwPresence, appVersionToRead.AppId))
|
||||
{
|
||||
recount -= 1;
|
||||
//read version, skip retries on SYSTEM 0x04-> FW nor present is a valid feedback
|
||||
var readFwVersionBytes = ReadRegister(Register.System.CheckFwPresence, 4);
|
||||
|
||||
if (WriteRegister(Register.System.CheckFwPresence, appVersionToRead.AppId))
|
||||
//the FW version as Uint32 will be used for comparison with the configuration.json
|
||||
if (readFwVersionBytes != null && readFwVersionBytes.Length > 0)
|
||||
{
|
||||
//read version, skip retries on SYSTEM 0x04-> FW nor present is a valid feedback
|
||||
var readFwVersionBytes = ReadRegister(Register.System.CheckFwPresence, 4);
|
||||
readFwVersion = (UInt32)(((readFwVersionBytes[1] & 0xF0) >> 4) * 10 +
|
||||
(readFwVersionBytes[1] & 0x0F)) * 100;
|
||||
readFwVersion += (UInt32)(((readFwVersionBytes[0] & 0xF0) >> 4) * 10 +
|
||||
(readFwVersionBytes[0] & 0x0F));
|
||||
//build the version string, because e.g. FLEXNETVERSION is one application which does not
|
||||
//follow the same rule. After the upper conversion, the hexadecimal outline will be lost
|
||||
versionString = BuildFwVersionString(readFwVersionBytes[1], readFwVersionBytes[0]);
|
||||
if (appVersionToRead.AppName == "FLEXNETVERSION")
|
||||
FwVersion = versionString;
|
||||
|
||||
//the FW version as Uint32 will be used for comparison with the configuration.json
|
||||
if (readFwVersionBytes != null && readFwVersionBytes.Length > 0)
|
||||
if (readFwVersion != 0)
|
||||
{
|
||||
readFwVersion = (UInt32)(((readFwVersionBytes[1] & 0xF0) >> 4) * 10 +
|
||||
(readFwVersionBytes[1] & 0x0F)) * 100;
|
||||
readFwVersion += (UInt32)(((readFwVersionBytes[0] & 0xF0) >> 4) * 10 +
|
||||
(readFwVersionBytes[0] & 0x0F));
|
||||
//build the version string, because e.g. FLEXNETVERSION is one application which does not
|
||||
//follow the same rule. After the upper conversion, the hexadecimal outline will be lost
|
||||
versionString = BuildFwVersionString(readFwVersionBytes[1], readFwVersionBytes[0]);
|
||||
if (appVersionToRead.AppName == "FLEXNETVERSION")
|
||||
FwVersion = versionString;
|
||||
|
||||
if (readFwVersion != 0)
|
||||
isInstalled = true;
|
||||
//write application Id to CRC register
|
||||
if (WriteRegister(Register.System.CheckFwCrc, appVersionToRead.AppId))
|
||||
{
|
||||
|
||||
isInstalled = true;
|
||||
//write application Id to CRC register
|
||||
if (WriteRegister(Register.System.CheckFwCrc, appVersionToRead.AppId))
|
||||
{
|
||||
readFwCrc = RegisterConverter.ConvertTo<UInt16>(ReadRegister(Register.System.CheckFwCrc));
|
||||
}
|
||||
break;
|
||||
readFwCrc = RegisterConverter.ConvertTo<UInt16>(ReadRegister(Register.System.CheckFwCrc));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1381,7 +1377,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
}
|
||||
|
||||
CheckRegionSizeLutCrc();
|
||||
|
||||
|
||||
//read metrology upgrade permission
|
||||
MetrologyUpgradePermission = RegisterConverter.ConvertTo<Byte>(
|
||||
ReadRegister(Register.System.MetrologyUpgradePermission));
|
||||
@@ -1491,7 +1487,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
{
|
||||
var registerAddForOldConfigs = registerToPotentialAdd.GroupBy(item => item.GetIdent())
|
||||
.Select(grp => grp.Aggregate((max, cur) =>
|
||||
(max == null || cur.RegisterDetail.Version.Last > max.RegisterDetail.Version.Last) ?
|
||||
(max == null || cur.RegisterDetail.Version.Last > max.RegisterDetail.Version.Last) ?
|
||||
cur : max));
|
||||
|
||||
foreach (var registerAddOldConfig in registerAddForOldConfigs)
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
/// </summary>
|
||||
public Int32 AdditionalRetryTimeoutMs;
|
||||
|
||||
private Int32 _timeOutMs;
|
||||
private Int32 _maxTimeOutMs;
|
||||
|
||||
private readonly String _ident;
|
||||
|
||||
@@ -215,38 +215,41 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
|
||||
//set timeout for one communication trial adding the transmit protocol specific timeout and
|
||||
//increase the timeout with each retry
|
||||
_timeOutMs = _recordInProcess.ResponseTimeoutMs + AdditionalRetryTimeoutMs +
|
||||
_maxTimeOutMs = _recordInProcess.ResponseTimeoutMs + AdditionalRetryTimeoutMs +
|
||||
CommunicationConfig.ResponseTimeoutMs * (_recordInProcess.RetryCtr + 1);
|
||||
//start initial communication or retry
|
||||
OnRecordReadyToSend?.Invoke(this, new ListBytePortDataEventArgs(_recordInProcess.EncodedRequestData));
|
||||
|
||||
//time reminder of request record
|
||||
var requestTimeUtc = DateTimeOffset.UtcNow;
|
||||
Int32 responseTimeMs;
|
||||
Int32 actualResponseWaitTimeMs;
|
||||
|
||||
//wait for communication acknowledge or until timeout, this also handles the inter record send delay
|
||||
do
|
||||
{
|
||||
//minimum delay is the inter record send delay
|
||||
Thread.Sleep(interRecordSendDelayMs);
|
||||
var timeoutTimeUtc = DateTimeOffset.UtcNow;
|
||||
var timeSpan = timeoutTimeUtc - requestTimeUtc;
|
||||
var actualTimeUtc = DateTimeOffset.UtcNow;
|
||||
//actual time difference from request to now
|
||||
var timeSpan = actualTimeUtc - requestTimeUtc;
|
||||
//avoid total milliseconds below zero at time overflow
|
||||
if (timeSpan.TotalMilliseconds < 0)
|
||||
{
|
||||
requestTimeUtc = DateTimeOffset.UtcNow;
|
||||
}
|
||||
responseTimeMs = (Int32)timeSpan.TotalMilliseconds;
|
||||
actualResponseWaitTimeMs = (Int32)timeSpan.TotalMilliseconds;
|
||||
|
||||
} while (_recordInProcess.Acknowledge != RequestAcknowledgeState.Ok &&
|
||||
_recordInProcess.SkipRetryErrorCode != _recordInProcess.ResponseErrorCode &&
|
||||
_timeOutMs > responseTimeMs);
|
||||
_maxTimeOutMs > actualResponseWaitTimeMs);
|
||||
|
||||
//if timeout value reaches zero, the response hasn't been received or the delay until
|
||||
//next communication needed to be hold
|
||||
if (_timeOutMs <= responseTimeMs)
|
||||
if (_maxTimeOutMs <= actualResponseWaitTimeMs)
|
||||
{
|
||||
_logger.Error(_recordInProcess.Acknowledge == RequestAcknowledgeState.NoResponse
|
||||
? $"{_ident} Response timeout({responseTimeMs}ms)"
|
||||
: $"{_ident} Communication delay({responseTimeMs}ms)");
|
||||
? $"{_ident} Response timeout({actualResponseWaitTimeMs}ms)"
|
||||
: $"{_ident} Communication delay({actualResponseWaitTimeMs}ms)");
|
||||
}
|
||||
|
||||
//skip loop to handle re-authorization
|
||||
@@ -395,28 +398,32 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
/// <remarks date="2022-Oct-04" author="T.Wiedebusch">
|
||||
/// - On wakeup message exit this routine.
|
||||
/// </remarks>
|
||||
/// <remarks date="2023-Feb-13" author="T.Wiedebusch">
|
||||
/// - Early exit on _recordInProcess == null,
|
||||
/// - Wakeup message retries from 5 to 2,
|
||||
/// - Removed error base from error code decision as error base is only the AppId
|
||||
/// </remarks>
|
||||
public override void DecodeRecord(IPortDataEventArgs data)
|
||||
{
|
||||
if (_recordInProcess == null) return;
|
||||
//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());
|
||||
|
||||
//if the current record is invalid or on protocol decoding failure
|
||||
if (null == _recordInProcess || responseRecord.Count == 0)
|
||||
//on protocol decoding failure
|
||||
if (responseRecord.Count == 0)
|
||||
{
|
||||
if (_recordInProcess != null)
|
||||
_recordInProcess.Acknowledge = RequestAcknowledgeState.DecodingError;
|
||||
_recordInProcess.Acknowledge = RequestAcknowledgeState.DecodingError;
|
||||
_logger.Debug($"{_ident} Message decoding error.");
|
||||
//reset timeout to a normal value if timeout is extremely high but response received
|
||||
if (_timeOutMs > CommunicationConfig.BusyTimeoutMs)
|
||||
_timeOutMs = CommunicationConfig.BusyTimeoutMs;
|
||||
if (_maxTimeOutMs > CommunicationConfig.BusyTimeoutMs)
|
||||
_maxTimeOutMs = CommunicationConfig.BusyTimeoutMs;
|
||||
return;
|
||||
}
|
||||
|
||||
//avoid wakeup retry on acknowledged record
|
||||
if (responseRecord.Count == WakeupMessage.Length
|
||||
&& null != _recordInProcess
|
||||
&& RequestAcknowledgeState.Ok != _recordInProcess.Acknowledge)
|
||||
{
|
||||
// check for wakeup message
|
||||
@@ -431,7 +438,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
{
|
||||
_recordInProcess.Acknowledge = RequestAcknowledgeState.WakeupMessage;
|
||||
//initiate a single retry on wakeup message response
|
||||
if ( _recordInProcess.WakeupMessageRetryCtr < 5)
|
||||
if ( _recordInProcess.WakeupMessageRetryCtr < 2)
|
||||
{
|
||||
_recordInProcess.WakeupMessageRetryCtr++;
|
||||
_logger.Debug($"{_ident} Wakeup message({_recordInProcess.WakeupMessageRetryCtr}) received");
|
||||
@@ -446,8 +453,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
// 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;
|
||||
if (_maxTimeOutMs > CommunicationConfig.BusyTimeoutMs)
|
||||
_maxTimeOutMs = CommunicationConfig.BusyTimeoutMs;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -501,7 +508,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
||||
}
|
||||
|
||||
//examine error code, if base (AppId) is not 0 the reason 0 may be an error!!!!
|
||||
if (_recordInProcess.ResponseErrorBase != 0 || _recordInProcess.ResponseErrorReason != 0)
|
||||
if (/*_recordInProcess.ResponseErrorBase != 0 ||*/ _recordInProcess.ResponseErrorReason != 0)
|
||||
{
|
||||
_logger.Warn($"{_ident} Error code received(0x{_recordInProcess.ResponseErrorBase:X2}" +
|
||||
$"{_recordInProcess.ResponseErrorReason:X2})");
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
5ed75d99ee45ff67821090f1b3dbb001dd9e4fe3
|
||||
1a3d4919c9c702245832d925951f2b7cb72fc333
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
0d85a5b3a7561b41163c20e5dc7713bcd0d65555
|
||||
f64d563def603c89cafafa61a3219ba97e1e344c
|
||||
|
||||
Reference in New Issue
Block a user