moonraker
moonraker copied to clipboard
Get Spoolman active Spool ID inside Klipper
Is your feature request related to a problem? Please describe
It's possible to expose to Klipper as a printer variable the Spoolman spool ID currently active in Moonraker?
Describe the solution you'd like
From any G-Code Macro we should be able to load current loaded filament data via printer.spoolman.id, printer.spoolman.material, printer.spoolman.extruder_temp etc. This will be amazing because in any macro you can get the currently loaded filament and adjust the parameters of the print accordingly.
Describe alternatives you've considered
No response
Additional information
No response
First result for "klipper macro active spool". have searched around & cant find a solution. I would like to add if statements somewhere in my LOAD_FILAMENT / RESUME / START_PROCEDURE macros that check if "active spool = none" & warns to select a spool first. Since i have it set so UNLOAD_FILAMENT clears the active spool. this feature would save me ever accidentally using a spool without tracking it. Plus the benefit of printing (or loading filament) using the correct temperature for the filament inserted, without needing to re-slice gcode. could also configure bed temp to be set to the layer1 filaments preferred bed temp. (ideally it would prompt with the spoolman integration to select a filament, but i dont know how one would achieve that with both webui & klipperscreen simultaneously)
I would like to get active spool id at least to achieve full workflow:
- remove old spool => unload macro clears current active spool
- load new spool => prompt for spool (optional and separate feature from current one)
- slice
- upload and print
- START_PRINT macro can be adjusted to make sure
GET /server/spoolman/spool_id
is set to something otherwise PAUSE print
I checked the current code, it looks like we need to register additional action to get the id from api in gcode https://github.com/Arksine/moonraker/blob/3008a13efb6045a007456cb4f34a64afa6140617/moonraker/components/spoolman.py#L54
Not sure if it's technically possible to make async request with action_call_remote_method
and use the response of it in macro...
As of right now Klipper does not have the ability to request data from its clients (ie: Moonraker). The action_call_remote_method
is fire and forget, it can send data to Moonraker but it cannot receive a response.
Klipper will need to add support for requesting data from its API Server clients before this feature request can be fulfilled.
Thank you! Good to know! As a workaround I was trying to manage copy of active spool id as a klipper variable, but I'm not sure how to catch the event "spoolman_set_active_spool" from UI to save id to variable. Clearing it is simply done on unload macro.
I think this is actually possible without any changes to Klipper if we use a continuation passing style, which is a bit odd, but seems potentially viable. Here's a simple proof of concept: https://github.com/ddfisher/moonraker/commit/12cf73917a2337f35ed4e185be82cb12cd0f28f5
Is this something that Moonraker would consider adding if it was fleshed out a bit?
I don't think its a good idea to "hack" in a response using macros as it doesn't resolve waiting/notification on the other end. If Klipper is going to request information from Moonraker I think there needs to be a clear API/protocol that deals with it.
Ahh, that makes sense. Thinking about it a bit more, I realize that the approach above only works for macros that are run in isolation on an otherwise idle printer and can't work for e.g. something in PRINT_START
.
Hi, i just found this issue that seems very similar to a discussion i'm having at the moment on klipper discourse: https://klipper.discourse.group/t/way-to-post-pre-process-gcode-through-moonraker/15058/15
I have forked moonraker to add my (quite hacky) solution for the above mentionned issues (automatic spools selection, unselection) pre-print filament checks etc...
I would be glad to see a cleaner version of this implemented and would be glad to contribute if need be.
On the klipper side, this would be very easy to solve:
[gcode_macro SET_ACTIVE_SPOOL]
gcode:
{% if params.ID %}
{% set id = params.ID|int %}
{% else %}
{% set id = printer.save_variables.variables.spool_id|int %}
{% endif %}
{action_call_remote_method(
"spoolman_set_active_spool",
spool_id=id
)}
SAVE_VARIABLE VARIABLE=spool_id VALUE='{ id }'
[gcode_macro CLEAR_ACTIVE_SPOOL]
gcode:
{action_call_remote_method(
"spoolman_set_active_spool",
spool_id=None
)}
[gcode_macro START_GCODE]
gcode:
CLEAR_PAUSE
SET_ACTIVE_SPOOL
This way, klipper itself remembers which spool was last loaded and automatically reactivates it whenever you call "SET_ACTIVE_SPOOL" without any parameters.
However, this only works when the SET_ACTIVE_SPOOL ID=... macro is called when switching spools. Which is how I stumbled across this issue by accident: Actually, I was looking for a way to make Mainsail call the macro when I switch spools via the UI.