Arksine / moonraker

Web API Server for Klipper
https://moonraker.readthedocs.io
GNU General Public License v3.0
1.02k stars 392 forks source link

Notifier Print Progress Enhancements #840

Open thankyousam opened 2 months ago

thankyousam commented 2 months ago

Notifier.py: Enable Layer Change progress messages through Notifier

Expanded the stub of existing code in notifier.py to generate a layer change notification at user specified % layer progress points during the print. This allows the user to receive notifications at set progress points. Only the current layer and total layer count is available in the print state data, so this doesn't necessarily represent linear progress.

Before this change it was only possible to automatically generate a notification at the start or end of the print, or if something went wrong and caused an error or pause.

Additional inclusion of a timestamp variable in all Notifier event data to allow the event time to be included in the notification text.

See the additional Notifier sections in the configuration.md documentation for usage.

Files updated: moonraker/common.py moonraker/components/job_state.py moonraker/components/notifier.py docs/configuration.md

Signed-off-by: David Osbourn thankyousam@gmail.com

nmaggioni commented 3 weeks ago

I've been using your changes for a couple of weeks (thanks!) but I can't seem to access the filename in the progress notification like I do with the other notifiers:

[notifier progress]
url: # ...
events: layer_changed
layer_trigger: 0.25
body: Progress printing {event_args[1].filename or 'N/A'}: {(event_args[1].info.current_layer / event_args[1].info.total_layer * 100 if event_args[1].info.total_layer is not none and event_args[1].info.total_layer > 0 else 0) | int}% (layer {event_args[1].info.current_layer} of {event_args[1].info.total_layer})

The above config produces this notification:

Progress printing N/A: 30% (layer 4 of 13)

Other kinds of events work as expected instead:

[notifier starting]
url: # ...
events: started
body: {event_name|title}{'d' if event_name.endswith('e') else ''} printing {event_args[1].filename}{' (%s)' % event_args[1].message if event_args[1].message|length > 0 else ''}

Started printing .gcode

Dumping the stats during a print shows that the filename field is correctly populated: printer['print_stats'].filename = <correct_filename_here>.gcode.

I'll add some debugging output and report back.

thankyousam commented 3 weeks ago

I've been using your changes for a couple of weeks (thanks!) but I can't seem to access the filename in the progress notification like I do with the other notifiers:

[notifier progress]
url: # ...
events: layer_changed
layer_trigger: 0.25
body: Progress printing {event_args[1].filename or 'N/A'}: {(event_args[1].info.current_layer / event_args[1].info.total_layer * 100 if event_args[1].info.total_layer is not none and event_args[1].info.total_layer > 0 else 0) | int}% (layer {event_args[1].info.current_layer} of {event_args[1].info.total_layer})

The above config produces this notification:

Progress printing N/A: 30% (layer 4 of 13)

Other kinds of events work as expected instead:

[notifier starting]
url: # ...
events: started
body: {event_name|title}{'d' if event_name.endswith('e') else ''} printing {event_args[1].filename}{' (%s)' % event_args[1].message if event_args[1].message|length > 0 else ''}

Started printing .gcode

Dumping the stats during a print shows that the filename field is correctly populated: printer['print_stats'].filename = <correct_filename_here>.gcode.

I'll add some debugging output and report back.

Thanks again for reviewing the code and testing this out.

The layer change event only appears to have the info payload from the printer. The filename only appears to be populated in the state changes, which is why it's there for started, complete, etc.

This is the extent of what I get in event_args[1] in the layer_change event, which is itself populated in _status_update in components/job_state.py

{'total_duration': 19.789630468934774, 'info': {'total_layer': 10, 'current_layer': 8}}

I don't know if we could work backwards up the event stack to see if the filename can be pulled through. I couldn't figure it out at the time. Could it be added into the GCode and pulled through that way like the total and current layer counts?

[Edit] I found the filename in the self.last_print_stats in the job_state status update handler. I'll add some extra code to pull this into event_args[1].filename

nmaggioni commented 3 weeks ago

@thankyousam Filename is now populated, thanks!

Progress printing .gcode: 53% (layer 7 of 13)