tbf/TestBenchFramework/BenchControl/Modbus/CometAmbient/Ambient.cs

172 lines
5.4 KiB
C#

///
/// 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
{
/// <summary>
/// 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.
/// </summary>
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;
/// <summary>The state of the measurement</summary>
MsrmntState msrmntState;
///
/// Measured values when MsrmntState == MsrmntState.Valid
///
float temperature; /// [deg C]
float pressure; /// [bar]
float humidity; /// [%]
/// <summary>Measurement time stamp when MsrmntState == MsrmntState.Valid</summary>
int msrmntTimeStamp;
public Ambient()
{
}
/// <summary>
/// Ambient temperature / humidity / pressure meter 'Greco' connected via serial interface (RS232)
/// </summary>
public Ambient(Generic.IComponentCfg cfg, IList<Generic.IComponent> 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());
}
/// <summary>Run this device</summary>
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);
}
}
public void RunDeviceAfter() { }
public void StopDevice() { }
public void StopDevice2() { }
///
/// 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;
}
/// <summary>Start this operation</summary>
public void Start()
{
if (tempBox != null) tempBox.Val = temperature;
if (pressureBox != null) pressureBox.Val = pressure;
if (humiBox != null) humiBox.Val = humidity;
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.FlowInDone or Event.FlowOutDone
/// </returns>
public Event Run()
{
if (tempBox != null) tempBox.Val = temperature;
if (pressureBox != null) pressureBox.Val = pressure;
if (humiBox != null) humiBox.Val = humidity;
return Event.AmbientDone;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}