diff --git a/automations/05_printers_and_workshop/05c_octoeverywhere_google_chat.yaml b/automations/05_printers_and_workshop/05c_octoeverywhere_google_chat.yaml index c1a23fe..b1fc64f 100644 --- a/automations/05_printers_and_workshop/05c_octoeverywhere_google_chat.yaml +++ b/automations/05_printers_and_workshop/05c_octoeverywhere_google_chat.yaml @@ -6,10 +6,12 @@ # # Card: header (printer + event), details (file, progress, layer, time, error), # camera snapshot, and an "Open printer" button to OctoEverywhere Quick View. +# Progress updates (event 6) get their own layout: percent in the header, a text +# progress bar, elapsed time, time left, and an estimated finish time. # If Google rejects the card or the request fails, a plain-text message is sent. # # Event types: https://docs.octoeverywhere.com/webhook-notifications/event-types/ -# Forwarded ("important only"): 1-5, 7-12, 16. Skipped: 6 Progress, 13, 14, 15. +# Forwarded: 1-12, 16. Skipped: 13, 14, 15. - id: '1793812953197' alias: OctoEverywhere to Google Chat @@ -28,7 +30,7 @@ - variables: p: "{{ trigger.json | default({}, true) }}" ev: "{{ p.EventType | default(0) | int(0) }}" - wanted: [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 16] + wanted: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16] names: "1": Print started "2": Print complete @@ -65,17 +67,34 @@ # Build the message - variables: printer: "{{ p.PrinterName | default('Printer', true) | string }}" - event_name: "{{ names[ev | string] | default('Event ' ~ ev, true) }}" - emoji: "{{ '🛑' if ev in [3, 8, 9] else '⚠️' if ev in [4, 7, 11, 12] else '✅' if ev == 2 else '🖨️' }}" + pct: "{{ p.Progress | int(0) }}" + event_name: >- + {{ 'Print progress: ' ~ pct ~ '%' if ev == 6 + else names[ev | string] | default('Event ' ~ ev, true) }} + emoji: "{{ '🛑' if ev in [3, 8, 9] else '⚠️' if ev in [4, 7, 11, 12] else '✅' if ev == 2 else '⏳' if ev == 6 else '🖨️' }}" # [label, value] rows, shared by the card and the plain-text fallback details: >- {%- set rows = [] -%} {%- if p.FileName %}{% set rows = rows + [['File', p.FileName | string]] %}{% endif -%} - {%- if p.Progress is defined and ev not in [1, 2] %}{% set rows = rows + [['Progress', (p.Progress | int(0)) ~ '%']] %}{% endif -%} + {%- if p.Progress is defined and ev == 6 -%} + {%- set filled = [[pct // 10, 0] | max, 10] | min -%} + {%- set rows = rows + [['Progress', '▰' * filled ~ '▱' * (10 - filled) ~ ' ' ~ pct ~ '%']] -%} + {%- elif p.Progress is defined and ev not in [1, 2] -%} + {%- set rows = rows + [['Progress', pct ~ '%']] -%} + {%- endif -%} {%- if (p.TotalLayers | int(0)) > 0 and ev not in [1, 2] %}{% set rows = rows + [['Layer', (p.CurrentLayer | int(0)) ~ ' of ' ~ (p.TotalLayers | int(0))]] %}{% endif -%} + {%- if (p.DurationSec | int(0)) > 0 and ev == 6 -%} + {%- set d = p.DurationSec | int(0) -%} + {%- set rows = rows + [['Elapsed', (d // 3600) ~ 'h ' ~ ((d % 3600) // 60) ~ 'm']] -%} + {%- endif -%} {%- if (p.TimeRemainingSec | int(0)) > 0 and ev not in [2, 3] -%} {%- set s = p.TimeRemainingSec | int(0) -%} {%- set rows = rows + [['Time left', (s // 3600) ~ 'h ' ~ ((s % 3600) // 60) ~ 'm']] -%} + {%- if ev == 6 -%} + {%- set eta = now() + timedelta(seconds=s) -%} + {%- set day = '' if eta.date() == now().date() else eta.strftime('%a ') -%} + {%- set rows = rows + [['Done around', day ~ (eta.strftime('%I:%M %p') | regex_replace('^0', ''))]] -%} + {%- endif -%} {%- endif -%} {%- if p.DurationSec is defined and ev in [2, 3] -%} {%- set d = p.DurationSec | int(0) -%}