diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs
index 414187a8..4adc6d71 100644
--- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs
+++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs
@@ -172,6 +172,11 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
///
public String SerialNumber { get; private set; }
+ ///
+ /// Lifetime of the FM2014 in hours
+ ///
+ public Int32 Lifetime_h { get; private set; }
+
///
/// FM2014 identification string e.g. FM2014.112.1
///
@@ -411,6 +416,20 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
return false;
}
+ ///
+ /// Common handler to publish the response.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// - Initial.
+ ///
+ private static void PublishResponse(FM2014 fm2014, ProcessExecEventArgs processExecEventArgs)
+ {
+ fm2014?.OnRawRecordReceived?.Invoke(fm2014, processExecEventArgs);
+ }
+
///
/// Read FM2014:
/// - Accesses directly to the 'SerialPort.ReadTo',
@@ -423,7 +442,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
///
/// - Initial.
///
- ///
+ ///
/// - Support for multiple FM2014s.
///
private static Boolean Read(CmdName cmdName, FM2014 fm2014, out String responseStr)
@@ -456,8 +475,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var isErrorStr = StatusReturn.Failed == statusReturn ? Resources.StrError + ": " : "";
var response = new CmdResponse(cmdName, $"{isErrorStr}{info} {responseStr}");
- fm2014?.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs("", specificInfoObj: response,
- statusReturn: statusReturn));
+ PublishResponse(fm2014, new ProcessExecEventArgs("", specificInfoObj: response, statusReturn: statusReturn));
return StatusReturn.Failed != statusReturn;
}
@@ -479,7 +497,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
///
/// - Initial.
///
- ///
+ ///
/// - Support for multiple FM2014s.
///
private static Boolean Write(CmdName cmdName, FM2014 fm2014, Object dataObj = null)
@@ -560,8 +578,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
var statusReturn = retVal ? StatusReturn.Okay : StatusReturn.Failed;
- fm2014.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs("", specificInfoObj: response,
- statusReturn: statusReturn));
+ PublishResponse(fm2014, new ProcessExecEventArgs("", specificInfoObj: response, statusReturn: statusReturn));
return retVal;
}
@@ -592,7 +609,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
var response = new CmdResponse(CmdName.CMD_ADDR_PC,
$"{Resources.StrCmdRespErrorBroadcast}");
- fm2014.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs(Resources.StrError,
+ PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response,
statusReturn: StatusReturn.Failed));
SharedCmdTypeReminderLastCmd = CmdType.NOT_INITIALIZED;
@@ -614,7 +631,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var cmdName = CmdName.CMD_CONNECT;
var info = GetCmdInfo(cmdName) + ": " + BROADCAST_ADDRESS;
var response = new CmdResponse(cmdName, info);
- fm2014.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs("", specificInfoObj: response));
+ PublishResponse(fm2014, new ProcessExecEventArgs("", specificInfoObj: response));
SharedCmdTypeReminderLastCmd = CmdType.BROADCAST;
return true;
}
@@ -622,7 +639,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
var response = new CmdResponse(CmdName.CMD_ADDR_PC,
$"{Resources.StrCmdRespErrorBroadcast} - {e.Message}");
- fm2014.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs(Resources.StrError,
+ PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
SharedCmdTypeReminderLastCmd = CmdType.NOT_INITIALIZED;
return false;
@@ -655,7 +672,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (!SharedSerialPort.IsOpen)
{
response = new CmdResponse(CmdName.CMD_ADDR_PC, $"{Resources.StrCmdRespErrorIndividual}");
- fm2014.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs(Resources.StrError,
+ PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response,
statusReturn: StatusReturn.Failed));
SharedCmdTypeReminderLastCmd = CmdType.NOT_INITIALIZED;
@@ -677,7 +694,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var cmdName = CmdName.CMD_CONNECT;
var info = GetCmdInfo(cmdName) + ": " + fm2014.AddressStr;
response = new CmdResponse(cmdName, info);
- fm2014.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs("", specificInfoObj: response));
+ PublishResponse(fm2014, new ProcessExecEventArgs("", specificInfoObj: response));
fm2014.ConnectResponse = fm2014.ConnectResponse.Replace(ADDR_RECORD_STR, "");
var fields = fm2014.ConnectResponse.Split('.');
fm2014.FwVersion = fields[1];
@@ -689,7 +706,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
response = new CmdResponse(CmdName.CMD_CONNECT, $"{Resources.StrCmdRespErrorIndividual}" +
$": {fm2014.AddressStr}" + $" - {e.Message}");
- fm2014.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs(Resources.StrError,
+ PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
SharedCmdTypeReminderLastCmd = CmdType.NOT_INITIALIZED;
fm2014.IsLoggedOn = false;
@@ -697,7 +714,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
response = new CmdResponse(CmdName.CMD_CONNECT, $"{Resources.StrCmdRespErrorIndividual}");
- fm2014.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs(Resources.StrError,
+ PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
SharedCmdTypeReminderLastCmd = CmdType.NOT_INITIALIZED;
return false;
@@ -789,7 +806,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
- OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
+ PublishResponse(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
return false;
}
@@ -841,7 +858,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
out var intValue))
{
var response = new CmdResponse(cmdNameRef, infoRef, intValue);
- fm2014.OnRawRecordReceived?.Invoke(fm2014,
+ PublishResponse(fm2014,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfoStr,
specificInfoObj: response));
}
@@ -854,7 +871,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
out var intValue))
{
var response = new CmdResponse(cmdNameDut, infoDut, intValue);
- fm2014.OnRawRecordReceived?.Invoke(fm2014,
+ PublishResponse(fm2014,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfoStr,
specificInfoObj: response));
}
@@ -864,7 +881,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
- fm2014?.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs(Resources.StrError,
+ PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
}
}
@@ -957,7 +974,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
- OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
+ PublishResponse(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
return false;
}
@@ -992,7 +1009,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var response = new CmdResponse(cmdName, info,
doubleValue: measTolerance * _toleranceRawToPercentScale * signMultiplier,
siUnit: SiUnits.GetInfo(SiUnits.SiUnitName.PERCENTAGE_NON_SI));
- fm2014?.OnRawRecordReceived?.Invoke(fm2014,
+ PublishResponse(fm2014,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfo,
specificInfoObj: response));
}
@@ -1012,7 +1029,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var response = new CmdResponse(cmdName, info,
doubleValue: TMR_RESOLUTION_s * 1000.0 * period,
siUnit: "m" + SiUnits.GetInfo(SiUnits.SiUnitName.TIME));
- fm2014?.OnRawRecordReceived?.Invoke(fm2014,
+ PublishResponse(fm2014,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfo,
specificInfoObj: response));
@@ -1022,7 +1039,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
response = new CmdResponse(cmdName, info,
doubleValue: 1.0 / (TMR_RESOLUTION_s * period),
siUnit: SiUnits.GetInfo(SiUnits.SiUnitName.FREQUENCY));
- fm2014?.OnRawRecordReceived?.Invoke(fm2014,
+ PublishResponse(fm2014,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfo,
specificInfoObj: response));
@@ -1033,7 +1050,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
info = GetCmdInfo(cmdName);
response = new CmdResponse(cmdName, info, doubleValue: flowRate_cm_per_h,
siUnit: SiUnits.GetInfo(SiUnits.SiUnitName.FLOW_RATE_NON_SI));
- fm2014?.OnRawRecordReceived?.Invoke(fm2014,
+ PublishResponse(fm2014,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfo,
specificInfoObj: response));
}
@@ -1054,7 +1071,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var response = new CmdResponse(cmdName, info,
doubleValue: TMR_RESOLUTION_s * 1000.0 * period,
siUnit: "m" + SiUnits.GetInfo(SiUnits.SiUnitName.TIME));
- fm2014?.OnRawRecordReceived?.Invoke(fm2014,
+ PublishResponse(fm2014,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfo,
specificInfoObj: response));
@@ -1064,7 +1081,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
response = new CmdResponse(cmdName, info,
doubleValue: 1.0 / (TMR_RESOLUTION_s * period),
siUnit: SiUnits.GetInfo(SiUnits.SiUnitName.FREQUENCY));
- fm2014?.OnRawRecordReceived?.Invoke(fm2014,
+ PublishResponse(fm2014,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfo,
specificInfoObj: response));
@@ -1075,7 +1092,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
info = GetCmdInfo(cmdName);
response = new CmdResponse(cmdName, info, doubleValue: flowRate_cm_per_h,
siUnit: SiUnits.GetInfo(SiUnits.SiUnitName.FLOW_RATE_NON_SI));
- fm2014?.OnRawRecordReceived?.Invoke(fm2014,
+ PublishResponse(fm2014,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfo,
specificInfoObj: response));
}
@@ -1094,7 +1111,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
// Publish the frequency in [Hz]
var response = new CmdResponse(cmdName, info, refFrequency,
siUnit: SiUnits.GetInfo(SiUnits.SiUnitName.FREQUENCY));
- fm2014?.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs("",
+ PublishResponse(fm2014, new ProcessExecEventArgs("",
actualProcessMessage: measurementInfo,
specificInfoObj: response));
@@ -1105,7 +1122,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
info = GetCmdInfo(cmdName);
response = new CmdResponse(cmdName, info, doubleValue: RefFlowRate_cm_per_h,
siUnit: SiUnits.GetInfo(SiUnits.SiUnitName.FLOW_RATE_NON_SI));
- fm2014?.OnRawRecordReceived?.Invoke(fm2014,
+ PublishResponse(fm2014,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfo,
specificInfoObj: response));
}
@@ -1114,7 +1131,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
- fm2014?.OnRawRecordReceived?.Invoke(fm2014, new ProcessExecEventArgs(Resources.StrError,
+ PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
}
}
@@ -1182,7 +1199,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
- OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
+ PublishResponse(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
}
return false;
@@ -1206,7 +1223,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
///
/// - Support for multiple FM2014s.
///
- private Boolean ReadAloneMeasurementControl(CmdName cmdName)
+ private Boolean ReadStandAloneMeasurement(CmdName cmdName)
{
// If the cyclic task has already been started everything is fine
if (SharedCyclicMeasSequ != CyclicMeasSequ.IDLE || !IsLoggedOn)
@@ -1257,9 +1274,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var info = GetCmdInfo(cmdName);
Attenuation = attenuation;
var response = new CmdResponse(cmdName, info, Attenuation);
- OnRawRecordReceived?.Invoke(this,
- new ProcessExecEventArgs("", actualProcessMessage: measurementInfoStr,
- specificInfoObj: response));
+ PublishResponse(this, new ProcessExecEventArgs("",
+ actualProcessMessage: measurementInfoStr, specificInfoObj: response));
}
}
if (str.Contains(StandAlonePartSearchScaleStr))
@@ -1272,7 +1288,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var info = GetCmdInfo(cmdName);
RefToDutScale_norm = value;
var response = new CmdResponse(cmdName, info, doubleValue: RefToDutScale_norm);
- OnRawRecordReceived?.Invoke(this,
+ PublishResponse(this,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfoStr,
specificInfoObj: response));
}
@@ -1287,7 +1303,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var info = GetCmdInfo(cmdName);
Dut_pulse_per_cm = value;
var response = new CmdResponse(cmdName, info, (Int32)Dut_pulse_per_cm);
- OnRawRecordReceived?.Invoke(this,
+ PublishResponse(this,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfoStr,
specificInfoObj: response));
// Added 2026-Jan-01 to overcome limitation of max 9999 Impulses per volume
@@ -1296,7 +1312,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
// Calculate REF pulses per cubic meter
Ref_pulse_per_cm = (UInt32)Math.Round(Dut_pulse_per_cm * RefToDutScale_norm, 1);
response = new CmdResponse(cmdName, info, (Int32)Ref_pulse_per_cm);
- OnRawRecordReceived?.Invoke(this,
+ PublishResponse(this,
new ProcessExecEventArgs("", actualProcessMessage: measurementInfoStr,
specificInfoObj: response));
}
@@ -1307,7 +1323,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
- OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
+ PublishResponse(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
return false;
}
@@ -1333,34 +1349,46 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (SharedCyclicMeasSequ != CyclicMeasSequ.IDLE)
return false;
- var cmdCode = GetCmdStr(CmdName.CMD_SERIAL);
- const CmdName cmdName = CmdName.CMD_SERIAL;
+ var cmdName = CmdName.CMD_SERIAL;
try
{
+ var cmdCode = GetCmdStr(cmdName);
// Read out the serial number of this FM2014
if (!Write(cmdName, this))
{
return false;
}
+ IsLoggedOn = true;
+
if (Read(cmdName, this, out var responseStr))
SerialNumber = responseStr;
if (!string.IsNullOrEmpty(SerialNumber))
{
SerialNumber = SerialNumber.Replace(cmdCode, "");
- IsLoggedOn = true;
}
- if (IsLoggedOn)
+ cmdName = CmdName.CMD_PRINT_STATISTICS;
+ // Read out the lifetime of this FM2014
+ if (!Write(cmdName, this))
{
- IsLoggedOn = ReadAloneMeasurementControl(CmdName.CMD_READ_EEP_MEAS_SETUP);
+ return false;
}
+
+ if (Read(cmdName, this, out responseStr))
+ {
+ var cleanedResponse = Regex.Replace(responseStr, "[^0-9]", string.Empty);
+ if (int.TryParse(cleanedResponse, /*NumberStyles.HexNumber, new CultureInfo("en"),*/ out var intValue))
+ Lifetime_h = intValue;
+ }
+
+ IsLoggedOn = ReadStandAloneMeasurement(CmdName.CMD_READ_EEP_MEAS_SETUP);
}
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
- OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
+ PublishResponse(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
return false;
}
@@ -1409,7 +1437,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
// Change the SI unit to ms instead of seconds
var response = new CmdResponse(CmdName.CMD_RST_MEAS, infoStr,
resetDelayCtr_ms, siUnit: "m" + SiUnits.GetInfo(SiUnits.SiUnitName.TIME));
- OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(infoStr,
+ PublishResponse(this, new ProcessExecEventArgs(infoStr,
actualProcessMessage: infoStr,
actualProcessPercent: _actualProcessProgress_percent,
specificInfoObj: response));