diff --git a/TestBenchFramework/BenchControl/Modbus/CometAmbient/Ambient.cs b/TestBenchFramework/BenchControl/Modbus/CometAmbient/Ambient.cs
new file mode 100644
index 000000000..739bca303
--- /dev/null
+++ b/TestBenchFramework/BenchControl/Modbus/CometAmbient/Ambient.cs
@@ -0,0 +1,176 @@
+///
+/// Copyright (c) 2017 Sensus Metering Systems
+///
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO.Ports;
+using System.Text;
+using log4net;
+using Config.Entities;
+using TBF.BenchControl.Generic;
+using TBF.Boxes;
+
+namespace TBF.BenchControl.Modbus.CometAmbient
+{
+ ///
+ /// Ambient temperature / humidity / pressure meter 'Greco' connected via serial interface (RS232)
+ /// Connection settings: 9600 Bd 8-bits No-parity 2-stop-bits Flow control: none.
+ ///
+ public class Ambient : ComponentBase, IDevice, IOperation, GenericDevices.IAmbient
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof(Ambient));
+ public override string ToString() { return string.Format("Ambient({0})", Cfg.ToString(1)); }
+
+ readonly AmbientCfg ambientCfg;
+ readonly GenericDevices.IModbus modbus;
+
+ /// The state of the measurement
+ MsrmntState msrmntState;
+
+ ///
+ /// Measured values when MsrmntState == MsrmntState.Valid
+ ///
+ float temperature; /// [deg C]
+ float pressure; /// [bar]
+ float humidity; /// [%]
+
+ /// Measurement time stamp when MsrmntState == MsrmntState.Valid
+ int msrmntTimeStamp;
+
+ public Ambient()
+ {
+ }
+
+ ///
+ /// Ambient temperature / humidity / pressure meter 'Greco' connected via serial interface (RS232)
+ ///
+ public Ambient(Generic.IComponentCfg cfg, IList components)
+ : base(cfg)
+ {
+ ambientCfg = cfg as AmbientCfg;
+
+ modbus = (GenericDevices.IModbus)TbfComponents.FindComponent(cfg.ParentName, components);
+ if (modbus == null) throw new Exception("Cannot find " + Name + " parent");
+
+ log.Debug(this.ToString());
+ }
+
+ public void Initialize()
+ {
+ if (ambientCfg.DebugLevel == DebugMode.Simulate)
+ {
+ temperature = 20.0f;
+ humidity = 40.0f;
+ pressure = 1.0f;
+ msrmntTimeStamp = StateMachine.Time;
+ msrmntState = MsrmntState.Valid;
+ return;
+ }
+
+ msrmntState = MsrmntState.Busy;
+
+ log.FatalFormat("Successfully initialized device {0}", ToString());
+ }
+
+ /// Run this device
+ public void RunDeviceBefore()
+ {
+ if (ambientCfg.DebugLevel == DebugMode.Simulate ||
+ ambientCfg.DebugLevel == DebugMode.FailureDuringOperation)
+ {
+ msrmntTimeStamp = StateMachine.Time;
+ return;
+ }
+
+ if (modbus.ReceivedTelegrams[ambientCfg.ModbusAddress].Count > 0)
+ {
+ byte[] telegram = modbus.ReceivedTelegrams[ambientCfg.ModbusAddress].Dequeue();
+
+ if (telegram.Length == 13 && telegram[1] == 3 && telegram[2] == 8)
+ {
+ int value = (int)telegram[3] * 256 + (int)telegram[4];
+ temperature = (float)value / 10.0f;
+
+ value = (int)telegram[5] * 256 + (int)telegram[6];
+ humidity = (float)value / 10.0f;
+
+ value = (int)telegram[9] * 256 + (int)telegram[10];
+ pressure = (float)value / 10000.0f;
+
+ msrmntTimeStamp = StateMachine.Time;
+ msrmntState = MsrmntState.Valid;
+ log.InfoFormat("Ambient: temperature = {0} C, humidity = {1} %, pressure = {2} mbar", temperature.ToString("F1"), humidity.ToString("F1"), (1000 * pressure).ToString("F0"));
+ }
+ }
+
+ if ((StateMachine.Time % 10) == (ambientCfg.ModbusAddress % 10)) /// Each 10 seconds
+ {
+ /// Read four registers: 0x31, 0x32, 0x33, 0x34
+ UInt16 regAddr = 0x0030; /// register addr. = 0x31 (Modbus!)
+ UInt16 count = 4;
+
+ /// Prepare data to be sent
+ byte[] msg = new byte[8];
+ msg[0] = ambientCfg.ModbusAddress;
+ msg[1] = 3; /// CMD = Read registers
+ 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);
+ }
+ }
+
+ /// Run this device
+ public void RunDeviceAfter()
+ {
+ }
+
+ /// Stop this device
+ public void StopDevice()
+ {
+ }
+
+ ///
+ /// Boxes for the operation result
+ ///
+ FloatBox tempBox;
+ FloatBox pressureBox;
+ FloatBox humiBox;
+
+ public IOperation ReadAmbientOp(FloatBox temperature, FloatBox pressure, FloatBox humidity)
+ {
+ this.tempBox = temperature;
+ this.pressureBox = pressure;
+ this.humiBox = humidity;
+ return this;
+ }
+
+ /// Start this operation
+ public void Start()
+ {
+ if (tempBox != null) tempBox.Val = temperature;
+ if (pressureBox != null) pressureBox.Val = pressure;
+ if (humiBox != null) humiBox.Val = humidity;
+ }
+
+ /// Run this operation
+ ///
+ /// Event.FlowInDone or Event.FlowOutDone
+ ///
+ public Event Run()
+ {
+ if (tempBox != null) tempBox.Val = temperature;
+ if (pressureBox != null) pressureBox.Val = pressure;
+ if (humiBox != null) humiBox.Val = humidity;
+ return Event.AmbientDone;
+ }
+
+ /// Stop this operation
+ public void Stop()
+ {
+ }
+ }
+}
diff --git a/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfg.cs b/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfg.cs
new file mode 100644
index 000000000..126a5aaf5
--- /dev/null
+++ b/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfg.cs
@@ -0,0 +1,45 @@
+///
+/// Copyright (c) 2017 Sensus Metering Systems
+///
+using System;
+using System.Xml.Serialization;
+using Config.Entities;
+using TBF.BenchControl.Generic;
+
+namespace TBF.BenchControl.Modbus.CometAmbient
+{
+ public class AmbientCfg : ComponentCfgBase, Generic.IChildComponentCfg
+ {
+ public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(AmbientCfg) })[0];
+ protected override XmlSerializer GetSerializer() { return Serializer; }
+
+ public IComponentCfgCtrl GetControl() { return new AmbientCfgCtrl(); }
+
+ ///
+ /// Serialized parameters
+ ///
+ public byte ModbusAddress; /// 1..255
+
+ /// Private parameterless constructor invoked by all other (public) constructors
+ AmbientCfg()
+ {
+ Name = "Ambient";
+ ParentName = "Modbus";
+ ModbusAddress = 1;
+ }
+
+ public AmbientCfg(IComponentFactory factory)
+ : this()
+ {
+ this.Factory = factory;
+ }
+
+ public string ToString(int i)
+ {
+ return string.Format("Name={0}, ModbusAddr={1}, Parent={2}",
+ Name,
+ ModbusAddress,
+ (string.IsNullOrEmpty(ParentName) ? "-" : ParentName));
+ }
+ }
+}
diff --git a/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfgCtrl.Designer.cs b/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfgCtrl.Designer.cs
new file mode 100644
index 000000000..5649b543a
--- /dev/null
+++ b/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfgCtrl.Designer.cs
@@ -0,0 +1,156 @@
+///
+/// Copyright (c) 2017 Sensus Metering Systems
+///
+namespace TBF.BenchControl.Modbus.CometAmbient
+{
+ partial class AmbientCfgCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.parentNameLabel = new System.Windows.Forms.Label();
+ this.nameTextBox = new System.Windows.Forms.TextBox();
+ this.nameLabel = new System.Windows.Forms.Label();
+ this.componentNameLabel = new System.Windows.Forms.Label();
+ this.modbusAddressLabel = new System.Windows.Forms.Label();
+ this.modbusAddressTextBox = new System.Windows.Forms.TextBox();
+ this.parentNameComboBox = new System.Windows.Forms.ComboBox();
+ this.reservoirNrTextBox = new System.Windows.Forms.TextBox();
+ this.reservoirNrLabel = new System.Windows.Forms.Label();
+ this.SuspendLayout();
+ //
+ // parentNameLabel
+ //
+ this.parentNameLabel.AutoSize = true;
+ this.parentNameLabel.Location = new System.Drawing.Point(28, 81);
+ this.parentNameLabel.Name = "parentNameLabel";
+ this.parentNameLabel.Size = new System.Drawing.Size(69, 13);
+ this.parentNameLabel.TabIndex = 3;
+ this.parentNameLabel.Text = "Parent Name";
+ //
+ // nameTextBox
+ //
+ this.nameTextBox.Enabled = false;
+ this.nameTextBox.Location = new System.Drawing.Point(138, 52);
+ this.nameTextBox.Name = "nameTextBox";
+ this.nameTextBox.Size = new System.Drawing.Size(130, 20);
+ this.nameTextBox.TabIndex = 2;
+ //
+ // nameLabel
+ //
+ this.nameLabel.AutoSize = true;
+ this.nameLabel.Location = new System.Drawing.Point(28, 55);
+ this.nameLabel.Name = "nameLabel";
+ this.nameLabel.Size = new System.Drawing.Size(35, 13);
+ this.nameLabel.TabIndex = 1;
+ this.nameLabel.Text = "Name";
+ //
+ // componentNameLabel
+ //
+ this.componentNameLabel.AutoSize = true;
+ this.componentNameLabel.Location = new System.Drawing.Point(135, 28);
+ this.componentNameLabel.Name = "componentNameLabel";
+ this.componentNameLabel.Size = new System.Drawing.Size(83, 13);
+ this.componentNameLabel.TabIndex = 0;
+ this.componentNameLabel.Text = "ComonentName";
+ //
+ // modbusAddressLabel
+ //
+ this.modbusAddressLabel.AutoSize = true;
+ this.modbusAddressLabel.Location = new System.Drawing.Point(28, 108);
+ this.modbusAddressLabel.Name = "modbusAddressLabel";
+ this.modbusAddressLabel.Size = new System.Drawing.Size(86, 13);
+ this.modbusAddressLabel.TabIndex = 7;
+ this.modbusAddressLabel.Text = "Modbus Address";
+ //
+ // modbusAddressTextBox
+ //
+ this.modbusAddressTextBox.Enabled = false;
+ this.modbusAddressTextBox.Location = new System.Drawing.Point(138, 105);
+ this.modbusAddressTextBox.Name = "modbusAddressTextBox";
+ this.modbusAddressTextBox.Size = new System.Drawing.Size(46, 20);
+ this.modbusAddressTextBox.TabIndex = 8;
+ //
+ // parentNameComboBox
+ //
+ this.parentNameComboBox.Enabled = false;
+ this.parentNameComboBox.FormattingEnabled = true;
+ this.parentNameComboBox.Location = new System.Drawing.Point(138, 78);
+ this.parentNameComboBox.Name = "parentNameComboBox";
+ this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
+ this.parentNameComboBox.TabIndex = 4;
+ //
+ // reservoirNrTextBox
+ //
+ this.reservoirNrTextBox.Enabled = false;
+ this.reservoirNrTextBox.Location = new System.Drawing.Point(138, 130);
+ this.reservoirNrTextBox.Name = "reservoirNrTextBox";
+ this.reservoirNrTextBox.Size = new System.Drawing.Size(46, 20);
+ this.reservoirNrTextBox.TabIndex = 10;
+ //
+ // reservoirNrLabel
+ //
+ this.reservoirNrLabel.AutoSize = true;
+ this.reservoirNrLabel.Location = new System.Drawing.Point(28, 133);
+ this.reservoirNrLabel.Name = "reservoirNrLabel";
+ this.reservoirNrLabel.Size = new System.Drawing.Size(67, 13);
+ this.reservoirNrLabel.TabIndex = 9;
+ this.reservoirNrLabel.Text = "Reservoir nr.";
+ //
+ // EasythermCfgCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.reservoirNrTextBox);
+ this.Controls.Add(this.reservoirNrLabel);
+ this.Controls.Add(this.parentNameComboBox);
+ this.Controls.Add(this.modbusAddressTextBox);
+ this.Controls.Add(this.modbusAddressLabel);
+ this.Controls.Add(this.parentNameLabel);
+ this.Controls.Add(this.nameTextBox);
+ this.Controls.Add(this.nameLabel);
+ this.Controls.Add(this.componentNameLabel);
+ this.Name = "EasythermCfgCtrl";
+ this.Size = new System.Drawing.Size(300, 200);
+ this.Load += new System.EventHandler(this.AmbientCfgCtrl_Load);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label parentNameLabel;
+ private System.Windows.Forms.TextBox nameTextBox;
+ private System.Windows.Forms.Label nameLabel;
+ private System.Windows.Forms.Label componentNameLabel;
+ private System.Windows.Forms.Label modbusAddressLabel;
+ private System.Windows.Forms.TextBox modbusAddressTextBox;
+ private System.Windows.Forms.ComboBox parentNameComboBox;
+ private System.Windows.Forms.TextBox reservoirNrTextBox;
+ private System.Windows.Forms.Label reservoirNrLabel;
+ }
+}
diff --git a/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfgCtrl.cs b/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfgCtrl.cs
new file mode 100644
index 000000000..2adaaa328
--- /dev/null
+++ b/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfgCtrl.cs
@@ -0,0 +1,106 @@
+///
+/// Copyright (c) 2017 Sensus Metering Systems
+///
+using System;
+using System.Windows.Forms;
+using log4net;
+using TBF.BenchControl.Generic;
+
+namespace TBF.BenchControl.Modbus.CometAmbient
+{
+ public partial class AmbientCfgCtrl : UserControl, IComponentCfgCtrl
+ {
+ static readonly ILog log = LogManager.GetLogger(typeof(AmbientCfgCtrl));
+
+ ComponentParametersDlg parent;
+
+ public bool ShowMore { get { return false; } }
+
+ AmbientCfg config;
+ public IComponentCfg Config
+ {
+ get { return config as IComponentCfg; }
+ set
+ {
+ config = value as AmbientCfg;
+ Redraw();
+ }
+ }
+
+ public AmbientCfgCtrl()
+ {
+ InitializeComponent();
+ }
+
+ private void AmbientCfgCtrl_Load(object sender, EventArgs e)
+ {
+ parent = ParentForm as ComponentParametersDlg;
+ if (parent == null) return;
+
+ if (parent.TbfComponents != null)
+ {
+ foreach (var cmpnt in parent.TbfComponents)
+ {
+ if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Modbus.Common.Factory)
+ {
+ parentNameComboBox.Items.Add(cmpnt.Name);
+ }
+ }
+ }
+
+ Redraw();
+ }
+
+ public void Closing()
+ {
+ }
+
+ void Redraw()
+ {
+ if (config == null) return; /// Control was not loaded, settings were not changed
+
+ componentNameLabel.Text = config.Factory.ClassName;
+ nameTextBox.Text = config.Name;
+ parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
+ modbusAddressTextBox.Text = config.ModbusAddress.ToString();
+ }
+
+ public void Unlock()
+ {
+ nameTextBox.Enabled = true;
+ parentNameComboBox.Enabled = true;
+ modbusAddressTextBox.Enabled = true;
+ }
+
+ public CfgUpdateFlags VerifyCfg(ref string message)
+ {
+ CfgUpdateFlags flags = CfgUpdateFlags.None;
+
+ int dummy;
+ if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
+ {
+ flags |= CfgUpdateFlags.Error;
+ message += Environment.NewLine + "Invalid 'Parent Name'";
+ }
+ if (!int.TryParse(modbusAddressTextBox.Text, out dummy) || dummy < 0 || dummy > 255)
+ {
+ flags |= CfgUpdateFlags.Error;
+ message += Environment.NewLine + "'Modbus Address' should be between 0 and 255";
+ }
+ return flags;
+ }
+
+ public CfgUpdateFlags UpdateCfg()
+ {
+ CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
+
+ if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
+
+ config.Name = nameTextBox.Text;
+ config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
+ config.ModbusAddress = (byte)int.Parse(modbusAddressTextBox.Text);
+
+ return flags;
+ }
+ }
+}
diff --git a/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfgCtrl.resx b/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfgCtrl.resx
new file mode 100644
index 000000000..1af7de150
--- /dev/null
+++ b/TestBenchFramework/BenchControl/Modbus/CometAmbient/AmbientCfgCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/TestBenchFramework/BenchControl/Modbus/CometAmbient/Factory.cs b/TestBenchFramework/BenchControl/Modbus/CometAmbient/Factory.cs
new file mode 100644
index 000000000..5c43f92cb
--- /dev/null
+++ b/TestBenchFramework/BenchControl/Modbus/CometAmbient/Factory.cs
@@ -0,0 +1,26 @@
+///
+/// Copyright (c) 2017 Sensus Metering Systems
+///
+using System.Collections.Generic;
+using TBF.BenchControl.Generic;
+
+namespace TBF.BenchControl.Modbus.CometAmbient
+{
+ public class Factory : IComponentFactory
+ {
+ public string ClassName { get { return this.GetType().Namespace.Substring(17); } }
+
+ public void ResetStaticProperties() { Ambient.ResetStaticProperties(); }
+
+ public IComponent DummyComponent() { return new Ambient(); }
+
+ public IComponent GetComponent(IComponentCfg cfg, IList components) { return new Ambient(cfg, components); }
+
+ public IComponentCfg DefaultConfig() { return new AmbientCfg(this); }
+
+ public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
+ {
+ return ComponentCfgBase.CreateFromDbEntity(AmbientCfg.Serializer, component, this);
+ }
+ }
+}
diff --git a/TestBenchFramework/BenchControl/TbfComponents.cs b/TestBenchFramework/BenchControl/TbfComponents.cs
index 8a20b27e0..710c3bb7e 100644
--- a/TestBenchFramework/BenchControl/TbfComponents.cs
+++ b/TestBenchFramework/BenchControl/TbfComponents.cs
@@ -74,7 +74,8 @@ namespace TBF.BenchControl
Factories.Add(new MettlerToledo.Standard.BalanceOldFactory()); /// MettlerToledoBalanceOld
Factories.Add(new MettlerToledo.Standard.BalanceNewFactory()); /// MettlerToledoBalanceSN
Factories.Add(new MettlerToledo.Multi.BalanceFactory()); /// MettlerToledo-Multi
- Factories.Add(new Modbus.Common.Factory()); /// Modbus
+ Factories.Add(new Modbus.CometAmbient.Factory()); /// Modbus.CometAmbient.Ambient
+ Factories.Add(new Modbus.Common.Factory()); /// Modbus
Factories.Add(new Modbus.Easytherm.Factory()); /// Modbus.Easytherm
Factories.Add(new Modbus.PressureMeter.Meret.Factory()); /// Modbus.PressureMeter.Meret - Meret pressure meter connected via modbus
Factories.Add(new Modbus.QuidoRS.Factory()); /// Modbus.QuidoRS
diff --git a/TestBenchFramework/Properties/AssemblyInfo.cs b/TestBenchFramework/Properties/AssemblyInfo.cs
index e87592da2..5d5e6d386 100644
--- a/TestBenchFramework/Properties/AssemblyInfo.cs
+++ b/TestBenchFramework/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
-[assembly: AssemblyVersion("2.17.677.1")]
-[assembly: AssemblyFileVersion("2.17.677.1")]
+[assembly: AssemblyVersion("2.17.678.1")]
+[assembly: AssemblyFileVersion("2.17.678.1")]
diff --git a/TestBenchFramework/TBF.csproj b/TestBenchFramework/TBF.csproj
index 4b04ad9da..2fe7b8389 100644
--- a/TestBenchFramework/TBF.csproj
+++ b/TestBenchFramework/TBF.csproj
@@ -568,6 +568,15 @@
+
+
+
+ UserControl
+
+
+ AmbientCfgCtrl.cs
+
+
@@ -2092,6 +2101,9 @@
BalanceCfgCtrl.cs
+
+ AmbientCfgCtrl.cs
+
ModbusCfgCtrl.cs