Auto: focas-f2a — DIAG: address scheme
New FocasAreaKind.Diagnostic parsed from DIAG:nnn (whole-CNC) and DIAG:nnn/axis (per-axis), validated against a per-series FocasCapabilityMatrix.DiagnosticRange table (16i: 0-499; 0i-F family: 0-999; 30i/31i/32i: 0-1023; Power Motion i: 0-255; Unknown: permissive per existing matrix convention). IFocasClient gains ReadDiagnosticAsync(diagNumber, axisOrZero, type, ct) with a default returning BadNotSupported so older transport variants degrade gracefully. FwlibFocasClient implements it via a new cnc_rddiag P/Invoke that reuses the IODBPSD struct (same shape as cnc_rdparam). FocasDriver.ReadAsync dispatches Diagnostic addresses through the new path; non-Diagnostic kinds keep the existing ReadAsync route unchanged. Tests: parser positives (DIAG:1031, DIAG:280/2, case-insensitive, zero, axis-8) + negatives (malformed, axis>31), capability matrix boundaries per series, driver-level dispatch verifying axis index threads through, init-time rejection on out-of-range, and BadNotSupported fallback when the wire client doesn't override the default. 266/266 pass in Driver.FOCAS.Tests. Closes #263 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -154,7 +154,7 @@ public sealed class FocasDriver : IDriver, IReadable, IWritable, ITagDiscovery,
|
||||
var parsed = FocasAddress.TryParse(tag.Address)
|
||||
?? throw new InvalidOperationException(
|
||||
$"FOCAS tag '{tag.Name}' has invalid Address '{tag.Address}'. " +
|
||||
$"Expected forms: R100, R100.3, PARAM:1815/0, MACRO:500.");
|
||||
$"Expected forms: R100, R100.3, PARAM:1815/0, MACRO:500, DIAG:1031, DIAG:280/2.");
|
||||
if (_devices.TryGetValue(tag.DeviceHostAddress, out var device)
|
||||
&& FocasCapabilityMatrix.Validate(device.Options.Series, parsed) is { } reason)
|
||||
{
|
||||
@@ -377,7 +377,10 @@ public sealed class FocasDriver : IDriver, IReadable, IWritable, ITagDiscovery,
|
||||
var client = await EnsureConnectedAsync(device, cancellationToken).ConfigureAwait(false);
|
||||
var parsed = FocasAddress.TryParse(def.Address)
|
||||
?? throw new InvalidOperationException($"FOCAS tag '{def.Name}' has malformed Address '{def.Address}'.");
|
||||
var (value, status) = await client.ReadAsync(parsed, def.DataType, cancellationToken).ConfigureAwait(false);
|
||||
var (value, status) = parsed.Kind == FocasAreaKind.Diagnostic
|
||||
? await client.ReadDiagnosticAsync(
|
||||
parsed.Number, parsed.BitIndex ?? 0, def.DataType, cancellationToken).ConfigureAwait(false)
|
||||
: await client.ReadAsync(parsed, def.DataType, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
results[i] = new DataValueSnapshot(value, status, now, now);
|
||||
if (status == FocasStatusMapper.Good)
|
||||
|
||||
Reference in New Issue
Block a user