From b94c990bbc4e2c37904c0a522cd0aa0f67c16d21 Mon Sep 17 00:00:00 2001 From: ScottW514 Date: Thu, 10 Sep 2026 13:08:33 -0400 Subject: [PATCH] Leave the lens to the cloud client in cloud mode cloud.verdict-hold printed to completion and then failed its hand-back on head/z_mode=0. That job's header carried ZSmd 0, gfhardware's set_mode_from_puls turns that into z_mode 0, and z_mode 0 is full step (lenshome.c): the cloud client had set the lens the way the pulse file it was playing asked. Nothing was left behind - the machine did what the job said. The baseline already skips nine attributes in cloud mode, for the reason written above the list: the cloud client sets its own values for them from every pulse header, and forcing the GRBL values under it would be the baseline configuring another controller's machine. head/z_current and head/z_mode are the same thing and were not on the list. They are now, in cloud mode only; in GRBL mode the pair is still checked against 1 and 1, which is the half of this an exemption could quietly break, so a test holds it. Host-proven: 89 baseline unit tests. --- forgetest/forgetest/baseline.py | 9 +++++++-- forgetest/tests/test_baseline.py | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/forgetest/forgetest/baseline.py b/forgetest/forgetest/baseline.py index 3621cec..82b4132 100644 --- a/forgetest/forgetest/baseline.py +++ b/forgetest/forgetest/baseline.py @@ -87,9 +87,14 @@ FIXED_SYSFS = [ # every pulse header (step_freq 10 kHz, the run currents), runs at the # service's own x8 with the module's ramp whatever xy_microsteps says, and # hands the hold currents back at idle; forcing the GRBL values under it -# would be the baseline configuring another controller's machine. +# would be the baseline configuring another controller's machine. The Z +# pair belongs with them: the cloud client takes the lens microstep mode +# from the pulse header it is playing (ZSmd, gfhardware z_axis +# set_mode_from_puls) and the current with it, so a job whose header asks +# for full step leaves z_mode 0 behind by doing what it was told. GRBL_CONTROLLER_SYSFS = ("cnc/motor_lock", "cnc/x_mode", "cnc/y_mode", "cnc/x_decay", "cnc/y_decay", - "cnc/step_freq", "cnc/ramp_rate", "pic/x_step_current", "pic/y_step_current") + "cnc/step_freq", "cnc/ramp_rate", "pic/x_step_current", "pic/y_step_current", + "head/z_current", "head/z_mode") # Settings the baseline never hands back as bare settings: controller_mode # is the persisted mirror of the live mode (the mode item restores it diff --git a/forgetest/tests/test_baseline.py b/forgetest/tests/test_baseline.py index d7b09da..6e3737d 100644 --- a/forgetest/tests/test_baseline.py +++ b/forgetest/tests/test_baseline.py @@ -400,6 +400,23 @@ class TransientNotLeftoverTests(BaselineTests): self.assertEqual(items[0].found, "1014") +class CloudOwnedSysfsTests(unittest.TestCase): + """In cloud mode the cloud client configures the machine from the + pulse header it is playing, the lens included: z_mode comes from + ZSmd through gfhardware's set_mode_from_puls. Handing the GRBL values + back under it would be the baseline configuring another controller's + machine. In GRBL mode the pair is checked as before.""" + + def test_the_z_pair_is_the_cloud_clients(self): + for attr in ("head/z_current", "head/z_mode"): + self.assertIn(attr, baseline.GRBL_CONTROLLER_SYSFS) + + def test_the_z_pair_is_still_checked_in_grbl_mode(self): + fixed = dict(baseline.fixed_sysfs()) + self.assertEqual(fixed.get("head/z_current"), "1") + self.assertEqual(fixed.get("head/z_mode"), "1") + + class PositionDeadbandTests(unittest.TestCase): """The counters count steps and a controller's own return lands within a few hundredths of a millimeter, not on the step: a difference that