nx_print_runtime_monitor.nx
buildroot/runtime/nx_print_runtime_monitor.nx
about
nx_print_runtime_monitor.nx -- LIDAR-class spaghetti prevention
from Klipper telemetry alone (no camera, no laser).
Operator directive (2026-05-20 immediate): lidar spaghetti prevention.
Bambu X1C has hardware LIDAR + camera for mid-print spaghetti
detection. Substrate alternative for Qidi X-Max 3 (which has
Klipper telemetry but no LIDAR): ingest the Moonraker WebSocket
telemetry stream + flag anomalies indicative of spaghetti BEFORE
they cascade into a 20-hour wasted print.
Three detection paths -- all from REAL TELEMETRY, no guesswork:
1. STUCK_LAYER
Z hasn't advanced for > N × expected_layer_time. Either
the print stalled (firmware issue) or the head is moving
without depositing material (spaghetti).
2. FLOW_ANOMALY
Extruder accumulated material but Z + XY barely changed.
Material is going somewhere -- if not into the print, into
the air = spaghetti.
3. EXTRUDER_RUNAWAY
Total extruded volume diverges from expected (computed from
XY × layer_height × line_width). Suggests the extruder is
grinding / over-pushing.
All three compose existing substrate state + arithmetic. No
heuristic thresholds beyond operator-supplied physical limits.
Caller responsibility: pump telemetry events from
nx_moonraker_io into nx_runtime_monitor_step + react to any
issue verdict (pause print, alert operator, etc.).
license_tier: ORIGINAL
dependencies 1 imports · 12 importers
diagram shows first 10 each side; +0 more imports, +2 more importers in the complete lists below.
imports: nx_syscalls.nx
imported by: nx_moonraker_loop_e2e_test.nxnx_print_loop_e2e_test.nxnx_print_response.nxnx_print_response_test.nxnx_print_runtime_compose_test.nxnx_print_runtime_monitor_test.nxnx_print_runtime_runout_test.nxnx_print_runtime_shift_test.nxnx_print_runtime_thermal_test.nxnx_print_runtime_zback_test.nxnx_print_telemetry.nxnx_print_telemetry_test.nx
structs
| 88 | struct NxRuntimeMonitor |
consts
| 39 | const NX_MAGIC_10000: i64 = 10000 |
| 42 | const NX_RT_ISSUE_NONE: i64 = 0 |
| 43 | const NX_RT_ISSUE_STUCK_LAYER: i64 = 1 |
| 44 | const NX_RT_ISSUE_FLOW_ANOMALY: i64 = 2 |
| 45 | const NX_RT_ISSUE_EXTRUDER_RUNAWAY: i64 = 3 |
| 49 | const NX_RT_ISSUE_BED_TEMP_DROP: i64 = 4 |
| 50 | const NX_RT_ISSUE_HOTEND_TEMP_DROP: i64 = 5 |
| 51 | const NX_RT_ISSUE_CHAMBER_TEMP_DROP: i64 = 6 |
| 58 | const NX_RT_ISSUE_Z_BACKWARD: i64 = 7 |
| 64 | const NX_RT_ISSUE_FILAMENT_RUNOUT: i64 = 8 |
| 72 | const NX_RT_ISSUE_LAYER_SHIFT: i64 = 9 |
| 73 | const NX_RT_ISSUE_N: i64 = 10 |
| 82 | const NX_RT_OK: i64 = 0 |
| 83 | const NX_RT_BAD_INPUT: i64 = 1 |
| 86 | const NX_RT_Q14: i64 = 16384 |
| 131 | const NX_RUNTIME_MONITOR_BYTES: i64 = 160 // 20 fields × 8 |
functions
| 75 | func nx_rt_issue_is_valid(k: i64) -> i64 |
| 133 | func nx_runtime_monitor_new( |
| 173 | func nx_runtime_monitor_set_layer_shift_tolerance( |
| 189 | func nx_runtime_monitor_step_layer_shift( |
| 218 | func nx_runtime_monitor_step_runout( |
| 241 | func nx_runtime_monitor_set_z_backward_tolerance( called by 1: main |
| 253 | func nx_runtime_monitor_set_thermal( |
| 276 | func nx_runtime_monitor_step( |
| 370 | func nx_runtime_monitor_last_issue(m: *NxRuntimeMonitor) -> i64 |
| 379 | func nx_rt_thermal_axis_check( called by 1: nx_runtime_monitor_step_thermal |
| 409 | func nx_runtime_monitor_step_thermal( |