Thanks Rod,
A few months ago I mentioned that I was working on an experiment to add a C++ interface layer for LinuxCNC UIs. The lower layer wraps LinuxCNC’s NML command/status channels and HAL polling, and then a higher-level controller layer sits on top of that to coordinate UI commands, wait for observable LinuxCNC state changes, and avoid treating command writes or echoes as completion. The same core can then support a local Node/N-API (or Python) UI and a WebSocket interface for remote clients, as long as those clients route machine-control actions through that higher-level command layer rather than bypassing it with raw NML calls.
As part of this, I am trying to make the higher-level UI commands report completion only when LinuxCNC has actually reached an observable machine/controller state, rather than when a command write succeeds or when command echo advances. For example, cycle start, pause, resume, stop, program load/reload, override changes, spindle state, WCS selection, and touch-off can all be treated this way because there is some later status observation that confirms the requested result.
`EMC_TASK_PLAN_STEP` is the current problem child. I do not want to say “step completed” merely because `PLAN_STEP` was accepted or echoed. I would prefer some public status/HAL indication that the requested native step has reached its end/completion.
Your suggestion about `motion.interp.line-number` and `motion.interp.motion-type` was helpful. The pins do exactly what you described for motion segments. They track the trajectory planner’s executing interpreter metadata, distinguish arc/linear motion, and in my probe they updated slightly ahead of the corresponding NML `motion_line` / `motion_id` fields. In an arc-followed-by-line test, the line/type changed at the blended segment boundary, which is very useful for execution display and diagnostics.
However, I do not think they solve the general completion problem for native STEP. In dwell or other non-motion STEP cases, `motion.interp.line-number` and `motion.interp.motion-type` did not change, so I still could not distinguish a completed non-motion native step from waiting, arming, or stale motion metadata. In an invalid MANUAL `PLAN_STEP` case, the command still wrote/echoed, the HAL interp pins stayed stale, and the asynchronous error channel was still required to detect the rejection.
So my current conclusion is:
* `motion.interp.*` is very useful for showing the currently executing motion segment.
* It is better timed than the NML motion-line fields in some cases.
* It does not appear to provide a per-request completion signal for `EMC_TASK_PLAN_STEP`.
* It does not cover dwell/non-motion interpreter items.
* It does not replace the error channel for rejected step requests.
For a UI that claims “STEP completed,” I think I would still need LinuxCNC to expose something closer to a public stepped-item sequence, stepped-line identity, or native step gate-closure signal that covers both motion and non-motion interpreter items.
Does that match your understanding of how `PLAN_STEP`, `steppingWait`, `steppedLine`, and the motion state tags fit together? Or is there another public field or HAL pin I should be watching for the non-motion STEP cases?