This commit is contained in:
Roland Drabesch
2023-12-11 13:26:42 +01:00
33 changed files with 17820 additions and 530 deletions
@@ -216,9 +216,11 @@
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="EventArguments\CalibDataEventArgs.cs" />
<Compile Include="EventArguments\BendDetectDataEventArgs.cs" />
<Compile Include="EventArguments\FlowDataEventArgs.cs" />
<Compile Include="EventArguments\RegisterUpdateEventArgs.cs" />
<Compile Include="EventArguments\RequestResponseDataEventArgs.cs" />
<Compile Include="MeasurementRecords\BendDetectionRecord.cs" />
<Compile Include="MeasurementRecords\CalibrationRecord.cs" />
<Compile Include="MeasurementRecords\FlowTestRecord.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -0,0 +1,22 @@
using System;
using Xylem.Common.Hardware.Interfaces.Protocols.ProtocolCore.EventArguments;
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords;
namespace Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.EventArguments
{
/// <inheritdoc />
public class BendDetectDataEventArgs : BaseDataEventArgs
{
/// <summary>
/// new record from Stream
/// </summary>
public BendDetectionRecord NewData;
/// <inheritdoc />
public override Object GetEventData()
{
return NewData;
}
}
}
@@ -0,0 +1,114 @@
using System;
using System.Text;
using Xylem.Common.Metrology.Measurements;
namespace Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords
{
/// <inheritdoc />
/// <summary>
/// Streaming record for protocol M (information about bend detection and correction)
/// </summary>
public class BendDetectionRecord : MeasurementRecord
{
/// <summary>
/// The status of the U0 detection for this measurement
/// </summary>
public enum StatusBendU0Enum
{
/// <summary>
/// Status okay
/// </summary>
OKAY = 0,
/// <summary>
/// Error code as defined by field name
/// </summary>
ERROR_GENESISFLOW_INSTALLATION_HIGH_TIME_DIFF = 0x0F41,
/// <summary>
/// Error code as defined by field name
/// </summary>
ERROR_GENESISFLOW_INSTALLATION_LOW_FLOW_IGNORE = 0x0F42,
/// <summary>
/// Error code as defined by field name
/// </summary>
ERROR_GENESISFLOW_INSTALLATION_BAD_CHANNELS = 0x0F43,
/// <summary>
/// Error code as defined by field name
/// </summary>
ERROR_GENESISFLOW_INSTALLATION_FIXED = 0x0F44
}
/// <summary>
/// An enum describing the installation type detected
/// </summary>
public enum InstallationTypeEnum
{
/// <summary>
/// Installation type code as defined by field name
/// </summary>
INSTALLATION_U0_180_360 = 0,
/// <summary>
/// Installation type code as defined by field name
/// </summary>
INSTALLATION_U0_90_270 = 1,
/// <summary>
/// Installation type code as defined by field name
/// </summary>
INSTALLATION_UNDISTURBED = 2
}
/// <summary>
/// Status of U0 Bend detection
/// </summary>
public StatusBendU0Enum StatusBendU0;
/// <summary>
/// Installation type code
/// </summary>
public InstallationTypeEnum InstallationType;
/// <summary>
/// The proportion of the installation correction to apply based on the detected
/// installation. 100% == 0x8000
/// </summary>
public Double CorrectionFactor_percent;
/// <summary>
/// The default proportion of the installation correction to apply based on the
/// detected installation. 100% == 0x8000
/// </summary>
private const UInt32 DefaultCorrectionFactor = 0x8000;
/// <summary>
/// Scale for correction factor to apply to convert it to percentage value 100% == 0x8000
/// </summary>
public const Double CorrectionFactorScale = 100.0 / DefaultCorrectionFactor;
/// <summary>
/// The volume in internal units before correction applied
/// </summary>
public Double PreCorrectionVolumeRaw;
/// <summary>
/// The volume in internal units after correction applied
/// </summary>
public Double PostCorrectionVolumeRaw;
/// <summary>
/// Get result as string
/// </summary>
/// <returns></returns>
public override String ToString()
{
var sb = new StringBuilder();
sb.Append($"Status={StatusBendU0}").Append(",")
.Append($"Installation={InstallationType}").Append(",")
.Append($"Factor={CorrectionFactor_percent}").Append(",")
.Append($"PreVolume={PreCorrectionVolumeRaw}").Append(",")
.Append($"PostVolume={PostCorrectionVolumeRaw}");
return sb.ToString();
}
}
}
@@ -8,6 +8,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Consts
/// </summary>
public enum LedMode
{
/// <summary>
/// Test mode with raw record to log.
/// Should give one <see cref="FlowTestRecord"/>
/// 3 times <see cref="CalibrationRecord"/> and
/// one <see cref="BendDetectionRecord"/>
/// </summary>
FlowTestAndCalibDataAndBendCorrect = 7,
/// <summary>
/// Test mode with raw record to log. Should give one <see cref="FlowTestRecord"/>
/// 3 times <see cref="CalibrationRecord"/> and repeat this till led mode is switch
@@ -369,6 +369,16 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
#region state machine and states
/// <summary>
/// Order number under which this meter has to be produced
/// </summary>
public Int32 OrderNumber;
/// <summary>
/// Radio address
/// </summary>
public Int64 RadioAddress;
/// <summary>
/// do not use it to set ProcessStatus
/// if you want to change ProcessStatus of this genesis use <see cref="ProcessStatus" />
@@ -1316,9 +1326,15 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// <remarks date="2023-Nov-27" author="Thomas Wiedebusch">
/// - Remind installed FW version of FLEXNETVERSION for StoreAllConfigurations.
/// </remarks>
/// <remarks date="2023-Dec-08..11" author="Thomas Wiedebusch">
/// - Avoid multiple assignment of identical register in dictionary as the configuration.json may overlap
/// on some versions. If one register has been added, this passed the test and is valid for this FW.
/// It has to be avoided to have the register multiple times as it may cause unpredictable assignments
/// of values to one and reading and compare from another which doesn't have a value!
/// </remarks>
private void ReadMeterFirmwareAndAssignRegisters()
{
//avoid overwriting of list if this already exits
// Avoid overwriting of list if this already exits
if (MeterAppListVersion.Any())
{
_logger.Warn($"Slot:{Slot} - Trying to override meter dictionary. Skip read out FW");
@@ -1388,7 +1404,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
ReadRegister(Register.System.MetrologyUpgradePermission));
//read core revision
var coreRegisterRead = RegisterConverter.ConvertTo<String>(ReadRegister(Register.System.CoreRevision, 16));
var coreRegisterRead = RegisterConverter.ConvertTo<String>(ReadRegister(Register.System.CoreRevision));
CoreRevision = null;
if (!string.IsNullOrEmpty(coreRegisterRead))
{
@@ -1437,23 +1453,27 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
{
var currentGroup = MeterAppListVersion.First(f => f.AppId == registerToCheck.Key.AppAddress);
if (!registerToCheck.Key.RegisterDetail.Version.First.HasValue &&
!registerToCheck.Key.RegisterDetail.Version.Last.HasValue)
{
//TODO legacy to collect not clear specified registers
registerToCheck.Key.IsAvailable = true;
_configRegister.MeterRegisterDic.TryAdd(registerToCheck.Key, null);
if (registerToCheck.Key?.RegisterDetail?.Version == null)
continue;
}
if (registerToCheck.Key.RegisterDetail.Version.Last != null &&
registerToCheck.Key.RegisterDetail.Version.First != null &&
registerToCheck.Key.RegisterDetail.Version.First.Value <= currentGroup.Version &&
registerToCheck.Key.RegisterDetail.Version.Last.Value >= currentGroup.Version)
if (// Legacy registers may not have an version assigned
(!registerToCheck.Key.RegisterDetail.Version.First.HasValue &&
!registerToCheck.Key.RegisterDetail.Version.Last.HasValue) ||
// Normal version assignment with first and last value
(registerToCheck.Key.RegisterDetail.Version.Last != null &&
registerToCheck.Key.RegisterDetail.Version.First != null &&
registerToCheck.Key.RegisterDetail.Version.First.Value <= currentGroup.Version &&
registerToCheck.Key.RegisterDetail.Version.Last.Value >= currentGroup.Version))
{
registerToCheck.Key.IsAvailable = true;
// Avoid multiple assignment of identical register in dictionary if one has passed the test
if (_configRegister.MeterRegisterDic.Any(reg =>
reg.Key.GetIdent().Equals(registerToCheck.Key.GetIdent())))
continue;
_configRegister.MeterRegisterDic.TryAdd(registerToCheck.Key, null);
registerToCheck.Key.IsAvailable = true;
}
}
foreach (var checkMinRegister in Register.GetMinRequiredRegisters())
{
if (_configRegister.MeterRegisterDic.All(a => a.Key.GetIdent() != checkMinRegister))
@@ -1472,8 +1492,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
}
catch (Exception ex)
{
_logger.Warn(ex, $"Slot:{Slot} - Not able to set minimum list of registers. check json file for {checkMinRegister} ");
_logger.Warn(ex.Message, $"Slot:{Slot} - Unable to set minimum list of registers. Check json file for {checkMinRegister} ");
}
}
}
@@ -2204,7 +2223,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
a.Key.RegisterName.ToLower() == "storeconfiguration" ||
a.Key.RegisterName.ToLower() == "storecalibration"))
{
if (!a.Key.IsAvailable) continue;
if (!a.Key.IsAvailable)
continue;
// retries for each register access
var retriesLeft = 2;
@@ -2234,10 +2254,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
a.Key.RegisterName.ToLower() == "storeconfiguration" ||
a.Key.RegisterName.ToLower() == "storecalibration"))
{
if (!a.Key.IsAvailable) continue;
if (!a.Key.IsAvailable)
continue;
// For R1.2.x the read back is corrected
if ( InstalledFwVersion < 1200 && (a.Key.AppName == "SENSUSRADIO" || a.Key.AppName == "NA2WALARMS"))
if (InstalledFwVersion < 1200 && (a.Key.AppName == "SENSUSRADIO" || a.Key.AppName == "NA2WALARMS"))
{
continue;
}
@@ -165,6 +165,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
//the DecodeMsg has assigned either a DataCalib or DataFlowTest data set
var calibrationRecord = sd.DataCalib;
var flowTestRecord = sd.DataFlowTest;
var bendDetectRecord = sd.DataBendDetectTest;
if (flowTestRecord != null)
{
@@ -172,6 +173,12 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
continue;
}
if (bendDetectRecord != null)
{
TotalValidationWithoutErrorsCount++;
continue;
}
if (calibrationRecord != null)
{
if (calibrationRecord.Validation == 0)
@@ -58,7 +58,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// <summary>
/// List for parameters which need to be removed from parameter list
/// if meter has radio
/// </summary>
public static readonly List<String> ProhibitedParameters = new List<String>
{
@@ -66,7 +65,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
};
/// <summary>
/// List for un-reversed parameters, all others need to be swapped byte-wise
/// if meter has radio
/// </summary>
public static readonly List<String> UnRevertedParameters = new List<String>
{
@@ -75,6 +73,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
"METROLOGYASST_FlowPoint"
};
/// <summary>
///
/// </summary>
public static readonly List<String> ExcludedFromCompareParameters = new List<String>
{
"SENSUSRADIO_UpgFWVersion" // After a FW-Update the FW version has changed and the compare will fail
};
/// <summary>
/// Pre programming parameters for all devices defined here, will be filled with radio parameters
/// if meter has radio
/// </summary>
@@ -383,6 +388,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// <remarks date="2023-Nov-20" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
/// <remarks date="2023-Nov-28" author="Thomas Wiedebusch">
/// - Compare registers reactivated based on new interface (configuration.json) with new
/// "StaticType": “approximate”.
/// </remarks>
/// <remarks date="2023-Dec-08" author="Thomas Wiedebusch">
/// - Removed <see cref="ExcludedFromCompareParameters"/> as those will change on e.g. FW update.
/// </remarks>
public Boolean CompareRegisters()
{
if (_pcbIdFinalRegisterRead != _pcbIdInitialRegisterRead ||
@@ -396,6 +408,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
// build a string list of the registers being able to sort those
var registerNames = _restoreRegisters.MeterRegisterDic.Select(register => register.Key.GetIdent()).ToList();
// Remove all excluded registers
foreach (var regName in ExcludedFromCompareParameters.Where(regName => registerNames.Any(reg => reg == regName)))
{
registerNames.Remove(regName);
}
// sort the list of register names
registerNames.Sort();
// limit the count to 1 to avoid division by zero
@@ -425,17 +442,65 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
var strRequiredRegisterValue = "";
try
{
var isIdentical = true;
for (var c = 0; c < dataSize; c++)
var isApproximated = false;
var isIdentical = false;
if (regDef.RegisterDetail.StaticType == StaticType.ReadBackApproximated)
{
if (restorableRawRegister[c] == finalReadRawRegister[c]) continue;
isIdentical = false;
break;
Int64 restoreValue = 0;
Int64 finalValue = 0;
if (regDef.DataType.Name.Equals("Int32"))
{
restoreValue = RegisterConverter.ConvertTo<Int32>(restorableRawRegister);
finalValue = RegisterConverter.ConvertTo<Int32>(finalReadRawRegister);
}
else if (regDef.DataType.Name.Equals("UInt32"))
{
restoreValue = RegisterConverter.ConvertTo<UInt32>(restorableRawRegister);
finalValue = RegisterConverter.ConvertTo<UInt32>(finalReadRawRegister);
}
// Just half of number range will work due to cast to Int64
else if (regDef.DataType.Name.Equals("UInt64"))
{
restoreValue = (Int64)RegisterConverter.ConvertTo<UInt64>(restorableRawRegister);
finalValue = (Int64)RegisterConverter.ConvertTo<UInt64>(finalReadRawRegister);
}
else if (regDef.DataType.Name.Equals("Int64"))
{
restoreValue = RegisterConverter.ConvertTo<UInt32>(restorableRawRegister);
finalValue = RegisterConverter.ConvertTo<UInt32>(finalReadRawRegister);
}
else if (regDef.DataType.Name.Equals("Byte"))
{
restoreValue = RegisterConverter.ConvertTo<Byte>(restorableRawRegister);
finalValue = RegisterConverter.ConvertTo<Byte>(finalReadRawRegister);
}
else if (regDef.DataType.Name.Equals("SByte"))
{
restoreValue = RegisterConverter.ConvertTo<SByte>(restorableRawRegister);
finalValue = RegisterConverter.ConvertTo<SByte>(finalReadRawRegister);
}
// Check limited to +/- 3
if (restoreValue - 3 <= finalValue && restoreValue + 3 >= finalValue)
{
isApproximated = true;
}
}
else
{
for (var c = 0; c < dataSize; c++)
{
if (restorableRawRegister[c] != finalReadRawRegister[c])
{
isIdentical = false;
break;
}
isIdentical = true;
}
}
// convert register content to text with raw and converted value depending on data type
strRequiredRegisterValue =
RegisterConverter.GetRegisterContentText(regDef, restorableRawRegister);
if (finalReadRawRegister != null && isIdentical)
if (finalReadRawRegister != null && (isIdentical || isApproximated))
{
strRequiredRegisterValue += $" - {Resources.StrRegisterCompareSucceeded}";
}
@@ -458,7 +523,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
}
finally
{
var actualProcessMsg = $"{Resources.StrRegisterCompare}: {strRequiredRegisterValue} ";
var actualProcessMsg = string.IsNullOrEmpty(strRequiredRegisterValue) ? "":
$"{Resources.StrRegisterCompare}: {strRequiredRegisterValue} ";
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrRegisterCompare}" +
$@" {ActualRegisterCtr} / {registersCount}",
@@ -497,16 +563,15 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// <remarks date="2023-Nov-21" author="Thomas Wiedebusch">
/// - Return false if PcbId between initial- and final-read does NOT match return false.
/// </remarks>
/// <remarks date="2023-Nov-30" author="Thomas Wiedebusch">
/// - Allow final read out as often as called even if done before.
/// </remarks>
public Boolean FinalReadRegisters()
{
if (_currentGenesis == null)
return false;
// deny update of registers if already done
if (_pcbIdFinalRegisterRead == _currentGenesis.PcbId)
return true;
_pcbIdFinalRegisterRead = _currentGenesis.PcbId;
_pcbIdFinalRegisterRead = _currentGenesis.PcbId;
// clear the contents of the restore registers if the water meter backed up was not identical
if (_pcbIdInitialRegisterRead != _pcbIdFinalRegisterRead)
{
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -29,6 +29,22 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol
private const Double AmplitudeToVoltFactor = 1.0 / 0x400000 / 1000.0; // 2^22 100 0000 0000 0000 0000 0000b
private const Double PulseWidthToRelFactor = 1.0 / 0x100; // 2^8
/// <summary>
/// Default data for bend detection tests of Genesis
/// </summary>
private readonly BendDetectionRecord _bendDetectionDefault = new BendDetectionRecord
{
StatusBendU0 = BendDetectionRecord.StatusBendU0Enum.OKAY,
InstallationType = BendDetectionRecord.InstallationTypeEnum.INSTALLATION_UNDISTURBED,
CorrectionFactor_percent = 0.0,
PreCorrectionVolumeRaw = 0.0,
PostCorrectionVolumeRaw = 0.0,
TimeS = 0.0,
OverflowTimeS = CpuTimeOverflowS,
Crc = 0xFFFF,
IsValid = false
};
/// <summary>
/// Default data for flow tests of Genesis
/// </summary>
@@ -76,6 +92,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol
private CalibrationRecord _dataCalibRec;
private FlowTestRecord _dataFlowTestRec;
private BendDetectionRecord _dataBendDetectRec;
private readonly Boolean _ignoreCorruptedData;
/// <summary>
@@ -85,6 +102,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol
{
_dataFlowTestRec = _dataDefault;
_dataCalibRec = _rawDataDefault;
_dataBendDetectRec = _bendDetectionDefault;
_ignoreCorruptedData = ignoreCorruptedData;
}
@@ -104,6 +122,14 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol
get; private set;
}
/// <summary>
/// Bend detection test data
/// </summary>
public BendDetectionRecord DataBendDetectTest
{
get; private set;
}
/// <summary>
/// Decoding the raw message
/// </summary>
@@ -112,6 +138,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol
/// <remarks date="2023-Mar-09" author="T.Wiedebusch">
/// - Modified using common CRC check before branching to the protocol specific decoder.
/// </remarks>
/// <remarks date="2023-Dec-06" author="T.Wiedebusch">
/// - Introduced protocol 'm' for bending detection.
/// </remarks>
public Boolean DecodeMsg(String rawMsg)
{
var rawRecordIsValid = false;
@@ -170,7 +199,16 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol
switch (rawMsgFields[0])
{
case "@f":
case "@m":
_dataBendDetectRec.IsValid = rawRecordIsValid;
if (rawRecordIsValid || !_ignoreCorruptedData)
{
DecodeProtocolM(ref _dataBendDetectRec, rawMsgFields);
DataBendDetectTest = _dataBendDetectRec;
}
break;
case "@f":
_dataFlowTestRec.IsValid = rawRecordIsValid;
if (rawRecordIsValid || !_ignoreCorruptedData)
{
@@ -205,6 +243,44 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol
return rawRecordIsValid;
}
/// <summary>
/// Extracting message from string fields for protocol 'm'
/// </summary>
/// <param name="dataBendTestRec">reference to bend detection test record</param>
/// <param name="fields">Separated fields containing the measurement as string</param>
/// <returns></returns>
/// <remarks date="2023-Mar-09" author="T.Wiedebusch">
/// - Modified using common CRC check in advance.
/// </remarks>
private static void DecodeProtocolM(ref BendDetectionRecord dataBendTestRec, IList<String> fields)
{
// time stamp attachment
dataBendTestRec.DecodedTime = DateTimeOffset.UtcNow;
// extract received CRC
dataBendTestRec.Crc = ushort.Parse(fields[(Int32)ProtMsubString.Crc],
NumberStyles.HexNumber);
// extract the status
dataBendTestRec.StatusBendU0 =
(BendDetectionRecord.StatusBendU0Enum)UInt32.Parse(fields[(Int32)ProtMsubString.Status],
NumberStyles.AllowHexSpecifier);
// extract the installation type
dataBendTestRec.InstallationType =
(BendDetectionRecord.InstallationTypeEnum)UInt32.Parse(fields[(Int32)ProtMsubString.Installation],
NumberStyles.AllowHexSpecifier);
// extract the correction factor in percent
dataBendTestRec.CorrectionFactor_percent =
UInt32.Parse(fields[(Int32)ProtMsubString.Factor],
NumberStyles.AllowHexSpecifier) * BendDetectionRecord.CorrectionFactorScale;
// build result values, the volume before and after correction can be positive or negative!
dataBendTestRec.PreCorrectionVolumeRaw = Int32.Parse(fields[(Int32)ProtMsubString.PreVolume],
NumberStyles.AllowHexSpecifier);
// build result values, the volume before and after correction can be positive or negative!
dataBendTestRec.PostCorrectionVolumeRaw = Int32.Parse(fields[(Int32)ProtMsubString.PostVolume],
NumberStyles.AllowHexSpecifier);
}
/// <summary>
/// Extracting message from string fields for protocol 'f'
/// </summary>
@@ -413,6 +489,18 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol
CpuTime,
Crc
}
/// field position in protocol 'm'
private enum ProtMsubString
{
//do not remove this needed for position in record
ProtType,
Status,
Installation,
Factor,
PreVolume,
PostVolume,
Crc
}
/// field position in protocol 'g'
private enum ProtGsubString
@@ -73,6 +73,27 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol
}
}
else if (_streamingDecode.DataBendDetectTest != null)
{
_streamingDecode.DataBendDetectTest.SyncMarkRecord = dataArgs.GetSyncMarkRecord();
_streamingDecode.DataBendDetectTest.ReceivedTime = dataArgs.GetReceivedTime();
if (_streamingDecode.DataBendDetectTest.IsValid)
{
OnRecordIsDecoded?.Invoke(this, new BendDetectDataEventArgs
{
NewData = _streamingDecode.DataBendDetectTest,
RawData = data
});
}
else if (!_ignoreCorruptedData)
{
OnRecordIsDecoded?.Invoke(this, new BendDetectDataEventArgs
{
NewData = _streamingDecode.DataBendDetectTest,
RawData = data
});
}
}
//toDo: handle trashy telegrams
}
@@ -26,19 +26,25 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes
/// <summary>
/// Static type to define restore capability
/// </summary>
private const String RestoreRequired = "static";
public const String RestoreRequired = "static";
/// <summary>
/// Static type approximate informs that the read back value may be not identical
/// to the written value and is approximated.
/// </summary>
public const String ReadBackApproximated = "approximate";
/// <summary>
/// Denied restore capability
/// </summary>
// ReSharper disable once UnusedMember.Local
private const String RestoreDenied = "dynamic";
public const String RestoreDenied = "dynamic";
/// <summary>
/// Unpredictable restore capability
/// </summary>
// ReSharper disable once UnusedMember.Local
private const String RestoreUnpredictable = "infrequentlyupdated";
public const String RestoreUnpredictable = "infrequentlyupdated";
/// <summary>
/// Check restore capability
@@ -46,7 +52,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes
/// <returns>true if restore required</returns>
public Boolean CheckRestoreCapability()
{
return StaticTypeValue == RestoreRequired;
return StaticTypeValue == RestoreRequired || StaticTypeValue == ReadBackApproximated;
}
/// <summary>