This commit is contained in:
Stoyan Zlatev 2026-02-25 12:02:16 +01:00
commit 19cb72be9b
20 changed files with 452 additions and 310 deletions

View File

@ -730,6 +730,10 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
/// <remarks date="2025-Feb-11" author="Thomas Wiedebusch">
/// - For special requirements the "not for production" version can be loaded.
/// </remarks>
/// <remarks date="2026-Feb-23" author="Thomas Wiedebusch">
/// - All FW versions as stated in the fwVersion string will be accepted as valid as those are defined in the
/// 'Standard-' or 'Special-Requirements'.
/// </remarks>
public static Boolean SearchProdFwInDb(String fwVersion, out Int32? fwPackageFileId, out String errorMsg,
Boolean isForProduction = true)
{
@ -746,7 +750,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
if (fwPackInfo != null)
{
foreach (var fw in fwPackInfo.Where(fw => (fw.CurrentForProd || !isForProduction) &&
foreach (var fw in fwPackInfo.Where(fw => //(fw.CurrentForProd || !isForProduction) &&
fw.Name.Contains(fwVersion)))
{
fwPackageFileId = fw.FileClusterStoreId;

View File

@ -1,46 +0,0 @@
/*********************************************************************************************************************/
/*! @file ConnectionStatus.cs
* @brief <i></i>
*
* @author Thomas Wiedebusch
* @date 2026-Feb-17
*
* @details <i>.</i>
*
* @copyright © SENSUS GmbH 2026. All rights reserved.
*********************************************************************************************************************/
using System;
using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts;
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
/// <summary>
/// Assembly of device status and multilingual information
/// </summary>
public struct ConnectionStatus
{
/// <summary>
/// Enumerator of command name acronym
/// </summary>
public readonly ConnectionStatusName Name;
/// <summary>
/// Multilingual information
/// </summary>
public readonly String InfoStr;
/// <summary>
/// Single command table entry to combine the name with the code and the communication type
/// </summary>
/// <param name="deviceConnectionStatus"></param>
/// <param name="statusInfoStr">Multilingual command information string</param>
public ConnectionStatus(ConnectionStatusName deviceConnectionStatus, String statusInfoStr)
{
Name = deviceConnectionStatus;
InfoStr = statusInfoStr;
}
}
}
/*********************************************** END OF FILE *********************************************************/

View File

@ -1,67 +0,0 @@
/*********************************************************************************************************************/
/*! @file Cmd.cs
* @brief <i></i>
*
* @author Thomas Wiedebusch
* @date 2026-Feb-17
*
* @details <i>.</i>
*
* @copyright © SENSUS GmbH 2026. All rights reserved.
*********************************************************************************************************************/
using System;
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts
{
/// <summary>
/// Assembly of command information and functional code
/// </summary>
public struct Cmd
{
/// <summary>
/// Enumerator of command name acronym
/// </summary>
public readonly CmdName CmdName;
/// <summary>
/// Code being sent to FM2014 as string
/// </summary>
public readonly String CmdCodeStr;
/// <summary>
/// Command type regarding the address (broadcast or individual) and answer
/// </summary>
public readonly CmdType CmdType;
/// <summary>
/// Command parameter style for raw data conversion from response string or for transmission
/// </summary>
public readonly ParaFormat ParamFormat;
/// <summary>
/// Multilingual command information string
/// </summary>
public readonly String CmdInfoStr;
/// <summary>
/// Single command table entry to combine the name with the code and the communication type
/// </summary>
/// <param name="cmdName">Enumerator of command name acronym</param>
/// <param name="cmdCodeStr">Code being sent to FM2014 as string</param>
/// <param name="cmdType">Command type regarding the address (broadcast or individual) and answer</param>
/// <param name="paraFormat">parameter format for conversion</param>
/// <param name="cmdInfoStr">Multilingual command information string</param>
public Cmd(CmdName cmdName, String cmdCodeStr, CmdType cmdType, ParaFormat paraFormat,
String cmdInfoStr)
{
CmdName = cmdName;
CmdCodeStr = cmdCodeStr;
CmdType = cmdType;
ParamFormat = paraFormat;
CmdInfoStr = cmdInfoStr;
}
}
}
/*********************************************** END OF FILE *********************************************************/

View File

@ -1,45 +0,0 @@
/*********************************************************************************************************************/
/*! @file CmdErrorMsg.cs
* @brief <i></i>
*
* @author Thomas Wiedebusch
* @date 2026-Feb-17
*
* @details <i>.</i>
*
* @copyright © SENSUS GmbH 2026. All rights reserved.
*********************************************************************************************************************/
using System;
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts
{
/// <summary>
/// Combine constant string returns from FM2014 firmware to multilingual information
/// </summary>
public struct CmdErrorMsg
{
/// <summary>
/// Hard coded return string from FM2014
/// </summary>
public String FM2014ErrorReturnStr;
/// <summary>
/// Multilingual forwarded string to GUI
/// </summary>
public String MultilingualForwardStr;
/// <summary>
/// Ctor
/// </summary>
/// <param name="fixedFwErrorStr"></param>
/// <param name="multilingualFeedback"></param>
public CmdErrorMsg(String fixedFwErrorStr, String multilingualFeedback)
{
FM2014ErrorReturnStr = fixedFwErrorStr;
MultilingualForwardStr = multilingualFeedback;
}
}
}
/*********************************************** END OF FILE *********************************************************/

View File

@ -15,7 +15,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co
/// <summary>
/// Parameter format to convert the response or the request
/// </summary>
public enum ParaFormat
public enum CmdParaFormat
{
/// <summary>
/// String taken directly to send or as received

View File

@ -37,6 +37,5 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co
/// </summary>
uninitialized
}
}
/*********************************************** END OF FILE *********************************************************/

View File

@ -15,7 +15,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co
/// <summary>
/// Device status of FM2014
/// </summary>
public enum ConnectionStatusName
public enum ConnectStatusName
{
/// <summary>
/// Unknown status

View File

@ -0,0 +1,46 @@
/*********************************************************************************************************************/
/*! @file ErrorStatus.cs
* @brief <i>FM2014 device error status</i>
*
* @author Thomas Wiedebusch
* @date 2026-Feb-24
*
* @details <i>.</i>
*
* @copyright © SENSUS GmbH 2026. All rights reserved.
*********************************************************************************************************************/
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts
{
/// <summary>
/// Error status returned from FM2014 with command '0x41 ' or 'UNICODE_ACK' as MSB - 1
/// </summary>
public enum ErrorStatus
{
/// <summary>
/// REF signal timeout during the adjustment measurement for two consecutive pulses of 21.889 s
/// </summary>
AdjustMeasurementRefTimeout = 0x80,
/// <summary>
/// DUT signal timeout during the adjustment measurement for two consecutive pulses of 21.889 s
/// </summary>
AdjustMeasurementDutTimeout = 0x40,
/// <summary>
/// DUT double pulse detected during the time measurement
/// </summary>
TimeMeasurementDoublePulseDutDetected = 0x04,
/// <summary>
/// REF signal timeout during the time measurement for two consecutive pulses of 21.889 s
/// </summary>
TimeMeasurementRefTimeout = 0x02,
/// <summary>
/// REF signal timeout during the time measurement for two consecutive pulses of 21.889 s
/// </summary>
TimeMeasurementDutTimeout = 0x01
}
}
/*********************************************** END OF FILE *********************************************************/

View File

@ -0,0 +1,47 @@
/*********************************************************************************************************************/
/*! @file Fault1Status.cs
* @brief <i>FM2014 device fault1 status</i>
*
* @author Thomas Wiedebusch
* @date 2026-Feb-24
*
* @details <i>.</i>
*
* @copyright © SENSUS GmbH 2026. All rights reserved.
*********************************************************************************************************************/
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts
{
/// <summary>
/// Fault1 status returned from FM2014 with command '0x43 ' or 'UNICODE_ACK' as LSB
/// </summary>
public enum Fault1Status
{
/// <summary>
/// Error for U/I converter for the current output of the tolerance DUT to REF display
/// </summary>
ErrorUiConverterCurrentOutput = 0x40,
/// <summary>
/// Setup of REF pulses is out of range command 'M'
/// </summary>
RefPulseSetupOor = 0x08,
/// <summary>
/// Setup of DUT pulses is out of range command 'H'
/// </summary>
DutPulseSetupOor = 0x04,
/// <summary>
/// Missing or out of range of the setup of the scale REF to DUT command 'K'
/// </summary>
MissingOrOorSetupScaleRefToDut = 0x02,
/// <summary>
/// Missing or out of range of double pulse ignorance deadtime command 'G' or 's' and 'S'
/// </summary>
MissingOrOorSetupDoublePulesDeadtime = 0x01
}
}
/*********************************************** END OF FILE *********************************************************/

View File

@ -0,0 +1,31 @@
/*********************************************************************************************************************/
/*! @file Fault2Status.cs
* @brief <i>FM2014 device fault2 status</i>
*
* @author Thomas Wiedebusch
* @date 2026-Feb-24
*
* @details <i>.</i>
*
* @copyright © SENSUS GmbH 2026. All rights reserved.
*********************************************************************************************************************/
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts
{
/// <summary>
/// Fault2 status returned from FM2014 with command '0x43 ' or 'UNICODE_ACK' as LSB
/// </summary>
public enum Fault2Status
{
/// <summary>
/// FLASH access error causing parameters set to default
/// </summary>
FlashAccessError = 0x10,
/// <summary>
/// Missing the setup for current output attenuation of the DUT to REF tolerance command 'T'
/// </summary>
MissingCurrentOutputAttenuation = 0x08,
}
}
/*********************************************** END OF FILE *********************************************************/

View File

@ -0,0 +1,56 @@
/*********************************************************************************************************************/
/*! @file MeasureStatus.cs
* @brief <i>FM2014 device measurement status</i>
*
* @author Thomas Wiedebusch
* @date 2026-Feb-24
*
* @details <i>.</i>
*
* @copyright © SENSUS GmbH 2026. All rights reserved.
*********************************************************************************************************************/
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts
{
/// <summary>
/// Measurement status returned from FM2014 with command '0x40 ' or 'UNICODE_ACK' as MSB
/// </summary>
public enum MeasureStatus
{
/// <summary>
/// Double pulse deadtime set to 0, means double pulse ignorance time is switched off
/// </summary>
DoublePulseDeadtimeInactive = 0x80,
/// <summary>
/// Time measurement of REF has finished
/// </summary>
TimeMeasureRefRdy = 0x40,
/// <summary>
/// Time measurement of DUT has finished
/// </summary>
TimeMeasureDutRdy = 0x20,
/// <summary>
/// Time measurement of REF is ongoing
/// </summary>
TimeMeasureRefActive = 0x10,
/// <summary>
/// Time measurement of DUT is ongoing
/// </summary>
TimeMeasureDutActive = 0x08,
/// <summary>
/// Adjustment measurement of REF is finished
/// </summary>
AdjustMeasureRefRdy = 0x02,
/// <summary>
/// Adjustment measurement of DUT is finished
/// </summary>
AdjustMeasureDutRdy = 0x01
}
}
/*********************************************** END OF FILE *********************************************************/

View File

@ -737,7 +737,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
do
{
// Change the SI unit to ms instead of seconds
var response = new CmdResponse(CmdName.CmdResetMeasurement, infoStr, (UInt32)resetDelayCtr_ms,
var response = new FM2014CmdResponse(CmdName.CmdResetMeasurement, infoStr, (UInt32)resetDelayCtr_ms,
unit: "m" + Units.GetInfo(Units.Name.TIME_s));
PublishResponse(BroadcastFm2014, new ProcessExecEventArgs("",
actualProcessMessage: infoStr,
@ -836,7 +836,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
/// <remarks date="2026-Feb-13..Feb-21" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
private static void ResponseEvent(FM2014 fm2014, CmdResponse cmdResponse,
private static void ResponseEvent(FM2014 fm2014, FM2014CmdResponse cmdResponse,
StatusReturn statusReturn = StatusReturn.Unknown)
{
var processExecEventArgs = new ProcessExecEventArgs("",
@ -900,7 +900,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
// Dispatch human-readable result
var info = Resources.StrInputMsgDoublePulseDeadTime;
var response = new CmdResponse(cmdName, info,
var response = new FM2014CmdResponse(cmdName, info,
doubleValue: fm2014.DoublePulseDeadtime_ms * 0.001,
unit: Units.GetInfo(Units.Name.TIME_s));
ResponseEvent(actualFm2014, response);
@ -996,7 +996,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
var response = new FM2014CmdResponse(cmdName, e.Message);
PublishResponse(firstActiveFm2014, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
return false;
@ -1052,7 +1052,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (Read(cmdName, fm2014, out var responseStr, out var status, out _))
{
info += $": {responseStr}";
var response = new CmdResponse(cmdName, info, status);
var response = new FM2014CmdResponse(cmdName, info, status);
ResponseEvent(fm2014, response);
}
}
@ -1061,7 +1061,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
if (Read(cmdNameRef, fm2014, out _, out var intValue, out _))
{
var response = new CmdResponse(cmdNameRef, infoRef, intValue);
var response = new FM2014CmdResponse(cmdNameRef, infoRef, intValue);
ResponseEvent(fm2014, response);
}
}
@ -1070,14 +1070,14 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
if (Read(cmdNameDut, fm2014, out _, out var intValue, out _))
{
var response = new CmdResponse(cmdNameDut, infoDut, intValue);
var response = new FM2014CmdResponse(cmdNameDut, infoDut, intValue);
ResponseEvent(fm2014, response);
}
}
}
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
var response = new FM2014CmdResponse(cmdName, e.Message);
PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
}
@ -1194,7 +1194,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
var response = new FM2014CmdResponse(cmdName, e.Message);
PublishResponse(firstActiveFm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
return false;
@ -1221,7 +1221,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (Read(cmdName, fm2014, out var responseStr, out var status, out _))
{
info += $": {responseStr}";
var response = new CmdResponse(cmdName, info, status);
var response = new FM2014CmdResponse(cmdName, info, status);
ResponseEvent(fm2014, response);
}
}
@ -1236,7 +1236,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
fm2014.DutToRefToleranceMeasured_percent = doubleValue *
fm2014.CurrentOutputDisplayRangeNominalToRealScale;
var response = new CmdResponse(cmdName, info,
var response = new FM2014CmdResponse(cmdName, info,
doubleValue: fm2014.DutToRefToleranceMeasured_percent,
unit: Units.GetInfo(Units.Name.PERCENT));
@ -1259,7 +1259,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (Read(cmdName, fm2014, out _, out var period, out _))
{
// Publish the period [ms]
var response = new CmdResponse(cmdName, info,
var response = new FM2014CmdResponse(cmdName, info,
doubleValue: TMR_RESOLUTION_s * 1000.0 * period,
unit: "m" + Units.GetInfo(Units.Name.TIME_s));
ResponseEvent(fm2014, response);
@ -1267,7 +1267,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
// Publish the frequency in [Hz]
cmdName = CmdName.CmdCalculatedFrequRefPeriod;
info = GetCmdInfo(cmdName);
response = new CmdResponse(cmdName, info,
response = new FM2014CmdResponse(cmdName, info,
doubleValue: 1.0 / (TMR_RESOLUTION_s * period),
unit: Units.GetInfo(Units.Name.FREQUENCY_Hz));
ResponseEvent(fm2014, response);
@ -1277,7 +1277,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
// Publish the calculated flow rate [m³/h]
cmdName = CmdName.CmdCalculatedFlowRefPeriod;
info = GetCmdInfo(cmdName);
response = new CmdResponse(cmdName, info, doubleValue: fm2014.RefFlowRate_cm_per_h,
response = new FM2014CmdResponse(cmdName, info, doubleValue: fm2014.RefFlowRate_cm_per_h,
unit: Units.GetInfo(Units.Name.FLOW_RATE_cm_per_h));
ResponseEvent(fm2014, response);
}
@ -1294,7 +1294,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (Read(cmdName, fm2014, out _, out var period, out _))
{
// Publish the period [ms]
var response = new CmdResponse(cmdName, info,
var response = new FM2014CmdResponse(cmdName, info,
doubleValue: TMR_RESOLUTION_s * 1000.0 * period,
unit: "m" + Units.GetInfo(Units.Name.TIME_s));
ResponseEvent(fm2014, response);
@ -1302,7 +1302,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
// Publish the frequency in [Hz]
cmdName = CmdName.CmdCalculatedFrequencyDutPeriod;
info = GetCmdInfo(cmdName);
response = new CmdResponse(cmdName, info,
response = new FM2014CmdResponse(cmdName, info,
doubleValue: 1.0 / (TMR_RESOLUTION_s * period),
unit: Units.GetInfo(Units.Name.FREQUENCY_Hz));
ResponseEvent(fm2014, response);
@ -1312,7 +1312,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
// Publish the calculated flow rate [m³/h]
cmdName = CmdName.CmdCalculatedFlowDutPeriod;
info = GetCmdInfo(cmdName);
response = new CmdResponse(cmdName, info, doubleValue: fm2014.DutFlowRate_cm_per_h,
response = new FM2014CmdResponse(cmdName, info, doubleValue: fm2014.DutFlowRate_cm_per_h,
unit: Units.GetInfo(Units.Name.FLOW_RATE_cm_per_h));
ResponseEvent(fm2014, response);
}
@ -1331,7 +1331,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
else statusReturn = StatusReturn.Okay;
// Publish the frequency in [Hz]
var response = new CmdResponse(cmdName, info, (UInt32)refFrequency,
var response = new FM2014CmdResponse(cmdName, info, (UInt32)refFrequency,
unit: Units.GetInfo(Units.Name.FREQUENCY_Hz));
ResponseEvent(fm2014, response, statusReturn);
@ -1340,7 +1340,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
// Publish the calculated flow rate [m³/h]
cmdName = CmdName.CmdCalculatedFlowRefFrequ;
info = GetCmdInfo(cmdName);
response = new CmdResponse(cmdName, info, doubleValue: fm2014.RefFlowRate_cm_per_h,
response = new FM2014CmdResponse(cmdName, info, doubleValue: fm2014.RefFlowRate_cm_per_h,
unit: Units.GetInfo(Units.Name.FLOW_RATE_cm_per_h));
ResponseEvent(fm2014, response, statusReturn);
}
@ -1348,7 +1348,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
var response = new FM2014CmdResponse(cmdName, e.Message);
PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
}
@ -1395,7 +1395,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
/// <param name="doublePulseDeadtime_ms">0 if double impulse deadtime detection is off</param>
/// </summary>
/// <returns></returns>
/// <remarks date="2026-Jan-14..Feb-21" author="Thomas Wiedebusch">
/// <remarks date="2026-Jan-14..Feb-24" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public static Boolean PulseTimeMeasurement(UInt16? refPulsesRequired = null, UInt16? dutPulsesRequired = null,
@ -1455,7 +1455,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
// Dispatch human-readable result
var info = Resources.StrCmdMsgRefSetPls;
var response = new CmdResponse(cmdName, info,
var response = new FM2014CmdResponse(cmdName, info,
intValue: firstActiveFm2014.RefPulsesRequired);
ResponseEvent(BroadcastFm2014, response);
}
@ -1469,14 +1469,14 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
// Dispatch human-readable result
var info = Resources.StrCmdMsgDutSetPls;
var response = new CmdResponse(cmdName, info,
var response = new FM2014CmdResponse(cmdName, info,
intValue: firstActiveFm2014.DutPulsesRequired);
ResponseEvent(BroadcastFm2014, response);
}
}
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
var response = new FM2014CmdResponse(cmdName, e.Message);
PublishResponse(firstActiveFm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
return false;
@ -1507,7 +1507,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (Read(cmdName, fm2014, out var responseStr, out var status, out _))
{
info += $": {responseStr}";
var response = new CmdResponse(cmdName, info, status);
var response = new FM2014CmdResponse(cmdName, info, status);
ResponseEvent(fm2014, response);
}
}
@ -1535,7 +1535,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
statusReturn = StatusReturn.Okay;
}
var response = new CmdResponse(cmdName, info, pulses);
var response = new FM2014CmdResponse(cmdName, info, pulses);
ResponseEvent(fm2014, response, statusReturn);
// Feed the progress counter
@ -1568,7 +1568,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
statusReturn = StatusReturn.Okay;
}
var response = new CmdResponse(cmdName, info, pulses);
var response = new FM2014CmdResponse(cmdName, info, pulses);
ResponseEvent(fm2014, response, statusReturn);
// Feed the progress counter but only if not done for REF pulses
@ -1596,7 +1596,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
// Is converting to a real time in seconds
fm2014.RefTimerTicksMeasured = (UInt32)timerTicks;
var response = new CmdResponse(cmdName, info, doubleValue: fm2014.RefTimeMeasured_s,
var response = new FM2014CmdResponse(cmdName, info, doubleValue: fm2014.RefTimeMeasured_s,
unit: Units.GetInfo(Units.Name.TIME_s));
ResponseEvent(fm2014, response);
}
@ -1618,7 +1618,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
// Is converting to a real time in seconds
fm2014.DutTimerTicksMeasured = (UInt32)timerTicks;
var response = new CmdResponse(cmdName, info, doubleValue: fm2014.DutTimeMeasured_s,
var response = new FM2014CmdResponse(cmdName, info, doubleValue: fm2014.DutTimeMeasured_s,
unit: Units.GetInfo(Units.Name.TIME_s));
ResponseEvent(fm2014, response);
}
@ -1648,7 +1648,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
statusReturn = StatusReturn.MeasurementOutOfRange;
else statusReturn = StatusReturn.MeasurementInRange;
var response = new CmdResponse(cmdName, info,
var response = new FM2014CmdResponse(cmdName, info,
doubleValue: fm2014.DutToRefToleranceMeasured_percent,
unit: Units.GetInfo(Units.Name.PERCENT));
ResponseEvent(fm2014, response, statusReturn);
@ -1661,7 +1661,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
var response = new FM2014CmdResponse(cmdName, e.Message);
PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
}
@ -1705,14 +1705,14 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var statusReturn = StatusReturn.Unknown;
var numberStyle = NumberStyles.None;
var paraFormat = GetParaFormat(cmdName);
if (paraFormat == ParaFormat.uintHexValue || paraFormat == ParaFormat.byteHexValuePlusSign)
if (paraFormat == CmdParaFormat.uintHexValue || paraFormat == CmdParaFormat.byteHexValuePlusSign)
{
numberStyle = NumberStyles.HexNumber;
}
switch (paraFormat)
{
case ParaFormat.byteHexValuePlusSign:
case CmdParaFormat.byteHexValuePlusSign:
// The response contains a sign!
var signMultiplier = responseStr.Contains("+") ? 1.0 : -1.0;
var cleanedStr = responseStr.Replace("+", "").Replace("-", "");
@ -1722,8 +1722,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
break;
case ParaFormat.uintHexValue:
case ParaFormat.uintDecimalValue:
case CmdParaFormat.uintHexValue:
case CmdParaFormat.uintDecimalValue:
if (uint.TryParse(responseStr, numberStyle, new CultureInfo("en"), out intValueParsed))
{
intValue = intValueParsed;
@ -1783,7 +1783,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
var isErrorStr = StatusReturn.Failed == statusReturn ? Resources.StrError + ": " : "";
var response = new CmdResponse(cmdName, $"{isErrorStr}{info} {responseStr}");
var response = new FM2014CmdResponse(cmdName, $"{isErrorStr}{info} {responseStr}");
// Publish the raw response for logging
ResponseEvent(fm2014, response, statusReturn);
@ -1851,8 +1851,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var cmdCodeStr = GetCmdStr(cmdName);
var info = GetCmdInfo(cmdName) + $": {cmdCodeStr}";
var isHexFormat = GetParaFormat(cmdName) == ParaFormat.uintHexValue;
CmdResponse response;
var isHexFormat = GetParaFormat(cmdName) == CmdParaFormat.uintHexValue;
FM2014CmdResponse response;
// Without data the command alone needs to be sent
if (dataObj == null)
{
@ -1860,7 +1860,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
var additionalInfo = GetCmdType(cmdName) == CmdType.broadcast
? Resources.StrCommDirectionSetup
: Resources.StrCommDirectionRequest;
response = new CmdResponse(cmdName, $"{additionalInfo}: {info}");
response = new FM2014CmdResponse(cmdName, $"{additionalInfo}: {info}");
}
else
{
@ -1868,7 +1868,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (dataObj is String)
{
SharedSerialPort.Write($"{dataObj}{END_OF_STR}");
response = new CmdResponse(cmdName, $"{Resources.StrCommDirectionSetup}: {info}: {dataObj}");
response = new FM2014CmdResponse(cmdName, $"{Resources.StrCommDirectionSetup}: {info}: {dataObj}");
}
// The data contains the preceding setup, the command code and string delimiter will be added here
@ -1876,13 +1876,13 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
var valueStr = isHexFormat ? $"{dataObj:X}{cmdCodeStr}" : $"{dataObj}{cmdCodeStr}";
SharedSerialPort.Write($"{valueStr}{END_OF_STR}");
response = new CmdResponse(cmdName,
response = new FM2014CmdResponse(cmdName,
$"{Resources.StrCommDirectionSetup}: {info}: {valueStr}");
}
else
{
response = new CmdResponse(cmdName,
response = new FM2014CmdResponse(cmdName,
$"{Resources.StrError}: {Resources.StrCommDirectionSetup}: {info} - " +
$"{Resources.StrCmdRespErrorPramTypeNotSupported} {dataObj}");
retVal = false;
@ -1913,7 +1913,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (fm2014 == null)
return false;
CmdResponse response;
FM2014CmdResponse response;
try
{
if (!SharedSerialPort.IsOpen)
@ -1921,7 +1921,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
SharedSerialPort.Open();
if (!SharedSerialPort.IsOpen)
{
response = new CmdResponse(CmdName.CmdAddress,
response = new FM2014CmdResponse(CmdName.CmdAddress,
$"{Resources.StrCmdRespErrorBroadcast}");
PublishResponse(BroadcastFm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response,
@ -1941,14 +1941,14 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
SharedSerialPort.Write(BROADCAST_ADDRESS + END_OF_STR);
var cmdName = CmdName.CmdConnect;
var info = GetCmdInfo(cmdName) + ": " + BROADCAST_ADDRESS;
response = new CmdResponse(cmdName, info);
response = new FM2014CmdResponse(cmdName, info);
PublishResponse(BroadcastFm2014, new ProcessExecEventArgs("", specificInfoObj: response));
SharedCmdTypeReminderLastCmd = CmdType.broadcast;
return true;
}
catch (Exception e)
{
response = new CmdResponse(CmdName.CmdAddress,
response = new FM2014CmdResponse(CmdName.CmdAddress,
$"{Resources.StrCmdRespErrorBroadcast} - {e.Message}");
PublishResponse(BroadcastFm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
@ -1973,7 +1973,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (fm2014 == null)
return false;
CmdResponse response;
FM2014CmdResponse response;
try
{
if (!SharedSerialPort.IsOpen)
@ -1981,7 +1981,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
SharedSerialPort.Open();
if (!SharedSerialPort.IsOpen)
{
response = new CmdResponse(CmdName.CmdAddress, $"{Resources.StrCmdRespErrorIndividual}");
response = new FM2014CmdResponse(CmdName.CmdAddress, $"{Resources.StrCmdRespErrorIndividual}");
PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response,
statusReturn: StatusReturn.Failed));
@ -2000,7 +2000,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
var cmdName = CmdName.CmdConnect;
var info = GetCmdInfo(cmdName) + ": " + fm2014.AddressStr;
response = new CmdResponse(cmdName, info);
response = new FM2014CmdResponse(cmdName, info);
PublishResponse(fm2014, new ProcessExecEventArgs("", specificInfoObj: response));
fm2014.ConnectResponse = fm2014.ConnectResponse.Replace(ADDR_RECORD_STR, "");
var fields = fm2014.ConnectResponse.Split('.');
@ -2011,7 +2011,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
catch (Exception e)
{
response = new CmdResponse(CmdName.CmdConnect, $"{Resources.StrCmdRespErrorIndividual}" +
response = new FM2014CmdResponse(CmdName.CmdConnect, $"{Resources.StrCmdRespErrorIndividual}" +
$": {fm2014.AddressStr}" + $" - {e.Message}");
PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
@ -2020,7 +2020,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
return false;
}
response = new CmdResponse(CmdName.CmdConnect, $"{Resources.StrCmdRespErrorIndividual}");
response = new FM2014CmdResponse(CmdName.CmdConnect, $"{Resources.StrCmdRespErrorIndividual}");
PublishResponse(fm2014, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response, statusReturn: StatusReturn.Failed));
SharedCmdTypeReminderLastCmd = CmdType.uninitialized;
@ -2048,6 +2048,18 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
}
/// <summary>
/// Calculation of pulse ratio
/// </summary>
/// <param name="pulsesMeasured">counted pulses</param>
/// <param name="volumeMeasured_liters">measured volume in liters</param>
/// <returns></returns>
public static UInt32 CalculatePulsesPerCm(Int32 pulsesMeasured, Int32 volumeMeasured_liters)
{
// Convert measured volume from liters to cubic-meters
return (UInt32)(pulsesMeasured / (volumeMeasured_liters / 1000.0) + 0.5);
}
/// <summary>
/// Dispose FM2014
/// </summary>
@ -2155,7 +2167,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
var response = new FM2014CmdResponse(cmdName, e.Message);
PublishResponse(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
}
@ -2226,7 +2238,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
cmdName = CmdName.CmdSetCurrentOutputAttenuation;
var info = GetCmdInfo(cmdName);
CurrentOutputAttenuation = attenuation;
var response = new CmdResponse(cmdName, info, CurrentOutputAttenuation);
var response = new FM2014CmdResponse(cmdName, info, CurrentOutputAttenuation);
ResponseEvent(this, response);
}
}
@ -2239,7 +2251,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
cmdName = CmdName.CmdRefToDutScale;
var info = GetCmdInfo(cmdName);
RefToDutScale_norm = value;
var response = new CmdResponse(cmdName, info, doubleValue: RefToDutScale_norm);
var response = new FM2014CmdResponse(cmdName, info, doubleValue: RefToDutScale_norm);
ResponseEvent(this, response);
}
}
@ -2252,14 +2264,14 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
cmdName = CmdName.CmdSetDutPulsesPerCm;
var info = GetCmdInfo(cmdName);
DutPulses_per_cm = value;
var response = new CmdResponse(cmdName, info, DutPulses_per_cm);
var response = new FM2014CmdResponse(cmdName, info, DutPulses_per_cm);
ResponseEvent(this, response);
// Added 2026-Jan-01 to overcome limitation of max 9999 Impulses per volume
cmdName = CmdName.CmdSetRefPulsesPerCm;
info = GetCmdInfo(cmdName);
// Calculate REF pulses per cubic meter
RefPulses_per_cm = (UInt32)Math.Round(DutPulses_per_cm * RefToDutScale_norm, 1);
response = new CmdResponse(cmdName, info, RefPulses_per_cm);
response = new FM2014CmdResponse(cmdName, info, RefPulses_per_cm);
ResponseEvent(this, response);
}
}
@ -2268,7 +2280,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
var response = new FM2014CmdResponse(cmdName, e.Message);
PublishResponse(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
return false;
@ -2339,7 +2351,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
SharedSerialPort.Open();
if (!SharedSerialPort.IsOpen)
{
var response = new CmdResponse(CmdName.CmdAddress,
var response = new FM2014CmdResponse(CmdName.CmdAddress,
$"{Resources.StrCmdRespErrorBroadcast}");
PublishResponse(this, new ProcessExecEventArgs(Resources.StrError,
specificInfoObj: response,
@ -2385,7 +2397,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
catch (Exception e)
{
var response = new CmdResponse(cmdName, e.Message);
var response = new FM2014CmdResponse(cmdName, e.Message);
PublishResponse(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
return false;

View File

@ -73,77 +73,180 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
private const String UNICODE_DC1 = "\u0011";
private const String UNICODE_DC2 = "\u0013";
/// <summary>
/// Assembly of command information and functional code
/// </summary>
internal struct Cmd
{
/// <summary>
/// Enumerator of command name acronym
/// </summary>
internal readonly CmdName CmdName;
/// <summary>
/// Code being sent to FM2014 as string
/// </summary>
internal readonly String CmdCodeStr;
/// <summary>
/// Command type regarding the address (broadcast or individual) and answer
/// </summary>
internal readonly CmdType CmdType;
/// <summary>
/// Command parameter style for raw data conversion from response string or for transmission
/// </summary>
internal readonly CmdParaFormat ParamFormat;
/// <summary>
/// Multilingual command information string
/// </summary>
internal readonly String CmdInfoStr;
/// <summary>
/// Single command table entry to combine the name with the code and the communication type
/// </summary>
/// <param name="cmdName">Enumerator of command name acronym</param>
/// <param name="cmdCodeStr">Code being sent to FM2014 as string</param>
/// <param name="cmdType">Command type regarding the address (broadcast or individual) and answer</param>
/// <param name="paraFormat">parameter format for conversion</param>
/// <param name="cmdInfoStr">Multilingual command information string</param>
internal Cmd(CmdName cmdName, String cmdCodeStr, CmdType cmdType, CmdParaFormat paraFormat,
String cmdInfoStr)
{
CmdName = cmdName;
CmdCodeStr = cmdCodeStr;
CmdType = cmdType;
ParamFormat = paraFormat;
CmdInfoStr = cmdInfoStr;
}
}
/// <summary>
/// Combine constant string returns from FM2014 firmware to multilingual information
/// </summary>
internal struct CmdErrorMsg
{
/// <summary>
/// Hard coded return string from FM2014
/// </summary>
internal String DeviceErrorReturnStr;
/// <summary>
/// Multilingual forwarded string to GUI
/// </summary>
internal String MultilingualForwardStr;
/// <summary>
/// Ctor
/// </summary>
/// <param name="fixedFwErrorStr"></param>
/// <param name="multilingualFeedback"></param>
internal CmdErrorMsg(String fixedFwErrorStr, String multilingualFeedback)
{
DeviceErrorReturnStr = fixedFwErrorStr;
MultilingualForwardStr = multilingualFeedback;
}
}
/// <summary>
/// Assembly of device status and multilingual information
/// </summary>
internal struct ConnectStatus
{
/// <summary>
/// Enumerator of command name acronym
/// </summary>
internal readonly ConnectStatusName Name;
/// <summary>
/// Multilingual information
/// </summary>
internal readonly String InfoStr;
/// <summary>
/// Single command table entry to combine the name with the code and the communication type
/// </summary>
/// <param name="deviceConnectStatusName"></param>
/// <param name="statusInfoStr">Multilingual command information string</param>
internal ConnectStatus(ConnectStatusName deviceConnectStatusName, String statusInfoStr)
{
Name = deviceConnectStatusName;
InfoStr = statusInfoStr;
}
}
/// <summary>
/// Command table for communication with FM2014 combines the name with the command code and additional info.
/// </summary>
public static readonly List<Cmd> CmdTbl = new List<Cmd>
internal static readonly List<Cmd> CmdTbl = new List<Cmd>
{
// FM2014 control and information
new Cmd(CmdName.CmdConnect, "", CmdType.individual, ParaFormat.parameterless, Resources.StrCmdMsgConnect),
new Cmd(CmdName.CmdUnlockErase, "&U@", CmdType.individual, ParaFormat.parameterless, Resources.StrCmdMsgUnlock),
new Cmd(CmdName.CmdEraseSerialNumber, "&E@", CmdType.individual, ParaFormat.parameterless, Resources.StrCmdMsgErase),
new Cmd(CmdName.CmdReadEepMeasSetup, "%D@", CmdType.individual, ParaFormat.parameterless, Resources.StrCmdMsgReadDefMeasSetup),
new Cmd(CmdName.CmdReadRamMeasSetup, "%A@", CmdType.individual, ParaFormat.parameterless, Resources.StrCmdMsgActualDefMeasSetup),
new Cmd(CmdName.CmdSaveRamToEepMeasSetup, "%S@", CmdType.individual, ParaFormat.parameterless, Resources.StrCmdMsgStoreDefMeasSetup),
new Cmd(CmdName.CmdSwitchToBootMode, "$B@", CmdType.individual, ParaFormat.parameterless, Resources.StrCmdMsgBootMode),
new Cmd(CmdName.CmdPrintAppInfo, "?A", CmdType.individual, ParaFormat.parameterless, Resources.StrCmdMsgPrintAppInfo),
new Cmd(CmdName.CmdPrintBootInfo, "?B", CmdType.individual, ParaFormat.parameterless, Resources.StrCmdMsgPrintBootInfo),
new Cmd(CmdName.CmdBaudratePc, "=BP", CmdType.individual, ParaFormat.uintDecimalValue, Resources.StrCmdMsgBaudrateAll),
new Cmd(CmdName.CmdGetVirtualAddress, " ", CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgGetVirtualAddress),
new Cmd(CmdName.CmdSerialNumber, "#", CmdType.individual, ParaFormat.uintDecimalValue, Resources.StrCmdMsgSerial),
new Cmd(CmdName.CmdGetStatus, UNICODE_ACK, CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgGetStatus),
new Cmd(CmdName.CmdSetVirtualAddress, "N", CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgSetVirtualAddress),
new Cmd(CmdName.CmdGetLifetime, "!", CmdType.individual, ParaFormat.stringValue, Resources.StrCmdMsgPrintStatistics),
new Cmd(CmdName.CmdConnect, "", CmdType.individual, CmdParaFormat.parameterless, Resources.StrCmdMsgConnect),
new Cmd(CmdName.CmdUnlockErase, "&U@", CmdType.individual, CmdParaFormat.parameterless, Resources.StrCmdMsgUnlock),
new Cmd(CmdName.CmdEraseSerialNumber, "&E@", CmdType.individual, CmdParaFormat.parameterless, Resources.StrCmdMsgErase),
new Cmd(CmdName.CmdReadEepMeasSetup, "%D@", CmdType.individual, CmdParaFormat.parameterless, Resources.StrCmdMsgReadDefMeasSetup),
new Cmd(CmdName.CmdReadRamMeasSetup, "%A@", CmdType.individual, CmdParaFormat.parameterless, Resources.StrCmdMsgActualDefMeasSetup),
new Cmd(CmdName.CmdSaveRamToEepMeasSetup, "%S@", CmdType.individual, CmdParaFormat.parameterless, Resources.StrCmdMsgStoreDefMeasSetup),
new Cmd(CmdName.CmdSwitchToBootMode, "$B@", CmdType.individual, CmdParaFormat.parameterless, Resources.StrCmdMsgBootMode),
new Cmd(CmdName.CmdPrintAppInfo, "?A", CmdType.individual, CmdParaFormat.parameterless, Resources.StrCmdMsgPrintAppInfo),
new Cmd(CmdName.CmdPrintBootInfo, "?B", CmdType.individual, CmdParaFormat.parameterless, Resources.StrCmdMsgPrintBootInfo),
new Cmd(CmdName.CmdBaudratePc, "=BP", CmdType.individual, CmdParaFormat.uintDecimalValue, Resources.StrCmdMsgBaudrateAll),
new Cmd(CmdName.CmdGetVirtualAddress, " ", CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgGetVirtualAddress),
new Cmd(CmdName.CmdSerialNumber, "#", CmdType.individual, CmdParaFormat.uintDecimalValue, Resources.StrCmdMsgSerial),
new Cmd(CmdName.CmdGetStatus, UNICODE_ACK, CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgGetStatus),
new Cmd(CmdName.CmdSetVirtualAddress, "N", CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgSetVirtualAddress),
new Cmd(CmdName.CmdGetLifetime, "!", CmdType.individual, CmdParaFormat.stringValue, Resources.StrCmdMsgPrintStatistics),
//measurement reset
new Cmd(CmdName.CmdResetMeasurement, "R", CmdType.broadcast, ParaFormat.parameterless, Resources.StrCmdMsgRstMeas),
new Cmd(CmdName.CmdResetMeasurement, "R", CmdType.broadcast, CmdParaFormat.parameterless, Resources.StrCmdMsgRstMeas),
// Double impulse detection settings
new Cmd(CmdName.CmdSetDoublePulseDeadtimeBase, "S", CmdType.broadcast, ParaFormat.uintDecimalValue, Resources.StrCmdMsgDplsLockTmr),
new Cmd(CmdName.CmdSetDoublePulseDeadtimeMultiplier, "s", CmdType.broadcast, ParaFormat.uintDecimalValue, Resources.StrCmdMsgDplsLockMult),
new Cmd(CmdName.CmdSwitchDoublePulseDeadtimeOff, "G", CmdType.broadcast, ParaFormat.parameterless, Resources.StrCmdMsgSetDbplUnlock),
new Cmd(CmdName.CmdSetDoublePulseDeadtimeBase, "S", CmdType.broadcast, CmdParaFormat.uintDecimalValue, Resources.StrCmdMsgDplsLockTmr),
new Cmd(CmdName.CmdSetDoublePulseDeadtimeMultiplier, "s", CmdType.broadcast, CmdParaFormat.uintDecimalValue, Resources.StrCmdMsgDplsLockMult),
new Cmd(CmdName.CmdSwitchDoublePulseDeadtimeOff, "G", CmdType.broadcast, CmdParaFormat.parameterless, Resources.StrCmdMsgSetDbplUnlock),
// Main measurement pulse settings and readout
new Cmd(CmdName.CmdSetDutPulsesRequired, "H", CmdType.broadcast, ParaFormat.uintHexValue, Resources.StrCmdMsgDutSetPls),
new Cmd(CmdName.CmdSetRefPulsesRequired, "M", CmdType.broadcast, ParaFormat.uintHexValue, Resources.StrCmdMsgRefSetPls),
new Cmd(CmdName.CmdGetDutPulsesRemaining, "I", CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgDutGetPlsRmn),
new Cmd(CmdName.CmdGetRefPulsesRemaining, "J", CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgRefGetPlsRmn),
new Cmd(CmdName.CmdSetDutPulsesRequired, "H", CmdType.broadcast, CmdParaFormat.uintHexValue, Resources.StrCmdMsgDutSetPls),
new Cmd(CmdName.CmdSetRefPulsesRequired, "M", CmdType.broadcast, CmdParaFormat.uintHexValue, Resources.StrCmdMsgRefSetPls),
new Cmd(CmdName.CmdGetDutPulsesRemaining, "I", CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgDutGetPlsRmn),
new Cmd(CmdName.CmdGetRefPulsesRemaining, "J", CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgRefGetPlsRmn),
// Pulse counters start, readout and backup
new Cmd(CmdName.CmdStartRefPulseCounter, "O", CmdType.broadcast, ParaFormat.parameterless, Resources.StrCmdMsgRefStrPlsCtr),
new Cmd(CmdName.CmdStartDutPulseCounter, "Q", CmdType.broadcast, ParaFormat.parameterless, Resources.StrCmdMsgDutStrPlsCtr),
new Cmd(CmdName.CmdGetRefPulsesCounted, "L", CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgRefGetPlsCtr),
new Cmd(CmdName.CmdGetDutPulsesCounted, "U", CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgDutGetPlsCtr),
new Cmd(CmdName.CmdGetRefPulsesCountedBackup, "l", CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgRefGetPlsCtrBu),
new Cmd(CmdName.CmdGetDutPulsesCountedBackup, "u", CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgDutGetPlsCtrBu),
new Cmd(CmdName.CmdStartRefAndDutPulseCounter, "o", CmdType.broadcast, ParaFormat.parameterless, Resources.StrCmdMsgRefDutStrPlsCtr),
new Cmd(CmdName.CmdBackupRefAndDutPulses, "q", CmdType.broadcast, ParaFormat.parameterless, Resources.StrCmdMsgRefDutBuPlsCtr),
new Cmd(CmdName.CmdStartRefPulseCounter, "O", CmdType.broadcast, CmdParaFormat.parameterless, Resources.StrCmdMsgRefStrPlsCtr),
new Cmd(CmdName.CmdStartDutPulseCounter, "Q", CmdType.broadcast, CmdParaFormat.parameterless, Resources.StrCmdMsgDutStrPlsCtr),
new Cmd(CmdName.CmdGetRefPulsesCounted, "L", CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgRefGetPlsCtr),
new Cmd(CmdName.CmdGetDutPulsesCounted, "U", CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgDutGetPlsCtr),
new Cmd(CmdName.CmdGetRefPulsesCountedBackup, "l", CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgRefGetPlsCtrBu),
new Cmd(CmdName.CmdGetDutPulsesCountedBackup, "u", CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgDutGetPlsCtrBu),
new Cmd(CmdName.CmdStartRefAndDutPulseCounter, "o", CmdType.broadcast, CmdParaFormat.parameterless, Resources.StrCmdMsgRefDutStrPlsCtr),
new Cmd(CmdName.CmdBackupRefAndDutPulses, "q", CmdType.broadcast, CmdParaFormat.parameterless, Resources.StrCmdMsgRefDutBuPlsCtr),
// General measurement setup
new Cmd(CmdName.CmdRefToDutScale, "K", CmdType.broadcast, ParaFormat.individual, Resources.StrCmdMsgRefSetScale),
new Cmd(CmdName.CmdSetDutPulsesPerCm, "V", CmdType.individualUnresponsive, ParaFormat.uintDecimalValue, Resources.StrCmdMsgDutLppScale),
new Cmd(CmdName.CmdSetRefPulsesPerCm, "W", CmdType.individualUnresponsive, ParaFormat.uintDecimalValue, Resources.StrCmdMsgRefLppScale),
new Cmd(CmdName.CmdSetCurrentOutputAttenuation, "T", CmdType.broadcast, ParaFormat.uintDecimalValue, Resources.StrCmdMsgMeasSetAttn),
new Cmd(CmdName.CmdRefToDutScale, "K", CmdType.broadcast, CmdParaFormat.individual, Resources.StrCmdMsgRefSetScale),
new Cmd(CmdName.CmdSetDutPulsesPerCm, "V", CmdType.individualUnresponsive, CmdParaFormat.uintDecimalValue, Resources.StrCmdMsgDutLppScale),
new Cmd(CmdName.CmdSetRefPulsesPerCm, "W", CmdType.individualUnresponsive, CmdParaFormat.uintDecimalValue, Resources.StrCmdMsgRefLppScale),
new Cmd(CmdName.CmdSetCurrentOutputAttenuation, "T", CmdType.broadcast, CmdParaFormat.uintDecimalValue, Resources.StrCmdMsgMeasSetAttn),
// Measurement result request
new Cmd(CmdName.CmdGetDutTimerTicks, "X", CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgDutGetTmr),
new Cmd(CmdName.CmdGetRefTimerTicks, "Y", CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgRefGetTmr),
new Cmd(CmdName.CmdCalculatedDutToRefTolerance, "", CmdType.individual, ParaFormat.doubleValue, Resources.StrCalDutToRefTol),
new Cmd(CmdName.CmdGetDutToRefToleranceUndamped, "Z", CmdType.individual, ParaFormat.byteHexValuePlusSign, Resources.StrCmdMsgGetUdtlc),
new Cmd(CmdName.CmdGetDutToRefToleranceDamped, "z", CmdType.individual, ParaFormat.byteHexValuePlusSign, Resources.StrCmdMsgGetDtlc),
new Cmd(CmdName.CmdGetRefPeriod, UNICODE_DLE, CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgGetRefPeriod),
new Cmd(CmdName.CmdGetDutPeriod, UNICODE_DC1, CmdType.individual,ParaFormat.uintHexValue, Resources.StrCmdMsgGetDutPeriod),
new Cmd(CmdName.CmdGetRefFrequency, UNICODE_DC2, CmdType.individual, ParaFormat.uintHexValue, Resources.StrCmdMsgGetRefFrequ),
new Cmd(CmdName.CmdCalculatedFrequRefPeriod, "", CmdType.individual, ParaFormat.doubleValue, Resources.StrCalRefFrequFromRefPeriod),
new Cmd(CmdName.CmdCalculatedFrequencyDutPeriod, "", CmdType.individual, ParaFormat.doubleValue, Resources.StrCalDutFrequFromDutPeriod),
new Cmd(CmdName.CmdCalculatedFlowRefFrequ, "", CmdType.individual, ParaFormat.doubleValue, Resources.StrCalRefFlowRateFromRefFrequ),
new Cmd(CmdName.CmdCalculatedFlowRefPeriod, "", CmdType.individual, ParaFormat.doubleValue, Resources.StrCalRefFlowRateFromRefPeriod),
new Cmd(CmdName.CmdCalculatedFlowDutPeriod, "", CmdType.individual, ParaFormat.doubleValue, Resources.StrCalDutFlowRateFromDutPeriod),
new Cmd(CmdName.CmdGetDutTimerTicks, "X", CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgDutGetTmr),
new Cmd(CmdName.CmdGetRefTimerTicks, "Y", CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgRefGetTmr),
new Cmd(CmdName.CmdCalculatedDutToRefTolerance, "", CmdType.individual, CmdParaFormat.doubleValue, Resources.StrCalDutToRefTol),
new Cmd(CmdName.CmdGetDutToRefToleranceUndamped, "Z", CmdType.individual, CmdParaFormat.byteHexValuePlusSign, Resources.StrCmdMsgGetUdtlc),
new Cmd(CmdName.CmdGetDutToRefToleranceDamped, "z", CmdType.individual, CmdParaFormat.byteHexValuePlusSign, Resources.StrCmdMsgGetDtlc),
new Cmd(CmdName.CmdGetRefPeriod, UNICODE_DLE, CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgGetRefPeriod),
new Cmd(CmdName.CmdGetDutPeriod, UNICODE_DC1, CmdType.individual,CmdParaFormat.uintHexValue, Resources.StrCmdMsgGetDutPeriod),
new Cmd(CmdName.CmdGetRefFrequency, UNICODE_DC2, CmdType.individual, CmdParaFormat.uintHexValue, Resources.StrCmdMsgGetRefFrequ),
new Cmd(CmdName.CmdCalculatedFrequRefPeriod, "", CmdType.individual, CmdParaFormat.doubleValue, Resources.StrCalRefFrequFromRefPeriod),
new Cmd(CmdName.CmdCalculatedFrequencyDutPeriod, "", CmdType.individual, CmdParaFormat.doubleValue, Resources.StrCalDutFrequFromDutPeriod),
new Cmd(CmdName.CmdCalculatedFlowRefFrequ, "", CmdType.individual, CmdParaFormat.doubleValue, Resources.StrCalRefFlowRateFromRefFrequ),
new Cmd(CmdName.CmdCalculatedFlowRefPeriod, "", CmdType.individual, CmdParaFormat.doubleValue, Resources.StrCalRefFlowRateFromRefPeriod),
new Cmd(CmdName.CmdCalculatedFlowDutPeriod, "", CmdType.individual, CmdParaFormat.doubleValue, Resources.StrCalDutFlowRateFromDutPeriod),
// Adjustment, place here Ids which may represent digital numbers from A to F
new Cmd(CmdName.CmdStartCurrentOffsetCorrection, "C", CmdType.broadcast, ParaFormat.parameterless, Resources.StrCmdMsgCorCurrent),
new Cmd(CmdName.CmdCurrentOutputMax, "+", CmdType.broadcast, ParaFormat.parameterless, Resources.StrCmdMsgSetXtrMax),
new Cmd(CmdName.CmdCurrentOutputMin, "-", CmdType.broadcast, ParaFormat.parameterless, Resources.StrCmdMsgSetXtrMin),
new Cmd(CmdName.CmdAddress, "A", CmdType.individual, ParaFormat.uintDecimalValue, Resources.StrCmdMsgAddrPc)
new Cmd(CmdName.CmdStartCurrentOffsetCorrection, "C", CmdType.broadcast, CmdParaFormat.parameterless, Resources.StrCmdMsgCorCurrent),
new Cmd(CmdName.CmdCurrentOutputMax, "+", CmdType.broadcast, CmdParaFormat.parameterless, Resources.StrCmdMsgSetXtrMax),
new Cmd(CmdName.CmdCurrentOutputMin, "-", CmdType.broadcast, CmdParaFormat.parameterless, Resources.StrCmdMsgSetXtrMin),
new Cmd(CmdName.CmdAddress, "A", CmdType.individual, CmdParaFormat.uintDecimalValue, Resources.StrCmdMsgAddrPc)
};
/// <summary>
/// Table of error codes received from FM2014
/// </summary>
public static readonly CmdErrorMsg[] CmdErrorCodes =
internal static readonly CmdErrorMsg[] CmdErrorCodes =
{
new CmdErrorMsg ("Parameter is out of range!", Resources.StrCmdRespErrorParamOutOfRange),
new CmdErrorMsg ("Command not supported!", Resources.StrCmdRespErrorCmdNotSupported),
@ -156,13 +259,13 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
/// <summary>
/// Translate the device connection status to multilingual answer
/// </summary>
public static readonly ConnectionStatus[] DeviceConnectionStati =
internal static readonly ConnectStatus[] DeviceConnectionStati =
{
new ConnectionStatus(ConnectionStatusName.unknown, "?"),
new ConnectionStatus(ConnectionStatusName.offline, "OFFLINE"),
new ConnectionStatus(ConnectionStatusName.standby, "STANDBY"),
new ConnectionStatus(ConnectionStatusName.online, "ONLINE"),
new ConnectionStatus(ConnectionStatusName.error, Resources.StrError)
new ConnectStatus(ConnectStatusName.unknown, "?"),
new ConnectStatus(ConnectStatusName.offline, "OFFLINE"),
new ConnectStatus(ConnectStatusName.standby, "STANDBY"),
new ConnectStatus(ConnectStatusName.online, "ONLINE"),
new ConnectStatus(ConnectStatusName.error, Resources.StrError)
};
/// <summary>
@ -188,7 +291,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
/// <remarks date="2026-Feb-03" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public static String GetConnectionStatusInfo(ConnectionStatusName name)
public static String GetConnectionStatusInfo(ConnectStatusName name)
{
return (from ct in DeviceConnectionStati
where ct.Name == name
@ -233,7 +336,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
/// <remarks date="2026-Feb-13" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public static ParaFormat GetParaFormat(CmdName cmdName)
public static CmdParaFormat GetParaFormat(CmdName cmdName)
{
return (from ct in CmdTbl
where ct.CmdName == cmdName

View File

@ -11,13 +11,14 @@
*********************************************************************************************************************/
using System;
using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts;
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
/// <summary>
/// Command response from FM2014
/// </summary>
public struct CmdResponse
public struct FM2014CmdResponse
{
/// <summary>
/// UTC timestamp
@ -57,7 +58,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co
/// <param name="intValue"></param>
/// <param name="doubleValue"></param>
/// <param name="unit"></param>
public CmdResponse(CmdName cmdName, String answerStr, UInt32? intValue = null, Double? doubleValue = null,
public FM2014CmdResponse(CmdName cmdName, String answerStr, UInt32? intValue = null, Double? doubleValue = null,
String unit = "")
{
TimestampUtc = DateTime.UtcNow;

View File

@ -282,15 +282,16 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Compile Include="ConnectionStatus.cs" />
<Compile Include="Consts\Cmd.cs" />
<Compile Include="Consts\CmdErrorMsg.cs" />
<Compile Include="Consts\CmdName.cs" />
<Compile Include="Consts\CmdResponse.cs" />
<Compile Include="FM2014CmdResponse.cs" />
<Compile Include="Consts\CmdType.cs" />
<Compile Include="Consts\ConnectionStatusName.cs" />
<Compile Include="Consts\ConnectStatusName.cs" />
<Compile Include="Consts\CyclicMeasSequ.cs" />
<Compile Include="Consts\ParaFormat.cs" />
<Compile Include="Consts\CmdParaFormat.cs" />
<Compile Include="Consts\ErrorStatus.cs" />
<Compile Include="Consts\Fault1Status.cs" />
<Compile Include="Consts\Fault2Status.cs" />
<Compile Include="Consts\MeasureStatus.cs" />
<Compile Include="FM2014CmdDef.cs" />
<Compile Include="FM2014.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

@ -1 +1 @@
Subproject commit 1cd877ff8628cdcb94a7ad2751d61dc77e1211da
Subproject commit 653498d43dcca1234a8fba95959ca02bb2c3f480

View File

@ -34,7 +34,7 @@
<appSettings>
<add key="Mode" value="1" /> <!--1 = EOL ; 2 = Picking-->
<add key="Mode" value="2" /> <!--1 = EOL ; 2 = Picking-->
</appSettings>

View File

@ -748,10 +748,10 @@ namespace Sensus.Ui.FM2014TestBench
if (!slotShallBeUsed || !fm2014.Connect(comPort))
{
ucFm2014Device.SetConnectionStatus(ConnectionStatusName.offline);
ucFm2014Device.SetConnectionStatus(ConnectStatusName.offline);
continue;
}
ucFm2014Device.SetConnectionStatus(ConnectionStatusName.online);
ucFm2014Device.SetConnectionStatus(ConnectStatusName.online);
if (!fm2014.IsLoggedOn)
{
@ -1192,7 +1192,7 @@ namespace Sensus.Ui.FM2014TestBench
SetTimeDisplay();
// Data dispatcher
var resp = (CmdResponse)e.SpecificInfoObj;
var resp = (FM2014CmdResponse)e.SpecificInfoObj;
String valueStr;
// Used as marker for error, null means measurement is in range or status or health is good
@ -2119,7 +2119,7 @@ namespace Sensus.Ui.FM2014TestBench
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks date="2026-Feb-09..Feb-18" author="Thomas Wiedebusch">
/// <remarks date="2026-Feb-09..Feb-24" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
private void tbxDutToRefToleranceMax_LostFocus(Object sender, EventArgs e)
@ -2139,7 +2139,7 @@ namespace Sensus.Ui.FM2014TestBench
var englishNumberFormat = tbxDutToRefTolMax.Text.Replace(',', '.');
if (double.TryParse(englishNumberFormat, NumberStyles.Any, new CultureInfo("en"), out var tolerance))
{
if (Math.Abs(backupDutToRefTolerance - tolerance) > 0.05)
if (Math.Abs(backupDutToRefTolerance - tolerance) > 0.01)
{
_programConfigurationSetupHasChanged = true;
// Preset to fill the configuration file storage ability
@ -2205,7 +2205,7 @@ namespace Sensus.Ui.FM2014TestBench
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks date="2026-Feb-09..Feb-18" author="Thomas Wiedebusch">
/// <remarks date="2026-Feb-09..Feb-24" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
private void tbxDutToRefToleranceMin_LostFocus(Object sender, EventArgs e)
@ -2225,7 +2225,7 @@ namespace Sensus.Ui.FM2014TestBench
var englishNumberFormat = tbxDutToRefTolMin.Text.Replace(',', '.');
if (double.TryParse(englishNumberFormat, NumberStyles.Any, new CultureInfo("en"), out var tolerance))
{
if (Math.Abs(backupDutToRefTolerance - tolerance) > 0.05)
if (Math.Abs(backupDutToRefTolerance - tolerance) > 0.01)
{
_programConfigurationSetupHasChanged = true;
// Preset to fill the configuration file storage ability
@ -2469,7 +2469,7 @@ namespace Sensus.Ui.FM2014TestBench
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks date="2026-Feb-09..18" author="Thomas Wiedebusch">
/// <remarks date="2026-Feb-09..24" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
private void tbxVolumeMeasuredLiters_LostFocus(Object sender, EventArgs e)
@ -2490,8 +2490,8 @@ namespace Sensus.Ui.FM2014TestBench
int.TryParse(tbxVolumeMeasuredLiters.Text, out var liters) && liters > 0)
{
// Calculate the new pulse ratio based on the manual calibration
var pulses_per_cm = (UInt32)(pulses / (liters / 1000.0) + 0.5);
var pulses_per_cm = FM2014.CalculatePulsesPerCm(pulses, liters);
// Try to set the new calculated REF pulses limited by the property setter
_fm2014Common.RefPulses_per_cm = pulses_per_cm;

View File

@ -81,7 +81,7 @@ namespace Sensus.Ui.Fm2014TestBench.UserControls
///<inheritdoc/>
public void Clear()
{
SetConnectionStatus(ConnectionStatusName.offline);
SetConnectionStatus(ConnectStatusName.offline);
HideMeasurements();
}
@ -125,7 +125,7 @@ namespace Sensus.Ui.Fm2014TestBench.UserControls
private void HideMeasurements()
{
UiElmEnable(brdFM2014Pic, true);
UiElmEnable(picFM2014, lblStatus.Content.Equals(ConnectionStatusName.online));
UiElmEnable(picFM2014, lblStatus.Content.Equals(ConnectStatusName.online));
// Hide all measurement borders
foreach (var borders in MeasurementBorders)
@ -156,7 +156,7 @@ namespace Sensus.Ui.Fm2014TestBench.UserControls
}
// Check if device is connected and logged in
if (!lblStatus.Content.Equals(GetConnectionStatusInfo(ConnectionStatusName.online)))
if (!lblStatus.Content.Equals(GetConnectionStatusInfo(ConnectStatusName.online)))
return false;
if (numberOfMeasurementFields == 0)
@ -187,16 +187,16 @@ namespace Sensus.Ui.Fm2014TestBench.UserControls
/// <remarks date="2026-Feb-03" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public void SetConnectionStatus(ConnectionStatusName statusName)
public void SetConnectionStatus(ConnectStatusName statusName)
{
var connectionStatusStr = GetConnectionStatusInfo(statusName);
Dispatcher.Invoke(DispatcherPriority.Send,
new Action(() =>
{
lblStatus.Content = connectionStatusStr;
var isEnabled = statusName.Equals(ConnectionStatusName.online);
var isEnabled = statusName.Equals(ConnectStatusName.online);
UiElmEnable(picFM2014, isEnabled);
if (!statusName.Equals(ConnectionStatusName.online))
if (!statusName.Equals(ConnectStatusName.online))
{
HideMeasurements();
lblStatus.Background = ColorStandardDisplayField;