diff --git a/Common/Hardware/Interfaces/Ports/PortCore/TransmitPortSettings.cs b/Common/Hardware/Interfaces/Ports/PortCore/TransmitPortSettings.cs
index 5f772635..d53f5b43 100644
--- a/Common/Hardware/Interfaces/Ports/PortCore/TransmitPortSettings.cs
+++ b/Common/Hardware/Interfaces/Ports/PortCore/TransmitPortSettings.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO.Ports;
namespace Xylem.Common.Hardware.Interfaces.Ports.PortCore
{
@@ -8,7 +9,7 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.PortCore
public struct TransmitPortSettings
{
///
- /// The transmission protocol needs to inform the communication port how to setup,
+ /// The transmission protocol needs to inform the communication port how to set up,
/// this is the data container.
///
///
@@ -18,8 +19,17 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.PortCore
///
///
///
- public TransmitPortSettings(Byte? protSyncByte, UInt16? protLengthIndex, UInt16 protAddLength, Int32 responseTimeoutMs, UInt32 baudRate,
- UInt32? receiveBufferFlushThreshold, Boolean doubleSyncByte = false)
+ ///
+ ///
+ ///
+ ///
+ /// - String delimiter for ASCII to support others than LF "\n",
+ /// - Flexible DataBits,
+ /// - Flexible parity.
+ ///
+ public TransmitPortSettings(Byte? protSyncByte, UInt16? protLengthIndex, UInt16 protAddLength, Int32 responseTimeoutMs,
+ UInt32 baudRate, UInt32? receiveBufferFlushThreshold, Boolean doubleSyncByte = false, Char stringDelimiter = '\n',
+ Int32 dataBits = 8, Parity parity = Parity.None )
{
ProtSyncByte = protSyncByte;
ProtLengthIndex = protLengthIndex;
@@ -28,7 +38,25 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.PortCore
BaudRate = baudRate;
ReceiveBufferFlushThreshold = receiveBufferFlushThreshold;
DoubleSyncByte = doubleSyncByte;
+ StringDelimiter = stringDelimiter;
+ DataBits = dataBits;
+ Parity = parity;
}
+ ///
+ /// String delimiter for ASCII to support others than LF "\n"
+ ///
+ public readonly Char StringDelimiter;
+
+ ///
+ /// Flexible DataBits to support 7 bits.
+ ///
+ public readonly Int32 DataBits;
+
+ ///
+ /// Flexible parity
+ ///
+ public readonly Parity Parity;
+
///
/// start of receiving synchronization byte at byte receive routine
/// syncByte == null: use the readLine routine (ASCII) and NOT the BYTE routine,
@@ -76,6 +104,6 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.PortCore
///
/// a special implementation may require the doubling of the sync byte to re-synchronize
///
- public Boolean DoubleSyncByte;
+ public readonly Boolean DoubleSyncByte;
}
}
diff --git a/Common/Hardware/Interfaces/Ports/SerialPorts/BaseSerialPort.cs b/Common/Hardware/Interfaces/Ports/SerialPorts/BaseSerialPort.cs
index db7501b0..ea3f43c0 100644
--- a/Common/Hardware/Interfaces/Ports/SerialPorts/BaseSerialPort.cs
+++ b/Common/Hardware/Interfaces/Ports/SerialPorts/BaseSerialPort.cs
@@ -294,7 +294,7 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts
//put the actual time stamp to this record being able to assign it correctly
//even if the decoding is delayed. This time stamp will be used to do the first
- //synchronization at start and stop of the measurement. Therefore the serial buffer
+ //synchronization at start and stop of the measurement. Therefore, the serial buffer
//has to be flushed in advance to avoid wrong time stamp to "old" records
_receiveTimeStampPc = DateTimeOffset.UtcNow;
@@ -426,6 +426,9 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts
///
/// - Dispose procedure changed.
///
+ ///
+ /// - Replaced 'ReadLine' with 'ReadTo' using a string delimiter to support others than LF "\n".
+ ///
private void ReadingThreadLoop()
{
//put the receive thread to JoinWaitSleep to avoid reading and logger output for timeout on
diff --git a/Common/Hardware/WaterMeter/Genesis/Protocols/RequestProtocol/RequestProtocol.cs b/Common/Hardware/WaterMeter/Genesis/Protocols/RequestProtocol/RequestProtocol.cs
index 4a8023bb..06fd805f 100644
--- a/Common/Hardware/WaterMeter/Genesis/Protocols/RequestProtocol/RequestProtocol.cs
+++ b/Common/Hardware/WaterMeter/Genesis/Protocols/RequestProtocol/RequestProtocol.cs
@@ -618,6 +618,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
/// - Removed useless too short comments as every string is going to be delimited by a 0 and usually won't match
/// to a 4 byte chunk.
///
+ ///
+ /// - Removed redundant 'return cRecord'.
+ ///
public RequestRecord CommandToMeter(Byte command, RegisterDefinition meterRegister = null,
Byte[] payload = null, Int32? expectedLength = null, Boolean hideDataInLog = false,
UInt16 skipRetryErrorCode = CommunicationConfig.SkipRetryErrorCode)
@@ -638,8 +641,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
cRecord.ResponsePayload = completeResponse;
OnMeterRegisterUpdated?.Invoke(this,
new RegisterUpdatedEventArgs(meterRegister, completeResponse.ToArray()));
-
- return cRecord;
}
return cRecord;
diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs
index 1cfac375..8753658e 100644
--- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs
+++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs
@@ -34,8 +34,9 @@
//using NLog;
using System;
using System.IO.Ports;
-using System.Threading;
+using System.Threading.Tasks;
using Xylem.Common.CommonCore.Consts;
+using Xylem.Common.Hardware.Interfaces.Ports.PortCore.EventArguments;
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
@@ -44,8 +45,20 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
///
public class FM2014 : IFM2014
{
+ #region events
+ ///
+ public virtual event EventHandler OnRawRecordReceived;
+ #endregion
+
#region properties
+ ///
+ public Boolean ReceiveTaskIsActive
+ {
+ get;
+ internal set;
+ }
+
///
/// Logger for raw data output
///
@@ -164,6 +177,43 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
return true;
}
+ public Boolean ManualRefCalibration()
+ {
+ if (SerialPort == null || !SerialPort.IsOpen)
+ {
+ return false;
+ }
+
+ // Stop receive task
+ if (ReceiveTaskIsActive)
+ {
+ ReceiveTaskIsActive = false;
+ return true;
+ }
+
+ ReceiveTaskIsActive = true;
+ Task.Run(() =>
+ {
+ var ctr = 0;
+ do
+ {
+ SerialPort.Write("#\r");
+ SerialNumber = SerialPort.ReadTo("\r");
+ if (ctr++ >= 100)
+ {
+ ReceiveTaskIsActive = false;
+ }
+
+ OnRawRecordReceived?.Invoke(this, new StringPortDataEventArgs($"{ctr:D3}"));
+
+ } while (ReceiveTaskIsActive);
+
+ ReceiveTaskIsActive = false;
+ });
+
+ return true;
+ }
+
///
public Boolean Login()
{
diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014Core.csproj b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014Core.csproj
index fa7e8a4e..ada2c4f1 100644
--- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014Core.csproj
+++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014Core.csproj
@@ -303,6 +303,10 @@
{1B02C79E-0B19-43E2-8F6B-71EF0C786C97}
CommonCore
+
+ {2e139f63-b6fe-4ea9-a098-85364fe9b26c}
+ PortCore
+
{3862d89c-e32d-4182-bb58-38777d43edd9}
FM2014Config
diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/IFM2014.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/IFM2014.cs
index b5b64e36..ce7308dc 100644
--- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/IFM2014.cs
+++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/IFM2014.cs
@@ -35,6 +35,7 @@ using System;
using System.IO.Ports;
//using NLog;
using Xylem.Common.CommonCore.Consts;
+using Xylem.Common.Hardware.Interfaces.Ports.PortCore.EventArguments;
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
{
@@ -46,8 +47,23 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
///
public interface IFM2014
{
+ #region events
+ ///
+ /// String data feedback
+ ///
+ event EventHandler OnRawRecordReceived;
+ #endregion
+
#region properties
///
+ /// Receive task is active:
+ /// Used to mark this event and to kill ongoing task if set inactive.
+ ///
+ Boolean ReceiveTaskIsActive
+ {
+ get;
+ }
+ ///
/// Serial number of the FM2014
///
String SerialNumber
diff --git a/MiniPrf/MiniPrf.sln b/MiniPrf/MiniPrf.sln
index f5fe3d1a..12955427 100644
--- a/MiniPrf/MiniPrf.sln
+++ b/MiniPrf/MiniPrf.sln
@@ -36,6 +36,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{755396FE
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logging", "..\Common\Utils\Logging\Logging.csproj", "{4B88B0D3-E791-4774-9521-EABEACDC420E}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interfaces", "Interfaces", "{14FE7B6A-2029-4DCD-AD07-2BDF77D42D94}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ports", "Ports", "{83A52B6E-DB81-4B43-B5C1-F9B637D135BE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Protocols", "Protocols", "{4E27EA04-8B52-4681-BB5E-4658BC3FF9A6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PortCore", "..\Common\Hardware\Interfaces\Ports\PortCore\PortCore.csproj", "{2E139F63-B6FE-4EA9-A098-85364FE9B26C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -62,6 +70,10 @@ Global
{4B88B0D3-E791-4774-9521-EABEACDC420E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B88B0D3-E791-4774-9521-EABEACDC420E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B88B0D3-E791-4774-9521-EABEACDC420E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2E139F63-B6FE-4EA9-A098-85364FE9B26C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2E139F63-B6FE-4EA9-A098-85364FE9B26C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2E139F63-B6FE-4EA9-A098-85364FE9B26C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2E139F63-B6FE-4EA9-A098-85364FE9B26C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -78,6 +90,10 @@ Global
{0B205BE7-90CD-4C3A-8EBD-1E414E39528A} = {02CE88CB-677E-45A7-9B33-5028110379E5}
{755396FE-7AD3-4D4A-9416-4C212A3BEF19} = {1C6D29D2-AC0D-48B2-932A-C9B94C3562F6}
{4B88B0D3-E791-4774-9521-EABEACDC420E} = {755396FE-7AD3-4D4A-9416-4C212A3BEF19}
+ {14FE7B6A-2029-4DCD-AD07-2BDF77D42D94} = {2C357743-AB88-48BF-805A-5DEED44934A3}
+ {83A52B6E-DB81-4B43-B5C1-F9B637D135BE} = {14FE7B6A-2029-4DCD-AD07-2BDF77D42D94}
+ {4E27EA04-8B52-4681-BB5E-4658BC3FF9A6} = {14FE7B6A-2029-4DCD-AD07-2BDF77D42D94}
+ {2E139F63-B6FE-4EA9-A098-85364FE9B26C} = {83A52B6E-DB81-4B43-B5C1-F9B637D135BE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B72A8444-29F9-4FA4-82BE-B6E230750911}
diff --git a/MiniPrf/Ui/FrmMainMiniPrf.Designer.cs b/MiniPrf/Ui/FrmMainMiniPrf.Designer.cs
index 8d6e3784..155f4f6e 100644
--- a/MiniPrf/Ui/FrmMainMiniPrf.Designer.cs
+++ b/MiniPrf/Ui/FrmMainMiniPrf.Designer.cs
@@ -514,6 +514,7 @@
this.btnManualRefCalibration.TabIndex = 38;
this.btnManualRefCalibration.Text = "Start Calibration";
this.btnManualRefCalibration.UseVisualStyleBackColor = true;
+ this.btnManualRefCalibration.Click += new System.EventHandler(this.btnManualRefCalibration_Click);
//
// gbxDutToRefRegulation
//
diff --git a/MiniPrf/Ui/FrmMainMiniPrf.cs b/MiniPrf/Ui/FrmMainMiniPrf.cs
index 8bc0be46..7d288e54 100644
--- a/MiniPrf/Ui/FrmMainMiniPrf.cs
+++ b/MiniPrf/Ui/FrmMainMiniPrf.cs
@@ -35,6 +35,7 @@
using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Config;
using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core;
+using Sensus.MiniPrf.Ui.Properties;
using System;
using System.Drawing;
using System.IO;
@@ -43,7 +44,7 @@ using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
-using Sensus.MiniPrf.Ui.Properties;
+using Xylem.Common.Hardware.Interfaces.Ports.PortCore.EventArguments;
namespace Sensus.MiniPrf.Ui
{
@@ -109,9 +110,15 @@ namespace Sensus.MiniPrf.Ui
///
/// Clear data table and set genesis to not connected
///
+ ///
+ /// - Initial.
+ ///
private void Init()
{
ViewProcessControl(false);
+ btnManualRefCalibration.Enabled = false;
+ btnDutToRefRegulation.Enabled = false;
+
// Load the configuration from the local file stored in AppData\FM2014
_fm2014Config.ReadFM2014Config();
@@ -202,6 +209,7 @@ namespace Sensus.MiniPrf.Ui
lblWaitingForMeterResponse.Visible = false;
SetFM2014AccessLocked();
+ btnFM2014Connect.Enabled = true;
btnFM2014Connect.Focus();
}
@@ -276,33 +284,13 @@ namespace Sensus.MiniPrf.Ui
#endregion TimerControls
#region ActivationControls
- ///
- /// Disable all buttons except the connect button
- ///
- private void DisableToolButtons()
- {
- btnSaveRegulationSetup.Enabled = false;
- btnManualRefCalibration.Enabled = false;
- btnDutToRefRegulation.Enabled = false;
- }
-
- ///
- /// Enable all buttons except the connect button
- ///
- private void EnableToolButtons()
- {
- btnSaveRegulationSetup.Enabled = true;
- btnManualRefCalibration.Enabled = true;
- btnDutToRefRegulation.Enabled = true;
- }
-
///
/// Lock all buttons, enable the connect button
///
private void SetFM2014AccessLocked()
{
- btnFM2014Connect.Enabled = true;
- DisableToolButtons();
+ btnSaveRegulationSetup.Enabled = false;
+ btnFM2014Connect.Enabled = false;
}
///
@@ -310,8 +298,12 @@ namespace Sensus.MiniPrf.Ui
///
private void SetFM2014AccessEnabled()
{
+ btnSaveRegulationSetup.Enabled = true;
+ btnManualRefCalibration.Enabled = true;
+ btnDutToRefRegulation.Enabled = true;
btnFM2014Connect.Enabled = true;
- EnableToolButtons();
+ btnManualRefCalibration.Text = Resources.StrBtnStartCalibration;
+ btnDutToRefRegulation.Text = Resources.StrBtnStartRegulation;
}
///
@@ -327,7 +319,7 @@ namespace Sensus.MiniPrf.Ui
SetFM2014AccessEnabled();
}
- #endregion ACtivationControls
+ #endregion ActivationControls
#region BoardControls
@@ -358,12 +350,17 @@ namespace Sensus.MiniPrf.Ui
ActionControl(true);
- _fm2014?.Dispose();
- //dispose old meter
- _fm2014 = null;
+ if (_fm2014 != null)
+ {
+ _fm2014.OnRawRecordReceived -= DataReceived_Handler;
+ _fm2014.Dispose();
+ //dispose old meter
+ _fm2014 = null;
+ }
//assign new meter
_fm2014 = new FM2014();
+ _fm2014.OnRawRecordReceived += DataReceived_Handler;
if (int.TryParse(cbxFM2014Address.SelectedItem.ToString(), out var address))
{
_fm2014.Address = address;
@@ -434,6 +431,11 @@ namespace Sensus.MiniPrf.Ui
_fm2014?.Dispose();
}
}
+
+ private void _fm2014_OnRawRecordReceived(object sender, StringPortDataEventArgs e)
+ {
+ throw new NotImplementedException();
+ }
#endregion BoardControls
#region ProcessControls
@@ -610,15 +612,38 @@ namespace Sensus.MiniPrf.Ui
#region Buttons and Controls
private void btnConnect_Click(Object sender, EventArgs e)
{
- if (_resetTimeMeasurement)
- {
- _startTime = DateTimeOffset.UtcNow;
- _resetTimeMeasurement = false;
- }
+ //if (_resetTimeMeasurement)
+ //{
+ _startTime = DateTimeOffset.UtcNow;
+ _resetTimeMeasurement = false;
+ //}
Connect();
}
+ private void btnManualRefCalibration_Click(object sender, EventArgs e)
+ {
+ if (!_fm2014.ReceiveTaskIsActive)
+ {
+ _startTime = DateTimeOffset.UtcNow;
+ _resetTimeMeasurement = true;
+ ActionControl(true);
+ btnDutToRefRegulation.Enabled = false;
+ if (_fm2014.ManualRefCalibration())
+ {
+ btnManualRefCalibration.Text = Resources.StrBtnStopCalibration;
+ }
+ }
+ else
+ {
+ if (_fm2014.ManualRefCalibration())
+ {
+ ActionControl(false);
+ btnManualRefCalibration.Text = Resources.StrBtnStartCalibration;
+ }
+ }
+ }
+
private void cbxFM2014ComPort_SelectedValueChanged(Object sender, EventArgs e)
{
if (_toleranceIdx != cbxFM2014TolerancePercent.SelectedIndex ||
@@ -632,5 +657,18 @@ namespace Sensus.MiniPrf.Ui
}
}
#endregion Buttons and Controls
+ #region Event handler
+
+ private void DataReceived_Handler(Object sender, BasePortDataEventArgs e)
+ {
+ LogText(e.GetData().ToString());
+
+ // Return to standby
+ if (!_fm2014.ReceiveTaskIsActive)
+ {
+ ActionControl(false);
+ }
+ }
+ #endregion
}
}
diff --git a/MiniPrf/Ui/MiniPrf.csproj b/MiniPrf/Ui/MiniPrf.csproj
index 89a633ad..7425c76b 100644
--- a/MiniPrf/Ui/MiniPrf.csproj
+++ b/MiniPrf/Ui/MiniPrf.csproj
@@ -109,6 +109,10 @@
+
+ {2e139f63-b6fe-4ea9-a098-85364fe9b26c}
+ PortCore
+
{3862D89C-E32D-4182-BB58-38777D43EDD9}
FM2014Config
diff --git a/MiniPrf/Ui/Properties/Resources.de.resx b/MiniPrf/Ui/Properties/Resources.de.resx
index 8811673c..34775575 100644
--- a/MiniPrf/Ui/Properties/Resources.de.resx
+++ b/MiniPrf/Ui/Properties/Resources.de.resx
@@ -221,6 +221,6 @@
Zeit [min:s]:
- Datum und -zeit [min:s]:
+ Datum und Zeit [min:s]:
\ No newline at end of file