diff --git a/automations/05_printers_and_workshop/05c_octoeverywhere_notify_events.yaml b/automations/05_printers_and_workshop/05c_octoeverywhere_notify_events.yaml new file mode 100644 index 0000000..e241fd1 --- /dev/null +++ b/automations/05_printers_and_workshop/05c_octoeverywhere_notify_events.yaml @@ -0,0 +1,100 @@ +### OctoEverywhere -> Notify.Events ### +# OctoEverywhere (LAN mode) POSTs fixed JSON to this webhook. Notify.Events can't +# parse that JSON itself, so this automation turns it into a readable alert. +# +# Token: the notify_events platform ignores per-platform api_key and always uses +# the global notify_events token (Cats). Passing `token` inside `data` overrides +# it per message, same pattern as script.notify_events_alerts. +# Requires `notify_event_octoeverywhere_token` in secrets.yaml (the Home Assistant +# source token from the Notify.Events "OctoEverywhere" channel). +# +# Event types: https://docs.octoeverywhere.com/webhook-notifications/event-types/ +# Forwarded ("important only"): 1-5, 7-12, 16. Skipped: 6 Progress, 13, 14, 15. + +- id: '1793812953197' + alias: OctoEverywhere to Notify.Events + description: Turns OctoEverywhere webhook JSON into readable Notify.Events alerts + mode: queued + max: 10 + triggers: + - trigger: webhook + webhook_id: octoeverywhere-7301a739d954078c5a5c5fb3 + allowed_methods: + - POST + local_only: true + actions: + # HA only fills trigger.json when the request's Content-Type contains "json". + # Otherwise the body is dropped and p is empty, which the safety net catches. + - 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] + names: + "1": Print started + "2": Print complete + "3": Print failed + "4": Print paused + "5": Print resumed + "6": Print progress + "7": Gadget possible failure + "8": Gadget paused the print + "9": Printer error + "10": First layer complete + "11": Filament change required + "12": Needs your attention + "13": OctoEverywhere daily notification limit reached + "14": Third layer complete + "15": Bed cool down complete + "16": Test notification + + # Safety net: body wasn't readable JSON, so say so instead of failing silently + - if: + - condition: template + value_template: "{{ not p }}" + then: + - action: notify.notify_events_alerts + data: + message: OctoEverywhere sent a webhook that Home Assistant could not read as JSON. Check this automation's trace. + data: + token: !secret notify_event_octoeverywhere_token + title: OctoEverywhere webhook problem + level: warning + - stop: Body was not JSON + + # Drop events we don't want + - condition: template + value_template: "{{ ev in wanted }}" + + # Build the message + - variables: + printer: "{{ p.PrinterName | default('Printer', true) }}" + event_name: "{{ names[ev | string] | default('Event ' ~ ev, true) }}" + level: "{{ 'error' if ev in [3, 8, 9] else 'warning' if ev in [4, 7, 11, 12] else 'success' if ev == 2 else 'info' }}" + priority: "{{ 'high' if ev in [3, 4, 7, 8, 9, 11, 12] else 'normal' }}" + images: "{{ [{'url': p.SnapshotUrl, 'name': 'snapshot.jpg'}] if p.SnapshotUrl else [] }}" + body: >- + {%- set parts = [] -%} + {%- if p.FileName %}{% set parts = parts + ['File: ' ~ p.FileName] %}{% endif -%} + {%- if p.Progress is defined and ev not in [1, 2] %}{% set parts = parts + ['Progress: ' ~ p.Progress ~ '%'] %}{% endif -%} + {%- if p.TimeRemainingSec is defined and (p.TimeRemainingSec | int(0)) > 0 and ev not in [2, 3] -%} + {%- set s = p.TimeRemainingSec | int(0) -%} + {%- set parts = parts + ['Time left: ' ~ (s // 3600) ~ 'h ' ~ ((s % 3600) // 60) ~ 'm'] -%} + {%- endif -%} + {%- if p.DurationSec is defined and ev in [2, 3] -%} + {%- set d = p.DurationSec | int(0) -%} + {%- set parts = parts + ['Ran for: ' ~ (d // 3600) ~ 'h ' ~ ((d % 3600) // 60) ~ 'm'] -%} + {%- endif -%} + {%- if p.Error %}{% set parts = parts + ['Error: ' ~ p.Error] %}{% endif -%} + {%- if p.QuickViewUrl %}{% set parts = parts + ['Open printer'] %}{% endif -%} + {{ parts | join('
') }} + + # Send it. If a snapshot ever breaks delivery, remove the images line. + - action: notify.notify_events_alerts + data: + message: "{{ body if body else event_name }}" + data: + token: !secret notify_event_octoeverywhere_token + title: "{{ printer }}: {{ event_name }}" + level: "{{ level }}" + priority: "{{ priority }}" + images: "{{ images }}"