Modbus.WaterAnalyzer added, ver.2.26.1447

This commit is contained in:
Milan Hanajik 2020-04-01 11:59:06 +02:00
parent 1dfcd24e34
commit e21464f24e
12 changed files with 466 additions and 9 deletions

View File

@ -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")]

View File

@ -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;

View File

@ -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);

View File

@ -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")]

View File

@ -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;
/// <summary>The state of the measurement</summary>
MsrmntState msrmntState;
///
/// Measured values when MsrmntState == MsrmntState.Valid
///
double conductivity; /// [???]
double temperature; /// [°C]
public double Level { get { return conductivity; } }
/// <summary>Measurement time stamp when MsrmntState == MsrmntState.Valid</summary>
int msrmntTimeStamp;
public Analyzer()
{
}
public Analyzer(Generic.IComponentCfg cfg, IList<Generic.IComponent> 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());
}
/// <summary>Initialize this device</summary>
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); }
/// <summary>Run this device</summary>
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() { }
}
}

View File

@ -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<string> parents = new List<string>();
// 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<string> 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
}
}
}

View File

@ -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<IComponent> 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);
}
}
}

View File

@ -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;
/// <summary>
/// Events: LevelDone or Error
/// </summary>
/// <param name="analyzer">Water level meter reference</param>
/// <param name="level">Reference to the measured level variable, value is in mm</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
public ReadConductivityOp(Analyzer analyzer, ref DoubleBox level)
{
if (analyzer == null) throw new ArgumentNullException("analyzer");
this.analyzer = analyzer;
this.conductivity = level;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
conductivity.Val = analyzer.ReadLevel();
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.LevelDone
/// </returns>
public Event Run()
{
conductivity.Val = analyzer.ReadLevel();
return Event.LevelDone;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}

View File

@ -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;
/// <summary>
/// Events: eventDone or Error
/// </summary>
/// <param name="analyzer">Water temperature meter reference</param>
/// <param name="temperature">Reference to the measured temperature variable, value is in l</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
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)
{
}
/// <summary>Start this operation</summary>
public void Start()
{
temperature.Val = analyzer.ReadTemperature();
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.temperatureDone
/// </returns>
public Event Run()
{
temperature.Val = analyzer.ReadTemperature();
return eventDone;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}

View File

@ -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());

View File

@ -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")]

View File

@ -767,6 +767,11 @@
<Compile Include="BenchControl\Modbus\UltrasoundLevelMeter\ReadLevelOp.cs" />
<Compile Include="BenchControl\Modbus\UltrasoundLevelMeter\ReadStableLevelOp.cs" />
<Compile Include="BenchControl\Modbus\UltrasoundLevelMeter\ReadTempOp.cs" />
<Compile Include="BenchControl\Modbus\WaterAnalyzer\Factory.cs" />
<Compile Include="BenchControl\Modbus\WaterAnalyzer\Analyzer.cs" />
<Compile Include="BenchControl\Modbus\WaterAnalyzer\AnalyzerCfg.cs" />
<Compile Include="BenchControl\Modbus\WaterAnalyzer\ReadConductivityOp.cs" />
<Compile Include="BenchControl\Modbus\WaterAnalyzer\ReadTempOp.cs" />
<Compile Include="BenchControl\Network\AdapterInfo.cs" />
<Compile Include="BenchControl\Network\Adapter\Netadapter.cs" />
<Compile Include="BenchControl\Network\Adapter\Factory.cs" />