Fix lost 3.9.2204.0 versioning and improve Poseidon CLI diagnostics

- restore the Morrisville release version metadata
- add end-to-end logs for CLI execution, reader state, parsed results,
  and UI updates
- prevent completed Poseidon reads from being started repeatedly in a cycle
- use a fixed CLI directory and reliable working directory
This commit is contained in:
Michal Buzik 2026-08-17 10:25:35 +02:00
parent f51fd4709e
commit 2fd2697e3b
7 changed files with 76 additions and 21 deletions

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// Build Number // Build Number
// Revision // Revision
// //
[assembly: AssemblyVersion("3.9.2203.1")] [assembly: AssemblyVersion("3.9.2204.1")]
[assembly: AssemblyFileVersion("3.9.2203.1")] [assembly: AssemblyFileVersion("3.9.2204.1")]

View File

@ -444,15 +444,26 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
if(poseidonReader == null) if(poseidonReader == null)
continue; continue;
poseidonReader.SetCliLogging(CliLogging); poseidonReader.SetCliLogging(CliLogging);
if (!(poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.ReadDatastream_Done // Start a read only once. The previous condition restarted a
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.ReadDatastream_Running)) // reader after it reached Done/Error, which kept the dialog in
// Loading... and repeatedly launched the CLI for every meter.
if (poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.None)
{ {
log.DebugFormat("Poseidon read: starting {0} for {1}", currentOp, poseidonReader.Name);
poseidonReader.SetCurrentOp((currentOp == CurrentOp.ReadDatastream_StartStates)? poseidonReader.SetCurrentOp((currentOp == CurrentOp.ReadDatastream_StartStates)?
PoseidonReader.CurrentPoseidonOp.ReadDataStream_Start : PoseidonReader.CurrentPoseidonOp.ReadDataStream_Start :
PoseidonReader.CurrentPoseidonOp.ReadDataStream_End); PoseidonReader.CurrentPoseidonOp.ReadDataStream_End);
} }
/// Send start data stream /// Send start data stream
poseidonReader.Run(); poseidonReader.Run();
if (poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Error)
{
log.ErrorFormat("Poseidon read: {0} completed with Error during {1}", poseidonReader.Name, currentOp);
}
else if (poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Done)
{
log.DebugFormat("Poseidon read: {0} completed during {1}", poseidonReader.Name, currentOp);
}
if (!(poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Done if (!(poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Done
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Error)) || poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Error))
{ {
@ -462,6 +473,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
} }
if (bAllReadersFinished) if (bAllReadersFinished)
{ {
log.DebugFormat("Poseidon read: all readers finished for {0}", currentOp);
finishedReading = true; finishedReading = true;
} }
else else

View File

@ -144,6 +144,9 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
private void SetUiBusy(bool busy, long deltaTime = -1) private void SetUiBusy(bool busy, long deltaTime = -1)
{ {
log.DebugFormat("Poseidon UI: SetUiBusy busy={0}, deltaTime={1}, enabledTextBoxes={2}",
busy, deltaTime, enabledTextBoxes.Count);
// show wait cursor for form and children // show wait cursor for form and children
this.UseWaitCursor = busy; this.UseWaitCursor = busy;
@ -290,10 +293,15 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
// Ensure we are on the UI thread // Ensure we are on the UI thread
if (InvokeRequired) if (InvokeRequired)
{ {
log.DebugFormat("Poseidon UI: queue UpdateValues startValue={0}, enableEdit={1}, deltaTime={2}",
stratValue, enableEdit, deltaTime);
BeginInvoke(new Action(() => UpdateValues(stratValue, enableEdit))); BeginInvoke(new Action(() => UpdateValues(stratValue, enableEdit)));
return; return;
} }
log.DebugFormat("Poseidon UI: UpdateValues on UI thread startValue={0}, enableEdit={1}, deltaTime={2}",
stratValue, enableEdit, deltaTime);
for (int i = 0; i < TextBoxesCount; i++) for (int i = 0; i < TextBoxesCount; i++)
{ {
if (stratValue) if (stratValue)
@ -317,6 +325,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
if (enableEdit) if (enableEdit)
{ {
SetUiBusy(false, deltaTime); SetUiBusy(false, deltaTime);
log.Debug("Poseidon UI: values applied and dialog released from Loading...");
} }
// if you also need to enable/disable editing, do it here, // if you also need to enable/disable editing, do it here,
// it's now safely on the UI thread. // it's now safely on the UI thread.

View File

@ -222,6 +222,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{ {
FileName = fileName, FileName = fileName,
Arguments = args, Arguments = args,
WorkingDirectory = System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(fileName)),
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true, RedirectStandardError = true,
UseShellExecute = false, UseShellExecute = false,
@ -314,6 +315,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{ {
FileName = fileName, FileName = fileName,
Arguments = args, Arguments = args,
WorkingDirectory = System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(fileName)),
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true, RedirectStandardError = true,
UseShellExecute = false, UseShellExecute = false,
@ -471,4 +473,4 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
}); });
} }
} }
} }

View File

@ -411,6 +411,11 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
CliRunner.Clear(); CliRunner.Clear();
_lastOpTimedOut = false; _lastOpTimedOut = false;
log.DebugFormat("{0}: starting CLI read, direction={1}, path='{2}', args='{3}'",
Name,
_isReadingStart ? "start" : "end",
serialPort == null ? "<not initialized>" : serialPort.SerialPortCmdClientPath,
serialPort == null ? "<not initialized>" : serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams));
CliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, CliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort,
SerialPortData.EMeterArg.AllParams); SerialPortData.EMeterArg.AllParams);
_currentOp = CurrentPoseidonOp.ReadDatastream_Running; _currentOp = CurrentPoseidonOp.ReadDatastream_Running;
@ -422,6 +427,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{ {
_currentOp = CurrentPoseidonOp.ReadDatastream_Done; _currentOp = CurrentPoseidonOp.ReadDatastream_Done;
incommingTime = CliRunner.IncommingTime; incommingTime = CliRunner.IncommingTime;
log.DebugFormat("{0}: CLI read task finished, taskCount={1}, incomingTime={2}",
Name, CliRunner.TaskPool.Count, incommingTime);
} }
else if (CliRunner.TimeOutReceived(SafetyTimeOut)) else if (CliRunner.TimeOutReceived(SafetyTimeOut))
{ {
@ -462,6 +469,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
if (data != null) if (data != null)
{ {
log.DebugFormat("{0}: CLI read result deviceId={1}, reading={2}, readingComplete={3}, nfcTagDetected={4}",
Name, data.DeviceId, data.Reading, data.ReadingComplete, data.NfcTagDetected);
if (string.IsNullOrEmpty(wmSerialNr)) if (string.IsNullOrEmpty(wmSerialNr))
{ {
try try

View File

@ -8,6 +8,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{ {
public class SerialPortData public class SerialPortData
{ {
public const string CliDirectory = @"C:\TBF\Cli";
private Boolean? _cliExists; private Boolean? _cliExists;
public bool CliExists { get { public bool CliExists { get {
if (_cliExists == null || !_cliExists.HasValue) if (_cliExists == null || !_cliExists.HasValue)
@ -16,13 +18,21 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
} }
return _cliExists.Value; return _cliExists.Value;
} } } }
public string SerialPortCmdClientPath { public string SerialPortCmdClientPath
#if DEBUG {
get { return Path.Combine("C:\\","TBF","Cli", CmdClientName);} get
#else {
get { return Path.Combine("C:\\","TBF","Cli", CmdClientName);} // The configured value is a file name, not an executable path.
#endif // Keeping the CLI directory fixed prevents a bench configuration
} // from starting an unintended executable or failing due to a
// relative path/current-directory change.
string cliFileName = Path.GetFileName(CmdClientName);
if (string.IsNullOrWhiteSpace(cliFileName))
cliFileName = "HalCli.exe";
return Path.Combine(CliDirectory, cliFileName);
}
}
public string CmdClientName { get; set; } = "HalCli.exe"; public string CmdClientName { get; set; } = "HalCli.exe";
public string PortName { get; set; } public string PortName { get; set; }
// Backward compatibility: old numeric meter type // Backward compatibility: old numeric meter type
@ -259,4 +269,4 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
} }
} }

View File

@ -66,7 +66,7 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop
string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams); string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams);
Assert.AreEqual( Assert.AreEqual(
"-p COM3 -m Poseidon --hat mth --timeout 10 --operation readall", "-p COM3 -m 74 --hat mth --timeout 10 --operation readall",
args); args);
} }
@ -83,7 +83,7 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop
string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.DeviceId); string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.DeviceId);
Assert.AreEqual( Assert.AreEqual(
"-p COM3 -m Poseidon --hat harry --timeout 30 --operation read --parameter DeviceId", "-p COM3 -m 74 --hat harry --timeout 30 --operation read --parameter DeviceId",
args); args);
} }
@ -104,7 +104,7 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop
{ {
var testCases = new[] var testCases = new[]
{ {
new { Meter = SerialPortData.MeterProduct.Poseidon, Expected = "Poseidon" }, new { Meter = SerialPortData.MeterProduct.Poseidon, Expected = "74" },
new { Meter = SerialPortData.MeterProduct.Ally, Expected = "ally" }, new { Meter = SerialPortData.MeterProduct.Ally, Expected = "ally" },
new { Meter = SerialPortData.MeterProduct.IperlPlus, Expected = "iperlplus" }, new { Meter = SerialPortData.MeterProduct.IperlPlus, Expected = "iperlplus" },
new { Meter = SerialPortData.MeterProduct.IperlLegacy, Expected = "iperllegacy" } new { Meter = SerialPortData.MeterProduct.IperlLegacy, Expected = "iperllegacy" }
@ -133,25 +133,38 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop
serialPort.Macro = "readmacro1"; serialPort.Macro = "readmacro1";
Assert.AreEqual( Assert.AreEqual(
"-p COM3 -m Poseidon --hat mth --timeout 10 --operation readmacro1", "-p COM3 -m 74 --hat mth --timeout 10 --operation readmacro1",
serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro1)); serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro1));
serialPort.Macro = "readmacro2"; serialPort.Macro = "readmacro2";
Assert.AreEqual( Assert.AreEqual(
"-p COM3 -m Poseidon --hat mth --timeout 10 --operation readmacro2", "-p COM3 -m 74 --hat mth --timeout 10 --operation readmacro2",
serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro2)); serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro2));
serialPort.Macro = "readmacro3"; serialPort.Macro = "readmacro3";
Assert.AreEqual( Assert.AreEqual(
"-p COM3 -m Poseidon --hat mth --timeout 10 --operation readmacro3", "-p COM3 -m 74 --hat mth --timeout 10 --operation readmacro3",
serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro3)); serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro3));
serialPort.Macro = "xxx"; serialPort.Macro = "xxx";
Assert.AreEqual( Assert.AreEqual(
"-p COM3 -m Poseidon --hat mth --timeout 10 --operation xxx", "-p COM3 -m 74 --hat mth --timeout 10 --operation xxx",
serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams)); serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams));
} }
[TestMethod]
public void SerialPortData_CliPath_ShouldAlwaysUseFixedCliDirectory()
{
SerialPortData serialPort = new SerialPortData(
"COM3",
@"D:\obsolete\HatCliDemo.exe",
SerialPortData.MeterProduct.Poseidon);
Assert.AreEqual(
@"C:\TBF\Cli\HatCliDemo.exe",
serialPort.SerialPortCmdClientPath);
}
[TestMethod] [TestMethod]
public void RunMultipleTimesTestProgram_CheckParalelWork() public void RunMultipleTimesTestProgram_CheckParalelWork()
{ {
@ -445,4 +458,4 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop
} }
} }
} }