tbf/TBF/Rig/RegisterReaders/GenesisRegReader/communication/Genesis/Registers/RegisterCheck.cs
Michal Buzik e26d88d437 Refactor Genesis use 3 chanels reader structure:
- Replace `Xylem.Common` namespace references with `TBF.Rig.RegisterReaders`.
- Introduce `GenesisSmartReaderTest` and `FakeSerialDriver` for unit testing.
- Revamp `FlowDirectionDetection` to support multiple channels.
- Make constants in `StreamingDecoder` public for enhanced accessibility.
- Update `AssemblyVersion` and `AssemblyFileVersion` to `3.9.3010.1`.
2026-03-24 08:53:16 +01:00

285 lines
14 KiB
C#

using System;
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Registers.DataTypes;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication.Genesis.Registers
{
/// <summary>
/// Check the register value for Out Of Boundaries (min, max) and optional if set to Default .
/// </summary>
public static class RegisterCheck
{
private enum RangeCheck
{
MinimumExceeded,
MaximumExceeded,
DefaultValue,
NotConvertible
};
private static String OutOfRangeMsg(RangeCheck rangeCheck, String value, String range, String name)
{
var msg = "";
switch (rangeCheck)
{
case RangeCheck.DefaultValue:
msg = $"{Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Properties.Resources.StrSetRegisterToDefault} {name}: ({value})";
break;
case RangeCheck.MaximumExceeded:
msg = $"{Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Properties.Resources.StrRegisterValueOutOfRange} {name}: ({value}) - Maximum ({range})";
break;
case RangeCheck.MinimumExceeded:
msg = $"{Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Properties.Resources.StrRegisterValueOutOfRange} {name}: ({value}) - Minimum ({range})";
break;
case RangeCheck.NotConvertible:
msg = $"{Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Properties.Resources.StrRegisterDataTypeUnknown} {name}";
break;
}
return msg;
}
/// <summary>
/// Check the registers for ot of range (below minimum or above maximum) and return empty string
/// if impossible to check (unset limits) or in range.
/// </summary>
/// <param name="regDef"></param>
/// <param name="value"></param>
/// <param name="msg">feedback message</param>
/// <param name="checkIfValueIsDefault">forces a warning if value is set to default</param>
/// <returns>
/// <see cref="StatusReturn.Warning"/> if default and check for this is required
/// <see cref="StatusReturn.Okay"/>if the value is in range or has no range defined
/// <see cref="StatusReturn.Failed"/>if value exceeds the limits
/// </returns>
/// <remarks date="????" author="Roland Drabesch">
/// - Init.
/// </remarks>
/// <remarks date="2024-Mar-21" author="Thomas Wiedebusch">
/// - Modified with try catch block.
/// </remarks>
/// <remarks date="2024-Sep-25" author="Thomas Wiedebusch">
/// - Returns warning on default, else error or okay.
/// </remarks>
/// <remarks date="2025-Feb-13" author="Thomas Wiedebusch">
/// - Ignore TimeT.
/// </remarks>
public static StatusReturn CheckRange(RegisterDefinition regDef, Byte[] value, out String msg,
Boolean checkIfValueIsDefault = false)
{
msg = "";
// for all registers without min and max or if type is of TimeT
if ((!regDef.Minimum.HasValue && !regDef.Maximum.HasValue) || regDef.DataType == typeof(TimeT))
{
return StatusReturn.Okay;
}
try
{
var type = regDef.DataType;
if (type == typeof(UInt16))
{
var checkValue = RegisterConverter.ByteArrayToValue<UInt16>(value);
if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(),
regDef.Minimum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(),
regDef.Maximum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value)
{
msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(),
regDef.Default.Value.ToString(), regDef.GetIdent());
return StatusReturn.Warning;
}
}
else if (type == typeof(UInt32))
{
var checkValue = RegisterConverter.ByteArrayToValue<UInt32>(value);
if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(),
regDef.Minimum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(),
regDef.Maximum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value)
{
msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(),
regDef.Default.Value.ToString(), regDef.GetIdent());
return StatusReturn.Warning;
}
}
else if (type == typeof(UInt64))
{
var checkValue = RegisterConverter.ByteArrayToValue<UInt64>(value);
if (regDef.Minimum.HasValue && checkValue < (UInt64)regDef.Minimum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(),
regDef.Minimum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (regDef.Maximum.HasValue && checkValue > (UInt64)regDef.Maximum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(),
regDef.Maximum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (checkIfValueIsDefault && regDef.Default.HasValue && 0 == checkValue.CompareTo(regDef.Default.Value))
{
msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(),
regDef.Default.Value.ToString(), regDef.GetIdent());
return StatusReturn.Warning;
}
}
else if (type == typeof(Int16))
{
var checkValue = RegisterConverter.ByteArrayToValue<Int16>(value);
if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(),
regDef.Minimum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(),
regDef.Maximum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value)
{
msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(),
regDef.Default.Value.ToString(), regDef.GetIdent());
return StatusReturn.Warning;
}
}
else if (type == typeof(Int32))
{
var checkValue = RegisterConverter.ByteArrayToValue<Int32>(value);
if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(),
regDef.Minimum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(),
regDef.Maximum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value)
{
msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(),
regDef.Default.Value.ToString(), regDef.GetIdent());
return StatusReturn.Warning;
}
}
else if (type == typeof(Int64))
{
var checkValue = RegisterConverter.ByteArrayToValue<Int64>(value);
if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(),
regDef.Minimum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(),
regDef.Maximum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value)
{
msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(),
regDef.Default.Value.ToString(), regDef.GetIdent());
return StatusReturn.Warning;
}
}
else if (type == typeof(Byte) || type == typeof(Enum8))
{
var checkValue = RegisterConverter.ByteArrayToValue<Byte>(value);
if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(),
regDef.Minimum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(),
regDef.Maximum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value)
{
msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(),
regDef.Default.Value.ToString(), regDef.GetIdent());
return StatusReturn.Warning;
}
}
else if (type == typeof(SByte))
{
var checkValue = RegisterConverter.ByteArrayToValue<SByte>(value);
if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(),
regDef.Minimum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value)
{
msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(),
regDef.Maximum.Value.ToString(), regDef.GetIdent());
return StatusReturn.Failed;
}
if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value)
{
msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(),
regDef.Default.Value.ToString(), regDef.GetIdent());
return StatusReturn.Warning;
}
}
else if (type == typeof(Boolean))
{
// call function to force exception if out of range
RegisterConverter.ByteArrayToValue<Boolean>(value);
}
else
{
msg = OutOfRangeMsg(RangeCheck.NotConvertible, "", "", regDef.GetIdent());
return StatusReturn.Failed;
}
}
catch (Exception e)
{
msg = e.Message;
return StatusReturn.Failed;
}
// the value is in range and not on default
return StatusReturn.Okay;
}
}
}