Skip to content

paxx12/klipper-router

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Klipper Router

Klipper Router is a small JSON-RPC bridge that connects multiple Klipper instances over their Unix sockets and lets them call each other using a shared set of remote methods. Its purpose is to support auxiliary functions that are independent from the main printer, and often non-critical, such as a printer with a dedicated LED controller, or a printer with multiple separate MMU controllers. With the router, the printer can reach the status of those services and vice versa.

What it does

  • Connects to multiple Klipper sockets defined in a router config.
  • Registers a shared set of remote methods on every Klipper instance.
  • Routes G-code, events, and object status updates across instances.

How It Works

Each Klipper instance connects to the router over a Unix socket. The router speaks Klipper’s JSON-RPC protocol and registers its own remote methods on every connected instance. When a macro calls a router method, the router forwards the request to the target instance and optionally turns the response into a G-code callback.

Key behavior from src/klipper_router.py:

  • Connects to each socket and calls info, then subscribes to webhooks status.
  • Marks a connection “ready” when Klipper reports state=ready.
  • Registers router methods like router/gcode/script, router/objects/subscribe, etc.
  • For object subscriptions, it forwards updates from one printer to another and converts status dictionaries into G-code parameters.

Mermaid Diagram

sequenceDiagram
    participant Main as Klipper (main)
    participant Router as Klipper Router
    participant LED as Klipper (led)

    Router->>Main: connect + info
    Router->>LED: connect + info
    Router->>Main: register_remote_method(router/*)
    Router->>LED: register_remote_method(router/*)

    LED->>Router: router/objects/subscribe target=main, objects={print_stats: [state]}, gcode_callback=ON_STATUS_UPDATE
    Router->>Main: objects/subscribe response_template=router/objects/update
    Main-->>Router: status_update (print_stats.state=printing)
    Router->>LED: router/objects/update params=status
    Router->>LED: gcode/script "ON_STATUS_UPDATE PRINT_STATS_STATE='printing'"
Loading

Configuration

Create a router config with one section per Klipper instance:

# router.cfg
[klippy main]
sock: /tmp/klippy_host_main_uds
on_connect: M118 Router connected to main

[klippy led]
sock: /tmp/klippy_host_led_uds
on_connect: M118 Router connected to LED

The example configuration lives in examples/klipper_router.cfg.example.

Service API (JSON-RPC)

These are the remote methods the router registers on every connected Klipper instance. They are used by Klipper macros via action_call_remote_method, but you can call them directly with JSON-RPC as well.

Method Params Purpose
router/gcode/script target (printer name), script (G-code string) Send G-code to another printer.
router/event/subscribe event, gcode, optional callback_target, optional callback_type (gcode or webhook) Register a global event handler.
router/event/trigger event, optional context (key/value map for template substitution) Trigger a global event.
router/printers/list none List printers with name, connected, ready.
router/objects/list target Proxy Klipper objects/list from the target.
router/objects/query target, objects (dict of objects to query) Proxy Klipper objects/query from the target.
router/objects/subscribe target, objects (dict of objects to subscribe), gcode_callback (macro name on the caller) Subscribe to target updates and forward status as a callback.
router/objects/update internal Internal method used as the subscription response template; forwards status to the gcode_callback.

G-code API (Macro Wrappers)

includes/router_api.cfg provides G-code macros that wrap the router methods:

  • ROUTER_GCODE_SCRIPT TARGET=<name> SCRIPT=<gcode>
  • ROUTER_EVENT_SUBSCRIBE EVENT=<name> GCODE=<gcode>
  • ROUTER_EVENT_TRIGGER EVENT=<name>
  • ROUTER_PRINTERS_LIST
  • ROUTER_OBJECTS_LIST TARGET=<name>
  • ROUTER_OBJECTS_QUERY TARGET=<name> OBJECTS=<obj1,obj2>
  • ROUTER_OBJECTS_SUBSCRIBE TARGET=<name> OBJECTS=<obj1,obj2> CALLBACK=<gcode>

You can include it in any Klipper config:

[include ../../includes/router_api.cfg]

Test: test/print_stats

This test spins up three Klipper instances (main, afc, led) and a router, then demonstrates how LED reacts to print_stats.state changes from the main printer.

Main (test/print_stats/klippy_host_main.cfg)

  • Configures a minimal virtual printer and virtual_sdcard.
  • Uses delayed_gcode to print test.gcode after 10 seconds.
  • That triggers Klipper’s print_stats state transitions: standbyprintingcomplete.

LED (test/print_stats/klippy_host_led.cfg)

  • Implements ROUTER_ON_CONNECTED to detect when main connects.
  • Calls SUBSCRIBE_MAIN_STATUS using router/objects/subscribe targeting main with objects={'print_stats': ['state']} and gcode_callback='ON_STATUS_UPDATE'.
  • ON_STATUS_UPDATE compares the last seen state and triggers the corresponding macro for printing, paused, complete, cancelled, error, or standby.
  • Each macro currently emits an M118 message and includes commented SET_LED commands you can enable.

How the print_stats update payload is mapped

When the main printer sends a status update, the router encodes the dictionary into G-code parameters. For print_stats.state, the callback receives:

ON_STATUS_UPDATE PRINT_STATS_STATE='printing'

The LED macro uses params.PRINT_STATS_STATE to decide which LED macro to run.

Running the Test

From the repo root:

./test/run.sh ./test/print_stats

For a tmux view with serial consoles:

./test/run-tmux.sh ./test/print_stats

About

Klipper Router is a small JSON-RPC bridge that connects multiple Klipper instances

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors