fix(driver-focas): resolve High code-review findings (Driver.FOCAS-001, Driver.FOCAS-002)
Driver.FOCAS-001: FocasDriverConfigDto exposed no FixedTree / AlarmProjection / HandleRecycle sections, so a deployment that opted into those features per docs/drivers/FOCAS.md had the sections silently dropped by case-insensitive JSON parsing and the features stayed at their disabled defaults. Added FocasFixedTreeDto / FocasAlarmProjectionDto / FocasHandleRecycleDto and Build* mappers in CreateInstance that populate the matching FocasDriverOptions properties; a missing section or field keeps its existing default. Driver.FOCAS-002: the fixed-tree bootstrap probe classified ProgramInfo as "supported" whenever GetProgramInfoAsync returned non-null, but WireFocasClient .GetProgramInfoAsync substituted defaults instead of throwing on a FOCAS error return, so a CNC series answering EW_FUNC/EW_NOOPT for cnc_exeprgname2 / cnc_rdopmode still got the Program/ and OperationMode/ subtrees. The method now throws InvalidOperationException when neither the program-name nor the op-mode read is IsOk, so SafeTryProbe correctly suppresses the capability. Added FocasFactoryConfigTests covering the three opt-in config sections round-tripping through CreateInstance and the fixed-tree bootstrap classifying ProgramInfo as unsupported when the probe throws. Added an internal FocasDriver.Options test seam. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -161,6 +161,9 @@ public sealed class FocasDriver : IDriver, IReadable, IWritable, ITagDiscovery,
|
||||
internal DeviceState? GetDeviceState(string hostAddress) =>
|
||||
_devices.TryGetValue(hostAddress, out var s) ? s : null;
|
||||
|
||||
/// <summary>Test seam — the resolved options the factory built this driver from.</summary>
|
||||
internal FocasDriverOptions Options => _options;
|
||||
|
||||
// ---- IReadable ----
|
||||
|
||||
public async Task<IReadOnlyList<DataValueSnapshot>> ReadAsync(
|
||||
|
||||
Reference in New Issue
Block a user