FM2014: - extended

This commit is contained in:
Thomas Wiedebusch 2026-01-13 12:58:04 +01:00
parent 57422da856
commit ff6254e66b
4 changed files with 108 additions and 52 deletions

View File

@ -32,15 +32,16 @@
*/
//using NLog;
using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Properties;
using System;
using System.Globalization;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts;
using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Properties;
using Xylem.Common.CommonCore.Consts;
using Xylem.Common.Utils.ProcessExec.EventArguments;
using static Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts.FM2014CmdDef;
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
@ -56,7 +57,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
#region properties
private const String _eos = FM2014CmdDef.END_OF_STR;
private const String _eos = END_OF_STR;
/// <inheritdoc/>
public Boolean CyclicReceiveTaskLoopIsActive
@ -94,8 +95,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
private set;
}
private const String _adrPre = FM2014CmdDef.ADDR_RECORD_STR;
private const String _adrPost = FM2014CmdDef.ADDR_VALIDATION_STR;
private const String _adrPre = ADDR_RECORD_STR;
private const String _adrPost = ADDR_VALIDATION_STR;
private Int32 _address;
/// <inheritdoc/>
@ -136,35 +137,35 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
public Boolean UseDampedTolerance
{
get;
private set;
set;
}
/// <inheritdoc/>
public UInt16 RefPulsePerCm
{
get;
private set;
set;
}
/// <inheritdoc/>
public UInt16 DutPulsePerCm
{
get;
private set;
set;
}
/// <inheritdoc/>
public Single RefToDutScaleNorm
{
get;
private set;
set;
}
/// <inheritdoc/>
public Byte Attenuation
{
get;
private set;
set;
}
/// <inheritdoc/>
@ -185,8 +186,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
/// Number of processing steps for this actual process progress
/// </summary>
private Int32 MaxActualProcessProgress
{
get;
{
get;
set;
}
@ -207,8 +208,6 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
_actualProcessProgress = MaxActualProcessProgress;
}
}
#endregion
#region methods
@ -255,7 +254,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
return false;
}
var cmdName = FM2014CmdDef.CmdName.CMD_NA;
var cmdName = CmdName.CMD_NA;
// Prepare REF-pulse counter measurement
try
@ -263,13 +262,13 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
switch (refCtrOn)
{
case true when dutCtrOn:
cmdName = FM2014CmdDef.CmdName.CMD_REF_DUT_STR_PLS_CTR;
cmdName = CmdName.CMD_REF_DUT_STR_PLS_CTR;
break;
case true:
cmdName = FM2014CmdDef.CmdName.CMD_REF_STR_PLS_CTR;
cmdName = CmdName.CMD_REF_STR_PLS_CTR;
break;
default:
cmdName = FM2014CmdDef.CmdName.CMD_DUT_STR_PLS_CTR;
cmdName = CmdName.CMD_DUT_STR_PLS_CTR;
break;
}
@ -281,7 +280,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
catch (Exception e)
{
var response = new FM2014CmdDef.CmdResponse(cmdName, e.Message);
var response = new CmdResponse(cmdName, e.Message);
OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
}
@ -291,39 +290,39 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
CyclicReceiveTaskLoopIsActive = true;
// Get the process information
var infoRef = FM2014CmdDef.GetCmdInfo(FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR);
var infoDut = FM2014CmdDef.GetCmdInfo(FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR);
var infoRef = GetCmdInfo(CmdName.CMD_REF_GET_PLS_CTR);
var infoDut = GetCmdInfo(CmdName.CMD_DUT_GET_PLS_CTR);
do
{
try
{
cmdName = FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR;
cmdName = CmdName.CMD_REF_GET_PLS_CTR;
if (refCtrOn && Write(cmdName))
{
var refPulseStr = SerialPort.ReadTo($"{_eos}");
if (int.TryParse(refPulseStr, NumberStyles.HexNumber, new CultureInfo("en"), out var refPulses))
{
var response = new FM2014CmdDef.CmdResponse(cmdName, infoRef, refPulses);
var response = new CmdResponse(cmdName, infoRef, refPulses);
OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(infoRef, specificInfoObj: response));
}
}
cmdName = FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR;
cmdName = CmdName.CMD_DUT_GET_PLS_CTR;
if (dutCtrOn && Write(cmdName))
{
var dutPulseStr = SerialPort.ReadTo($"{_eos}");
if (int.TryParse(dutPulseStr, NumberStyles.HexNumber, new CultureInfo("en"), out var dutPulses))
{
var response = new FM2014CmdDef.CmdResponse(cmdName, infoDut, dutPulses);
var response = new CmdResponse(cmdName, infoDut, dutPulses);
OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(infoDut, specificInfoObj: response));
}
}
}
catch (Exception e)
{
var response = new FM2014CmdDef.CmdResponse(cmdName, e.Message);
var response = new CmdResponse(cmdName, e.Message);
OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
}
@ -344,8 +343,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
public Boolean Login()
{
IsLoggedOn = false;
var cmdCode = FM2014CmdDef.GetCmdStr(FM2014CmdDef.CmdName.CMD_SERIAL);
const FM2014CmdDef.CmdName cmdName = FM2014CmdDef.CmdName.CMD_SERIAL;
var cmdCode = GetCmdStr(CmdName.CMD_SERIAL);
const CmdName cmdName = CmdName.CMD_SERIAL;
try
{
// Establish connection to one specific FM2014
@ -369,7 +368,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
catch (Exception e)
{
var response = new FM2014CmdDef.CmdResponse(cmdName, e.Message);
var response = new CmdResponse(cmdName, e.Message);
OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
}
@ -401,11 +400,22 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
return true;
}
// Establish connection to all FM2014s with broadcast address
SerialPort.Write(FM2014CmdDef.BROADCAST_ADDRESS);
BroadcastCommIsActive = true;
return true;
try
{
// Establish connection to all FM2014s with broadcast address
SerialPort.Write(BROADCAST_ADDRESS);
BroadcastCommIsActive = true;
return true;
}
catch (Exception e)
{
var response = new CmdResponse(CmdName.CMD_ADDR_PC,
$"{Resources.StrCmdRespErrorBroadcast} - {e.Message}");
OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
BroadcastCommIsActive = false;
return false;
}
}
/// <summary>
@ -428,18 +438,28 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
}
// Establish connection to one specific FM2014
SerialPort.Write(AddressStr);
FullId = SerialPort.ReadTo(_eos);
if (!string.IsNullOrEmpty(FullId))
try
{
FullId = FullId.Replace(_adrPre, "");
var fields = FullId.Split('.');
FwVersion = fields[1];
BroadcastCommIsActive = false;
return true;
// Establish connection to one specific FM2014
SerialPort.Write(AddressStr);
FullId = SerialPort.ReadTo(_eos);
if (!string.IsNullOrEmpty(FullId))
{
FullId = FullId.Replace(_adrPre, "");
var fields = FullId.Split('.');
FwVersion = fields[1];
BroadcastCommIsActive = false;
return true;
}
}
catch (Exception e)
{
var response = new CmdResponse(CmdName.CMD_ADDR_PC,
$"{Resources.StrCmdRespErrorIndividual} - {e.Message}");
OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
}
return false;
@ -453,7 +473,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
/// <param name="cmdName"></param>
/// <param name="dataObj"></param>
/// <returns></returns>
public Boolean Write(FM2014CmdDef.CmdName cmdName, Object dataObj = null)
public Boolean Write(CmdName cmdName, Object dataObj = null)
{
if (SerialPort == null || !SerialPort.IsOpen)
{
@ -465,7 +485,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
// Initiate communication using the individual or broadcast address
var retVal = true;
if (FM2014CmdDef.CmdType.BROADCAST == FM2014CmdDef.GetCmdCmdType(cmdName))
if (CmdType.BROADCAST == GetCmdCmdType(cmdName))
{
if (!BroadcastCommIsActive)
{
@ -483,7 +503,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (retVal)
{
// TODO THW Prepare data object
var cmdCodeStr = FM2014CmdDef.GetCmdStr(cmdName);
var cmdCodeStr = GetCmdStr(cmdName);
SerialPort.Write($"{cmdCodeStr}{_eos}");
}
@ -504,20 +524,26 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
CyclicReceiveTaskLoopIsActive = false;
// Reset measurement
var infoStr = FM2014CmdDef.GetCmdInfo(FM2014CmdDef.CmdName.CMD_RST_MEAS);
if (!Write(FM2014CmdDef.CmdName.CMD_RST_MEAS))
var infoStr = GetCmdInfo(CmdName.CMD_RST_MEAS);
if (!Write(CmdName.CMD_RST_MEAS))
return false;
// Wait until FM2014 calibration finished
var resetDelayCtr_ms = 4000;
const Int32 loopTime_ms = 500;
MaxActualProcessProgress = resetDelayCtr_ms / loopTime_ms;
ActualProcessProgress = 0;
do
{
var response = new FM2014CmdDef.CmdResponse(FM2014CmdDef.CmdName.CMD_RST_MEAS, infoStr,
var response = new CmdResponse(CmdName.CMD_RST_MEAS, infoStr,
resetDelayCtr_ms);
OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(infoStr, specificInfoObj: response));
OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(infoStr,
actualProcessMessage:infoStr,
actualProcessPercent: ActualProcessProgress,
specificInfoObj: response));
Thread.Sleep(loopTime_ms);
resetDelayCtr_ms -= loopTime_ms;
ActualProcessProgress += 1;
} while (resetDelayCtr_ms > 0);
return true;

View File

@ -466,6 +466,15 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Pr
}
}
/// <summary>
/// Looks up a localized string similar to Brodcast addressing failed.
/// </summary>
internal static string StrCmdRespErrorBroadcast {
get {
return ResourceManager.GetString("StrCmdRespErrorBroadcast", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Command not supported.
/// </summary>
@ -484,6 +493,15 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Pr
}
}
/// <summary>
/// Looks up a localized string similar to Individual addressing failed.
/// </summary>
internal static string StrCmdRespErrorIndividual {
get {
return ResourceManager.GetString("StrCmdRespErrorIndividual", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Measurement incomplete.
/// </summary>

View File

@ -273,4 +273,10 @@
<data name="StrCmdMsgPrintBootInfo" xml:space="preserve">
<value>Auslesen Bootcodeinformation</value>
</data>
<data name="StrCmdRespErrorBroadcast" xml:space="preserve">
<value>Broadcast Adressierung fehlgeschlagen</value>
</data>
<data name="StrCmdRespErrorIndividual" xml:space="preserve">
<value>Individuelle Adressierung fehlgeschlagen</value>
</data>
</root>

View File

@ -273,4 +273,10 @@
<data name="StrCmdMsgPrintBootInfo" xml:space="preserve">
<value>Print boot code information</value>
</data>
<data name="StrCmdRespErrorBroadcast" xml:space="preserve">
<value>Brodcast addressing failed</value>
</data>
<data name="StrCmdRespErrorIndividual" xml:space="preserve">
<value>Individual addressing failed</value>
</data>
</root>