230 lines
7.9 KiB
C#
230 lines
7.9 KiB
C#
///
|
|
/// Copyright (c) 2013-2019 Sensus Slovensko a.s.
|
|
///
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO.Ports;
|
|
using log4net;
|
|
using Common;
|
|
using Config.Entities;
|
|
using TBF.BenchControl.Generic;
|
|
using TBF.Boxes;
|
|
|
|
namespace TBF.BenchControl.Ambient.Comet
|
|
{
|
|
/// <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("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
|
|
|
private readonly AmbientCfg ambientCfg;
|
|
|
|
/// Private fields
|
|
SerialPort serialPort;
|
|
|
|
/// Measured values when MsrmntState == MsrmntState.Valid
|
|
float temperature; /// [°C]
|
|
float pressure; /// [bar]
|
|
float humidity; /// [R%]
|
|
|
|
/// <summary>Last valid measurement time stamp</summary>
|
|
int msrmntTimeStamp;
|
|
|
|
|
|
public Ambient() { }
|
|
|
|
/// <summary>
|
|
/// Ambient temperature / humidity / pressure meter 'Comet' connected via serial interface (RS232)
|
|
/// </summary>
|
|
public Ambient(Generic.IComponentCfg cfg)
|
|
: base(cfg)
|
|
{
|
|
ambientCfg = cfg as AmbientCfg;
|
|
}
|
|
|
|
public override void Initialize()
|
|
{
|
|
temperature = 20.0f;
|
|
humidity = 40.0f;
|
|
pressure = 1.0f;
|
|
msrmntTimeStamp = 0;
|
|
|
|
if (ambientCfg.DebugLevel == DebugMode.Normal)
|
|
{
|
|
string comPortName = "COM" + ambientCfg.ComPortNr.ToString();
|
|
serialPort = new SerialPort(comPortName, ambientCfg.BaudRate, ambientCfg.Parity, ambientCfg.DataBits, ambientCfg.StopBits);
|
|
serialPort.Handshake = ambientCfg.Handshake;
|
|
serialPort.Open();
|
|
if (ambientCfg.SetDtrToOne) serialPort.DtrEnable = true;
|
|
log.FatalFormat("{0} initialized: {1}", Name, this);
|
|
}
|
|
else
|
|
{
|
|
serialPort = null;
|
|
log.FatalFormat("{0} simulated: {1}", Name, this);
|
|
}
|
|
}
|
|
|
|
/// <summary>Run this device</summary>
|
|
public void RunDeviceBefore()
|
|
{
|
|
if ((ambientCfg.DebugLevel == DebugMode.Normal) && (serialPort != null))
|
|
{
|
|
///
|
|
/// Read response
|
|
///
|
|
try
|
|
{
|
|
int receivedBytes = serialPort.BytesToRead;
|
|
|
|
if (receivedBytes >= 13)
|
|
{
|
|
byte[] byteArr = new byte[receivedBytes];
|
|
for (int i = 0; i < receivedBytes; i++) byteArr[i] = (byte)serialPort.ReadByte();
|
|
log.Debug(Telegram.LogTelegram("Received ", byteArr));
|
|
|
|
if ((receivedBytes == 13) && (byteArr[0] == 1) && (byteArr[1] == 3) && (byteArr[2] == 8) && Telegram.VerifyTelegramCRC(byteArr))
|
|
{
|
|
int value = (int)byteArr[3] * 256 + (int)byteArr[4];
|
|
temperature = (float)value / 10.0f;
|
|
|
|
value = (int)byteArr[5] * 256 + (int)byteArr[6];
|
|
humidity = (float)value / 10.0f;
|
|
|
|
value = (int)byteArr[9] * 256 + (int)byteArr[10];
|
|
pressure = (float)value / 10000.0f;
|
|
|
|
msrmntTimeStamp = StateMachine.Time;
|
|
|
|
UpdateProcessData(temperature, pressure, humidity);
|
|
|
|
log.InfoFormat("Ambient: temperature = {0:F1} C, humidity = {1:F1} %, pressure = {2:F0} mbar", temperature, humidity, 1000 * pressure);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
DebugLevel = DebugMode.FailureDuringOperation;
|
|
//serialPort.Close(); /// ?
|
|
serialPort = null;
|
|
|
|
log.FatalFormat("Ambient: Serial 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()
|
|
{
|
|
if ((ambientCfg.DebugLevel == DebugMode.Normal) && (serialPort != null))
|
|
{
|
|
if ((StateMachine.Time % 10) == 0)
|
|
{
|
|
///
|
|
/// Send request once per 10 seconds
|
|
///
|
|
try
|
|
{
|
|
/// 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] = 1; /// (byte)ambientCfg.BusAddress;
|
|
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
|
|
Telegram.UpdateTelegramCRC(msg);
|
|
|
|
log.Debug(Telegram.LogTelegram("Sending ", msg));
|
|
serialPort.Write(msg, 0, msg.Length);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
DebugLevel = DebugMode.FailureDuringOperation;
|
|
//serialPort.Close(); /// ?
|
|
serialPort = null;
|
|
|
|
log.FatalFormat("Ambient: Serail port read failure : {0}", e.Message);
|
|
if (e.InnerException != null)
|
|
{
|
|
log.FatalFormat("InnerMessage : {0}", e.InnerException.Message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Stop this device</summary>
|
|
public void StopDevice()
|
|
{
|
|
if ((ambientCfg.DebugLevel == DebugMode.Normal) && (serialPort != null))
|
|
{
|
|
serialPort.Close();
|
|
serialPort = null;
|
|
}
|
|
}
|
|
|
|
public void StopDevice2() { }
|
|
|
|
void UpdateProcessData(float temperature, float pressure, float humidity)
|
|
{
|
|
TBF.BenchControl.Sequences.ProcessData.AmbTemp.Val = temperature;
|
|
TBF.BenchControl.Sequences.ProcessData.AmbPress.Val = pressure;
|
|
TBF.BenchControl.Sequences.ProcessData.AmbHumi.Val = humidity;
|
|
}
|
|
|
|
|
|
///
|
|
/// 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()
|
|
{
|
|
}
|
|
}
|
|
}
|