/// /// Copyright (c) 2013-2015 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.Comet { /// /// 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)); } private readonly AmbientCfg ambientCfg; /// Private fields SerialPort serialPort; /// The state of the measurement MsrmntState msrmntState; /// Measured temperature when MsrmntState == MsrmntState.Valid float temperature; /// Measured humidity when MsrmntState == MsrmntState.Valid float humidity; /// Measured pressure when MsrmntState == MsrmntState.Valid float pressure; /// Measurement time stamp when MsrmntState == MsrmntState.Valid int msrmntTimeStamp; public Ambient() { } /// /// 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. /// public Ambient(AmbientCfg cfg, IList components) : base(cfg) { ambientCfg = cfg; 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(); 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; } 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 / 10.0f; msrmntTimeStamp = StateMachine.Time; msrmntState = MsrmntState.Valid; log.InfoFormat("Ambient: temperature = {0} C, humidity = {1} %, pressure = {2} hPa", temperature.ToString("F1"), humidity.ToString("F1"), pressure.ToString("F0")); } } } 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); } } } /// Run this device public void RunDeviceAfter() { if (ambientCfg.DebugLevel == DebugMode.Simulate || ambientCfg.DebugLevel == DebugMode.FailureDuringOperation) { return; } try { /// Each 10 seconds if ((StateMachine.Time % 10) == 0) { /// 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 = null; log.FatalFormat("Ambient: Serail port read failure : {0}", e.Message); if (e.InnerException != null) { log.FatalFormat("InnerMessage : {0}", e.InnerException.Message); } } } /// Stop this device public void StopDevice() { if (serialPort != null) serialPort.Close(); } /// /// 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() { } } }