diff --git a/docs/LIGHTBURN.md b/docs/LIGHTBURN.md index 3e6ec93..e8183a1 100644 --- a/docs/LIGHTBURN.md +++ b/docs/LIGHTBURN.md @@ -35,7 +35,8 @@ The laser fires only inside an operator-armed window: cancels the wait at any time. Opening the lid (or a Pro's interlock loop) while the button is lit cancels the job the same way — the message names the reason, the latch relocks, and a press with the lid - open never arms; close the lid, clear the alarm, and start again. + open never arms; the job ends for LightBurn (a clean cancel, no alarm to + clear); close the lid and start again. - One press covers one job — power changes and M5/M3 toggles do not re-prompt. The window relocks when the job ends (program end `M2`/`M30`), when the sender connection changes, or after diff --git a/forgetest/forgetest/suite/laser.py b/forgetest/forgetest/suite/laser.py index 8d976af..25abcb6 100644 --- a/forgetest/forgetest/suite/laser.py +++ b/forgetest/forgetest/suite/laser.py @@ -436,9 +436,9 @@ def kill_mid_fire(ctx): "When the white button lights, do NOT press it: open the lid instead."], description="Start a laser job so the controller unlocks the latch and lights the button, " "then open the lid while it waits. The wait must abort with the lid named as the " - "reason and alarm 3, the armed window closed (armed -> false), the kernel latch " - "back to locked, and no emission; closing the lid and clearing the alarm returns " - "the controller to Idle. No press is given, so nothing can fire.") + "reason, cancelled with a soft reset (no alarm - nothing to unlock), the armed " + "window closed (armed -> false), the kernel latch back to locked, and no emission; " + "the controller ends Idle. No press is given, so nothing can fire.") def arm_wait_lid(ctx): ev = ctx.evidence with ctx.grbl() as g, LiveJob(ctx, g): @@ -463,14 +463,15 @@ def arm_wait_lid(ctx): while time.time() - t1 < 15: ctx.checkpoint() text += g.drain() - if "job cancelled" in text and "ALARM:3" in text: + if "job cancelled" in text and "help]" in text: break time.sleep(0.1) ev["messages"] = [ln for ln in text.splitlines() if ln.startswith("[MSG:") or ln.startswith("ALARM")] ctx.log("controller: %s", ev["messages"]) ctx.check("lid opened during arm - job cancelled" in text, "the lid open was not reported as cancelling the arm") - ctx.check("ALARM:3" in text, "no alarm 3 after the lid-open cancel") + ctx.check("help]" in text, "no reset banner after the lid-open cancel (it must be a clean cancel)") + ctx.check("ALARM" not in text, "an alarm was raised on the lid-open cancel") # Armed window closed and the kernel latch locked. t2 = time.time() s = None @@ -489,11 +490,10 @@ def arm_wait_lid(ctx): ctx.check(not ev["emission"], "emission_samples nonzero (%s) - nothing may have fired", ev["emission"]) ctx.instruct("Close the lid, then click Done.") ctx.sleep(1) - ctx.log("unlock: %s", g.command("$X")) st = g.status_report()["state"] ev["state_after"] = st - ctx.check(st.startswith("Idle"), "controller is %s after $X, expected Idle", st) - ctx.log("PASS: lid open during the arm wait cancelled the job (alarm 3), armed=false, latch locked") + ctx.check(st.startswith("Idle"), "controller is %s after the cancel, expected Idle (no unlock needed)", st) + ctx.log("PASS: lid open during the arm wait cancelled the job (clean reset, no alarm), armed=false, latch locked") @test("laser.lid-cancel-mid-fire", title="Lid open mid-burn: beam off in hardware, job cancelled, head home", diff --git a/scripts/bench/laser_lifecycle_test.py b/scripts/bench/laser_lifecycle_test.py index 6fe9e42..f43a75c 100644 --- a/scripts/bench/laser_lifecycle_test.py +++ b/scripts/bench/laser_lifecycle_test.py @@ -18,8 +18,8 @@ reported messages: armed message appears 6. with a switch source present (GF_SWITCH_FILE), the arm blocks on the button: a press with the lid closed arms, and the lid or the - interlock loop opening during the wait cancels the job (alarm, - latch relocked, never armed) + interlock loop opening during the wait cancels the job (a clean + soft reset, no alarm; latch relocked, never armed) 7. outside the arm wait the button is the pause/resume toggle: a press while running feed-holds, a press while held resumes; the arming press itself is not a pause press @@ -433,8 +433,10 @@ def test_lid_open_in_wait(): s.set_switches(SW_LID_OPEN) if not wait_for(s.log, LID_CANCEL, 5, s.sock): fail("[lid-in-wait] lid open during the wait was not reported as a cancel") - if not wait_for(s.log, "ALARM:3", 5, s.sock): - fail("[lid-in-wait] no alarm after the lid-open cancel") + if not wait_for(s.log, "for help]", 5, s.sock): + fail("[lid-in-wait] no reset banner after the lid-open cancel (a clean cancel, not an alarm)") + if "ALARM" in "".join(s.log): + fail("[lid-in-wait] an alarm was raised on the lid-open cancel") # Press with the lid still open: nothing may arm. s.set_switches(1 << 2) read_avail(s.sock, s.log, 1.0)