189 lines
7.2 KiB
C#
189 lines
7.2 KiB
C#
///
|
|
/// 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;
|
|
|
|
/// <summary>The state of the measurement</summary>
|
|
MsrmntState msrmntState;
|
|
|
|
///
|
|
/// Measured values when MsrmntState == MsrmntState.Valid
|
|
///
|
|
double distance; /// [mm]
|
|
double level; /// [mm]
|
|
double percentage; /// [%]
|
|
double volume; /// [l]
|
|
double temperature; /// [°C]
|
|
ushort state;
|
|
|
|
public double Level { get { return level; } }
|
|
|
|
/// <summary>Measurement time stamp when MsrmntState == MsrmntState.Valid</summary>
|
|
int msrmntTimeStamp;
|
|
|
|
|
|
public LevelMeter()
|
|
{
|
|
}
|
|
|
|
public LevelMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> 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());
|
|
}
|
|
|
|
/// <summary>Initialize this device</summary>
|
|
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); }
|
|
|
|
|
|
/// <summary>Run this device</summary>
|
|
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() { }
|
|
}
|
|
}
|