moonraker icon indicating copy to clipboard operation
moonraker copied to clipboard

Get Spoolman active Spool ID inside Klipper

Open lettore opened this issue 1 year ago • 14 comments

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

lettore avatar Aug 15 '23 11:08 lettore

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)

Terror-Gene avatar Dec 16 '23 04:12 Terror-Gene

I would like to get active spool id at least to achieve full workflow:

  1. remove old spool => unload macro clears current active spool
  2. load new spool => prompt for spool (optional and separate feature from current one)
  3. slice
  4. upload and print
  5. 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...

evgarthub avatar Jan 13 '24 13:01 evgarthub

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.

Arksine avatar Jan 13 '24 19:01 Arksine

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.

evgarthub avatar Jan 13 '24 21:01 evgarthub

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?

ddfisher avatar Feb 25 '24 21:02 ddfisher

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.

Arksine avatar Feb 25 '24 23:02 Arksine

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.

ddfisher avatar Feb 27 '24 04:02 ddfisher

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.

CooperGerman avatar Mar 27 '24 08:03 CooperGerman

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.

TinkerTob avatar May 26 '24 11:05 TinkerTob