diff --git a/Common/Common.sln b/Common/Common.sln
index aaf2a991..8c87c10b 100644
--- a/Common/Common.sln
+++ b/Common/Common.sln
@@ -152,6 +152,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MjkControlledCodeRef", "MjkControlledCodeRef", "{B4F8545B-F379-42A5-BDE9-763FD7B79598}"
ProjectSection(SolutionItems) = preProject
MagFluxApi\magflux_api.dll = MagFluxApi\magflux_api.dll
+ MagFluxApi\shared_code.dll = MagFluxApi\shared_code.dll
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MagFluxToolBox", "Ui\MagFluxToolBox\MagFluxToolBox.csproj", "{A5E7CE52-3101-4E9B-B896-C2C0FADE4812}"
@@ -232,6 +233,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.UI.WPFConnector", "U
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.UI.WPF", "Ui\Common.UI.WPF\Common.UI.WPF.csproj", "{F7316525-FF8E-4651-BA67-3C9B948D1E91}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "API_Docu", "API_Docu", "{9158A215-69E2-4D4C-B1DA-DDED9C3460AB}"
+ ProjectSection(SolutionItems) = preProject
+ MagFluxApi\api_doc\CalibrationPoint.cs = MagFluxApi\api_doc\CalibrationPoint.cs
+ MagFluxApi\api_doc\CalibrationPoints.cs = MagFluxApi\api_doc\CalibrationPoints.cs
+ MagFluxApi\api_doc\IMagFlux.cs = MagFluxApi\api_doc\IMagFlux.cs
+ MagFluxApi\api_doc\IMagFluxAPI.cs = MagFluxApi\api_doc\IMagFluxAPI.cs
+ MagFluxApi\api_doc\IMagFluxRequestProtocol.cs = MagFluxApi\api_doc\IMagFluxRequestProtocol.cs
+ MagFluxApi\api_doc\SensorInfo.cs = MagFluxApi\api_doc\SensorInfo.cs
+ EndProjectSection
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
Utils\DateTimeServerShared\DateTimeServerShared.projitems*{4806d89a-fbfb-41bc-aaa7-2242444bf55a}*SharedItemsImports = 4
@@ -5682,6 +5693,7 @@ Global
{05F0CCAF-9F2B-45F9-A7F8-12F29AD182F3} = {7A0EE7B8-6B7E-41E9-B679-319C8CA48CF1}
{37E4BF89-44AE-4133-BE0B-8355F791A79D} = {03D4F23E-7E4A-4091-BC96-036C996D351A}
{F7316525-FF8E-4651-BA67-3C9B948D1E91} = {03D4F23E-7E4A-4091-BC96-036C996D351A}
+ {9158A215-69E2-4D4C-B1DA-DDED9C3460AB} = {B4F8545B-F379-42A5-BDE9-763FD7B79598}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4BCB7B69-696C-436A-86F7-C91EA5588164}
diff --git a/Common/MagFluxApi/api_doc/CalibrationPoint.cs b/Common/MagFluxApi/api_doc/CalibrationPoint.cs
new file mode 100644
index 00000000..3d3fcf63
--- /dev/null
+++ b/Common/MagFluxApi/api_doc/CalibrationPoint.cs
@@ -0,0 +1,136 @@
+// Ignore Spelling: lps
+
+using System;
+using XYLEM.Base;
+
+namespace XYLEM
+{
+ ///
+ /// A single calibration point
+ ///
+ [Serializable]
+ public class CalibrationPoint : IComparable, IEquatable
+ {
+ ///
+ /// Reference flow in liter / second
+ /// https://xyleminc.atlassian.net/wiki/spaces/MJKMF/pages/6661802342
+ ///
+ public Single ReferenceFlowRate_lps { get; set; }
+
+ ///
+ /// DUT Reported flow in liter / second
+ /// https://xyleminc.atlassian.net/wiki/spaces/MJKMF/pages/6661802342
+ ///
+ public Single ReportedFlowRate_lps { get; set; }
+
+ public CalibrationPoint()
+ {
+ ReferenceFlowRate_lps = ReportedFlowRate_lps = 0;
+ }
+
+ ///
+ /// Ctor
+ ///
+ /// reference flow rate [l/s] given by the flow-test-bench
+ /// reported flow rate [l/s] by the DUT
+ public CalibrationPoint(Single referenceFlowRate_lps, Single reportedFlowRate_lps)
+ {
+ ReferenceFlowRate_lps = referenceFlowRate_lps;
+ ReportedFlowRate_lps = reportedFlowRate_lps;
+ }
+
+ public override string ToString()
+ {
+ const int w1 = 11;
+ return $"Ref={ReferenceFlowRate_lps*3.6,w1:F6} m3/h DUT={ReportedFlowRate_lps*3.6,w1:F6} m3/h " +
+ $"(Ref={ReferenceFlowRate_lps,w1:F6} l/s DUT={ReportedFlowRate_lps,w1:F6} l/s)";
+ }
+
+ public int CompareTo(CalibrationPoint other)
+ {
+ // If null, it can't be the same
+ if (System.Object.ReferenceEquals(other, null))
+ {
+ return -1;
+ }
+ // Any of them is not okay
+ if ((this.ReferenceFlowRate_lps!= other.ReferenceFlowRate_lps) || (this.ReportedFlowRate_lps!= other.ReportedFlowRate_lps))
+ {
+ return -1; // Not the same
+ }
+ return 0; // is the same
+ }
+
+ public bool Equals(CalibrationPoint other)
+ {
+ return this.CompareTo(other) == 0;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is CalibrationPoint)) return false;
+
+ CalibrationPoint p = (CalibrationPoint)obj;
+ return this == p;
+ }
+
+ public override int GetHashCode()
+ {
+ return HashTools.ShiftAndWrap(ReferenceFlowRate_lps.GetHashCode(), 2) ^ ReportedFlowRate_lps.GetHashCode();
+ }
+
+ #region Operator == > < ! ..
+ public static bool operator ==(CalibrationPoint a, CalibrationPoint b)
+ {
+ // If both are null, or both are same instance, return true.
+ if (System.Object.ReferenceEquals(a, b))
+ {
+ return true;
+ }
+
+ // If one is null, but not both, return false.
+ // from https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-define-value-equality-for-a-type?redirectedfrom=MSDN
+ if (a is null)
+ {
+ // null == null = true.
+ if (b is null)
+ {
+ return true;
+ }
+ // Only the left side is null.
+ return false;
+ }
+
+ // Return true if the fields match:
+ return (a.Equals(b));
+ }
+
+ public static bool operator !=(CalibrationPoint a, CalibrationPoint b)
+ {
+ return !(a == b);
+ }
+
+ public static bool operator <(CalibrationPoint a, CalibrationPoint b)
+ {
+ return a.CompareTo(b) < 0;
+ }
+
+ public static bool operator >(CalibrationPoint a, CalibrationPoint b)
+ {
+ return a.CompareTo(b) > 0;
+ }
+
+ public static bool operator >=(CalibrationPoint a, CalibrationPoint b)
+ {
+ return a.CompareTo(b) >= 0;
+ }
+
+ public static bool operator <=(CalibrationPoint a, CalibrationPoint b)
+ {
+ return a.CompareTo(b) <= 0;
+ }
+
+ #endregion
+ }
+
+}
\ No newline at end of file
diff --git a/Common/MagFluxApi/api_doc/CalibrationPoints.cs b/Common/MagFluxApi/api_doc/CalibrationPoints.cs
new file mode 100644
index 00000000..1fcffee1
--- /dev/null
+++ b/Common/MagFluxApi/api_doc/CalibrationPoints.cs
@@ -0,0 +1,221 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using XYLEM.Base;
+using XYLEM.Base.XML;
+
+namespace XYLEM
+{
+ [Serializable]
+ public class CalibrationPoints : IComparable, IEquatable
+ {
+ ///
+ /// calibrations to or from DUT
+ ///
+ public List calibrations { get; private set; }
+
+ public void SaveToFile(string filePath)
+ {
+ XMLWriteFuncClass.WriteToXmlFile(filePath, calibrations, false);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// Is a valid calibration for DUT
+ public bool LoadFromFile(string filePath)
+ {
+ var pointsSaved = XMLWriteFuncClass.ReadFromXmlFile>(filePath);
+ calibrations = pointsSaved;
+ return IsOkay();
+ }
+
+ ///
+ /// Constructor for A empty list of calibrations, to use for loading calibrations from file
+ ///
+ public CalibrationPoints()
+ {
+ calibrations = new List();
+ }
+
+
+ ///
+ ///
+ ///
+ ///
+ /// Maximum numbers of calibration able to write to device
+ public CalibrationPoints(List cal_points, int maxTotalPoints)
+ {
+ if (cal_points == null)
+ {
+ throw new ArgumentNullException("Calibrations points can't be zero");
+ }
+ if (cal_points.Count > maxTotalPoints)
+ {
+ throw new Exception($"Has {cal_points.Count} calibrations points and only support {maxTotalPoints}");
+ }
+ // Pad with zero if not the full size. Done to make a working writing and comparing two calibrations.
+ if (cal_points.Count < maxTotalPoints)
+ {
+ var missing = maxTotalPoints-cal_points.Count;
+ cal_points.AddRange(Enumerable.Range(0, missing).Select(_ => new CalibrationPoint(0, 0)));
+ }
+ calibrations = cal_points;
+ }
+
+ ///
+ /// Is a valid calibration to or from DUT
+ ///
+ ///
+ public Boolean IsOkay()
+ {
+ if ((null == calibrations) || (0 > calibrations.Count))
+ {
+ return false; // Not okay
+ }
+ return true; // Is okay
+ }
+
+ ///
+ /// Number of calibrations to or from DUT
+ ///
+ /// is 0 or more if okay and -1 on error / not okay
+ public int Get_number_of_calibrations()
+ {
+ if (!IsOkay())
+ {
+ return -1;
+ }
+ return calibrations.Count;
+ }
+
+ public override string ToString()
+ {
+ if (!IsOkay())
+ {
+ return "No valide calibration to print out";
+ }
+ var ret_txt = "";
+ var idx = 0;
+ foreach (var cal in calibrations)
+ {
+ ret_txt += $"{idx++}: {cal}\n";
+ }
+ return ret_txt;
+ }
+
+ public int CompareTo(CalibrationPoints other)
+ {
+ // If null, it can't be the same
+ if (System.Object.ReferenceEquals(other, null))
+ {
+ return -1;
+ }
+
+ // Any of them is not okay
+ if (!this.IsOkay() || !other.IsOkay())
+ {
+ return -1; // Not the same
+ }
+ // if number of items is not the same
+ if (this.Get_number_of_calibrations() != other.Get_number_of_calibrations())
+ {
+ return -1; // Not the same
+ }
+ var num_of_cals = this.calibrations.Count;
+ var my_cals = this.calibrations;
+ var others_cals = other.calibrations;
+ for (int i = 0; i < num_of_cals; i++)
+ {
+ if (my_cals[i] != others_cals[i])
+ {
+ return -1; // Not the same
+ }
+ }
+ return 0; // is the same
+ }
+
+ public bool Equals(CalibrationPoints other)
+ {
+ return this.CompareTo(other) == 0;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is CalibrationPoints)) return false;
+
+ CalibrationPoints p = (CalibrationPoints)obj;
+ return this == p;
+ }
+
+ public override int GetHashCode()
+ {
+ if (calibrations == null)
+ {
+ return base.GetHashCode();
+ }
+ else
+ {
+ int hash = 0;
+ foreach (var calibration in calibrations)
+ {
+ hash = HashTools.ShiftAndWrap(hash.GetHashCode(), 2) ^ calibration.GetHashCode();
+ }
+ return hash;
+ }
+ }
+
+ #region Operator == > < ! ..
+ public static bool operator ==(CalibrationPoints a, CalibrationPoints b)
+ {
+ // If both are null, or both are same instance, return true.
+ if (System.Object.ReferenceEquals(a, b))
+ {
+ return true;
+ }
+
+ // If one is null, but not both, return false.
+ // from https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-define-value-equality-for-a-type?redirectedfrom=MSDN
+ if (a is null)
+ {
+ // null == null = true.
+ if (b is null)
+ {
+ return true;
+ }
+ // Only the left side is null.
+ return false;
+ }
+
+ // Return true if the fields match:
+ return (a.Equals(b));
+ }
+
+ public static bool operator !=(CalibrationPoints a, CalibrationPoints b)
+ {
+ return !(a == b);
+ }
+
+ public static bool operator <(CalibrationPoints a, CalibrationPoints b)
+ {
+ return a.CompareTo(b) < 0;
+ }
+
+ public static bool operator >(CalibrationPoints a, CalibrationPoints b)
+ {
+ return a.CompareTo(b) > 0;
+ }
+
+ public static bool operator >=(CalibrationPoints a, CalibrationPoints b)
+ {
+ return a.CompareTo(b) >= 0;
+ }
+
+ public static bool operator <=(CalibrationPoints a, CalibrationPoints b)
+ {
+ return a.CompareTo(b) <= 0;
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Common/MagFluxApi/api_doc/IMagFlux.cs b/Common/MagFluxApi/api_doc/IMagFlux.cs
new file mode 100644
index 00000000..900a6477
--- /dev/null
+++ b/Common/MagFluxApi/api_doc/IMagFlux.cs
@@ -0,0 +1,67 @@
+using System;
+using System.IO.Ports;
+using XYLEM.Base.Config;
+using XYLEM.Communication;
+
+namespace XYLEM
+{
+ ///
+ /// Command interface for MagFlux 6200
+ /// https://xyleminc.atlassian.net/wiki/spaces/MJKMF/pages/7112855120/Command+Interface+Draft
+ ///
+ internal interface IMagFlux : IMagFluxRequestProtocol
+ {
+ #region When sharing same serial port
+
+ ///
+ /// Connect when using same serial port
+ ///
+ ///
+ ///
+ ///
+ Boolean Connect(UInt16 id, ModbusCom md_com);
+
+ ///
+ /// Get current device com settings
+ ///
+ ///
+ SerialPortSettingClass GetComSetting();
+
+ ///
+ /// Current modbus device device ID / address
+ ///
+ UInt16 Device_ID { get; }
+
+ #endregion
+
+
+ #region For stand alone use without sharing same serial port
+
+ #endregion
+ ///
+ /// Make communication connection to Meter
+ /// !!NOTE!! Only one meter is supported for each com port
+ ///
+ /// Like "COM1"
+ /// >Device modbus address / ID 1..247 (default 1) Warning!! use 247 with single device connected, most MJK devices replay no matter it's id setting
+ /// true on okay or false on error
+ Boolean Connect(string comport, UInt16 id = 1);
+
+ ///
+ /// Make communication connection to Meter with a specific communication setup
+ /// !!NOTE!! Only one meter is supported for each com port
+ ///
+ /// >Like "COM1"
+ /// >Device modbus address / ID 1..247 (default 1) Warning!! use 247 with single device connected, most MJK devices replay no matter it's id setting
+ /// Like 9600 (default on RS485)
+ /// Like Parity.Even (default on RS485)
+ ///
+ Boolean Connect(string comport, UInt16 id, UInt32 baudRate, Parity parity);
+
+ ///
+ /// Close communication connection to Meter
+ ///
+ /// true on okay or false on error
+ Boolean CloseConnection();
+ }
+}
diff --git a/Common/MagFluxApi/api_doc/IMagFluxAPI.cs b/Common/MagFluxApi/api_doc/IMagFluxAPI.cs
new file mode 100644
index 00000000..b6c16d95
--- /dev/null
+++ b/Common/MagFluxApi/api_doc/IMagFluxAPI.cs
@@ -0,0 +1,40 @@
+using System.IO.Ports;
+using XYLEM.Device;
+
+namespace XYLEM
+{
+ public interface IMagFluxAPI
+ {
+
+ ///
+ /// Make communication connection to Meter
+ ///
+ /// Imported note: Devices placed on same serial connection, must have same communication settings.
+ /// Ex. All devices on same serial connection must be configured to same baudrate, parity
+ ///
+ ///
+ /// Like "COM1"
+ /// Device modbus address / ID 1..247 (default 1) Warning!! use 247 with single device connected, most MJK devices replay no matter it's id setting
+ /// folder path for where to log file should be saved
+ /// RUN_TYPE.Normal with connection to serial port, if not set
+ /// Return a MagFlux device or "null" if failing connect
+ IMagFluxRequestProtocol Connect(string comport, ushort id = 1, string log_path = null, RUN_TYPE runAs = RUN_TYPE.Normal);
+
+ ///
+ /// Make communication connection to Meter with a specific communication setup
+ ///
+ /// Imported note: Devices placed on same serial connection, must have same communication settings.
+ /// Ex. All devices on serial connection must be configured to same baudrate, parity
+ ///
+ ///
+ /// >Like "COM1"
+ /// Device modbus address / ID 1..247 (default 1) Warning!! use 247 with single device connected, most MJK devices replay no matter it's id setting
+ /// Like 9600 (default on RS485)
+ /// Like Parity.Even (default on RS485)
+ /// folder path for where to log file should be saved
+ /// RUN_TYPE.Normal with connection to serial port, if not set
+ /// Return a MagFlux device or "null" if failing connect
+ /// if the configuration is not valid
+ IMagFluxRequestProtocol Connect(string comport, ushort id, uint baudRate, Parity parity, string log_path = null, RUN_TYPE runAs = RUN_TYPE.Normal);
+ }
+}
\ No newline at end of file
diff --git a/Common/MagFluxApi/api_doc/IMagFluxRequestProtocol.cs b/Common/MagFluxApi/api_doc/IMagFluxRequestProtocol.cs
new file mode 100644
index 00000000..3c2e8a05
--- /dev/null
+++ b/Common/MagFluxApi/api_doc/IMagFluxRequestProtocol.cs
@@ -0,0 +1,350 @@
+using System;
+using System.Collections.Generic;
+using XYLEM.Base;
+
+namespace XYLEM
+{
+ ///
+ /// Command interface for MagFlux
+ /// https://xyleminc.atlassian.net/wiki/spaces/MJKMF/pages/7112855120/Command+Interface+Draft
+ ///
+ public interface IMagFluxRequestProtocol
+ {
+ ///
+ /// Is connected
+ ///
+ /// true if yes
+ Boolean IsConnected();
+
+ ///
+ /// Get current device Modbus ID / Device Address
+ ///
+ /// 1-246
+ /// true on okay or false on error
+ Boolean GetDeviceID(out int value_out);
+
+ ///
+ /// Simple Check if a device ID is Free or responding
+ /// Reads address 0 to check on any device response
+ /// Is used in SetDeviceID() before attempting change ID
+ ///
+ ///
+ /// Return True if no device was responding on ID
+ Boolean IsDeviceID_Free(uint id_to_check);
+
+ ///
+ /// Set current device Modbus ID / Device Address
+ ///
+ /// 1-246 (Don't use device ID 247, it is a MJK broad cast)
+ /// true on okay or false on error
+ /// Notes:
+ /// There is a simple check on new device id is free (read address 0 check on)
+ /// Change of device ID is instantly and may loose any communication if not able to function on this ID.
+ /// Troubleshooting on failing:
+ /// * Power off and remove optional USBC cable on MagFlux.
+ /// * Remove all other devices on RS485 and retry connection.
+ /// * Check Device ID manually on LCD other program like 840126 with USBC connection.
+ Boolean SetDeviceID(UInt16 new_id);
+
+ ///
+ /// Get printout of communication counters
+ ///
+ ///
+ string GetComCounters();
+
+ ///
+ /// Set location for where log data can saved.
+ ///
+ /// path for where to log file should be saved
+ /// set a custom log file name without extension (ex. "UserCustomLogFile") or null if use default
+ /// true on okay or false on error
+ Boolean SetLogLocation(String path, string filename = null);
+
+ ///
+ /// Open saved log file
+ ///
+ void OpenLogFile();
+
+ ///
+ /// Get latest log added to log file while this program was running
+ ///
+ /// How long to go back after log messages, if Null then standard 1 minute
+ /// "Lasted" Log messages Queue After last connection
+ List GetLatestLogs(DateTime? from = null);
+
+ ///
+ /// Unique-ID for the MagFlux electronics
+ ///
+ /// a hex decimal string 0x1234ABCDEF or NULL at error
+ /// true on okay or false on error
+ Boolean GetUniqueId(out string value_out);
+
+ ///
+ /// MagFlux metrology board serial number
+ /// More info on:
+ /// https://xyleminc.atlassian.net/wiki/spaces/MJKMF/pages/7648215086/Metrology+and+Application+serial+numbers
+ ///
+ /// a serial number ex. 510360.00000105W46Y23 or NULL at error
+ /// true on okay or false on error
+ Boolean GetBoardSerialNo(out string value_out);
+
+ ///
+ /// MagFlux metrology board serial number
+ /// More info on:
+ /// https://xyleminc.atlassian.net/wiki/spaces/MJKMF/pages/7648215086/Metrology+and+Application+serial+numbers
+ ///
+ /// a serial number ex. 510360.00000105W46Y23
+ /// true on okay or false on error
+ Boolean SetBoardSerialNo(string new_serial_number);
+
+ ///
+ /// Get the firmware version
+ ///
+ /// like 1.2.4 (MAJOR.MINOR.REVISION)
+ /// true on okay or false on error
+ Boolean GetFirmwareVersion(out string value_out);
+
+ ///
+ /// Get Current device register version
+ ///
+ /// like "51" or on connecting error "?", "0", "-1"
+ /// true on okay or false on error
+ Boolean GetRegisterVersion(out string value_out);
+
+ ///
+ /// Get Current communication register version used by the interface
+ ///
+ /// like "51" or on error "?", "0", "-1"
+ /// true on okay or false on error
+ Boolean GetAPIRegisterVersion(out string value_out);
+
+ ///
+ /// Get the firmware build date
+ ///
+ /// like 2022/12/24 13:00:00 or 2022-12-24 13:45:10
+ /// true on okay or false on error
+ Boolean GetFwBuildDate(out string value_out);
+
+ ///
+ /// Git Hash to Unique identify firmware
+ ///
+ /// like 0xABCDE123
+ /// true on okay or false on error
+ Boolean GetFwGitHash(out string value_out);
+
+ ///
+ /// Flow rate calibrated
+ ///
+ /// Actual flow rate [l/s]
+ /// true on okay or false on error
+ Boolean GetFlowRate_lps(out Single value_out);
+
+ ///
+ /// !!! Warning make sure to turn off simulation, when calibration off sensor is done !!!
+ /// ----
+ /// Set a fixed test flow to force MagFlux, for check of digital output pulse etc.
+ /// ----
+ /// Will also activate and start fixed simulated flow in device
+ /// Used for getting a fixed simulated flow before sensor calibration from MagFlux
+ /// Note on limitation:
+ /// The actual resulting flow is depended on sensor calibration and MagFlux conversion from m/s to flow.
+ /// Always check resulting flow with GetFlowRate_lps() to verify if the same as expected
+ /// With a calibration of all 0 (equal no calibration 1:1) normally produce same GetFlowRate_lps() down to 3 digit precision.
+ ///
+ /// The fixed flow to force MagFlux to output [l/s]
+ /// true on okay or false on error
+ Boolean SetSimulatedFlow_lps(double value_lps);
+
+ ///
+ /// Get the correction factor from board "1.0000" is default none calibration board
+ ///
+ ///
+ /// true on okay or false on error
+ Boolean GetElectrodeBoardCorrectionFactor(out Single value_out);
+
+ ///
+ /// Get Empty pipe control bits
+ /// Bit0="EPD disabled", 1="Enabled w. Flags only", 2="EPD enabled full"
+ ///
+ /// empty pipe control bits
+ /// true on okay or false on error
+ Boolean GetEmptyPipeControl(out Int32 epd_cntl_bits);
+
+ ///
+ /// !!! Warning don't use this feature on already correct calibrated and configured boards !!!
+ /// Can only be used for demo and not for real sensor customer calibration measurement
+ /// ----
+ /// Set a uncalibrated blank board to defaults, that allow using it for testing
+ /// ----
+ /// Note:
+ /// Limitations will take up to a minute to exit, if all configs needs to be set in a blank device
+ /// * If "1.00" and device Healthy not, then rewrite "ElectrodeBoardCorrectionFactor" as "1.00" to remove PDS Invalid system calibration error
+ /// * If Sensor serial number is "0", it will be changed to "2"
+ /// * If Flange type is "0", It will be changed to "1" equal "EN-1092-1"
+ /// * If board PCB SN is blank "", then to "Demo [Date on change]"
+ /// * if Empty Pipe Control bits is all "0", then turn on "Enable w. flags only"
+ /// * Prepare with a default calibration that is 1:1
+ ///
+ /// true on okay or false on error
+ Boolean SetPCBToDemoDefaults();
+
+ ///
+ /// Is the fixed test flow active
+ /// Used for getting a fixed simulated flow from MagFlux
+ ///
+ /// true if ON
+ Boolean IsSimulatedFlowActive();
+
+ ///
+ /// Turn on/off fixed test flow output from MagFlux
+ /// Used for getting a fixed simulated flow from MagFlux
+ ///
+ ///
+ /// true on okay or false on error
+ Boolean SetSimulatedFlowActive(Boolean testFlowOn);
+
+ ///
+ /// Total forward volume (Positive flow volume totalizator)
+ ///
+ /// volume in in liter [l]
+ /// true on okay or false on error
+ Boolean GetForwardVolume_l(out Double value_out);
+
+ ///
+ /// Total backward volume (Reversed or negative flow volume totalizator)
+ ///
+ ///
+ /// true on okay or false on error
+ Boolean GetBackwardVolume_l(out Double value_out);
+
+ ///
+ /// Get the general sensor information
+ ///
+ /// sensor information
+ /// true on okay or false on error
+ Boolean GetSensorInfo(out SensorInfo value_out);
+
+ ///
+ /// MagFlux Sensor serial number
+ ///
+ /// a decimal serial number ex. 12345678 or NULL at error
+ /// true on okay or false on error
+ Boolean GetSensorSerialNo(out string value_out);
+
+ ///
+ /// Set MagFlux Sensor serial number
+ ///
+ ///
+ /// true on okay or false on error
+ Boolean SetSensorSerialNo(UInt64 new_serial_number);
+
+ ///
+ /// MagFlux Sensor nominal DN size in millimeters
+ ///
+ /// DN size in [mm] is -1 on error
+ /// true on okay or false on error
+ Boolean GetDn_mm(out Int32 dn_mm_out);
+
+ ///
+ /// Set Sensor nominal DN size in millimeters
+ ///
+ /// DN size in [mm] ex 50 is 50mm or DN50
+ /// true on okay or false on error
+ Boolean SetDn_mm(UInt16 new_dn_mm);
+
+ ///
+ /// Get Sensor Flange Type
+ /// 0 = Unknown, 1="EN-1092-1", 2=AS 4087-2004 or AS 2129-2000", 3="ANSI or ASME B16.5", 4="AWWA C207"
+ ///
+ /// Flange type number
+ /// true on okay or false on error
+ Boolean GetFlangeType(out Int32 flangeType_out);
+
+ ///
+ /// Set Sensor Flange Type
+ /// 0 = Unknown, 1="EN-1092-1", 2=AS 4087-2004 or AS 2129-2000", 3="ANSI or ASME B16.5", 4="AWWA C207"
+ ///
+ /// Flange type number
+ /// true on okay or false on error
+ Boolean SetFlangeType(UInt16 new_flangeType);
+
+ ///
+ /// get what volume per pulse for both forward and reverse counter is
+ /// Note: will return only forward pulse volume if both settings is not the same.
+ ///
+ /// A pulse volume in [ml] (milliliter)
+ /// true on okay or false on error
+ Boolean GetVolumePerPulse_ml(out UInt32 pls_vol_ml);
+
+ ///
+ /// Set what volume per pulse for both forward and reverse counter is
+ ///
+ /// A pulse volume in [ml] (milliliter)
+ /// true on okay or false on error
+ Boolean SetVolumePerPulse_ml(UInt32 pls_vol_ml);
+
+ ///
+ /// Get what pulse turn on time for both forward and reverse counter is
+ /// Note: will return only forward turn on time if both settings is not the same.
+ ///
+ /// A pulse turn on time in ms (millisecond) Note setting to 0 will result in pulse time be as fast as device support
+ /// true on okay or false on error
+ Boolean GetPulseOutput_Ton_ms(out UInt16 pls_Ton_ms);
+
+ ///
+ /// Set what pulse turn on time for both forward and reverse counter is
+ ///
+ /// A pulse turn on time in ms (millisecond)
+ /// true on okay or false on error
+ Boolean SetPulseOutput_Ton_ms(UInt16 pls_Ton_ms);
+
+ ///
+ /// Check if there is problem with the DUT
+ /// use " to get a list of error messages for debug problems
+ ///
+ /// >true if device operates correctly
+ Boolean GetDeviceHealthy();
+
+ ///
+ /// get a list of error messages for debug problem
+ ///
+ /// Will return a empty list if there is no messages to return
+ /// true on okay or false on error
+ Boolean GetDeviceErrorMessages(out List status_list_out);
+
+ ///
+ /// This function prepares the DUT for the calibration.
+ ///
+ /// ATTENTION:
+ /// This function needs to be called before the calibration process starts any flow of water.
+ ///
+ /// true on okay or false on error
+ Boolean PrepareDeviceForCalibration();
+
+ ///
+ /// This function will abort started or failed calibration to bring DUT back to normal calibration state
+ ///
+ /// true on okay or false on error
+ Boolean AbortDeviceForCalibration();
+
+ ///
+ /// The maximum calibration points that is supported by the device
+ ///
+ int CalibrationPointsMax { get; }
+
+ ///
+ /// Get list of calibration points saved in DUT
+ ///
+ /// The calibrations points from device
+ /// true on okay or false on error
+ Boolean GetCalibrationPoints(out CalibrationPoints values_read);
+
+ ///
+ /// set calibration in DUT.
+ /// Remember to run before the calibration process is started.
+ ///
+ /// A list of calibration points to write to DUT
+ /// true on okay or false on error
+ Boolean SetCalibrationPoints(CalibrationPoints new_calibration_points);
+ }
+}
diff --git a/Common/MagFluxApi/api_doc/SensorInfo.cs b/Common/MagFluxApi/api_doc/SensorInfo.cs
new file mode 100644
index 00000000..7a8b4451
--- /dev/null
+++ b/Common/MagFluxApi/api_doc/SensorInfo.cs
@@ -0,0 +1,90 @@
+using System;
+
+namespace XYLEM
+{
+ public class SensorInfo
+ {
+ ///
+ ///Sensor serial number ex. 0x1234ABCDEF or 0 as unknown / not defined
+ ///
+ public UInt64 SerialNumber { get; private set; }
+
+ ///
+ /// MagFlux Sensor nominal DN size in millimeters
+ ///
+ public Int32 DN_mm { get; private set; }
+
+ ///
+ /// MagFlux Sensor Flange Type
+ /// 0 = Unknown, 1="EN-1092-1", 2=AS 4087-2004 or AS 2129-2000", 3="ANSI or ASME B16.5", 4="AWWA C207"
+ ///
+ public Int32 FlangeType { get; private set; }
+
+ ///
+ /// Calibration method was used. 0 is default, for calibration on flow rig for 5 min per point
+ ///
+ public Int32 CalibrationVersion { get; private set; }
+
+ ///
+ /// Sampling scheme code used by front end measurement. //NL// 0=32/40, 1=20/40
+ ///
+ public Int32 SamplingSchemeCode { get; private set; }
+
+ ///
+ /// Coil driver frequency, 0 = 0.625Hz, 1= 1.25Hz, 2 = 2.5Hz, 3 = 5Hz, 4 = 10Hz,
+ ///
+ public Int32 CoilDriverFrequencyConfig { get; private set; }
+
+ ///
+ /// Number of calibration points
+ /// The same as calling "Calibration.Get_number_of_calibrations()"
+ ///
+ public Int32 NumberOfCalibrations { get; private set; }
+
+ ///
+ /// List of calibration points saved in DUT
+ ///
+ public CalibrationPoints Calibration { get; private set; }
+
+
+ public SensorInfo(
+ UInt64 SerialNumber,
+ Int32 DN_mm,
+ Int32 FlangeType,
+ Int32 CalibrationVersion,
+ Int32 SamplingSchemeCode,
+ Int32 CoilDriverFrequencyConfig,
+ CalibrationPoints Calibration)
+ {
+ this.SerialNumber = SerialNumber;
+ this.DN_mm = DN_mm;
+ this.FlangeType = FlangeType;
+ this.CalibrationVersion = CalibrationVersion;
+ this.SamplingSchemeCode = SamplingSchemeCode;
+ this.CoilDriverFrequencyConfig = CoilDriverFrequencyConfig;
+ this.Calibration = Calibration;
+ if (null == this.Calibration)
+ {
+ this.NumberOfCalibrations = 0;
+ }
+ else
+ {
+ this.NumberOfCalibrations = this.Calibration.Get_number_of_calibrations();
+ }
+ }
+
+ public override String ToString()
+ {
+ String strReturn = "";
+ strReturn += $"SN: {SerialNumber}" + Environment.NewLine;
+ strReturn += $"DN{DN_mm} [mm]" + Environment.NewLine;
+ strReturn += $"Flange: {FlangeType}" + Environment.NewLine;
+ strReturn += $"Cal. Ver: {CalibrationVersion}" + Environment.NewLine;
+ strReturn += $"Sampling Scheme: {SamplingSchemeCode}" + Environment.NewLine;
+ strReturn += $"Coil Freq.: {CoilDriverFrequencyConfig}" + Environment.NewLine;
+ strReturn += $"Number of Cal.points: {NumberOfCalibrations}" + Environment.NewLine;
+ strReturn += $"Cal.points:" + Environment.NewLine + Calibration.ToString();
+ return strReturn;
+ }
+ }
+}
diff --git a/Common/MagFluxApi/magflux_api.dll b/Common/MagFluxApi/magflux_api.dll
index 02e4c018..4342706a 100644
Binary files a/Common/MagFluxApi/magflux_api.dll and b/Common/MagFluxApi/magflux_api.dll differ
diff --git a/Common/MagFluxApi/shared_code.dll b/Common/MagFluxApi/shared_code.dll
new file mode 100644
index 00000000..552413dd
Binary files /dev/null and b/Common/MagFluxApi/shared_code.dll differ