- Introduced simulation timers in `FlyingStartStopTestOp`. - Added `Simulate` methods in `WaterMetrologyData`, `WaterMetrologyDataC7`, and `WaterMetrologyDataC2`. - Enhanced `SmartCommunicationForm` with textbox resizing logic and initialization code. - Implemented flow rate and volume calculation from optohead telemetry in `SmartReader`. - Added unit tests for Poseidon correction parsing.
203 lines
6.5 KiB
C#
203 lines
6.5 KiB
C#
using System;
|
|
using System.IO.Ports;
|
|
using System.Threading.Tasks;
|
|
using Common;
|
|
using log4net;
|
|
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols;
|
|
using TBF.Rig.Sequences;
|
|
using SERIAL_Driver = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.SERIAL_Driver;
|
|
using WaterMetrologyData = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.WaterMetrologyData;
|
|
|
|
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
|
{
|
|
public class OptoHeadService
|
|
{
|
|
static readonly ILog log = LogManager.GetLogger("PoseidonConnection");
|
|
|
|
public class Con
|
|
{
|
|
|
|
public string com = "COM5";
|
|
public int baudrate = 38400;
|
|
public int dataBits = 8;
|
|
public Parity parity = Parity.None;
|
|
public StopBits stopbits = StopBits.Two;
|
|
public int readTimeout = 5000;
|
|
public int writeTimeout = 1000;
|
|
private DebugMode _debugLevel;
|
|
public DebugMode DebugModeSetting { get => _debugLevel; }
|
|
|
|
public Con(string com, int baudrate, int dataBits, Parity parity, StopBits stopbits, int readTimeout,
|
|
int writeTimeout) : this(com)
|
|
{
|
|
this.baudrate = baudrate;
|
|
this.dataBits = dataBits;
|
|
this.parity = parity;
|
|
this.stopbits = stopbits;
|
|
this.readTimeout = readTimeout;
|
|
this.writeTimeout = writeTimeout;
|
|
}
|
|
|
|
public Con(DebugMode debugLevel,string com, int baudrate, int dataBits, Parity parity, StopBits stopbits, int readTimeout,
|
|
int writeTimeout) : this(com)
|
|
{
|
|
this._debugLevel = debugLevel;
|
|
this.baudrate = baudrate;
|
|
this.dataBits = dataBits;
|
|
this.parity = parity;
|
|
this.stopbits = stopbits;
|
|
this.readTimeout = readTimeout;
|
|
this.writeTimeout = writeTimeout;
|
|
}
|
|
|
|
public Con(string com, DebugMode debugLevel = DebugMode.Normal)
|
|
{
|
|
this.com = com;
|
|
this._debugLevel = debugLevel;
|
|
}
|
|
}
|
|
|
|
private Con Connection { get; set; }
|
|
private SERIAL_Driver driver;
|
|
/// <summary>
|
|
/// Filed After Run() is called.
|
|
/// </summary>
|
|
public WaterMetrologyData WaterMetrologyData { get; private set; }
|
|
|
|
public OptoHeadService(Con con)
|
|
{
|
|
Connection = con;
|
|
driver = new SERIAL_Driver();
|
|
OnOptoReceivedHandler = null;
|
|
}
|
|
|
|
public bool CreateSerialConnection()
|
|
{
|
|
OnOptoReceivedHandler = null;
|
|
bool isopen = false;
|
|
Con con = Connection;
|
|
if (con == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
byte[] message = {0x00};
|
|
byte[] bytesReceived;
|
|
|
|
if (con?.DebugModeSetting == DebugMode.Simulate)
|
|
{
|
|
isopen = true;
|
|
}
|
|
else if (!driver.isOpen())
|
|
{
|
|
|
|
isopen = driver.OpenConnection(
|
|
con.com,
|
|
con.baudrate,
|
|
con.dataBits,
|
|
con.parity,
|
|
con.stopbits,
|
|
con.readTimeout,
|
|
con.writeTimeout);
|
|
}
|
|
|
|
_bRunStarted = false;
|
|
|
|
return isopen;
|
|
}
|
|
|
|
public void CloseSerialConnection()
|
|
{
|
|
dissableRunLoop = true;
|
|
OnOptoReceivedHandler = null;
|
|
if (Connection?.DebugModeSetting != DebugMode.Simulate)
|
|
{
|
|
driver.Close();
|
|
}
|
|
_bRunStarted = false;
|
|
}
|
|
|
|
private EventHandler<CommonRR.IPerl.communication.OptoReceivedEventArgs> OnOptoReceivedHandler;
|
|
|
|
|
|
|
|
public bool IsRunning
|
|
{
|
|
get { return !dissableRunLoop
|
|
&& ((Connection?.DebugModeSetting != DebugMode.Simulate) ? driver.isOpen() : true)
|
|
&& _bRunStarted;}
|
|
}
|
|
|
|
public void RunLoop(EventHandler<CommonRR.IPerl.communication.OptoReceivedEventArgs> onOptoReceivedHandler)
|
|
{
|
|
log.Debug("RunLoop started on event!");
|
|
OnOptoReceivedHandler = onOptoReceivedHandler;
|
|
Task.Run(() => Run());
|
|
}
|
|
|
|
public void RunLoop()
|
|
{
|
|
log.Debug("RunLoop started!");
|
|
Task.Run(() => Run());
|
|
}
|
|
|
|
private bool dissableRunLoop = false;
|
|
private bool _bRunStarted = false;
|
|
/// <summary>
|
|
/// Run the service. Catch one communication to WaterMetrologyData field.
|
|
/// </summary>
|
|
public void Run()
|
|
{
|
|
while (!dissableRunLoop)
|
|
{
|
|
_bRunStarted = true;
|
|
WaterMetrologyData = ParseData(RunReading());
|
|
if (OnOptoReceivedHandler != null && WaterMetrologyData != null)
|
|
{
|
|
log.Debug($"Received OptoData: {WaterMetrologyData}");
|
|
OnOptoReceivedHandler?.Invoke(this, new CommonRR.IPerl.communication.OptoReceivedEventArgs(WaterMetrologyData?.ToString(), WaterMetrologyData));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
byte[] RunReading()
|
|
{
|
|
if (Connection?.DebugModeSetting != DebugMode.Simulate)
|
|
{
|
|
return new byte[] {0x00};
|
|
}
|
|
if (driver.isOpen())
|
|
{
|
|
driver.SendMessage(new byte[] {0x00}, 1);
|
|
byte[] rawData = driver.GetRawData();
|
|
log.Debug($"Received data size: {rawData?.Length ?? 0} bytes, raw data: {(rawData==null? "" :BitConverter.ToString(rawData))}");
|
|
return rawData;
|
|
}
|
|
else
|
|
{
|
|
log.Debug("Serial port is not open.");
|
|
dissableRunLoop = true;
|
|
}
|
|
|
|
return new byte[] {0xFF};
|
|
}
|
|
|
|
public WaterMetrologyData ParseData(byte[] data)
|
|
{
|
|
if (Connection?.DebugModeSetting != DebugMode.Simulate)
|
|
{
|
|
return WaterMetrologyData.SimulateC7();
|
|
}
|
|
try
|
|
{
|
|
if (data == null || data.Length == 0)
|
|
return null;
|
|
return WaterMetrologyData.Parse(data, DateTime.Now, "");
|
|
}catch(Exception e)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
} |