- 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`.
285 lines
14 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|