///
/// Copyright (c) 2018 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.UltrasoundLevelMeter
{
public class LevelMeter : ComponentBase, GenericDevices.ILevelMeter, GenericDevices.IVolumeMeter, GenericDevices.ITempMeter, IDevice
{
private static readonly ILog log = LogManager.GetLogger(typeof(LevelMeter));
public override string ToString() { return string.Format("LevelMeter({0})", Cfg.ToString(1)); }
readonly LevelMeterCfg myCfg;
readonly GenericDevices.IModbus modbus;
/// The state of the measurement
MsrmntState msrmntState;
///
/// Measured values when MsrmntState == MsrmntState.Valid
///
double distance; /// [mm]
double level; /// [mm]
double percentage; /// [%]
double volume; /// [l]
double temperature; /// [°C]
ushort state;
/// Measurement time stamp when MsrmntState == MsrmntState.Valid
int msrmntTimeStamp;
public LevelMeter()
{
}
public LevelMeter(Generic.IComponentCfg cfg, IList components)
: base(cfg)
{
myCfg = cfg as LevelMeterCfg;
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)
{
distance = 200.0;
level = 0;
percentage = 0;
volume = 0;
temperature = 20.0;
state = 0;
msrmntTimeStamp = StateMachine.Time;
msrmntState = MsrmntState.Valid;
return;
}
msrmntState = MsrmntState.Busy;
log.FatalFormat("Successfully initialized device {0}", ToString());
}
public double ReadLevel() { return level; } /// Returns water level in mm
public double ReadVolume() { return volume; } /// Returns volume in l
public double ReadTemperature() { return temperature; } /// Returns temperature in °C
public IOperation ReadLevelOp(ref DoubleBox level) { return new ReadLevelOp(this, ref level); }
public IOperation ReadVolumeOp(ref DoubleBox volume) { return new ReadVolumeOp(this, ref volume); }
public IOperation ReadTempOp(ref DoubleBox temperature) { return new ReadTempOp(this, ref temperature); }
public IOperation ReadLevelOp(ref DoubleBox level, Event eventDone) { return new ReadLevelOp(this, ref level, eventDone); }
public IOperation ReadVolumeOp(ref DoubleBox volume, Event eventDone) { return new ReadVolumeOp(this, ref volume, eventDone); }
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 == 15 && telegram[1] == 3 && telegram[2] == 10)
{
distance = (double)(256 * telegram[3] + telegram[4]);
level = (double)(256 * telegram[5] + telegram[6]);
percentage = (double)(256 * telegram[7] + telegram[8]);
temperature = (double)256 * telegram[9] + telegram[10];
state = (ushort)(256 * telegram[11] + telegram[12]);
volume = 0; /// TODO
string line = string.Format("dist={0} mm level={1} mm, %={2} %, temp={3} °C, volume={4} l, state={5}",
distance, level, percentage, temperature, volume, state);
log.Debug(line);
Debug.WriteLine(line);
}
}
byte[] msg = new byte[8]; /// Buffer for data to send
if ((StateMachine.Time % 3) == 0) /// Each 3 seconds
{
///
/// Read distance, level, quantity, percentage and temperature in IEEE754 (DWORD-s)
///
UInt16 regAddr = 100;
UInt16 count = 5;
/// 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);
}
else if ((StateMachine.Time % 3) == 1) /// Each 3 seconds
{
/////
///// Read STATUS1
/////
//UInt16 regAddr = 104;
//UInt16 count = 1;
///// 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);
}
else if ((StateMachine.Time % 3) == 2) /// Each 3 seconds
{
/////
///// Read distance, level, quantity, percentage and temperature in IEEE754 (DWORD-s)
/////
//UInt16 regAddr = 300;
//UInt16 count = 10;
///// 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() { }
}
}