Auto: focas-f1b — parts count + cycle time

Closes #258
This commit is contained in:
Joseph Doherty
2026-04-25 14:14:54 -04:00
parent 329e222aa2
commit 3d9697b918
5 changed files with 318 additions and 0 deletions

View File

@@ -155,6 +155,38 @@ internal sealed class FwlibFocasClient : IFocasClient
Edit: buf.Edit));
}
public Task<FocasProductionInfo?> GetProductionAsync(CancellationToken cancellationToken)
{
if (!_connected) return Task.FromResult<FocasProductionInfo?>(null);
if (!TryReadInt32Param(6711, out var produced) ||
!TryReadInt32Param(6712, out var required) ||
!TryReadInt32Param(6713, out var total))
{
return Task.FromResult<FocasProductionInfo?>(null);
}
// Cycle-time timer (type=2). Total seconds = minute*60 + msec/1000. Best-effort:
// a non-zero return leaves cycle-time at 0 rather than failing the whole snapshot
// — the parts counters are still useful even when cycle-time isn't supported.
var cycleSeconds = 0;
var tmrBuf = new FwlibNative.IODBTMR();
if (FwlibNative.RdTimer(_handle, type: 2, ref tmrBuf) == 0)
cycleSeconds = checked(tmrBuf.Minute * 60 + tmrBuf.Msec / 1000);
return Task.FromResult<FocasProductionInfo?>(new FocasProductionInfo(
PartsProduced: produced,
PartsRequired: required,
PartsTotal: total,
CycleTimeSeconds: cycleSeconds));
}
private bool TryReadInt32Param(ushort number, out int value)
{
var buf = new FwlibNative.IODBPSD { Data = new byte[32] };
var ret = FwlibNative.RdParam(_handle, number, axis: 0, length: 4 + 4, ref buf);
if (ret != 0) { value = 0; return false; }
value = BinaryPrimitives.ReadInt32LittleEndian(buf.Data);
return true;
}
// ---- PMC ----
private (object? value, uint status) ReadPmc(FocasAddress address, FocasDataType type)