Refactor PoseidonReader to use lazy initialization for CliRunner, introduce SafetyTimeOut, enhance JSON deserialization with fallback logic, and improve error logging using log4net.
This commit is contained in:
parent
35e4078dda
commit
780d44166e
@ -346,7 +346,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
if (iRegReader is PoseidonReader)
|
||||
{
|
||||
PoseidonReader poseidonReader = (iRegReader as PoseidonReader);
|
||||
if(poseidonReader != null)
|
||||
if(poseidonReader == null)
|
||||
continue;
|
||||
if (!(poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.ReadDatastream_Done
|
||||
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.ReadDatastream_Running))
|
||||
|
||||
@ -2,14 +2,19 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using log4net;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SharedDatabase;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
public class CliRunner
|
||||
{
|
||||
static readonly ILog log = LogManager.GetLogger(typeof(CliRunner));
|
||||
private List<Task> taskPool = new List<Task>();
|
||||
private long startTime;
|
||||
|
||||
@ -96,13 +101,13 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
return allOutput;
|
||||
}
|
||||
|
||||
public void AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg)
|
||||
public void AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg) where T : new()
|
||||
{
|
||||
var task = RunAndCaptureJsonAsync<T>(data.SerialPortCmdClientPath, data.DefaultArgSettings(eMeterArg));
|
||||
taskPool.Add(task);
|
||||
}
|
||||
|
||||
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args)
|
||||
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args) where T : new()
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
@ -136,12 +141,58 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|
||||
if (json != null)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(json);
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Debug(ex.Message);
|
||||
return TryConvert<T>(json);
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
private static T TryConvert<T>(string json) where T : new()
|
||||
{
|
||||
|
||||
T obj = new T();
|
||||
|
||||
try
|
||||
{
|
||||
JObject jObject = JObject.Parse(json);
|
||||
|
||||
foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
if (!prop.CanWrite) continue;
|
||||
|
||||
JToken token;
|
||||
if (jObject.TryGetValue(prop.Name, StringComparison.OrdinalIgnoreCase, out token))
|
||||
{
|
||||
try
|
||||
{
|
||||
object value = token.ToObject(prop.PropertyType);
|
||||
prop.SetValue(obj, value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// leave default if conversion fails
|
||||
}
|
||||
}
|
||||
// else → keep default value
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"TryConvert failed: {ex.Message}");
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
private string ExtractJson(string text)
|
||||
{
|
||||
int start = text.IndexOf('{');
|
||||
|
||||
@ -31,7 +31,15 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|
||||
private bool activeHandlerSessioEnabled = false;
|
||||
private CliRunner _cliRunner;
|
||||
|
||||
|
||||
private CliRunner CliRunner
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_cliRunner != null ? _cliRunner : (_cliRunner = new CliRunner()));
|
||||
}
|
||||
}
|
||||
|
||||
public enum CurrentPoseidonOp
|
||||
{
|
||||
None,
|
||||
@ -300,23 +308,23 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
//TODO BUMI start CLI serial port
|
||||
_cliRunner = new CliRunner();
|
||||
}
|
||||
|
||||
private static long SafetyTimeOut = 30 * 1000; /// 30 seconds
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>eventDone</returns>
|
||||
public Event Run()
|
||||
{
|
||||
if (_currentOp == CurrentPoseidonOp.SendStartDataStream)
|
||||
{
|
||||
_cliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
return Event.Busy;
|
||||
}
|
||||
else if (_currentOp == CurrentPoseidonOp.SendStartDataStream_Runing)
|
||||
{
|
||||
if (_cliRunner.AreTasksDone()
|
||||
|| _cliRunner.TimeOutReceived(5000))
|
||||
if (CliRunner.AreTasksDone()
|
||||
|| CliRunner.TimeOutReceived(SafetyTimeOut))
|
||||
{
|
||||
_currentOp = CurrentPoseidonOp.SendStartDataStream_Done;
|
||||
}
|
||||
@ -331,13 +339,13 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|| _currentOp == CurrentPoseidonOp.ReadDataStream_End)
|
||||
{
|
||||
_isReadingStart = (_currentOp == CurrentPoseidonOp.ReadDataStream_Start);
|
||||
_cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
CliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
_currentOp = CurrentPoseidonOp.ReadDatastream_Running;
|
||||
return Event.Busy;
|
||||
}else if (_currentOp == CurrentPoseidonOp.ReadDatastream_Running)
|
||||
{
|
||||
if (_cliRunner.AreTasksDone()
|
||||
|| _cliRunner.TimeOutReceived(5000))
|
||||
if (CliRunner.AreTasksDone()
|
||||
|| CliRunner.TimeOutReceived(SafetyTimeOut))
|
||||
{
|
||||
_currentOp = CurrentPoseidonOp.ReadDatastream_Done;
|
||||
}
|
||||
@ -346,7 +354,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
else if (_currentOp == CurrentPoseidonOp.ReadDatastream_Done)
|
||||
{
|
||||
JsonDataFromPoseidon data = null;
|
||||
var first = _cliRunner.TaskPool.FindLast(t => t is Task<JsonDataFromPoseidon>);
|
||||
var first = CliRunner.TaskPool.FindLast(t => t is Task<JsonDataFromPoseidon>);
|
||||
if (first != null && first is Task<JsonDataFromPoseidon>)
|
||||
{
|
||||
data = (first as Task<JsonDataFromPoseidon>).Result;
|
||||
@ -438,10 +446,9 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
else
|
||||
{
|
||||
//TODO BUMI start session - CMD send data to Poseidon
|
||||
_cliRunner = new CliRunner();
|
||||
_cliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
|
||||
_cliRunner.WaitAll();
|
||||
foreach (Task task in _cliRunner.TaskPool)
|
||||
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
|
||||
CliRunner.WaitAll();
|
||||
foreach (Task task in CliRunner.TaskPool)
|
||||
{
|
||||
if (task is Task<string>)
|
||||
{
|
||||
@ -453,7 +460,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
}
|
||||
}
|
||||
|
||||
_cliRunner.Clear();
|
||||
CliRunner.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -482,7 +489,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
if (_cliRunner != null)
|
||||
{
|
||||
|
||||
_cliRunner.Clear();
|
||||
}
|
||||
activeHandlerSessioEnabled = false;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user