Skip to content

Fix bugs, add tests, and simplify WebSocket refactor - #436

Merged
nlef merged 8 commits into
nlef:websocket-helper-refactorfrom
KapJI:improve-websocket-refactor
Apr 7, 2026
Merged

Fix bugs, add tests, and simplify WebSocket refactor#436
nlef merged 8 commits into
nlef:websocket-helper-refactorfrom
KapJI:improve-websocket-refactor

Conversation

@KapJI

@KapJI KapJI commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Found several bugs while reviewing the refactor and added integration tests that would have caught them. Also reverted some abstractions that made things worse rather than better.

Bug fixes

  • set_timelapse_params/set_notify_params drop the first parameter — the prefix is stripped by the caller, then the downstream method does pop(0) on what's left, eating the first real param. Fixed by removing pop(0) so they just accept params directly.
  • _update_print_stats_from_message uses walrus operator if val := dict.get(key) which silently skips zero/empty values (e.g. filament_used=0 at print start, filename=""). Replaced with if "key" in dict guards to handle any value including falsy ones.
  • status_response triggers height notifications and timelapse photos on reconnect after the unification with notify_status_update — on initial connection these are state snapshots, not real Z moves.

Why dispatch tables were reverted

The dispatch tables lose all type info — everything is Callable[..., Any], so mypy can't check anything. The lambdas need setattr/getattr hacks for simple assignments.

_PRINT_STATE_CONFIGS also introduced behavioral regressions: paused state was setting timelapse.is_running = False (original never touched it), and error/cancelled/standby were gating is_running = False behind manual_mode (original stopped timelapse unconditionally on these). The per-state logic is too conditional for a flat config — different ordering, nested branches, some states gate behind manual_mode and others don't. Reverted to the original if/elif which is explicit and mypy can actually check.

For the gcode command dispatch, used str.partition(" ") to split command from payload, then if/elif on the exact command word. No more prefix ordering issues ("tgnotify" matching before "tgnotify_photo"), no string duplication, no lambdas.

Kept the sensor prefix tuples and klippy reconnect states — those are just data, no Callable types involved.

Other changes

  • KlippyState and PrintState are now str, Enum so comparisons with JSON strings are type-safe
  • Renamed internal bot states to NOTIFY_START/NOTIFY_FINISH to make it obvious they don't come from Klipper
  • Added PAUSED and COMPLETE to PrintState (Klipper sends these but they were missing)

@nlef
nlef merged commit 7a5b9a6 into nlef:websocket-helper-refactor Apr 7, 2026
6 checks passed
@KapJI
KapJI deleted the improve-websocket-refactor branch April 7, 2026 23:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants