From 5e15654b7effbb8ec096d420db62107003be00c3 Mon Sep 17 00:00:00 2001 From: Thomas Wiedebusch Date: Wed, 25 Feb 2026 16:54:54 +0100 Subject: [PATCH] FM2014: - status decoder --- .../FM2014/FM2014Config/FM2014Config.csproj | 2 +- .../FM2014Core/Consts/CyclicMeasSequ.cs | 8 +- .../FM2014/FM2014Core/Consts/ErrorStatus.cs | 46 --- .../FM2014/FM2014Core/Consts/Fault1Status.cs | 47 --- .../FM2014/FM2014Core/Consts/Fault2Status.cs | 31 -- .../FM2014/FM2014Core/Consts/MeasureStatus.cs | 56 --- .../FM2014/FM2014Core/FM2014.cs | 178 +++++---- .../FM2014/FM2014Core/FM2014CmdDef.cs | 370 +++++++++++++++++- .../FM2014/FM2014Core/FM2014Core.csproj | 4 - .../Properties/Resources.Designer.cs | 171 ++++++++ .../FM2014Core/Properties/Resources.de.resx | 57 +++ .../FM2014Core/Properties/Resources.resx | 57 +++ .../Ui/Fm2014sTest/FM2014TestBenchWindow.xaml | 4 +- .../Fm2014sTest/FM2014TestBenchWindow.xaml.cs | 53 ++- .../Ui/Fm2014sTest/Fm2014TestBench.csproj | 2 +- .../Ui/Fm2014sTest/Properties/AssemblyInfo.cs | 5 +- 16 files changed, 810 insertions(+), 281 deletions(-) delete mode 100644 Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/ErrorStatus.cs delete mode 100644 Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/Fault1Status.cs delete mode 100644 Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/Fault2Status.cs delete mode 100644 Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/MeasureStatus.cs diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Config/FM2014Config.csproj b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Config/FM2014Config.csproj index cfc2d86a..59835743 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Config/FM2014Config.csproj +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Config/FM2014Config.csproj @@ -11,7 +11,7 @@ Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Config v4.8.1 512 - false + true SAK SAK SAK diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/CyclicMeasSequ.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/CyclicMeasSequ.cs index f7f9d332..0335ccea 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/CyclicMeasSequ.cs +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/CyclicMeasSequ.cs @@ -20,22 +20,22 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// /// All measurements idle /// - idle, + Idle, /// /// Pulse counter measurements /// - pulseCounterMeasurement, + PulseCounterMeasurement, /// /// Regulation measurement ongoing /// - regulationMeasurement, + RegulationMeasurement, /// /// Calibration measurement ongoing /// - timeMeasurement + TimeMeasurement } } /*********************************************** END OF FILE *********************************************************/ \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/ErrorStatus.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/ErrorStatus.cs deleted file mode 100644 index aa55c103..00000000 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/ErrorStatus.cs +++ /dev/null @@ -1,46 +0,0 @@ -/*********************************************************************************************************************/ -/*! @file ErrorStatus.cs - * @brief FM2014 device error status - * - * @author Thomas Wiedebusch - * @date 2026-Feb-24 - * - * @details . - * - * @copyright © SENSUS GmbH 2026. All rights reserved. - *********************************************************************************************************************/ - -namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts -{ - /// - /// Error status returned from FM2014 with command '0x41 ' or 'UNICODE_ACK' as MSB - 1 - /// - public enum ErrorStatus - { - /// - /// REF signal timeout during the adjustment measurement for two consecutive pulses of 21.889 s - /// - AdjustMeasurementRefTimeout = 0x80, - - /// - /// DUT signal timeout during the adjustment measurement for two consecutive pulses of 21.889 s - /// - AdjustMeasurementDutTimeout = 0x40, - - /// - /// DUT double pulse detected during the time measurement - /// - TimeMeasurementDoublePulseDutDetected = 0x04, - - /// - /// REF signal timeout during the time measurement for two consecutive pulses of 21.889 s - /// - TimeMeasurementRefTimeout = 0x02, - - /// - /// REF signal timeout during the time measurement for two consecutive pulses of 21.889 s - /// - TimeMeasurementDutTimeout = 0x01 - } -} -/*********************************************** END OF FILE *********************************************************/ \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/Fault1Status.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/Fault1Status.cs deleted file mode 100644 index 04006941..00000000 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/Fault1Status.cs +++ /dev/null @@ -1,47 +0,0 @@ -/*********************************************************************************************************************/ -/*! @file Fault1Status.cs - * @brief FM2014 device fault1 status - * - * @author Thomas Wiedebusch - * @date 2026-Feb-24 - * - * @details . - * - * @copyright © SENSUS GmbH 2026. All rights reserved. - *********************************************************************************************************************/ - -namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts -{ - /// - /// Fault1 status returned from FM2014 with command '0x43 ' or 'UNICODE_ACK' as LSB - /// - public enum Fault1Status - { - /// - /// Error for U/I converter for the current output of the tolerance DUT to REF display - /// - ErrorUiConverterCurrentOutput = 0x40, - - /// - /// Setup of REF pulses is out of range command 'M' - /// - RefPulseSetupOor = 0x08, - - /// - /// Setup of DUT pulses is out of range command 'H' - /// - DutPulseSetupOor = 0x04, - - /// - /// Missing or out of range of the setup of the scale REF to DUT command 'K' - /// - MissingOrOorSetupScaleRefToDut = 0x02, - - /// - /// Missing or out of range of double pulse ignorance deadtime command 'G' or 's' and 'S' - /// - MissingOrOorSetupDoublePulesDeadtime = 0x01 - - } -} -/*********************************************** END OF FILE *********************************************************/ \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/Fault2Status.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/Fault2Status.cs deleted file mode 100644 index 2f2ada98..00000000 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/Fault2Status.cs +++ /dev/null @@ -1,31 +0,0 @@ -/*********************************************************************************************************************/ -/*! @file Fault2Status.cs - * @brief FM2014 device fault2 status - * - * @author Thomas Wiedebusch - * @date 2026-Feb-24 - * - * @details . - * - * @copyright © SENSUS GmbH 2026. All rights reserved. - *********************************************************************************************************************/ - -namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts -{ - /// - /// Fault2 status returned from FM2014 with command '0x43 ' or 'UNICODE_ACK' as LSB - /// - public enum Fault2Status - { - /// - /// FLASH access error causing parameters set to default - /// - FlashAccessError = 0x10, - - /// - /// Missing the setup for current output attenuation of the DUT to REF tolerance command 'T' - /// - MissingCurrentOutputAttenuation = 0x08, - } -} -/*********************************************** END OF FILE *********************************************************/ \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/MeasureStatus.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/MeasureStatus.cs deleted file mode 100644 index e7ad2dc9..00000000 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/MeasureStatus.cs +++ /dev/null @@ -1,56 +0,0 @@ -/*********************************************************************************************************************/ -/*! @file MeasureStatus.cs - * @brief FM2014 device measurement status - * - * @author Thomas Wiedebusch - * @date 2026-Feb-24 - * - * @details . - * - * @copyright © SENSUS GmbH 2026. All rights reserved. - *********************************************************************************************************************/ - -namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts -{ - /// - /// Measurement status returned from FM2014 with command '0x40 ' or 'UNICODE_ACK' as MSB - /// - public enum MeasureStatus - { - /// - /// Double pulse deadtime set to 0, means double pulse ignorance time is switched off - /// - DoublePulseDeadtimeInactive = 0x80, - - /// - /// Time measurement of REF has finished - /// - TimeMeasureRefRdy = 0x40, - - /// - /// Time measurement of DUT has finished - /// - TimeMeasureDutRdy = 0x20, - - /// - /// Time measurement of REF is ongoing - /// - TimeMeasureRefActive = 0x10, - - /// - /// Time measurement of DUT is ongoing - /// - TimeMeasureDutActive = 0x08, - - /// - /// Adjustment measurement of REF is finished - /// - AdjustMeasureRefRdy = 0x02, - - /// - /// Adjustment measurement of DUT is finished - /// - AdjustMeasureDutRdy = 0x01 - } -} -/*********************************************** END OF FILE *********************************************************/ \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs index ee1d07b5..e86a652c 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs @@ -198,6 +198,13 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core public event EventHandler OnRawRecordReceived; #endregion ---------------------------------------- events ---------------------------------------------------- #region ------------------------------------------- static properties ----------------------------------------- + + /// + /// Reminder of actual ongoing measurement information + /// + private static UInt32 StatusDecodingMask { get; set; } = STATUS_MEASURE_MASK | STATUS_ERROR_MASK | + STATUS_FAULT1_MASK | STATUS_FAULT2_MASK; + /// /// Reminder of actual ongoing measurement information /// @@ -336,7 +343,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core set { _address = value; - AddressStr = $"{ADDR_RECORD_STR}{_address}{ADDR_VALIDATION_STR}"; + AddressStr = $"{ADDR_RECORD_STR}{_address}{VALIDATION_STR}"; } } @@ -710,14 +717,14 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// public static Boolean ResetHardwareAllDevices() { - if (SharedCyclicMeasSequ == CyclicMeasSequ.idle) + if (SharedCyclicMeasSequ == CyclicMeasSequ.Idle) return true; if (BroadcastFm2014 == null) return false; // Exit tasks - SharedCyclicMeasSequ = CyclicMeasSequ.idle; + SharedCyclicMeasSequ = CyclicMeasSequ.Idle; // Schedule to other tasks to avoid side effects through the reset command Task.Factory.StartNew(() => @@ -761,7 +768,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// public static Boolean StoreAllConfigurations() { - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle || + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle || RegisteredFm2014s == null || RegisteredFm2014s.Count == 0 || RegisteredFm2014s.All(x => !x.IsLoggedOn)) @@ -861,6 +868,50 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core fm2014?.OnRawRecordReceived?.Invoke(fm2014, processExecEventArgs); } + /// + /// Set the mask for the FM2014 status decoding to multilingual output + /// + /// + /// + /// + public static void SetStatusDecodingMask(Boolean measMaskOn = true, Boolean errorMaskOn = true, + Boolean faultMaskOn = true) + { + StatusDecodingMask = 0; + if (measMaskOn) StatusDecodingMask += STATUS_MEASURE_MASK; + if (errorMaskOn) StatusDecodingMask += STATUS_ERROR_MASK; + if (faultMaskOn) StatusDecodingMask += (STATUS_FAULT1_MASK + STATUS_FAULT2_MASK); + } + + /// + /// Read, decoding and publish status to multilingual messages based on status decoding mask + /// + /// + /// + /// - Initial. + /// + private static void ReadDecodeAndPublishStatus(FM2014 fm2014) + { + var cmdName = CmdName.CmdGetStatus; + var cmdInfo = GetCmdInfo(cmdName); + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle && Write(cmdName, fm2014)) + { + if (Read(cmdName, fm2014, out _, out var status, out _)) + { + if (status != null) + { + var statusStrs = GetDecodedStatusInfos((UInt32)status, StatusDecodingMask); + foreach (var statusStr in statusStrs) + { + var info = $"{cmdInfo}: {statusStr}"; + var response = new FM2014CmdResponse(cmdName, info); + ResponseEvent(fm2014, response); + } + } + } + } + } + /// /// Common method to check and dispatch the double impulse deadtime to the FM2014. /// The commands will be dispatched as broadcast. @@ -932,23 +983,26 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// true if initialization successfully executed or /// marks the already started cyclic requests /// for all registered FM2014s - /// + /// /// - Initial. /// public static Boolean PulseCounterMeasurement(Boolean refPulseCtrOn, Boolean dutPulseCtrOn) { // If the cyclic task has already been started everything is fine - if (SharedCyclicMeasSequ == CyclicMeasSequ.pulseCounterMeasurement) + if (SharedCyclicMeasSequ == CyclicMeasSequ.PulseCounterMeasurement) return true; // Marked measurement isn't pulse counter measurement, other FM2014s cannot activate this - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle) + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle) return false; var firstActiveFm2014 = GetFirstConnectedAndLoggedInFm2014(); if (firstActiveFm2014 == null) return false; + // Setup status mask to ignore unimportant settings and feedbacks for the time and regulation measurement + StatusDecodingMask = GetBitMask(CyclicMeasSequ.PulseCounterMeasurement); + // Publish setting to all connected and logged in FM2014s as those will be delivered // for all via broadcast foreach (var fm2014 in RegisteredFm2014s.Where(fm2014 => fm2014.IsLoggedOn)) @@ -1007,7 +1061,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core { // Mark pulse counter measurement as active - SharedCyclicMeasSequ = CyclicMeasSequ.pulseCounterMeasurement; + SharedCyclicMeasSequ = CyclicMeasSequ.PulseCounterMeasurement; do { @@ -1034,7 +1088,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core var infoDut = GetCmdInfo(cmdNameDut); // Make a backup of the pulse counters to synchronize those and read out the backups - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && syncPulseCtr) + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle && syncPulseCtr) { // Synchronized backup of REF and DUT pulse counter Write(CmdName.CmdBackupRefAndDutPulses, firstActiveFm2014); @@ -1045,19 +1099,9 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core try { // Read the device status to check for timeout between pulses - cmdName = CmdName.CmdGetStatus; - var info = GetCmdInfo(cmdName); - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && Write(cmdName, fm2014)) - { - if (Read(cmdName, fm2014, out var responseStr, out var status, out _)) - { - info += $": {responseStr}"; - var response = new FM2014CmdResponse(cmdName, info, status); - ResponseEvent(fm2014, response); - } - } + ReadDecodeAndPublishStatus(fm2014); - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && fm2014.RefPulseCtrOn && Write(cmdNameRef, fm2014)) + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle && fm2014.RefPulseCtrOn && Write(cmdNameRef, fm2014)) { if (Read(cmdNameRef, fm2014, out _, out var intValue, out _)) { @@ -1066,7 +1110,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core } } - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && fm2014.DutPulseCtrOn && Write(cmdNameDut, fm2014)) + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle && fm2014.DutPulseCtrOn && Write(cmdNameDut, fm2014)) { if (Read(cmdNameDut, fm2014, out _, out var intValue, out _)) { @@ -1086,7 +1130,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core Thread.Sleep(THREAD_SLEEP_TIME_ms); } // loop all FM2014s - } while (SharedCyclicMeasSequ != CyclicMeasSequ.idle); + } while (SharedCyclicMeasSequ != CyclicMeasSequ.Idle); }, SharedCancellationToken).ContinueWith(delegate { foreach (var fm2014 in RegisteredFm2014s) @@ -1129,18 +1173,18 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// /// /// - /// + /// /// - Initial. /// public static Boolean RegulationMeasurement(UInt32 refPulses_per_cm, UInt16 dutPulses_per_cm, UInt16 doublePulseDeadtime_ms, Byte currentOutputAttenuation) { // If the cyclic task has already been started everything is fine - if (SharedCyclicMeasSequ == CyclicMeasSequ.regulationMeasurement) + if (SharedCyclicMeasSequ == CyclicMeasSequ.RegulationMeasurement) return true; // Marked measurement isn't pulse counter measurement, other FM2014s cannot activate this - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle) + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle) return false; // Initially, check if any device is connected and logged in, if not => exit @@ -1148,6 +1192,9 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core if (firstActiveFm2014 == null) return false; + // Setup status mask to ignore unimportant settings and feedbacks for the time measurement + StatusDecodingMask = GetBitMask(CyclicMeasSequ.RegulationMeasurement); + // Publish setting to all connected and logged in FM2014s as those will be delivered // for all via broadcast foreach (var fm2014 in RegisteredFm2014s.Where(fm2014 => fm2014.IsLoggedOn)) @@ -1204,7 +1251,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core Task.Run(() => { // Mark regulation measurement as active - SharedCyclicMeasSequ = CyclicMeasSequ.regulationMeasurement; + SharedCyclicMeasSequ = CyclicMeasSequ.RegulationMeasurement; do { @@ -1214,23 +1261,13 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core { StatusReturn statusReturn; // Read the device status to check for timeout between pulses - cmdName = CmdName.CmdGetStatus; - var info = GetCmdInfo(cmdName); - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && Write(cmdName, fm2014)) - { - if (Read(cmdName, fm2014, out var responseStr, out var status, out _)) - { - info += $": {responseStr}"; - var response = new FM2014CmdResponse(cmdName, info, status); - ResponseEvent(fm2014, response); - } - } + ReadDecodeAndPublishStatus(fm2014); // Read out the damped/undamped tolerance and convert the raw value (0, +/-1..255 digits) to the // tolerance in percent depending on the setup to 3 % (3.3) of 5 % (5.5) cmdName = fm2014.UseDampedTolerance ? CmdName.CmdGetDutToRefToleranceDamped : CmdName.CmdGetDutToRefToleranceUndamped; - info = GetCmdInfo(cmdName); - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && Write(cmdName, fm2014)) + var info = GetCmdInfo(cmdName); + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle && Write(cmdName, fm2014)) { if (Read(cmdName, fm2014, out _, out _, out var doubleValue)) { @@ -1253,7 +1290,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core // Read the REF period and calculate the frequency [Hz] and flow rate [m³/h] based on this period cmdName = CmdName.CmdGetRefPeriod; info = GetCmdInfo(cmdName); - if (fm2014.RequestDebugInformation && SharedCyclicMeasSequ != CyclicMeasSequ.idle && + if (fm2014.RequestDebugInformation && SharedCyclicMeasSequ != CyclicMeasSequ.Idle && Write(cmdName, fm2014)) { if (Read(cmdName, fm2014, out _, out var period, out _)) @@ -1288,7 +1325,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core cmdName = CmdName.CmdGetDutPeriod; info = GetCmdInfo(cmdName); if (fm2014.RequestDebugInformation && - SharedCyclicMeasSequ != CyclicMeasSequ.idle && + SharedCyclicMeasSequ != CyclicMeasSequ.Idle && Write(cmdName, fm2014)) { if (Read(cmdName, fm2014, out _, out var period, out _)) @@ -1321,7 +1358,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core // Read the REF frequency [Hz] directly and calculate the flow rate [m³/h] based on this frequency cmdName = CmdName.CmdGetRefFrequency; info = GetCmdInfo(cmdName); - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && Write(cmdName, fm2014)) + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle && Write(cmdName, fm2014)) { if (Read(cmdName, fm2014, out _, out var refFrequency, out _)) { @@ -1357,7 +1394,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core Thread.Sleep(THREAD_SLEEP_TIME_ms); } // loop all FM2014s - } while (SharedCyclicMeasSequ != CyclicMeasSequ.idle); + } while (SharedCyclicMeasSequ != CyclicMeasSequ.Idle); }, SharedCancellationToken); @@ -1395,18 +1432,18 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// 0 if double impulse deadtime detection is off /// /// - /// + /// /// - Initial. /// public static Boolean PulseTimeMeasurement(UInt16? refPulsesRequired = null, UInt16? dutPulsesRequired = null, UInt16 doublePulseDeadtime_ms = 0) { // If the cyclic task has already been started everything is fine - if (SharedCyclicMeasSequ == CyclicMeasSequ.timeMeasurement) + if (SharedCyclicMeasSequ == CyclicMeasSequ.TimeMeasurement) return true; // Marked measurement isn't pulse counter measurement, other FM2014s cannot activate this - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle) + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle) return false; // Initially, check if any device is connected and logged in, if not => exit @@ -1423,6 +1460,9 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core return false; } + // Setup status mask to ignore unimportant settings for this measurement 'T' and 'K' + StatusDecodingMask = GetBitMask(CyclicMeasSequ.TimeMeasurement); + // Publish setting to all connected and logged in FM2014s as those will be delivered // for all via broadcast foreach (var fm2014 in RegisteredFm2014s.Where(fm2014 => fm2014.IsLoggedOn)) @@ -1486,7 +1526,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core Task.Run(() => { // Mark calibration measurement as active - SharedCyclicMeasSequ = CyclicMeasSequ.timeMeasurement; + SharedCyclicMeasSequ = CyclicMeasSequ.TimeMeasurement; // Set up the progress maximal counter value base on required pulses for REF or DUT InitActualProcessProgress(refPulsesRequired != null ? (Int32)firstActiveFm2014.RefPulsesRequired : @@ -1500,24 +1540,14 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core { StatusReturn statusReturn; // Read the device status to check for timeout between pulses - cmdName = CmdName.CmdGetStatus; - var info = GetCmdInfo(cmdName); - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && Write(cmdName, fm2014)) - { - if (Read(cmdName, fm2014, out var responseStr, out var status, out _)) - { - info += $": {responseStr}"; - var response = new FM2014CmdResponse(cmdName, info, status); - ResponseEvent(fm2014, response); - } - } + ReadDecodeAndPublishStatus(fm2014); // Read the remaining REF pulses if required if (refPulsesRequired != null) { cmdName = CmdName.CmdGetRefPulsesRemaining; - info = GetCmdInfo(cmdName); - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && Write(cmdName, fm2014)) + var info = GetCmdInfo(cmdName); + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle && Write(cmdName, fm2014)) { if (Read(cmdName, fm2014, out _, out var pulses, out _)) { @@ -1549,8 +1579,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core if (dutPulsesRequired != null) { cmdName = CmdName.CmdGetDutPulsesRemaining; - info = GetCmdInfo(cmdName); - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && Write(cmdName, fm2014)) + var info = GetCmdInfo(cmdName); + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle && Write(cmdName, fm2014)) { if (Read(cmdName, fm2014, out _, out var pulses, out _)) { @@ -1589,8 +1619,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core if (refPulsesRequired != null) { cmdName = CmdName.CmdGetRefTimerTicks; - info = GetCmdInfo(cmdName); - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && Write(cmdName, fm2014)) + var info = GetCmdInfo(cmdName); + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle && Write(cmdName, fm2014)) { if (Read(cmdName, fm2014, out _, out var timerTicks, out _)) { @@ -1611,8 +1641,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core if (dutPulsesRequired != null) { cmdName = CmdName.CmdGetDutTimerTicks; - info = GetCmdInfo(cmdName); - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle && Write(cmdName, fm2014)) + var info = GetCmdInfo(cmdName); + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle && Write(cmdName, fm2014)) { if (Read(cmdName, fm2014, out _, out var timerTicks, out _)) { @@ -1633,7 +1663,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core if (refPulsesRequired != null && dutPulsesRequired != null) { cmdName = CmdName.CmdCalculatedDutToRefTolerance; - info = GetCmdInfo(cmdName); + var info = GetCmdInfo(cmdName); // Is converting to a real time in seconds if (fm2014.RefTimeMeasured_s > 0.0) { @@ -1677,9 +1707,9 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core { ResetHardwareAllDevices(); // Exit this task - SharedCyclicMeasSequ = CyclicMeasSequ.idle; + SharedCyclicMeasSequ = CyclicMeasSequ.Idle; } - } while (SharedCyclicMeasSequ != CyclicMeasSequ.idle); + } while (SharedCyclicMeasSequ != CyclicMeasSequ.Idle); }, SharedCancellationToken); @@ -1819,7 +1849,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core { SharedCmdTypeReminderLastCmd = CmdType.uninitialized; fm2014.IsLoggedOn = false; - SharedCyclicMeasSequ = CyclicMeasSequ.idle; + SharedCyclicMeasSequ = CyclicMeasSequ.Idle; return false; } if (!DisableWriteReadActualProcessIncreasing) @@ -2111,7 +2141,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core { // If the cyclic task has already been started the login isn't allowed anymore // until this has been finished - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle) + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle) return false; return InitiateIndividualComm(this); @@ -2127,7 +2157,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core private Boolean SaveStandAloneMeasurement() { // If the cyclic task has already been started everything is fine - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle || !IsLoggedOn) + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle || !IsLoggedOn) return false; var cmdName = CmdName.CmdSetRefPulsesPerCm; @@ -2190,7 +2220,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core private Boolean ReadStandAloneMeasurement(CmdName cmdName) { // If the cyclic task has already been started everything is fine - if (SharedCyclicMeasSequ != CyclicMeasSequ.idle || !IsLoggedOn) + if (SharedCyclicMeasSequ != CyclicMeasSequ.Idle || !IsLoggedOn) return false; // Allow explicit standalone measurement commands diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014CmdDef.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014CmdDef.cs index 47b6d1dd..45211623 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014CmdDef.cs +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014CmdDef.cs @@ -36,7 +36,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// /// Address assignment validation behind the address number /// - public const String ADDR_VALIDATION_STR = "@"; + public const String VALIDATION_STR = "@"; /// /// Partial search string for @@ -65,7 +65,25 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// /// Broadcast address definition /// - public static readonly String BROADCAST_ADDRESS = $"{ADDR_RECORD_STR}0{ADDR_VALIDATION_STR}"; + public static readonly String BROADCAST_ADDRESS = $"{ADDR_RECORD_STR}0{VALIDATION_STR}"; + + /// + /// Status mask for measurement + /// + public const UInt32 STATUS_MEASURE_MASK = 0xFF000000; + /// + /// Status mask for error + /// + public const UInt32 STATUS_ERROR_MASK = 0x00FF0000; + /// + /// Status mask for fault1 + /// + public const UInt32 STATUS_FAULT1_MASK = 0x0000FF00; + /// + /// Status mask for fault2 + /// + public const UInt32 STATUS_FAULT2_MASK = 0x000000FF; + // Unicode Strings for command table private const String UNICODE_ACK = "\u0006"; @@ -175,6 +193,233 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core InfoStr = statusInfoStr; } } + /// + /// Measurement status returned from FM2014 with command '0x40 ' or 'UNICODE_ACK' as MSB + /// + internal enum MeasureStatusName + { + /// + /// Double pulse deadtime set to 0, means double pulse ignorance time is switched off + /// + DoublePulseDeadtimeInactive = 0x80, + + /// + /// Time measurement of REF has finished + /// + TimeMeasureRefRdy = 0x40, + + /// + /// Time measurement of DUT has finished + /// + TimeMeasureDutRdy = 0x20, + + /// + /// Time measurement of REF is ongoing + /// + TimeMeasureRefActive = 0x10, + + /// + /// Time measurement of DUT is ongoing + /// + TimeMeasureDutActive = 0x08, + + /// + /// Adjustment measurement of REF is finished + /// + AdjustMeasureRefRdy = 0x02, + + /// + /// Adjustment measurement of DUT is finished + /// + AdjustMeasureDutRdy = 0x01 + } + + /// + /// Combine measure status name from FM2014 firmware to multilingual information + /// + internal struct MeasureStatus + { + /// + /// Hard coded measure status returned from FM2014 + /// + internal readonly MeasureStatusName StatusName; + + /// + /// Multilingual forwarded string to GUI + /// + internal readonly String MultilingualStr; + + /// + /// Ctor + /// + /// + /// + internal MeasureStatus(MeasureStatusName statusName, String multilingualFeedback) + { + StatusName = statusName; + MultilingualStr = multilingualFeedback; + } + } + + /// + /// Error status returned from FM2014 with command '0x41 ' or 'UNICODE_ACK' as MSB - 1 + /// + internal enum ErrorStatusName + { + /// + /// REF signal timeout during the adjustment measurement for two consecutive pulses of 21.889 s + /// + AdjustMeasurementRefTimeout = 0x80, + + /// + /// DUT signal timeout during the adjustment measurement for two consecutive pulses of 21.889 s + /// + AdjustMeasurementDutTimeout = 0x40, + + /// + /// DUT double pulse detected during the time measurement + /// + TimeMeasurementDoublePulseDutDetected = 0x04, + + /// + /// REF signal timeout during the time measurement for two consecutive pulses of 21.889 s + /// + TimeMeasurementRefTimeout = 0x02, + + /// + /// REF signal timeout during the time measurement for two consecutive pulses of 21.889 s + /// + TimeMeasurementDutTimeout = 0x01 + } + + /// + /// Combine error status name from FM2014 firmware to multilingual information + /// + internal struct ErrorStatus + { + /// + /// Hard coded error status returned from FM2014 + /// + internal readonly ErrorStatusName StatusName; + + /// + /// Multilingual forwarded string to GUI + /// + internal readonly String MultilingualStr; + + /// + /// Ctor + /// + /// + /// + internal ErrorStatus(ErrorStatusName statusName, String multilingualFeedback) + { + StatusName = statusName; + MultilingualStr = multilingualFeedback; + } + } + + /// + /// Fault1 status returned from FM2014 with command '0x43 ' or 'UNICODE_ACK' as LSB + /// + internal enum Fault1StatusName + { + /// + /// Error for U/I converter for the current output of the tolerance DUT to REF display + /// + ErrorUiConverterCurrentOutput = 0x40, + + /// + /// Setup of REF pulses is out of range command 'M' + /// + RefPulseSetupOor = 0x08, + + /// + /// Setup of DUT pulses is out of range command 'H' + /// + DutPulseSetupOor = 0x04, + + /// + /// Missing or out of range of the setup of the scale REF to DUT command 'K' + /// + MissingOrOorSetupScaleRefToDut = 0x02, + + /// + /// Missing or out of range of double pulse ignorance deadtime command 'G' or 's' and 'S' + /// + MissingOrOorSetupDoublePulesDeadtime = 0x01 + } + + /// + /// Combine fault1 status name from FM2014 firmware to multilingual information + /// + internal struct Fault1Status + { + /// + /// Hard coded fault1 status returned from FM2014 + /// + internal readonly Fault1StatusName StatusName; + + /// + /// Multilingual forwarded string to GUI + /// + internal readonly String MultilingualStr; + + /// + /// Ctor + /// + /// + /// + internal Fault1Status(Fault1StatusName statusName, String multilingualFeedback) + { + StatusName = statusName; + MultilingualStr = multilingualFeedback; + } + } + + /// + /// Fault2 status returned from FM2014 with command '0x43 ' or 'UNICODE_ACK' as LSB + /// + internal enum Fault2StatusName + { + /// + /// FLASH access error causing parameters set to default + /// + FlashAccessError = 0x10, + + /// + /// Missing the setup for current output attenuation of the DUT to REF tolerance command 'T' + /// + MissingToleranceDisplayAttenuation = 0x08, + } + + /// + /// Combine fault2 status name from FM2014 firmware to multilingual information + /// + internal struct Fault2Status + { + /// + /// Hard coded fault2 status returned from FM2014 + /// + internal readonly Fault2StatusName StatusName; + + /// + /// Multilingual forwarded string to GUI + /// + internal readonly String MultilingualStr; + + /// + /// Ctor + /// + /// + /// + internal Fault2Status(Fault2StatusName statusName, String multilingualFeedback) + { + StatusName = statusName; + MultilingualStr = multilingualFeedback; + } + } + /// /// Command table for communication with FM2014 combines the name with the command code and additional info. @@ -268,6 +513,57 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core new ConnectStatus(ConnectStatusName.error, Resources.StrError) }; + /// + /// Measurement status collection to return multilingual answer + /// + internal static readonly MeasureStatus[] MeasureStati = + { + new MeasureStatus(MeasureStatusName.DoublePulseDeadtimeInactive, Resources.StrStatusMeasDoublePulseDeadtimeInactive), + new MeasureStatus(MeasureStatusName.TimeMeasureRefRdy, Resources.StrStatusMeasTimeMeasureRefRdy), + new MeasureStatus(MeasureStatusName.TimeMeasureDutRdy, Resources.StrStatusMeasTimeMeasureDutRdy), + new MeasureStatus(MeasureStatusName.TimeMeasureRefActive, Resources.StrStatusMeasTimeMeasureRefActive), + new MeasureStatus(MeasureStatusName.TimeMeasureDutActive, Resources.StrStatusMeasTimeMeasureDutActive), + new MeasureStatus(MeasureStatusName.AdjustMeasureRefRdy, Resources.StrStatusMeasAdjustMeasureRefRdy), + new MeasureStatus(MeasureStatusName.AdjustMeasureDutRdy, Resources.StrStatusMeasAdjustMeasureDutRdy) + }; + + /// + /// Error status collection to return multilingual answer + /// + internal static readonly ErrorStatus[] ErrorStati = + { + new ErrorStatus(ErrorStatusName.AdjustMeasurementRefTimeout, Resources.StrStatusErrorAdjustMeasureRefTimeout), + new ErrorStatus(ErrorStatusName.AdjustMeasurementDutTimeout, Resources.StrStatusErrorAdjustMeasureDutTimeout), + new ErrorStatus(ErrorStatusName.TimeMeasurementDoublePulseDutDetected, + Resources.StrStatusErrorDoublePulseOnDutDetected), + new ErrorStatus(ErrorStatusName.TimeMeasurementRefTimeout, Resources.StrStatusErrorTimeMeasureRefTimeout), + new ErrorStatus(ErrorStatusName.TimeMeasurementDutTimeout, Resources.StrStatusErrorTimeMeasureRefTimeout) + }; + + /// + /// Fault1 status collection to return multilingual answer + /// + internal static readonly Fault1Status[] Fault1Stati = + { + new Fault1Status(Fault1StatusName.ErrorUiConverterCurrentOutput, Resources.StrStatusFault1UiConverter), + new Fault1Status(Fault1StatusName.RefPulseSetupOor, Resources.StrStatusFault1RefPulseSetupOor), + new Fault1Status(Fault1StatusName.DutPulseSetupOor, Resources.StrStatusFault1DutPulseSetupOor), + new Fault1Status(Fault1StatusName.MissingOrOorSetupScaleRefToDut, + Resources.StrStatusFault1ScaleRefToDutMissingOrOor), + new Fault1Status(Fault1StatusName.MissingOrOorSetupDoublePulesDeadtime, + Resources.StrStatusFault1DoublePulseDeadtimeMissingOrOor) + }; + + /// + /// Fault1 status collection to return multilingual answer + /// + internal static readonly Fault2Status[] Fault2Stati = + { + new Fault2Status(Fault2StatusName.FlashAccessError, Resources.StrStatusFault2FlashAccessError), + new Fault2Status(Fault2StatusName.MissingToleranceDisplayAttenuation, + Resources.StrStatusFault2MissingToleranceAttenuation) + }; + /// /// Get String command code from command name /// @@ -342,5 +638,75 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core where ct.CmdName == cmdName select ct.ParamFormat).FirstOrDefault(); } + + /// + /// Decoding the status unsigned double word using the mask to select the appropriate fields + /// + /// + /// + /// + public static List GetDecodedStatusInfos(UInt32 status, UInt32 statusMask = 0xFFFFFFFF) + { + var responseStrs = new List(); + status &= statusMask; + var measureStati = (status >> 24) & 0xFF; + var errorStati = (status >> 16) & 0xFF; + var fault1Stati = (status >> 8) & 0xFF; + var fault2Stati = status & 0xFF; + + foreach (var s in MeasureStati) + { + if (((UInt32)s.StatusName & measureStati) == (UInt32)s.StatusName) + { + responseStrs.Add(s.MultilingualStr); + } + } + + foreach (var s in ErrorStati) + { + if (((UInt32)s.StatusName & errorStati) == (UInt32)s.StatusName) + { + responseStrs.Add(s.MultilingualStr); + } + } + + foreach (var s in Fault1Stati) + { + if (((UInt32)s.StatusName & fault1Stati) == (UInt32)s.StatusName) + { + responseStrs.Add(s.MultilingualStr); + } + } + + foreach (var s in Fault2Stati) + { + if (((UInt32)s.StatusName & fault2Stati) == (UInt32)s.StatusName) + { + responseStrs.Add(s.MultilingualStr); + } + } + + return responseStrs; + } + + /// + /// Get the required status mask for different measurement sequences to ignore unimportant + /// stati feedback of unused setting. + /// + /// + /// + public static UInt32 GetBitMask(CyclicMeasSequ sequence) + { + if (sequence == CyclicMeasSequ.TimeMeasurement) + return 0xF8074D10; + + if (sequence == CyclicMeasSequ.RegulationMeasurement) + return 0x83C04318; + + if (sequence == CyclicMeasSequ.PulseCounterMeasurement) + return 0x80004010; + + return 0xFFFFFFFF; + } } } diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014Core.csproj b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014Core.csproj index 52fa01af..06167dd0 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014Core.csproj +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014Core.csproj @@ -288,10 +288,6 @@ - - - - diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.Designer.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.Designer.cs index 0dd367f9..7add7c0f 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.Designer.cs +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.Designer.cs @@ -708,5 +708,176 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Pr return ResourceManager.GetString("StrMeasMsgStanaloneRegulation", resourceCulture); } } + + /// + /// Looks up a localized string similar to Regulation measurement DUT signal timeout. + /// + internal static string StrStatusErrorAdjustMeasureDutTimeout { + get { + return ResourceManager.GetString("StrStatusErrorAdjustMeasureDutTimeout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Regulation measurement REF signal timeout. + /// + internal static string StrStatusErrorAdjustMeasureRefTimeout { + get { + return ResourceManager.GetString("StrStatusErrorAdjustMeasureRefTimeout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time measurement double pulse on DUT detected. + /// + internal static string StrStatusErrorDoublePulseOnDutDetected { + get { + return ResourceManager.GetString("StrStatusErrorDoublePulseOnDutDetected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time measurement DUT signal timeout. + /// + internal static string StrStatusErrorTimeMeasureDutTimeout { + get { + return ResourceManager.GetString("StrStatusErrorTimeMeasureDutTimeout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time measurement REF signal timeout. + /// + internal static string StrStatusErrorTimeMeasureRefTimeout { + get { + return ResourceManager.GetString("StrStatusErrorTimeMeasureRefTimeout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Double pulse deadtime missing or out of range. + /// + internal static string StrStatusFault1DoublePulseDeadtimeMissingOrOor { + get { + return ResourceManager.GetString("StrStatusFault1DoublePulseDeadtimeMissingOrOor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Required pulses DUT setup out of range. + /// + internal static string StrStatusFault1DutPulseSetupOor { + get { + return ResourceManager.GetString("StrStatusFault1DutPulseSetupOor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Required pulses REF setup out of range. + /// + internal static string StrStatusFault1RefPulseSetupOor { + get { + return ResourceManager.GetString("StrStatusFault1RefPulseSetupOor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Scale REF to DUT missing or out of range. + /// + internal static string StrStatusFault1ScaleRefToDutMissingOrOor { + get { + return ResourceManager.GetString("StrStatusFault1ScaleRefToDutMissingOrOor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tolerance display error. + /// + internal static string StrStatusFault1UiConverter { + get { + return ResourceManager.GetString("StrStatusFault1UiConverter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to FLASH access error, setups set to default. + /// + internal static string StrStatusFault2FlashAccessError { + get { + return ResourceManager.GetString("StrStatusFault2FlashAccessError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tolerance display attenuation missing. + /// + internal static string StrStatusFault2MissingToleranceAttenuation { + get { + return ResourceManager.GetString("StrStatusFault2MissingToleranceAttenuation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Regulation measurement DUT ready. + /// + internal static string StrStatusMeasAdjustMeasureDutRdy { + get { + return ResourceManager.GetString("StrStatusMeasAdjustMeasureDutRdy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Regulation measurement REF ready. + /// + internal static string StrStatusMeasAdjustMeasureRefRdy { + get { + return ResourceManager.GetString("StrStatusMeasAdjustMeasureRefRdy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Double pulse deadtime inactive. + /// + internal static string StrStatusMeasDoublePulseDeadtimeInactive { + get { + return ResourceManager.GetString("StrStatusMeasDoublePulseDeadtimeInactive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time measurement DUT active. + /// + internal static string StrStatusMeasTimeMeasureDutActive { + get { + return ResourceManager.GetString("StrStatusMeasTimeMeasureDutActive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time measurement DUT ready. + /// + internal static string StrStatusMeasTimeMeasureDutRdy { + get { + return ResourceManager.GetString("StrStatusMeasTimeMeasureDutRdy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time measurement REF active. + /// + internal static string StrStatusMeasTimeMeasureRefActive { + get { + return ResourceManager.GetString("StrStatusMeasTimeMeasureRefActive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time measurement REF ready. + /// + internal static string StrStatusMeasTimeMeasureRefRdy { + get { + return ResourceManager.GetString("StrStatusMeasTimeMeasureRefRdy", resourceCulture); + } + } } } diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.de.resx b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.de.resx index 12f561c7..d6f74a59 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.de.resx +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.de.resx @@ -333,4 +333,61 @@ Doppelimpulstotzeit + + Doppelimpulstotzeit inaktiv + + + Zeitmessungsmessung REF fertig + + + Zeitmessungsmessung DUT fertig + + + Zeitmessungsmessung REF aktiv + + + Zeitmessungsmessung DUT aktiv + + + Regulierungsmessung REF fertig + + + Regulierungsmessung DUT fertig + + + FLASH Zugriffsfehler, Einstellungen auf Standard + + + Fehlende oder falsche Toleranzanzeigendämpfungseinstellung + + + Toleranzanzeigenfehler + + + Bereichsüberschreitung Impulszähler REF + + + Bereichsüberschreitung Impulszähler DUT + + + Falsche oder fehlende Skalierung REF zu DUT + + + Fehlerhafte Doppelimpulstotzeit + + + Regulierungsmessung REF Signaltimeout + + + Regulierungsmessung DUT Signaltimeout + + + Zeitmessung REF Signaltimeout + + + Zeitmessung DUT Signaltimeout + + + Zeitmessung Doppelimpuls DUT erkannt + \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.resx b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.resx index 759b2cfa..30cfd14a 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.resx +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.resx @@ -333,4 +333,61 @@ Double pulse daedtime + + Double pulse deadtime inactive + + + Time measurement REF ready + + + Time measurement DUT ready + + + Time measurement REF active + + + Time measurement DUT active + + + Regulation measurement REF ready + + + Regulation measurement DUT ready + + + FLASH access error, setups set to default + + + Tolerance display attenuation missing + + + Tolerance display error + + + Required pulses REF setup out of range + + + Required pulses DUT setup out of range + + + Scale REF to DUT missing or out of range + + + Double pulse deadtime missing or out of range + + + Regulation measurement REF signal timeout + + + Regulation measurement DUT signal timeout + + + Time measurement REF signal timeout + + + Time measurement DUT signal timeout + + + Time measurement double pulse on DUT detected + \ No newline at end of file diff --git a/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml b/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml index ff600047..39d705df 100644 --- a/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml +++ b/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml @@ -266,8 +266,8 @@ - - + + diff --git a/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml.cs b/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml.cs index 10678e6d..803e8104 100644 --- a/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml.cs +++ b/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml.cs @@ -464,9 +464,12 @@ namespace Sensus.Ui.FM2014TestBench ClearInfoWindow(); if (_version != null) { - var version = $"Version: {_version.Major}.{_version.Minor}.{_version.Build}"; + // Logging to history window + var timeUtc = DateTime.UtcNow; + var timeUtcStr = $"{timeUtc:yyyy-MM-dd HH:mm:ss:fff} UTC"; + var version = $"Version: {_version}"; Title = $@"FM2014 Test Bench - {version}"; - LogText($"FM2014 Test Bench: {version}"); + LogText($"{timeUtcStr} - FM2014 Test Bench: {version}"); LogText(StrSeparator); } @@ -762,10 +765,13 @@ namespace Sensus.Ui.FM2014TestBench if (fm2014.IsLoggedOn) { // Logging to history window + var timeUtc = DateTime.UtcNow; + var timeUtcStr = $"{timeUtc:yyyy-MM-dd HH:mm:ss:fff} UTC"; + LogText(StrSeparator); - LogText($"Ad: {fm2014.Address} - FM2014 ID: {fm2014.ConnectResponse}"); - LogText($"Ad: {fm2014.Address} - FM2014 Firmware Version: {fm2014.FwVersion}"); - LogText($"Ad: {fm2014.Address} - FM2014 {StrLblFM2014SerialNumber} {fm2014.SerialNumber}"); + LogText($"{timeUtcStr} - Ad: {fm2014.Address} - FM2014 ID: {fm2014.ConnectResponse}"); + LogText($"{timeUtcStr} - Ad: {fm2014.Address} - FM2014 Firmware Version: {fm2014.FwVersion}"); + LogText($"{timeUtcStr} - Ad: {fm2014.Address} - FM2014 {StrLblFM2014SerialNumber} {fm2014.SerialNumber}"); LogText(StrSeparator); } } @@ -1209,7 +1215,7 @@ namespace Sensus.Ui.FM2014TestBench else if (e.StatusReturn == StatusReturn.MeasurementInRange) statusColor = ColorSuccess; - var timeUtcStr = $"{resp.TimestampUtc:yyyy-MM-dd HH:mm:ss} UTC"; + var timeUtcStr = $"{resp.TimestampUtc:yyyy-MM-dd HH:mm:ss:fff} UTC"; if (e.StatusReturn == StatusReturn.Failed) { LogErrorText($"{timeUtcStr} - Ad: {fm2014.Address} - {resp.AnswerStr}"); @@ -1366,7 +1372,7 @@ namespace Sensus.Ui.FM2014TestBench private void btnDutToRefCalibration_Click(Object sender, EventArgs e) { _startTime = DateTimeOffset.UtcNow; - if (FM2014.SharedCyclicMeasSequ == CyclicMeasSequ.idle) + if (FM2014.SharedCyclicMeasSequ == CyclicMeasSequ.Idle) { // Disable and hide dynamic measurement labels foreach (var measLbl in MeasurementLabels) @@ -1474,7 +1480,7 @@ namespace Sensus.Ui.FM2014TestBench private void btnDutToRefRegulation_Click(Object sender, EventArgs e) { _startTime = DateTimeOffset.UtcNow; - if (FM2014.SharedCyclicMeasSequ == CyclicMeasSequ.idle) + if (FM2014.SharedCyclicMeasSequ == CyclicMeasSequ.Idle) { // Disable and hide dynamic measurement labels foreach (var measLbl in MeasurementLabels) @@ -1531,7 +1537,7 @@ namespace Sensus.Ui.FM2014TestBench private void btnRefToVolumeCalibration_Click(Object sender, EventArgs e) { _startTime = DateTimeOffset.UtcNow; - if (FM2014.SharedCyclicMeasSequ == CyclicMeasSequ.idle) + if (FM2014.SharedCyclicMeasSequ == CyclicMeasSequ.Idle) { // Disable and hide dynamic measurement labels foreach (var measLbl in MeasurementLabels) @@ -2539,7 +2545,34 @@ namespace Sensus.Ui.FM2014TestBench } + /// + /// Change the font size on mouse wheel and [Ctrl] button. + /// Needs to be registered for: + /// 1. MouseWheel="rtbLog_MouseWheel" and + /// 2. PreviewMouseWheel="rtbLog_MouseWheel", + /// otherwise the window will first scroll up/down and only reaching the limits (fully up/down) firing the + /// MouseWheel event! + /// + /// + /// + /// + /// - Initial. + /// + private void rtbLog_MouseWheel(Object sender, MouseWheelEventArgs e) + { + if (Keyboard.IsKeyDown(Key.RightCtrl) || Keyboard.IsKeyDown(Key.LeftCtrl)) + { + e.Handled = true; + if (e.Delta > 0) + { + Dispatcher.Invoke(() => rtbLog.FontSize += 1); + } + else + { + Dispatcher.Invoke(() => rtbLog.FontSize -= 1); + } + } + } #endregion ---------------------------------------- Buttons and Controls -------------------------------------- - } } \ No newline at end of file diff --git a/FM2014TestApp/Ui/Fm2014sTest/Fm2014TestBench.csproj b/FM2014TestApp/Ui/Fm2014sTest/Fm2014TestBench.csproj index 43416cb2..0a3bd625 100644 --- a/FM2014TestApp/Ui/Fm2014sTest/Fm2014TestBench.csproj +++ b/FM2014TestApp/Ui/Fm2014sTest/Fm2014TestBench.csproj @@ -13,7 +13,7 @@ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 true - true + false AnyCPU diff --git a/FM2014TestApp/Ui/Fm2014sTest/Properties/AssemblyInfo.cs b/FM2014TestApp/Ui/Fm2014sTest/Properties/AssemblyInfo.cs index 9f9a67e3..dbe3897c 100644 --- a/FM2014TestApp/Ui/Fm2014sTest/Properties/AssemblyInfo.cs +++ b/FM2014TestApp/Ui/Fm2014sTest/Properties/AssemblyInfo.cs @@ -26,7 +26,7 @@ using System.Windows; //the NeutralResourceLanguage attribute below. Update the "en-US" in //the line below to match the UICulture setting in the project file. -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] +//[assembly: NeutralResourcesLanguage("en", UltimateResourceFallbackLocation.Satellite)] [assembly: ThemeInfo( @@ -46,5 +46,4 @@ using System.Windows; // Build Number // Revision // -[assembly: AssemblyVersion("1.0.1.0")] -[assembly: AssemblyFileVersion("1.0.1.0")] +[assembly: AssemblyVersion("1.0.1.*")]