tbf/TBF/BenchControl/Ambient/Greco/Ambient.cs

214 lines
6.3 KiB
C#

///
/// Copyright (c) 2013-2016 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.Ambient.Greco
{
/// <summary>
/// Ambient temperature / humidity / pressure meter 'Greco' connected via serial interface (RS232)
/// Connection settings: 19200 Bd 8-bits No-parity 1-stop-bit Flow control: none or hardware.
/// </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)); }
private readonly AmbientCfg ambientCfg;
/// Private fields
SerialPort serialPort;
StringBuilder measurementBuilder;
/// <summary>The state of the measurement</summary>
MsrmntState msrmntState;
///
/// Measured values when MsrmntState == MsrmntState.Valid
///
float temperature; /// [°C]
float pressure; /// [bar]
float humidity; /// [R%]
/// <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)
/// Connection settings: 19200 Bd 8-bits No-parity 1-stop-bit Flow control: none or hardware.
/// </summary>
public Ambient(AmbientCfg cfg, IList<Generic.IComponent> components)
: this(cfg)
{
}
public Ambient(Generic.IComponentCfg cfg)
: base(cfg)
{
ambientCfg = cfg as AmbientCfg;
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;
}
string comPortName = "COM" + ambientCfg.ComPortNr.ToString();
serialPort = new SerialPort(comPortName, ambientCfg.BaudRate, ambientCfg.Parity, ambientCfg.DataBits, ambientCfg.StopBits);
serialPort.Handshake = ambientCfg.Handshake;
serialPort.Open();
measurementBuilder = new StringBuilder(40);
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;
}
try
{
measurementBuilder.Append(serialPort.ReadExisting());
int len = measurementBuilder.Length;
///
/// Device sends each 20 sec one line of ASCII text with data in the following format:
/// (temp) 6 characters, two decimal digits, with leading spaces
/// TAB 1 character
/// (humi) 6 characters, two decimal digits, with leading spaces
/// TAB 1 character
/// (pressure) 6 characters, one decimal digits, with leading spaces is LT 1000
/// CR + LF 2 characters
/// Example:
/// 23.42 38.08 1061.1
/// 23.39 38.04 1060.8
/// 23.39 38.08 1061.4
///
if (len >= 22)
{
string measurement = measurementBuilder.ToString();
measurementBuilder.Clear();
float t = 0;
float h = 0;
float p = 0;
if (float.TryParse(measurement.Substring(len - 22, 6), NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out t) &&
measurement[len - 16] == '\t' &&
float.TryParse(measurement.Substring(len - 15, 6), NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out h) &&
measurement[len - 9] == '\t' &&
float.TryParse(measurement.Substring(len - 8, 6), NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out p) &&
measurement[len - 2] == '\r' &&
measurement[len - 1] == '\n')
{
temperature = t;
humidity = h;
pressure = p / 1000.0F;
msrmntTimeStamp = StateMachine.Time;
msrmntState = MsrmntState.Valid;
log.InfoFormat("Ambient: temperature = {0:F1} C, humidity = {1:F1} %, pressure = {2:F0} mbar", temperature, humidity, 1000 * pressure);
}
else
{
log.Warn("Invalid string received: " + measurement);
}
}
}
catch (Exception e)
{
DebugLevel = DebugMode.FailureDuringOperation;
serialPort = null;
log.FatalFormat("Ambient: Serail port read failure : {0}", e.Message);
if (e.InnerException != null)
{
log.FatalFormat("InnerMessage : {0}", e.InnerException.Message);
}
}
}
/// <summary>Run this device</summary>
public void RunDeviceAfter()
{
}
/// <summary>Stop this device</summary>
public void StopDevice()
{
if (serialPort != null) serialPort.Close();
}
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()
{
}
}
}