Last active
October 15, 2025 16:24
-
-
Save wd5gnr/75fb01e899c43d2f84375a0089d77531 to your computer and use it in GitHub Desktop.
Telegram notifier for klipper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| By Al Williams ([email protected]) | |
| You need to do a few things. | |
| 1) Create a telegram bot (go to @botfather, follow instructions, get long string to put in two places inside the moonraker.conf file) | |
| 2) Get notify.cfg on the printer and make your printer.cfg include it: [include notify.cfg] | |
| 3) Add the user.moonraker.conf text to your moonraker config | |
| (if you don't have a camera, you can take out the "attach" lines) | |
| 4) In your slicer on layer change you need to do this (or equivalent): | |
| GNR_ON_LAYER_CHANGE LAYER={layer_num + 1} TOTAL={total_layer_count} | |
| 5) Put klip-notify somewhere (prefer on path) and modify notify.cfg to point to it. Make file executable (chmod +x klip-notify) | |
| You'll need to restart moonraker/clipper to get all of that to take. | |
| You can test from console: | |
| GNR_ON_LAYER_CHANGE LAYER=10 TOTAL=100 | |
| If that works, you can slice/print and you should see progress on the telegram bot. | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/ash | |
| /usr/bin/wget -qO- "http://127.0.0.1:7125/printer/gcode/script?script=GNR_DO_LAYER_NOTIFY%20LAYER=$1%20TOTAL=$2%20PCT=$3" & | |
| exit 0 | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [gcode_shell_command GNR_LAYER_WGET] | |
| # Use absolute path to klip-notify if possible | |
| command: /opt/bin/klip-notify | |
| timeout: 1.0 | |
| verbose: False | |
| [gcode_macro ENABLE_LAYER_NOTIFY] | |
| description: Turn layer notify on/off ENABLED=0/1 | |
| gcode: | |
| {% set enabled = params.ENABLED|default(1)|int %} | |
| SET_GCODE_VARIABLE MACRO=GNR_ON_LAYER_CHANGE VARIABLE=push_enabled VALUE={enabled} | |
| [gcode_macro GNR_ON_LAYER_CHANGE] | |
| description: Called by slicer on each layer change (e.g., timelapse, notification) | |
| variable_lastnotify: 0 | |
| variable_push_enabled: 1 | |
| gcode: | |
| {% set layer = params.LAYER|default(0)|int %} | |
| {% set total = params.TOTAL|default(0)|int %} | |
| {% if total > 0 %} | |
| {% set pct = ((layer|float / total) * 100)|int %} | |
| {% else %} | |
| {% set pct = 0 %} | |
| {% endif %} | |
| {% if push_enabled != 0 %} | |
| {% set last = printer["gcode_macro GNR_ON_LAYER_CHANGE"].lastnotify|int %} | |
| # The logic here is we don't want to notify 0% or 100% (because the system does start/complete) | |
| # But we do want to trigger every 10% but we don't know for sure we will always hit exactly | |
| # so an 8 layer print will be 0%, 12.5%, 25%,... So by checking the top digit | |
| # we will print once per decade and won't get multiple for any given decade | |
| # On new print 1 != 9 so we are good to go again. The first layer should always be 0% so... | |
| {% if pct//10 != last %} | |
| SET_GCODE_VARIABLE MACRO=GNR_ON_LAYER_CHANGE VARIABLE=lastnotify VALUE={pct//10} | |
| {% if pct != 100 and pct//10 != 0 %} | |
| SET_GCODE_VARIABLE MACRO=GNR_LAYER_VAR VARIABLE=layer VALUE={layer} | |
| SET_GCODE_VARIABLE MACRO=GNR_LAYER_VAR VARIABLE=total VALUE={total} | |
| SET_GCODE_VARIABLE MACRO=GNR_LAYER_VAR VARIABLE=pct VALUE={pct} | |
| UPDATE_DELAYED_GCODE ID=GNR_LAYER_DELAYED DURATION=1.0 | |
| {% endif %} | |
| {% endif %} | |
| {% endif %} | |
| [gcode_macro GNR_LAYER_VAR] | |
| description: Variables for delayed notify | |
| variable_layer: 0 | |
| variable_total: 0 | |
| variable_pct: 0 | |
| gcode: | |
| [delayed_gcode GNR_LAYER_DELAYED] | |
| gcode: | |
| {% set layer = printer['gcode_macro GNR_LAYER_VAR'].layer|int %} | |
| {% set total = printer['gcode_macro GNR_LAYER_VAR'].total|int %} | |
| {% set pct = printer['gcode_macro GNR_LAYER_VAR'].pct|int %} | |
| RESPOND MSG="{ 'Firing async layer notify: %d/%d (%d%%)' % (layer,total,pct) }" | |
| RUN_SHELL_COMMAND CMD=GNR_LAYER_WGET PARAMS="{layer} {total} {pct}" | |
| [gcode_macro GNR_DO_LAYER_NOTIFY] | |
| # Executes on Moonraker side, non-real-time | |
| gcode: | |
| {action_call_remote_method("notify", | |
| name="gnr_progress_notify", | |
| message="Layer %s/%s (%s%%) complete" % | |
| (params.LAYER, params.TOTAL, params.PCT))} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # add the following to your moonraker config | |
| [notifier gnr_status_notify] | |
| url: tgram://{your telegram bot ID} | |
| events: * | |
| body: "Printer status: {event_name}" | |
| body_format: text | |
| title: AD5X Status | |
| attach: http://localhost:8080/?action=snapshot | |
| [notifier gnr_progress_notify] | |
| url: tgram://{your telegram bot ID} | |
| events: gcode | |
| body: "{event_message}" | |
| body_format: text | |
| title: AD5X Progress | |
| attach: http://localhost:8080/?action=snapshot |
Author
Author
Ok that'll teach me to make a last minute change (worked with my short test print, fails bad on bigger print).
The only change is in notify.cfg where I was doing /10 and should have done //10. Will test in a second, but should be OK.
Author
Ok probably last update... hahaha
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Oops, I changed the logic a bit and now it notifies too often... I need to fix something... will post here when it is done.