diff --git a/Config/Properties/AssemblyInfo.cs b/Config/Properties/AssemblyInfo.cs
index e55fb988a..517d0e3d8 100644
--- a/Config/Properties/AssemblyInfo.cs
+++ b/Config/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.25.1440.0")]
-[assembly: AssemblyFileVersion("2.25.1440.0")]
+[assembly: AssemblyVersion("2.26.1447.0")]
+[assembly: AssemblyFileVersion("2.26.1447.0")]
diff --git a/Results/Entities/TestRslt.cs b/Results/Entities/TestRslt.cs
index 19ac18a80..577bcc254 100644
--- a/Results/Entities/TestRslt.cs
+++ b/Results/Entities/TestRslt.cs
@@ -115,6 +115,11 @@ namespace Results.Entities
public virtual float FlowEnd { get; set; } /// [m3/h] flow at the end of test from the reference flowmeter
public virtual float FlowMin { get; set; } /// [m3/h]
public virtual float FlowMax { get; set; } /// [m3/h]
+ public virtual float ConductMean { get; set; } /// [uS/cm]
+ public virtual float ConductStart { get; set; } /// [uS/cm]
+ public virtual float ConductEnd { get; set; } /// [uS/cm]
+ public virtual float ConductMin { get; set; } /// [uS/cm]
+ public virtual float ConductMax { get; set; } /// [uS/cm]
public virtual float Uncertnt { get; set; } /// [%] Relative error uncertainty
public virtual float UncertntScale { get; set; } /// [%] Contribution to uncertainty from scale
@@ -331,6 +336,11 @@ namespace Results.Entities
FlowEnd = src.FlowEnd;
FlowMin = src.FlowMin;
FlowMax = src.FlowMax;
+ ConductMean = src.ConductMean;
+ ConductStart = src.ConductStart;
+ ConductEnd = src.ConductEnd;
+ ConductMin = src.ConductMin;
+ ConductMax = src.ConductMax;
Custom1 = src.Custom1;
Custom2 = src.Custom2;
diff --git a/Results/Mappings/TestRsltMap.cs b/Results/Mappings/TestRsltMap.cs
index 3e33b4121..d7cf3437b 100644
--- a/Results/Mappings/TestRsltMap.cs
+++ b/Results/Mappings/TestRsltMap.cs
@@ -1,5 +1,5 @@
///
-/// Copyright (c) 2015-2019 Sensus Slovensko a.s.
+/// Copyright (c) 2015-2020 Sensus Slovensko a.s.
///
using FluentNHibernate.Mapping;
using Results.Entities;
@@ -102,7 +102,13 @@ namespace Results.Mappings
Map(x => x.FlowEnd);
Map(x => x.FlowMin);
Map(x => x.FlowMax);
-
+#if TURA_IPERL || TURA_IPERL_NEW || TURA_SPECIAL
+ Map(x => x.ConductMean);
+ Map(x => x.ConductStart);
+ Map(x => x.ConductEnd);
+ Map(x => x.ConductMin);
+ Map(x => x.ConductMax);
+#endif
Map(x => x.Uncertnt);
Map(x => x.UncertntScale);
Map(x => x.UncertntDensity);
diff --git a/Results/Properties/AssemblyInfo.cs b/Results/Properties/AssemblyInfo.cs
index 80bcb247c..10dc0f906 100644
--- a/Results/Properties/AssemblyInfo.cs
+++ b/Results/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.25.1440.0")]
-[assembly: AssemblyFileVersion("2.25.1440.0")]
+[assembly: AssemblyVersion("2.26.1447.0")]
+[assembly: AssemblyFileVersion("2.26.1447.0")]
diff --git a/TBF/BenchControl/Modbus/WaterAnalyzer/Analyzer.cs b/TBF/BenchControl/Modbus/WaterAnalyzer/Analyzer.cs
new file mode 100644
index 000000000..609daf91b
--- /dev/null
+++ b/TBF/BenchControl/Modbus/WaterAnalyzer/Analyzer.cs
@@ -0,0 +1,141 @@
+///
+/// Copyright (c) 2020 Sensus Slovensko a.s.
+///
+using System;
+using System.Collections.Generic;
+using log4net;
+using TBF.BenchControl.Generic;
+using TBF.Boxes;
+using Config.Entities;
+using System.Diagnostics;
+
+namespace TBF.BenchControl.Modbus.WaterAnalyzer
+{
+ public class Analyzer : ComponentBase, GenericDevices.ITempMeter, IDevice
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof(Analyzer));
+ public override string ToString() { return string.Format("Analyzer({0})", Cfg.ToString(1)); }
+
+ readonly AnalyzerCfg myCfg;
+ readonly GenericDevices.IModbus modbus;
+
+ /// The state of the measurement
+ MsrmntState msrmntState;
+
+ ///
+ /// Measured values when MsrmntState == MsrmntState.Valid
+ ///
+ double conductivity; /// [???]
+ double temperature; /// [°C]
+
+ public double Level { get { return conductivity; } }
+
+ /// Measurement time stamp when MsrmntState == MsrmntState.Valid
+ int msrmntTimeStamp;
+
+
+ public Analyzer()
+ {
+ }
+
+ public Analyzer(Generic.IComponentCfg cfg, IList components)
+ : base(cfg)
+ {
+ myCfg = cfg as AnalyzerCfg;
+
+ modbus = (GenericDevices.IModbus)TbfComponents.FindComponent(cfg.ParentName, components);
+ if (modbus == null) throw new Exception("Cannot find " + Name + " parent");
+
+ /// Connect to handler
+ //ModbusAddress.MeretRS485Address[Idx0] = ModbusAddress;
+
+ log.Debug(this.ToString());
+ }
+
+ /// Initialize this device
+ public void Initialize()
+ {
+ if (myCfg.DebugLevel == DebugMode.Simulate)
+ {
+ conductivity = 0.0;
+ temperature = 0.0;
+
+ msrmntTimeStamp = StateMachine.Time;
+ msrmntState = MsrmntState.Valid;
+ return;
+ }
+
+ msrmntState = MsrmntState.Busy;
+
+ log.FatalFormat("Successfully initialized device {0}", ToString());
+ }
+
+
+ public double ReadLevel() { return conductivity; } /// Returns water level in mm
+ public double ReadTemperature() { return temperature; } /// Returns temperature in °C
+
+ public ReadConductivityOp ReadLevelOp(ref DoubleBox level) { return new ReadConductivityOp(this, ref level); }
+ public IOperation ReadTempOp(ref DoubleBox temperature) { return new ReadTempOp(this, ref temperature); }
+ public IOperation ReadTempOp(ref DoubleBox temperature, Event eventDone) { return new ReadTempOp(this, ref temperature, eventDone); }
+
+
+ /// Run this device
+ public void RunDeviceBefore()
+ {
+ if (myCfg.DebugLevel == Config.Entities.DebugMode.Simulate ||
+ myCfg.DebugLevel == Config.Entities.DebugMode.FailureDuringOperation)
+ {
+ msrmntTimeStamp = StateMachine.Time;
+ return;
+ }
+
+ if (modbus.ReceivedTelegrams[myCfg.ModbusAddress].Count > 0)
+ {
+ byte[] telegram = modbus.ReceivedTelegrams[myCfg.ModbusAddress].Dequeue();
+
+ if (telegram.Length == 9 && telegram[1] == 3 && telegram[2] == 4)
+ {
+ ///
+ /// Telegram with values
+ ///
+ byte[] conductBytes = new byte[] { telegram[4], telegram[3], telegram[6], telegram[5] };
+ float _conductivity = System.BitConverter.ToSingle(conductBytes, 0);
+ string line = string.Format("conductivity = {0} uS/cm", _conductivity);
+ if (true)
+ {
+ conductivity = _conductivity;
+ }
+
+ log.Debug(line);
+ Debug.WriteLine(line);
+ }
+ }
+
+
+ byte[] msg = new byte[8]; /// Buffer for data to send
+
+ if ((StateMachine.Time % 10) == 0) /// Each 10 seconds
+ {
+ ///
+ /// Send command to request 1 float value in 2 registers at addresses 0x50 and 0x51 from Modbus.WaterAnalyzer
+ ///
+ UInt16 regAddr = 0x50;
+ UInt16 count = 2;
+
+ /// Prepare data to be sent
+ msg[0] = myCfg.ModbusAddress;
+ msg[1] = 3; /// CMD =
+ msg[2] = (byte)(regAddr >> 8); /// Control Word Hi
+ msg[3] = (byte)(regAddr & 0xFF); /// Control Word Lo
+ msg[4] = (byte)(count >> 8); /// Serial Com Reference Hi
+ msg[5] = (byte)(count & 0xFF); /// Serial Com Reference Lo
+
+ modbus.SendMessage(msg);
+ }
+ }
+
+ public void RunDeviceAfter() { }
+ public void StopDevice() { }
+ public void StopDevice2() { }
+ }
+}
diff --git a/TBF/BenchControl/Modbus/WaterAnalyzer/AnalyzerCfg.cs b/TBF/BenchControl/Modbus/WaterAnalyzer/AnalyzerCfg.cs
new file mode 100644
index 000000000..d5c47c041
--- /dev/null
+++ b/TBF/BenchControl/Modbus/WaterAnalyzer/AnalyzerCfg.cs
@@ -0,0 +1,146 @@
+///
+/// Copyright (c) 2020 Sensus Slovensko a.s.
+///
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml.Serialization;
+using Config.Entities;
+using TBF.BenchControl.Generic;
+
+namespace TBF.BenchControl.Modbus.WaterAnalyzer
+{
+ public class AnalyzerCfg : ComponentCfgBase, Generic.IChildComponentCfg, Config.Entities.IParamsProvider
+ {
+ public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(AnalyzerCfg) })[0];
+ public override XmlSerializer GetSerializer() { return Serializer; }
+
+ public IComponentCfgCtrl GetControl()
+ {
+ IList parents = new List();
+ // TODO:
+ //if (StateMachine.Components != null)
+ //{
+ // foreach (var cmpnt in StateMachine.Components)
+ // {
+ // if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.BenchControl.Modbus.Common.Factory)
+ // {
+ // parents.Add(cmpnt.Name);
+ // }
+ // }
+ //}
+ parents.Add("Modbus");
+ parents.Add("ModbusUSB");
+
+ return new Configs.ParamsProvider.ComponentCfgCtrl(this, parents);
+ }
+
+ ///
+ /// Serialized parameters
+ ///
+ public byte ModbusAddress; /// 1..247
+
+ /// Private parameterless constructor invoked by all other (public) constructors
+ AnalyzerCfg() {}
+
+ public AnalyzerCfg(string name, IComponentFactory factory)
+ : this()
+ {
+ Factory = factory;
+ Name = name;
+ ParentName = "ModbusUSB";
+ InitializeAll();
+ }
+
+ public string ComponentName { get { return Name; } }
+
+ public void InitializeAll()
+ {
+ ModbusAddress = 51;
+ }
+
+
+ string[] paramNames = new string[]
+ {
+ "Modbus address",
+ };
+ public string ParamName(int i) { return paramNames[i]; }
+ public int ParamsCount() { return paramNames.Length; }
+ public IList ParamValues(int i) { return null; }
+
+ public string ToString(int i)
+ {
+ if (i == -1)
+ {
+ return string.Format("ModbusAddr={0}", ModbusAddress);
+ }
+
+ switch (i)
+ {
+ case 0: return ModbusAddress.ToString();
+ default: return string.Empty;
+ }
+ }
+
+
+ public CfgUpdateFlags UpdateParam(int i, string strValue)
+ {
+ switch (i)
+ {
+ case 0:
+ byte addr = byte.Parse(strValue);
+ if (ModbusAddress != addr)
+ {
+ ModbusAddress = addr;
+ return CfgUpdateFlags.RestartRqrd;
+ }
+ else
+ {
+ return CfgUpdateFlags.None;
+ }
+
+ default:
+ return CfgUpdateFlags.None;
+ }
+ }
+
+ public bool ValidateParam(int i, string strValue, out string message)
+ {
+ message = string.Empty;
+ int dummy;
+
+ switch (i)
+ {
+ case 0:
+ if (int.TryParse(strValue, out dummy) && dummy >= 1 && dummy <= 247) return true;
+ message = ParamName(i) + " is invalid. Address range is 1 .. 247";
+ return false;
+ default:
+ message = "Invalid index";
+ return false;
+ }
+
+ message = ParamName(i) + " is invalid";
+ return false;
+ }
+
+ void CopyContentTo(AnalyzerCfg prms)
+ {
+ prms.ParentName = this.ParentName;
+ prms.ModbusAddress = this.ModbusAddress;
+ }
+
+
+ public Config.Entities.IParamsProvider Clone()
+ {
+ AnalyzerCfg pars = new AnalyzerCfg();
+ CopyContentTo(pars);
+ return pars;
+ }
+
+ public bool UpdateEmbeddedDbEntity()
+ {
+ return true; /// =OK, do nothing
+ }
+ }
+}
diff --git a/TBF/BenchControl/Modbus/WaterAnalyzer/Factory.cs b/TBF/BenchControl/Modbus/WaterAnalyzer/Factory.cs
new file mode 100644
index 000000000..6b948c1be
--- /dev/null
+++ b/TBF/BenchControl/Modbus/WaterAnalyzer/Factory.cs
@@ -0,0 +1,26 @@
+///
+/// Copyright (c) 2020 Sensus Slovensko a.s.
+///
+using System.Collections.Generic;
+using TBF.BenchControl.Generic;
+
+namespace TBF.BenchControl.Modbus.WaterAnalyzer
+{
+ public class Factory : IComponentFactory
+ {
+ public string ClassName { get { return this.GetType().Namespace.Substring(17); } }
+
+ public void ResetStaticProperties() { Analyzer.ResetStaticProperties(); }
+
+ public IComponent DummyComponent() { return new Analyzer(); }
+
+ public IComponent GetComponent(IComponentCfg cfg, IList components) { return new Analyzer(cfg, components); }
+
+ public IComponentCfg DefaultConfig() { return new AnalyzerCfg(this.GetType().Namespace.Substring(24), this); }
+
+ public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
+ {
+ return ComponentCfgBase.CreateFromDbEntity(AnalyzerCfg.Serializer, component, this);
+ }
+ }
+}
diff --git a/TBF/BenchControl/Modbus/WaterAnalyzer/ReadConductivityOp.cs b/TBF/BenchControl/Modbus/WaterAnalyzer/ReadConductivityOp.cs
new file mode 100644
index 000000000..6111c4b5d
--- /dev/null
+++ b/TBF/BenchControl/Modbus/WaterAnalyzer/ReadConductivityOp.cs
@@ -0,0 +1,58 @@
+///
+/// Copyright (c) 2020 Sensus Slovensko a.s.
+///
+using System;
+using log4net;
+using TBF.Boxes;
+
+namespace TBF.BenchControl.Modbus.WaterAnalyzer
+{
+ public class ReadConductivityOp : IOperation
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof(ReadConductivityOp));
+ public override string ToString() { return string.Format("ReadLevelOp(.,.)"); }
+
+ /// Set by the constructor
+ readonly Analyzer analyzer;
+
+ /// Measured value
+ DoubleBox conductivity;
+
+ ///
+ /// Events: LevelDone or Error
+ ///
+ /// Water level meter reference
+ /// Reference to the measured level variable, value is in mm
+ /// Event to be returned by Run() when completed OK
+ public ReadConductivityOp(Analyzer analyzer, ref DoubleBox level)
+ {
+ if (analyzer == null) throw new ArgumentNullException("analyzer");
+ this.analyzer = analyzer;
+ this.conductivity = level;
+
+ log.Debug(this.ToString());
+ }
+
+
+ /// Start this operation
+ public void Start()
+ {
+ conductivity.Val = analyzer.ReadLevel();
+ }
+
+ /// Run this operation
+ ///
+ /// Event.LevelDone
+ ///
+ public Event Run()
+ {
+ conductivity.Val = analyzer.ReadLevel();
+ return Event.LevelDone;
+ }
+
+ /// Stop this operation
+ public void Stop()
+ {
+ }
+ }
+}
diff --git a/TBF/BenchControl/Modbus/WaterAnalyzer/ReadTempOp.cs b/TBF/BenchControl/Modbus/WaterAnalyzer/ReadTempOp.cs
new file mode 100644
index 000000000..2cedf3e6c
--- /dev/null
+++ b/TBF/BenchControl/Modbus/WaterAnalyzer/ReadTempOp.cs
@@ -0,0 +1,64 @@
+///
+/// Copyright (c) 2020 Sensus Slovensko a.s.
+///
+using System;
+using log4net;
+using TBF.Boxes;
+
+namespace TBF.BenchControl.Modbus.WaterAnalyzer
+{
+ public class ReadTempOp : IOperation
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof(ReadTempOp));
+ public override string ToString() { return string.Format("ReadTempOp(.,{0},.)", eventDone); }
+
+ /// Set by the constructor
+ readonly Analyzer analyzer;
+ readonly Event eventDone;
+
+ /// Measured value
+ DoubleBox temperature;
+
+ ///
+ /// Events: eventDone or Error
+ ///
+ /// Water temperature meter reference
+ /// Reference to the measured temperature variable, value is in l
+ /// Event to be returned by Run() when completed OK
+ public ReadTempOp(Analyzer analyzer, ref DoubleBox temperature, Event eventDone)
+ {
+ if (analyzer == null) throw new ArgumentNullException("analyzer");
+ this.analyzer = analyzer;
+ this.temperature = temperature;
+ this.eventDone = eventDone;
+
+ log.Debug(this.ToString());
+ }
+ public ReadTempOp(Analyzer levelMeter, ref DoubleBox temperature)
+ : this(levelMeter, ref temperature, Event.TempDone)
+ {
+ }
+
+
+ /// Start this operation
+ public void Start()
+ {
+ temperature.Val = analyzer.ReadTemperature();
+ }
+
+ /// Run this operation
+ ///
+ /// Event.temperatureDone
+ ///
+ public Event Run()
+ {
+ temperature.Val = analyzer.ReadTemperature();
+ return eventDone;
+ }
+
+ /// Stop this operation
+ public void Stop()
+ {
+ }
+ }
+}
diff --git a/TBF/BenchControl/TbfComponents.cs b/TBF/BenchControl/TbfComponents.cs
index 4482fa701..68d58a016 100644
--- a/TBF/BenchControl/TbfComponents.cs
+++ b/TBF/BenchControl/TbfComponents.cs
@@ -120,7 +120,8 @@ namespace TBF.BenchControl
Factories.Add(new Modbus.QuidoRS.Factory()); /// Modbus.QuidoRS
Factories.Add(new Modbus.TankSelector.Factory()); /// Modbus.TankSelector
Factories.Add(new Modbus.UltrasoundLevelMeter.Factory());
- Factories.Add(new Network.Adapter.Factory());
+ Factories.Add(new Modbus.WaterAnalyzer.Factory());
+ Factories.Add(new Network.Adapter.Factory());
Factories.Add(new Network.Camera.CLP1611.Factory());
Factories.Add(new Network.Camera.Display.Factory());
Factories.Add(new Network.Camera.Roi.Factory());
diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs
index 93e9717ef..75cdf8419 100644
--- a/TBF/Properties/AssemblyInfo.cs
+++ b/TBF/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
-[assembly: AssemblyVersion("2.25.1440.0")]
-[assembly: AssemblyFileVersion("2.25.1440.0")]
+[assembly: AssemblyVersion("2.26.1447.0")]
+[assembly: AssemblyFileVersion("2.26.1447.0")]
diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj
index 65142a17a..d89bae87d 100644
--- a/TBF/TBF.csproj
+++ b/TBF/TBF.csproj
@@ -767,6 +767,11 @@
+
+
+
+
+