Common/../StreamingDecoder: - Protocol @m for bend detection, see BendDetectDataEventArgs

This commit is contained in:
Thomas Wiedebusch 2023-12-06 17:54:30 +01:00
parent 49ad983abd
commit 34595d9fb0
13 changed files with 255 additions and 3 deletions

1
.gitignore vendored
View File

@ -18,7 +18,6 @@
mono_crash.*
# Build results
bin/
[Aa]pp_[Dd]ata/
[Dd]ebug/
[Dd]ebugPublic/

View File

@ -27,6 +27,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataPackages", "Hardware\Wa
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".Shared", ".Shared", "{26EB462B-1FAC-4CEA-A9B9-DB96CA9CC864}"
ProjectSection(SolutionItems) = preProject
..\.gitignore = ..\.gitignore
Hardware\WaterMeter\Genesis\GenesisCore\configuration.json = Hardware\WaterMeter\Genesis\GenesisCore\configuration.json
.shared\NlogConfig.xml = .shared\NlogConfig.xml
.shared\SharedAssemblyInfo.cs = .shared\SharedAssemblyInfo.cs

View File

@ -28,6 +28,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>

View File

@ -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" />

View File

@ -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;
}
}
}

View File

@ -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();
}
}
}

View File

@ -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

View File

@ -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>
@ -170,7 +196,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 +240,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 +486,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

View File

@ -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
}

View File

@ -129,7 +129,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
WriteValue(Register.Genesisflow.SampleRate, SampleRateHz);
_channels = 4;
WriteValue(Register.Genesisflow.LedMode, (Byte)LedMode.FlowTestAndCalibData);
WriteValue(Register.Genesisflow.LedMode, (Byte)LedMode.FlowTestAndCalibDataAndBendCorrect);
if (_currentGenesis.IsLoggedOn)
{