diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs
index 2dd23f72..c6f5ebd5 100644
--- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs
+++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs
@@ -59,7 +59,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
private const Char _eos = FM2014CmdDef.END_OF_STRING;
///
- public Boolean ReceiveTaskIsActive
+ public Boolean CyclicReceiveTaskLoopIsActive
{
get;
private set;
@@ -94,13 +94,42 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
private set;
}
+ private const Char _adrPre = FM2014CmdDef.ADDR_RECORD_CHAR;
+ private const Char _adrPost = FM2014CmdDef.ADDR_VALIDATION_CHAR;
+
+ private Int32 _address;
///
public Int32 Address
+ {
+ get => _address;
+ set
+ {
+ _address = value;
+ AddressStr = $"{_adrPre}{_adrPre}{Address}{_adrPost}{_eos}";
+ }
+ }
+
+ ///
+ /// Marker if broadcast connection was last communication
+ ///
+ public Boolean BroadcastCommIsActive
{
get;
set;
}
+ ///
+ /// Broadcast address without answer for all FM2014
+ ///
+ public static readonly String BrodcastAddressStr = $"{_adrPre}{_adrPre}0{_adrPost}{_eos}";
+
+ ///
+ public String AddressStr
+ {
+ get;
+ private set;
+ }
+
///
public Int32? TolerancePercent
{
@@ -217,7 +246,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
/// request to count REF pulses
/// request to count DUT pulses
///
- ///
+ ///
/// - Initial.
///
public Boolean StartPulseCounting(Boolean refCtrOn = true, Boolean dutCtrOn = false)
@@ -227,32 +256,41 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
return false;
}
- ReceiveTaskIsActive = true;
var cmdName = FM2014CmdDef.CmdName.CMD_NA;
-
+
// Prepare REF-pulse counter measurement
try
{
- if (refCtrOn && dutCtrOn)
- cmdName = FM2014CmdDef.CmdName.CMD_REF_DUT_STR_PLS_CTR;
- else if (refCtrOn)
- cmdName = FM2014CmdDef.CmdName.CMD_REF_STR_PLS_CTR;
- else
- cmdName = FM2014CmdDef.CmdName.CMD_DUT_STR_PLS_CTR;
+ switch (refCtrOn)
+ {
+ case true when dutCtrOn:
+ cmdName = FM2014CmdDef.CmdName.CMD_REF_DUT_STR_PLS_CTR;
+ break;
+ case true:
+ cmdName = FM2014CmdDef.CmdName.CMD_REF_STR_PLS_CTR;
+ break;
+ default:
+ cmdName = FM2014CmdDef.CmdName.CMD_DUT_STR_PLS_CTR;
+ break;
+ }
- var cmdCodeChar = FM2014CmdDef.GetCmdChar(cmdName);
- SerialPort.Write($"{cmdCodeChar}{_eos}");
+ // Start the pulse counter measurement
+ if (!Write(cmdName))
+ {
+ return false;
+ }
}
catch (Exception e)
{
var response = new FM2014CmdDef.CmdResponse(cmdName, e.Message);
- OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
+ OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
}
// Measurement Loop
Task.Run(() =>
{
+ CyclicReceiveTaskLoopIsActive = true;
// Get the process information
var infoRef = FM2014CmdDef.GetCmdInfo(FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR);
var cmdCodeRef = FM2014CmdDef.GetCmdChar(FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR);
@@ -262,9 +300,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
try
{
- if (refCtrOn)
+ if (refCtrOn && Write(FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR))
{
- SerialPort.Write($"{cmdCodeRef}{_eos}");
var refPulseStr = SerialPort.ReadTo($"{_eos}");
if (int.TryParse(refPulseStr, NumberStyles.HexNumber, new CultureInfo("en"), out var refPulses))
@@ -274,9 +311,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(infoRef, specificInfoObj: response));
}
}
- if (dutCtrOn)
+ if (dutCtrOn && Write(FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR))
{
- SerialPort.Write($"{cmdCodeDut}{_eos}");
var dutPulseStr = SerialPort.ReadTo($"{_eos}");
if (int.TryParse(dutPulseStr, NumberStyles.HexNumber, new CultureInfo("en"), out var dutPulses))
@@ -290,12 +326,12 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
catch (Exception e)
{
var response = new FM2014CmdDef.CmdResponse(cmdName, e.Message);
- OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
+ OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response,
statusReturn: StatusReturn.Failed));
}
//Thread.Sleep(500);
- } while (ReceiveTaskIsActive);
+ } while (CyclicReceiveTaskLoopIsActive);
});
return true;
@@ -321,30 +357,23 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
SerialPort.Open();
- const Char adrPre = FM2014CmdDef.ADDR_RECORD_CHAR;
- const Char adrPost = FM2014CmdDef.ADDR_VALIDATION_CHAR;
// Establish connection to one specific FM2014
- SerialPort.Write($"{adrPre}{adrPre}{Address}{adrPost}{_eos}");
- FullId = SerialPort.ReadTo($"{_eos}");
-
- if (!string.IsNullOrEmpty(FullId))
+ if (InitiateIndividualComm())
{
- FullId = FullId.Replace($"{adrPre}", "");
- var fields = FullId.Split('.');
- FwVersion = fields[1];
-
var cmdCode = FM2014CmdDef.GetCmdChar(FM2014CmdDef.CmdName.CMD_SERIAL);
// Read out the serial number of this FM2014
- SerialPort.Write($"{cmdCode}{_eos}");
- SerialNumber = SerialPort.ReadTo($"{_eos}");
+ if (!Write(FM2014CmdDef.CmdName.CMD_SERIAL))
+ {
+ return false;
+ }
+ SerialNumber = SerialPort.ReadTo($"{_eos}");
if (!string.IsNullOrEmpty(SerialNumber))
{
SerialNumber = SerialNumber.Replace($"{cmdCode}", "");
IsLoggedOn = true;
}
}
-
}
catch (Exception e)
{
@@ -353,6 +382,98 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
return IsLoggedOn;
}
+ ///
+ /// Initiate the broadcast communication
+ ///
+ private Boolean InitiateBroadcastComm()
+ {
+ if (SerialPort == null || !SerialPort.IsOpen)
+ {
+ return false;
+ }
+
+ // If broadcast communication is already active
+ if (BroadcastCommIsActive)
+ {
+ return true;
+ }
+
+ // Establish connection to all FM2014s with broadcast address
+ SerialPort.Write(BrodcastAddressStr);
+
+ BroadcastCommIsActive = true;
+ return true;
+ }
+
+ ///
+ /// Initiate communication to individual node
+ ///
+ ///
+ private Boolean InitiateIndividualComm()
+ {
+ if (SerialPort == null || !SerialPort.IsOpen)
+ {
+ return false;
+ }
+
+ // Establish connection to one specific FM2014
+ SerialPort.Write(AddressStr);
+ FullId = SerialPort.ReadTo($"{_eos}");
+
+ if (!string.IsNullOrEmpty(FullId))
+ {
+ FullId = FullId.Replace($"{_adrPre}", "");
+ var fields = FullId.Split('.');
+ FwVersion = fields[1];
+ BroadcastCommIsActive = false;
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Write command to FM2014:
+ /// - Select broadcast or individual addressing based on the command table,
+ /// - Transmits optional data.
+ ///
+ ///
+ ///
+ ///
+ public Boolean Write(FM2014CmdDef.CmdName cmdName, Object dataObj = null)
+ {
+ if (SerialPort == null || !SerialPort.IsOpen)
+ {
+ return false;
+ }
+
+ // Initiate communication using the individual or broadcast address
+ var retVal = true;
+ if (FM2014CmdDef.CmdType.BROADCAST == FM2014CmdDef.GetCmdCmdType(cmdName))
+ {
+ if (!BroadcastCommIsActive)
+ {
+ retVal = InitiateBroadcastComm();
+ }
+ }
+ else
+ {
+ if (BroadcastCommIsActive)
+ {
+ retVal = InitiateIndividualComm();
+ }
+ }
+
+ if (retVal)
+ {
+ // TODO THW Prepare data object
+ var cmdCodeChar = FM2014CmdDef.GetCmdChar(cmdName);
+ SerialPort.Write($"{cmdCodeChar}{_eos}");
+ }
+
+ return retVal;
+ }
+
///
/// Reset the measurement but only if receive task is active.
///
@@ -362,19 +483,15 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
///
public Boolean ResetMeasurement()
{
- if (SerialPort == null || !SerialPort.IsOpen)
- return false;
-
- if (!ReceiveTaskIsActive)
+ if (!CyclicReceiveTaskLoopIsActive)
return true;
- ReceiveTaskIsActive = false;
+ CyclicReceiveTaskLoopIsActive = false;
// Reset measurement
- var cmdCode = FM2014CmdDef.GetCmdChar(FM2014CmdDef.CmdName.CMD_RST_MEAS);
var infoStr = FM2014CmdDef.GetCmdInfo(FM2014CmdDef.CmdName.CMD_RST_MEAS);
- // Read out the serial number of this FM2014
- SerialPort?.Write($"{cmdCode}{_eos}");
-
+ if (!Write(FM2014CmdDef.CmdName.CMD_RST_MEAS))
+ return false;
+
// Wait until FM2014 calibration finished
var resetDelayCtr_ms = 4000;
const Int32 loopTime_ms = 500;
diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/IFM2014.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/IFM2014.cs
index 2579ce9c..e1739fc6 100644
--- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/IFM2014.cs
+++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/IFM2014.cs
@@ -59,7 +59,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
/// Receive task is active:
/// Used to mark this event and to kill ongoing task if set inactive.
///
- Boolean ReceiveTaskIsActive
+ Boolean CyclicReceiveTaskLoopIsActive
{
get;
}
@@ -87,13 +87,21 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
}
///
- /// FM2014 address string
+ /// FM2014 address
///
Int32 Address
{
get;
}
+ ///
+ /// FM2014 address string
+ ///
+ String AddressStr
+ {
+ get;
+ }
+
///
/// Tolerance output of current loop in percent:
/// - hardware dependent 3% or 5%
diff --git a/Common/SoftwareAccessHelper/Access.cs b/Common/SoftwareAccessHelper/Access.cs
index 1c4b6d7a..a97673e7 100644
--- a/Common/SoftwareAccessHelper/Access.cs
+++ b/Common/SoftwareAccessHelper/Access.cs
@@ -44,7 +44,7 @@ namespace Xylem.Common.Logic.SoftwareAccessHelper
}
var url = $"{ServiceUrls.GetSoftwareStartUpAccessUrl()}?Program={program}&Major={major}&Minor={minor}&Build={build}";
- var requestResponse = LocalWebRequest.GetRequest(url, 1200);
+ var requestResponse = LocalWebRequest.GetRequest(url, 8000);
var ret = bool.Parse(requestResponse.Trim('"'));
return ret;
diff --git a/MiniPrf/MiniPrf.sln.DotSettings b/MiniPrf/MiniPrf.sln.DotSettings
index 74692081..6acc8a8b 100644
--- a/MiniPrf/MiniPrf.sln.DotSettings
+++ b/MiniPrf/MiniPrf.sln.DotSettings
@@ -1,5 +1,6 @@
True
+ True
True
True
True
diff --git a/MiniPrf/Ui/FrmMainMiniPrf.cs b/MiniPrf/Ui/FrmMainMiniPrf.cs
index ff9d9341..45657aeb 100644
--- a/MiniPrf/Ui/FrmMainMiniPrf.cs
+++ b/MiniPrf/Ui/FrmMainMiniPrf.cs
@@ -624,7 +624,7 @@ namespace Sensus.MiniPrf.Ui
///
private void btnManualRefCalibration_Click(Object sender, EventArgs e)
{
- if (!_fm2014.ReceiveTaskIsActive)
+ if (!_fm2014.CyclicReceiveTaskLoopIsActive)
{
_startTime = DateTimeOffset.UtcNow;
ActionControl(true);
@@ -668,7 +668,7 @@ namespace Sensus.MiniPrf.Ui
///
/// Feedback from FM2014.
///
- ///
+ ///
/// - Initial.
///
private void DataReceived_Handler(Object sender, ProcessExecEventArgs e)
@@ -676,7 +676,15 @@ namespace Sensus.MiniPrf.Ui
var resp = (FM2014CmdDef.CmdResponse)e.SpecificInfoObj;
if (resp.IntValue != null)
+ {
+ Invoke(new Action(() =>
+ {
+ lblActualProcess.Text = resp.AnswerStr;
+ if (e.ActualProcessPercent != null && !_autoProgressBar && _progressBarOn)
+ barSingleProgressUpdate.Value = (Int32)e.ActualProcessPercent;
+ }));
LogText($"{resp.AnswerStr}: {resp.IntValue:D}");
+ }
}
#endregion
}