/// /// Copyright (c) 2020 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using log4net; using TBF.BenchControl.Generic; using TBF.Boxes; using Config.Entities; using System.Diagnostics; namespace TBF.BenchControl.Modbus.WaterAnalyzer { public class Analyzer : ComponentBase, GenericDevices.ITempMeter, IDevice { private static readonly ILog log = LogManager.GetLogger(typeof(Analyzer)); public override string ToString() { return string.Format("Analyzer({0})", Cfg.ToString(1)); } readonly AnalyzerCfg myCfg; readonly GenericDevices.IModbus modbus; /// The state of the measurement MsrmntState msrmntState; /// /// Measured values when MsrmntState == MsrmntState.Valid /// float conductivity; /// [uS/cm] electrical conductivity of water double temperature; /// [°C] water temperature public float Conductivity { get { return conductivity; } } /// Measurement time stamp when MsrmntState == MsrmntState.Valid int msrmntTimeStamp; public Analyzer() { } public Analyzer(Generic.IComponentCfg cfg, IList components) : base(cfg) { myCfg = cfg as AnalyzerCfg; modbus = (GenericDevices.IModbus)TbfComponents.FindComponent(cfg.ParentName, components); if (modbus == null) throw new Exception("Cannot find " + Name + " parent"); /// Connect to handler //ModbusAddress.MeretRS485Address[Idx0] = ModbusAddress; log.Debug(this.ToString()); } /// Initialize this device public void Initialize() { if (myCfg.DebugLevel == DebugMode.Simulate) { conductivity = 0.0F; temperature = 0.0; msrmntTimeStamp = StateMachine.Time; msrmntState = MsrmntState.Valid; return; } msrmntState = MsrmntState.Busy; log.FatalFormat("Successfully initialized device {0}", ToString()); } public float ReadConductivity() { return conductivity; } /// Returns electrical conductivity of water in [uS/cm] public double ReadTemperature() { return temperature; } /// Returns water temperature in [°C] public ReadConductivityOp ReadConductivityOp(ref FloatBox conduct) { return new ReadConductivityOp(this, ref conduct); } public IOperation ReadTempOp(ref DoubleBox temperature) { return new ReadTempOp(this, ref temperature); } public IOperation ReadTempOp(ref DoubleBox temperature, Event eventDone) { return new ReadTempOp(this, ref temperature, eventDone); } /// Run this device public void RunDeviceBefore() { if (myCfg.DebugLevel == Config.Entities.DebugMode.Simulate || myCfg.DebugLevel == Config.Entities.DebugMode.FailureDuringOperation) { msrmntTimeStamp = StateMachine.Time; return; } if (modbus.ReceivedTelegrams[myCfg.ModbusAddress].Count > 0) { byte[] telegram = modbus.ReceivedTelegrams[myCfg.ModbusAddress].Dequeue(); if (telegram.Length == 9 && telegram[1] == 3 && telegram[2] == 4) { /// /// Telegram with values /// byte[] conductBytes = new byte[] { telegram[4], telegram[3], telegram[6], telegram[5] }; conductivity = System.BitConverter.ToSingle(conductBytes, 0); UpdateProcessData(conductivity); string line = string.Format("conductivity = {0} uS/cm", conductivity); log.Debug(line); Debug.WriteLine(line); } } byte[] msg = new byte[8]; /// Buffer for data to send if ((StateMachine.Time % 10) == 0) /// Each 10 seconds { /// /// Send command to request 1 float value in 2 registers at addresses 0x50 and 0x51 from Modbus.WaterAnalyzer /// UInt16 regAddr = 0x50; UInt16 count = 2; /// Prepare data to be sent msg[0] = myCfg.ModbusAddress; msg[1] = 3; /// CMD = 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() { } void UpdateProcessData(float conduct) { TBF.BenchControl.Sequences.ProcessData.Conductivity.Val = conduct; } } }