mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-10-15 17:19:55 -07:00
forgetest: motion.button-hold-resume leaves the catalog
motion.button-hold-resume held on the machine that the button holds a travel job and the next press resumes it to its target. The host proves it now: laser_lifecycle_test rule 7 runs the same job (M5, G91, G1 X40 F300) through the toggle and lands it within 0.05 mm of +40 (a0a4edb), beside the armed half that owns the pause and resume messages. Real stepping stays with the kept motion tests; the physical button with setup.check-switches. - The test goes; no helper was its alone (start_move and Watch serve motion.lid-cancel-home, which keeps _LID_COVERS). - laser.pause-resume-lid-cancel no longer requires it. The removed test required only motion.pacing, which motion.lid-cancel-home still brings. Proof: the coverage lint reports 0 uncovered paths and 0 host-tested row problems over 106 tests (its one failure is setup.check-lens's src/lensfind.* entry, which the forgectrl pin bump clears); the gate self-check refuses an empty artifact cleanly; pyflakes adds no finding. The unit modules that load the whole catalog pass under Linux: test_artifact, test_campaign, test_cooling_order, test_fixture, test_manifest, test_operator. Acceptance: motion.py's shared text and laser.pause-resume-lid-cancel's own text move. Against the image on the bench that adds no run:6a434bbalready changed both laser.py's and motion.py's shared text.
This commit is contained in:
@@ -706,7 +706,7 @@ def armed_kill(ctx):
|
||||
subsystem="laser", kind="live", mode="grbl", est_min=7,
|
||||
covers=_LASER_COVERS + [("grblhal-glowforge", "src/glowforge_switches.c"),
|
||||
("grblhal-glowforge", "src/glowforge_switch_map.h")],
|
||||
requires=["laser.emission-witness", "motion.lid-cancel-home", "motion.button-hold-resume"],
|
||||
requires=["laser.emission-witness", "motion.lid-cancel-home"],
|
||||
actions=["button", "lid"],
|
||||
steps=["Scrap under the head with 40 mm of free +X and +Y travel; lid closed; exhaust on.",
|
||||
"Press the physical button when it lights white (arm). Once the cut is under way the "
|
||||
|
||||
@@ -1223,69 +1223,6 @@ def expect_cancel_and_return(ctx, g, ev, start, k0, why, tag):
|
||||
return drift
|
||||
|
||||
|
||||
@test("motion.button-hold-resume", title="The button pauses and resumes a job",
|
||||
subsystem="motion", kind="operator", mode="grbl", est_min=2,
|
||||
covers=_LID_COVERS, requires=["motion.pacing"], actions=["button"],
|
||||
steps=["Bed clear; the head needs 40 mm of free +X travel. No laser is involved.",
|
||||
"On Ready the head starts an 8 s move: press the button once while it moves (the "
|
||||
"job holds), then once more when told (it resumes and finishes)."],
|
||||
description="A travel job is running; one press of the big button feed-holds it (the sender "
|
||||
"sees Hold), the next press resumes it (Run) and the move completes with its "
|
||||
"position intact - the factory's pause/resume on the machine.")
|
||||
def button_hold_resume(ctx):
|
||||
ev = ctx.evidence
|
||||
with ctx.grbl() as g:
|
||||
clean_slate(ctx, g)
|
||||
start = g.status_report()["MPos"]
|
||||
ctx.ready("On Ready the head starts an 8 s move along +X. Press the button ONCE while it "
|
||||
"moves; the job holds and the test sees it.")
|
||||
g.command("M5")
|
||||
g.command("G91")
|
||||
start_move(ctx, g, "G1X40F300") # an 8 s move
|
||||
g.drain() # the message window opens here
|
||||
w = Watch(g)
|
||||
ctx.act("button", "press", until=w.in_state("Hold"), timeout=12, fail=False)
|
||||
st, text = w.last, w.text
|
||||
ctx.check(st is not None and st["state"].startswith("Hold"),
|
||||
"the press did not hold the job (state %s)", st["state"] if st else "?")
|
||||
ev["held_state"] = st["state"]
|
||||
ev["held_at_mm"] = round(st["MPos"][0] - start[0], 3)
|
||||
ev["pause_message"] = "job paused" in text
|
||||
ctx.log("held: %s at %.3f mm of 40; message seen: %s", st["state"], ev["held_at_mm"],
|
||||
ev["pause_message"])
|
||||
# The press is proven by the job LEAVING the hold. Catching it in Run
|
||||
# is a race: a pause late in the move leaves a fraction of a second of
|
||||
# travel, which can be over before the next poll - the machine did
|
||||
# exactly the right thing and the test would still have called it a
|
||||
# failure.
|
||||
w = Watch(g)
|
||||
ctx.act("button", "press", text="The head is stopped: the press resumes the move.",
|
||||
until=w.left_state("Hold"), timeout=60, fail=False)
|
||||
st, text = w.last, w.text
|
||||
if st is not None and st["state"].startswith("Hold"):
|
||||
st = None
|
||||
ev["state_after_resume"] = st["state"] if st else None
|
||||
ev["resume_message"] = "job resumed" in text
|
||||
ctx.check(st is not None, "the second press did not resume the job (still held: %s)",
|
||||
g.status_report()["state"])
|
||||
# Leaving the hold for Run or Idle is the resume; leaving it for Alarm
|
||||
# or Door is something else entirely, and must not read as a pass.
|
||||
ctx.check(st["state"].startswith(("Run", "Idle")),
|
||||
"the job left the hold into %s, not into motion", st["state"])
|
||||
ctx.log("resumed: %s; message seen: %s", ev["state_after_resume"], ev["resume_message"])
|
||||
peak, states, st = wait_idle(ctx, g, 40)
|
||||
ctx.check("TIMEOUT" not in states, "the resumed move did not complete: %s", states)
|
||||
moved = st["MPos"][0] - start[0]
|
||||
ev["moved_mm"] = round(moved, 3)
|
||||
ctx.log("move completed after pause/resume: %.3f mm of 40", moved)
|
||||
ctx.check(abs(moved - 40.0) <= 0.05, "the resumed move did not land on its target (%.3f mm)", moved)
|
||||
g.command("$J=G91X-40F2400")
|
||||
wait_idle(ctx, g, 30)
|
||||
g.command("G90")
|
||||
machine_idle(ctx)
|
||||
ctx.log("PASS: button press held the job (%s), the next press resumed it, target reached", ev["held_state"])
|
||||
|
||||
|
||||
@test("motion.lid-cancel-home", title="Lid open during a job - running or paused - cancels it and returns "
|
||||
"to the job start",
|
||||
subsystem="motion", kind="operator", mode="grbl", est_min=5,
|
||||
|
||||
Reference in New Issue
Block a user