From e5f568d01f7ff5909ca58263aeb78b55a4df942e Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 18 Jun 2026 12:32:55 -0400 Subject: [PATCH] docs(focas): retire stale 'wire backend returns no figures' comments after cnc_getfigure shipped --- .../FocasDriver.cs | 16 ++++++++-------- .../FocasPositionAutoScaleTests.cs | 4 ++-- .../FocasPositionScalingTests.cs | 5 +++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS/FocasDriver.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS/FocasDriver.cs index f619dadb..a7636c99 100644 --- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS/FocasDriver.cs +++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS/FocasDriver.cs @@ -657,7 +657,7 @@ public sealed class FocasDriver : IDriver, IReadable, IWritable, ITagDiscovery, // Per-axis decimal-place figures (cnc_getfigure), fetched once. Auto figures win // over the manual PositionDecimalPlaces config at the publish seam; an empty list - // (the managed wire backend today) makes every axis fall back to the config knob. + // (or a failed/empty figure read) makes every axis fall back to the config knob. // Defensive: a figure-read failure must NOT fault device init — default to empty. state.PositionFigures = await SafeProbe(() => client.GetPositionFiguresAsync(ct), []); @@ -830,9 +830,8 @@ public sealed class FocasDriver : IDriver, IReadable, IWritable, ITagDiscovery, // an auto cnc_getfigure figure WINS, and the configured PositionDecimalPlaces is the // fallback when the CNC didn't report one for that axis (see AxisFactor). A figure of // 0 yields factor 1.0 — i.e. the integer widened to double, byte-identical to legacy - // behaviour (12345 / 1.0 == 12345.0). CAVEAT: the managed WireFocasClient returns no - // figures today, so the REAL backend always uses the manual fallback; live auto-fetch - // lands when a FocasWireClient cnc_getfigure wire command is added. FeedRate / + // behaviour (12345 / 1.0 == 12345.0). The managed WireFocasClient fetches figures live + // via ReadPositionFiguresAsync; the config knob is the per-axis fallback only. FeedRate / // SpindleSpeed (rate snapshot) and ServoLoad are NOT position-scaled (published elsewhere). var factor = AxisFactor(state, axisIndex); state.LastFixedSnapshots[FixedTreeReference(host, $"Axes/{axis.Display}/AbsolutePosition")] = snap.AbsolutePosition / factor; @@ -845,8 +844,9 @@ public sealed class FocasDriver : IDriver, IReadable, IWritable, ITagDiscovery, /// Resolve the position-scale factor (10^figure) for a single axis. Auto /// (cnc_getfigure) wins per-axis; manual PositionDecimalPlaces is the /// fallback when the CNC didn't report a figure for that axis. Both clamp non-negative; - /// 0 ⇒ factor 1.0 (legacy byte-identical). The managed wire backend returns no figures - /// today, so the real backend always takes the manual-fallback branch. + /// 0 ⇒ factor 1.0 (legacy byte-identical). The managed wire backend fetches figures live + /// via ReadPositionFiguresAsync; the fallback branch fires only when the CNC + /// reports no figure for a given axis (or the figure read returns empty). /// private static double AxisFactor(DeviceState state, int axisIndex) { @@ -1202,8 +1202,8 @@ public sealed class FocasDriver : IDriver, IReadable, IWritable, ITagDiscovery, /// /// Gets or sets the per-axis position decimal-place figures fetched once at init via /// cnc_getfigure (parallel to the axis-name list; index = axis). An auto figure - /// for an axis WINS over the configured PositionDecimalPlaces; an empty list (the - /// managed wire backend's behaviour today) makes every axis fall back to that config knob. + /// for an axis WINS over the configured PositionDecimalPlaces; an empty list (or + /// a failed/empty figure read) makes every axis fall back to that config knob. /// public IReadOnlyList PositionFigures { get; set; } = []; diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasPositionAutoScaleTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasPositionAutoScaleTests.cs index 756d8648..9c698a6b 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasPositionAutoScaleTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasPositionAutoScaleTests.cs @@ -9,8 +9,8 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests; /// per-axis position decimal-place figures at init and applies them at the /// publish seam. Precedence: an auto figure for an axis WINS; /// the configured PositionDecimalPlaces is the per-axis fallback when the CNC did -/// not report a figure for that axis. (The managed wire backend returns no figures today, -/// so the real backend always uses the manual fallback — these tests drive the Fake.) +/// not report a figure for that axis. These tests drive the Fake to exercise the driver's +/// auto-scale-vs-fallback logic independently of the wire path. /// [Trait("Category", "Unit")] public sealed class FocasPositionAutoScaleTests diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasPositionScalingTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasPositionScalingTests.cs index ebc818ae..860de0dc 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasPositionScalingTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasPositionScalingTests.cs @@ -8,8 +8,9 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests; /// Phase 4 data-type tier — axis-position scaling. cnc_rddynamic2 returns /// positions as scaled integers; the driver applies a 10^PositionDecimalPlaces /// divide at the publish seam so positions surface in -/// engineering units on the Float64 axis nodes. DecimalPlaces is config-supplied -/// (auto-fetch via cnc_getfigure is deferred — wire-gated). +/// engineering units on the Float64 axis nodes. The managed wire backend fetches per-axis +/// figures live via cnc_getfigure; the config knob is the per-axis fallback used +/// when the CNC reports no figure for an axis. These tests cover the config-supplied path. /// [Trait("Category", "Unit")] public sealed class FocasPositionScalingTests