34 Commits
Author SHA1 Message Date
simplytoast1 b42d39ffcc Add native Notify! alerts, Live Activities and Lock Screen widgets (#3265) 2026-10-09 09:08:38 +02:00
maziggy f471fe7b27 Add Gotify as a notification provider (#2743)
Posts to the server's /message endpoint with the app token in the
X-Gotify-Key header. Each event's priority level is sent to Gotify as
0, 2, 5, 8 or 10, set in the same per-event priority section ntfy uses.
Events without a level go out at 5. The snapshot goes out as a
bigImageUrl, and the outcome confirmation opens its dialog on tap.

-----

List notification providers alphabetically

The Provider Type list in the Add Notification Provider dialog is now
sorted by the name shown on screen, in the current UI language, so the
order holds in every locale.
2026-10-05 12:24:02 +02:00
Benji 7f64e2ba8b Add feature: Attach camera snapshots to notifications (issue #3089) (#3199) 2026-10-01 08:43:44 +02:00
Thomansky 1c316e2ad6 Answer the outcome prompt by reacting to the Telegram message (#3129) 2026-09-29 16:06:51 +02:00
maziggy 6855d65d12 Let other applications send messages through the notification channels
POST /notifications/app-message delivers an app's message to every channel
with the new "Messages from connected apps" switch on (off by default),
through quiet hours, the digest and the log. API keys need the new "Send
notifications" permission, and their owner notifications:update; plain text,
http(s) links, 20 messages a minute per key. The electricity-price door and
this one now share one scoped-key check. /queue?batch=<id> opens and
highlights one batch order.
2026-09-27 12:45:50 +02:00
Thomansky 44c7e6fb39 Post-print outcome confirmation: good/reject verdicts, one-tap links, yield stats (#3047) 2026-09-26 15:37:19 +02:00
maziggy 1b20d1a968 fix(notifications): send the ntfy priority the dialog was collecting (issue #3139)
The per-event Priority header from #990 never reached ntfy. The dialog
builds its rows from the provider's event toggles and stores the map
under those names -- on_print_complete, on_print_failed -- while every
sender is called with the bare event name, print_complete. The lookup
missed for all 18 events the dialog offers, so every notification went
out at the ntfy server's default with the configured priority sitting
untouched in the database.

Both ends looked healthy, which is why it shipped. The stored config
held exactly what was set, and the tests were green because they called
_send_ntfy directly with the prefixed name -- the one spelling the
running system never produces.

- notification_service.py: accept either spelling, bare first, so
  existing configs keep working and nothing needs migrating.
- schemas/notification.py: document both key forms, and which one the
  UI writes.
- tests: use the bare names, and add one that runs from a finished
  print through to the outgoing request. Without the fix it fails on a
  header dict holding only Title, which is the assertion that was
  missing.

The daily digest is unchanged: send_digest sends with no event_type at
all, and the dialog offers no priority for it -- it is one message for
several events.
2026-09-24 10:00:33 +02:00
maziggy d9bc7ae47a Read a NULL notification flag as off instead of dropping every provider (issue #2827)
Adding on_stock_reorder_alert and on_stock_break_alert to the provider
schema made them required on the way out as well as in: the response model
inherits the write model. Every on_* column on notification_providers is
nullable with no server default, and where the table was created from
Base.metadata before run_migrations, the ALTER ... DEFAULT false that
introduced those columns was swallowed as a duplicate and never backfilled
existing rows. Those NULLs were harmless until the flags were read, at
which point the row failed validation -- and a list is validated as a
whole, so one row took every provider with it. The route returned 500 and
the UI rendered an empty list, so configured providers looked deleted.

Backfill them to off, which is what the sender already assumed: it selects
providers with IS TRUE, so a NULL flag never sent anything. A NULL flag now
also reads as off rather than failing the response, across all of them, so
the next flag added to this schema cannot repeat it. Writes are unchanged.
2026-08-25 13:09:24 +02:00
MagicMelody84 54af3146a3 [Feature]: Bind Home Assistant sensors to storage locations (dryboxes/bins) (#2827) 2026-08-25 12:17:23 +02:00
maziggy 328bac450a Stop auto-drying re-arming into a threshold it can never reach (#2770)
An H2D armed five 12-hour drying cycles inside four hours, one of them six
seconds after the previous one ended, and none ran more than a couple of
hours.

Two things combine. The firmware ends a cycle when it decides the filament
is dry rather than when the clock runs out, and reports no fault doing it --
across this printer's history the run length tracks how wet the spools were,
from nearly the full 12 hours starting at 32% down to minutes once the unit
sat at 10-13%. That part is the AMS doing its job.

The loop is ours. An AMS reports higher relative humidity while it is warm
than once it has cooled: the same unit read 10-13% cold and 15-20% through
every cycle. With the threshold at 14% the reading at the moment a cycle
ended was always still above it, so the next 30-second pass armed another
12-hour cycle. Nothing counted, nothing waited, and it only stopped when the
box finally cooled enough to read 13%.

Auto-drying now waits 30 minutes after a cycle ends before arming another on
the same unit, and gives up on a unit after two consecutive cycles that
bring the reading no lower -- logging why and sending a new notification,
on by default because it reports that Bambuddy has stopped acting. Progress
is judged against the lowest reading any cycle on that unit has ended at,
not against the threshold, so a genuinely wet spool in a humid room coming
down 40-37-35 keeps drying however far it still is from the target;
comparing against the best so far rather than the previous end stops a
sensor wobbling by one point reading as progress every other cycle. The
suspension lifts by itself once the reading falls below the threshold.

Neither guard can stop a running cycle, and a cycle Bambuddy cut short for a
print, or that the user stopped by hand, is not counted against the unit --
so a farm that dries between queue jobs is unaffected. The threshold field
now warns below 20%, and every cycle end logs the unit's temperature and
humidity, which is what made this diagnosable.

The same bundle showed unrelated tasks failing with "database is locked",
each inside a 30.000-second Discord connect timeout. Alarms are raised from
inside the loop that records sensor history, at a point where the new rows
are added but not committed; the first read in the notification path flushed
them to satisfy itself, opening a write transaction, and the provider was
then contacted over the network with that transaction still open. SQLite
allows one writer and 30 seconds outlives the 15-second busy timeout, so
every other write in that window failed. The two reads that run before a
provider is contacted no longer flush the caller's pending work, and the
connect timeout is 5 seconds rather than 30 -- the body keeps the full 30,
so image uploads on a slow uplink are unaffected. SQLite only; Postgres has
no single-writer limit.
2026-08-08 12:40:17 +02:00
behrinml dd1d40b0d4 implemented pr (worth fixing) feedback
update commit
2026-08-06 20:27:25 +02:00
maziggy cd004df817 Show Home Assistant sensors on the printer card (#1148, #448)
Binds binary_sensor and reading-carrying sensor entities to a printer and
renders their state on its card, worded by Home Assistant's device_class.
Optional per-sensor alert condition drives a notification on the transition
into the alert state and an opt-in interlock that holds queued prints while
alerting -- a hold with a readable waiting_reason, never a failure, and only
ever on a sensor that was read successfully.

Sensors get their own table rather than a wider entity pattern on SmartPlug:
get_smart_plug_by_printer would otherwise hand the card's power button a door
contact to switch.

The hold is passed to the model matcher directly rather than merged into
busy_printers: _check_auto_drying reads that set as "is currently printing"
and would put an idle-but-held printer down the mid-print drying path.

The notification_providers migration spells its default FALSE, not 0 --
Postgres rejects an integer default for a boolean and _safe_execute swallows
the error.
2026-08-05 14:26:38 +02:00
maziggy 8fd1f884dc feat(mqtt): publish the plate-clear gate and add a notification for it (#2525)
When a print reaches a terminal state Bambuddy holds the queue until
someone confirms the build plate is clear. That gate was visible only in
the Web UI: the printer's own MQTT push reports nothing beyond RUNNING,
PAUSE, FAILED, FINISH and IDLE, so an external automation could not tell
"finished" from "finished and still waiting for a human".

The per-printer status topic now carries an awaiting_plate_clear field,
and every transition is additionally published on a new retained topic,
bambuddy/printers/{serial}/plate_clear. Retained, and published from the
flag itself rather than from printer telemetry: a subscriber learns the
state of every printer the moment it connects, and the state stays
correct after Auto Off powers a printer down - telemetry stops there,
which would otherwise leave the status topic frozen at false.

Publishing is edge-triggered. The queue clears the gate on every
dispatch whether or not it was up, and no subscriber should see a
"plate cleared" for a plate that was never dirty. Persistence and the
WebSocket broadcast stay unconditional; they are idempotent and predate
this.

A matching Plate Clear Required notification event was added, off by
default on every provider because it fires after every print at the
same moment as the print-complete alert. Only the rising edge notifies.
Acknowledging still goes through POST /printers/{id}/clear-plate.

Two tests in test_printer_manager_status_broadcast.py asserted
_schedule_async.call_count == 2 for the setter. The new emission makes
it three on a transition, so they now assert that the persist and
broadcast coroutines are actually scheduled - which is the contract

Translated in all locales; wiki updated. Covered by backend and
frontend tests.
2026-07-28 13:36:55 +02:00
maziggy 62ba751278 feat(notifications): Bark notification provider (#1495)
Bark is the open-source, account-free iOS push app (self-hostable
via bark-server). Configure with just the device key from the app;
the server URL defaults to the official api.day.app relay and
accepts a self-hosted instance. Optional settings: notification
Group, Sound, and iOS Interruption Level - Time Sensitive breaks
through scheduled summaries, Critical bypasses Silent mode and
Focus, Passive delivers silently.

bark-server can wrap failures in an HTTP 200 body ({"code": 400}),
so the sender checks the body code as well as the HTTP status.
Unknown interruption levels are dropped rather than forwarded.
2026-07-28 10:58:08 +02:00
maziggy 1555fad539 fix(notifications): send Pushover retry/expire for Emergency priority (#2586)
Pushover rejects priority-2 (Emergency) messages unless they carry retry
and expire. _send_pushover never sent them, so setting priority 2 always
failed with Pushover's "retry and expire are required" error. Now at
priority 2 we send retry/expire (default 60s/3600s, clamped to Pushover's
30-10800s range), surfaced as two provider fields shown only when priority
is 2. Added PushoverConfig schema fields, i18n labels across all locales,
and unit tests.
2026-07-17 10:02:19 +02:00
maziggy 4206d675eb feat(notifications): dedicate AI Failure Detection notification event (#1794)
Split Obico failure-detection dispatch out of the multiplexed
  on_printer_error event onto its own on_ai_failure_detection event so
  users can subscribe to AI alerts without also enabling HMS hardware-
  error pages, and so the discoverable label "AI Failure Detection" is
  what subscribes them rather than the unrelated "Printer Error" toggle.

  New column on notification_providers (default False, branched
  SQLite/Postgres migration), new notification_service.on_ai_failure_detection
  method, new ai_failure_detection template, obico_actions._notify swap.
  Frontend gets a summary badge, a toggle row with description, and ntfy
  priority surfacing. 14 new tests pin the routing + the regression guard
  ("Printer Error" alone must NOT receive AI notifications now). 11 locales
  covered.

  Existing providers keep working: HMS hardware errors continue to ride
  on_printer_error unchanged; users who want spaghetti alerts opt in via
  the new toggle.
2026-06-22 08:15:29 +02:00
maziggy 35edc036bd feat(notifications): per-event ntfy priority headers (#990)
ntfy supports a Priority header (1=min, 2=low, 3=default, 4=high, 5=urgent)
  that controls escalation on the receiving device, but every event was being
  sent at the server default — so a "50% complete" ping looked identical to
  "print failed" or "printer offline". Add a per-event priority dropdown
  section in the Add/Edit Notification modal (visible only for ntfy, listing
  only enabled events); the backend reads config.event_priorities and emits
  the matching Priority header on POST and PUT (image-attachment) paths.
  Unmapped events fall through to the ntfy server default. Out-of-range
  and non-numeric values are dropped, not clamped, so a misconfigured value
  never silently sends at the wrong urgency. Test sends omit the header by
  design so the test path can't accidentally page someone at urgent priority.

  Backward compatible: existing providers without event_priorities behave
  exactly as before. NtfyConfig.event_priorities is optional; the route
  stores config as a JSON blob so no migration is needed.

  i18n: full translations across all 8 locales (en/de/fr/it/ja/pt-BR/zh-CN/
  zh-TW). README, CHANGELOG, and the wiki notifications page updated.

  Tests: 6 backend (Priority set on mapped, omitted on unmapped/missing/
  no-priorities, ignored for bad values, propagated through attachment
  path), 6 frontend (section visible only for ntfy, lists only enabled
  events, save round-trip, edit pre-fill, toggle drops row, non-ntfy
  never writes the key).
2026-04-25 12:33:58 +02:00
Keybored 3f7d0e2d55 Add notification for no spool assigned for active trays, improve usage tracker logic in edge cases (#789)
Add notification for no spool assigned for active trays, improve usage tracker logic in edge cases (#789)
2026-03-24 11:31:32 +01:00
maziggy 35ce075486 [Fix] Suppress spurious "waiting for filament" notification when printers are busy (#753)
When all matching printers were busy and a job was queued with ASAP
  timing, the scheduler immediately fired a "Job Waiting for Filament"
  notification even though the job was just waiting for a printer to
  finish — no user action required.

  Added _is_busy_only() check to skip the waiting notification when the
  only reason is "Busy". Notifications still fire for actionable reasons
  (missing filament, offline, wrong color). Also renamed the default
  notification template title to "Queue Job Waiting" and updated
  descriptions across all 7 locales.
2026-03-20 11:34:23 +01:00
maziggy 0b6facc91c Add first layer complete notification with camera snapshot (#679)
Notify users when the first layer finishes printing so they can check
  adhesion remotely. Triggers once per print when layer 2 begins
  (layer_num >= 2, capped at <= 5 to handle reconnects). Includes a
  camera snapshot attachment. Adds the on_first_layer_complete toggle
  to all notification providers, with backend/frontend/i18n support
  across all 7 locales.
2026-03-13 10:53:21 +01:00
maziggy f28421d1ae Add Home Assistant as notification provider (#656)
Sends persistent notifications to the HA dashboard using the existing
  HA connection from Settings. Zero config — just select "Home Assistant"
  as provider type. Users can forward notifications to mobile via HA
  automations.
2026-03-10 10:10:14 +01:00
maziggy 0faf03ecb3 Fix Python 3.10 compatibility (StrEnum requires 3.11)
enum.StrEnum was added in Python 3.11, but the documented minimum is
  3.10. Add a compatibility shim in backend/app/core/compat.py that falls
  back to (str, Enum) on older versions. Updated all 5 import sites and
  lowered pyproject.toml target-version to py310.
2026-03-05 10:44:24 +01:00
maziggy 53a4933c36 feat: add bed cooled notification after print completes (#378)
Notify users when the print bed cools below a configurable threshold
(default 35°C) after a print finishes, so they know when to remove parts.

- Backend: DB migration, model, schemas, notification template, service
  method, background cooldown monitor (polls every 15s, 30min timeout)
- Frontend: event toggle in provider card/modal, threshold setting in
  Settings > Notifications, i18n keys for all 5 locales
- Tests: 4 backend + 4 frontend tests
- Docs: README, website, wiki updated
2026-02-15 10:59:07 +01:00
maziggy 1401962a08 Fixed ruff errors 2026-02-04 15:17:34 +01:00
maziggy 7c5c4ee5bb Model-based queue assignment with filament validation and queue notifications (#162)
Model-based queue assignment:
- Extract printer_model from sliced 3MF files during upload
- Display sliced-for model in archive view
- New queue mode: assign to "Any [Model]" instead of specific printer
- Scheduler auto-assigns to first idle printer of matching model
- Filament validation: only assign to printers with required filament types loaded
- Waiting reason display shows why jobs are waiting (e.g., "Waiting for filament: Printer1 (needs PLA)")
- "Waiting" status badge (purple) distinguishes from regular "Pending"

Queue notifications (7 new events):
- Job Added: When a job is added to queue
- Job Assigned: When a model-based job is assigned to a printer
- Job Started: When a queue job starts printing
- Job Waiting: When a job is waiting for filament (enabled by default)
- Job Skipped: When a job is skipped due to previous failure (enabled by default)
- Job Failed: When a job fails to start (enabled by default)
- Queue Complete: When all queued jobs finish

Backend changes:
- New columns: print_queue.target_model, print_queue.required_filament_types, print_queue.waiting_reason
- New columns: notification_providers.on_queue_job_* (7 event triggers)
- Notification templates for all queue events
- Scheduler validates filament compatibility before model-based assignment
- Queue API extracts filament types from 3MF when adding model-based items
- Local backup/restore includes queue notification settings

Frontend changes:
- TypeScript interfaces updated for new fields
- Queue page shows waiting reason and "Waiting" badge
- Notification settings includes "Print Queue" section with 7 toggles

Closes #162
2026-01-28 13:39:08 +01:00
maziggy b9495877fc Add HMS error notifications with translations and plate detection fixes
New Features:
- HMS error notifications with human-readable messages (853 error codes)
- Plate not empty notification category (separate toggle in settings)
- Module-friendly names: Print/Task, AMS/Filament, Nozzle/Extruder, etc.
- Backup/restore now includes plate calibration reference images

Fixes:
- Plate calibration images now persist after restart in Docker
- Telegram notifications no longer fail on error codes with underscores
- Plate detection combo button: main toggles detection, chevron opens modal

Tests:
- Added HMS error code tests (10 tests)
- Implemented Dashboard, FileManagerModal, UploadModal tests (previously skipped)
- Added notification service tests for HMS errors and plate detection
- Fixed AuthContext unmount memory leak in tests
2026-01-27 08:48:57 +01:00
maziggy 83cbac04b7 - Add interactive API Browser to Settings > API Keys
- New APIBrowser component with full OpenAPI schema integration
    - Fetches and parses /openapi.json automatically
    - Groups endpoints by API tags (printers, archives, settings, etc.)
    - Expandable endpoint sections with color-coded method badges
    - Path parameter, query parameter, and JSON body editors
    - Auto-populates request body with schema examples
    - Live API request execution with response display
    - Response shows status code, timing, and formatted JSON
    - Copy response button with clipboard fallback
    - Search to filter endpoints across all categories
    - Expand All / Collapse All buttons
    - Link to Swagger UI (/docs)

  - Two-column layout for API Keys tab
    - Left: API key management + webhook documentation
    - Right: API Browser with dedicated test key input

  - Parameter validation
    - Shows warning for missing required parameters
    - Validates before sending requests to avoid 422 errors

  - UX improvements
    - "Use in API Browser" button on newly created keys
    - Responsive layout (stacked on mobile, side-by-side on xl+)
2026-01-02 15:00:21 +01:00
maziggy 1a4f146dd0 Notifications:
- Separate AMS and AMS-HT notification switches (one per device type)
  - Fix notification variables not showing (duration, filament, estimated_time)
  - Add fallback values for empty notification variables ("Unknown" instead of blank)

  Settings:
  - Fix API keys badge count only showing after visiting tab
  - Move External Links card to third column above Updates
  - Add Release Notes modal for viewing full notes before updating

  Statistics:
  - Fix filament usage trends not showing (wrong API parameters)
  - Move dashboard controls (Hidden, Reset Layout) to header row
  - Remove duplicate Reset Layout button

  Camera:
  - Fix ffmpeg processes not killed when closing webcam window
  - Add /camera/stop endpoint with POST support for sendBeacon
  - Track active streams and proper cleanup on disconnect
2025-12-12 09:18:59 +01:00
maziggy ea6d84031a Removed PWA P´push notification 2025-12-11 11:37:13 +01:00
maziggy 2f1ac92598 Restored some files that were deleted by mistake 2025-12-11 11:15:25 +01:00
maziggy e392597192 Added notification module for AMS humidity and temperature 2025-12-10 20:02:22 +01:00
maziggy c74f24353a - Added smart plug monitoring and scheduling
- Added daily digest to notification module
2025-12-08 16:30:53 +00:00
Martin Ziegler f126b0a075 Added auto app update; Added maintenance module with notifications 2025-12-01 08:39:07 +01:00
Martin Ziegler 17c37a7ccd Added notification module 2025-11-30 16:51:27 +01:00