Adds atc_droptool/atc_grabtool/atc_release/atc_clamp wrappers in
AuxAxis (each just an RPC waiting on the matching terminal reply
line from the firmware), and registers them as internal hook
handlers in Ctrl. Macros and gcode programs can now invoke the
tool changer with:
(MSG,HOOK:droptool:)
(MSG,HOOK:grabtool:)
(MSG,HOOK:release:)
(MSG,HOOK🗜️)
block_unpause + auto_resume mirrors the W-axis hooks: the program
pauses while the ESP runs the pneumatic sequence and resumes when
done. Soft timeouts match the worst-case ESP sequence durations.
Add a lightweight, self-contained phase tracer for measuring end-to-end
bbctrl restart and Pi boot time. Disabled by setting BBCTRL_TRACE=0.
- src/py/bbctrl/Trace.py: monotonic-anchored event log + sd_notify helper.
- bbctrl/__init__.py: marks for imports, args parsed, ioloop, web init,
listen, and an sd_notify READY=1 once HTTP is bound.
- bbctrl/Ctrl.py: spans around each subsystem (avr, i2c, lcd, mach,
preplanner, jog, pwr, hooks, aux, mach.connect).
- bbctrl/Comm.py: avr.firmware_rebooted mark.
- bbctrl/Web.py: TimingHandler (GET /api/diag/timing) and
UITimingHandler (PUT /api/diag/timing/ui), plus a ws.first_open mark.
- src/js/restart-timing.js + app.js: UI-side performance.now() marks
(script.load, ws.open, ws.first_msg, ui.first_state, window.load),
posted once to the controller.
- scripts/bbctrl.service: stdout/stderr -> journal so TRACE lines are
visible via journalctl -u bbctrl. (Was StandardOutput=null.)
Revert: git revert this commit. To disable at runtime without
reverting, set BBCTRL_TRACE=0 in the bbctrl service environment.
Rather than rebuild gplan + the AVR firmware to add a true 7th axis,
we treat W as a synchronous out-of-band axis that moves between G-code
blocks. The pipeline:
upload -> AuxPreprocessor rewrites W tokens into (MSG,HOOK:aux:N)
comments -> planner sees only XYZ + messages -> Hooks fires the
registered internal handler -> AuxAxis sends STEPS/HOME over serial
to the ESP and blocks the planner until done.
New files:
src/py/bbctrl/AuxAxis.py serial worker + RPC layer
src/py/bbctrl/AuxPreprocessor.py G-code rewriter
docs/AUX_W_AXIS.md design + ops notes
Changed:
Hooks.py register_internal(); fix the (MSG,HOOK:...) listener
to read the 'messages' state list (was broken before)
Ctrl.py instantiate AuxAxis, register aux/aux_rel/aux_home/
aux_setzero hooks
FileHandler.py rewrite uploads in place when they use W
Mach.py rewrite W tokens in MDI input the same way
Web.py REST endpoints under /api/aux/*
The ESP firmware in ../auxcnc was extended in lockstep: HOME, HOMECFG
(NVS-persisted), WPOS, HOMED?, LIMIT?, abortable STEPS with
limit-aware abort, trapezoidal ramps, deterministic [topic] reply
tokens, [boot] banner.
Real-time decisions (limit switch, step pulses) live on the ESP. The
host owns mm units, soft limits, and aux_homed bookkeeping. ESP
reboot mid-job clears aux_homed and surfaces a message; per design
manual jogs are still allowed without homing.
- New Hooks module (src/py/bbctrl/Hooks.py) that watches controller state
and fires webhooks or scripts on events:
- tool-change (M6), program-start, program-end, pause, estop,
homing-start, homing-end, custom (via MSG comments)
- API endpoints:
- GET /api/hooks - get current hook config
- PUT /api/hooks/save - save hook config
- PUT /api/hooks/fire/<event> - manually fire a hook (for testing)
- Hook config stored in hooks.json with two types:
- webhook: HTTP POST/PUT to external URL with JSON context
- script: run local command with env vars (HOOK_OLD_TOOL, etc.)
- Fix tornado.web.asynchronous deprecation in Camera.py
- Wired into Ctrl initialization and state listener system