diff --git a/CHANGELOG.md b/CHANGELOG.md index 1147136ab..526a56987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ All notable changes to Bambuddy will be documented in this file. - **Separate Permission for AMS Spool Assignments** ([#635](https://github.com/maziggy/bambuddy/issues/635)) — Added a new `inventory:view_assignments` permission that controls whether spool-to-AMS-slot assignment data is visible on the Printers page. Previously, viewing spool assignments on printer cards required `inventory:read`, which also exposed the full Inventory page in the sidebar. Admins can now grant `inventory:view_assignments` without `inventory:read` so users can see what's loaded in the AMS without accessing the full spool inventory. All default groups (Administrators, Operators, Viewers) include the new permission automatically. Also fixed multi-word permission labels in the group editor (e.g. "Update_Own" → "Update Own"). Reported by @Minebuddy. ### Fixed +- **Bed Cooled Notification Never Fires** ([#497](https://github.com/maziggy/bambuddy/issues/497)) — The bed cooldown monitor always timed out after 30 minutes without sending a notification. After print completion, P1S (and likely other models) sends partial MQTT status updates that don't include `bed_temper`, so the cached bed temperature stayed frozen at the end-of-print value and never dropped below the threshold. The monitor now sends periodic `pushall` commands to the printer to force fresh temperature data. Also added debug logging to the polling loop for future diagnostics. +- **Notification Provider Missing Event Toggles on Create** ([#497](https://github.com/maziggy/bambuddy/issues/497)) — When creating a new notification provider, the `on_bed_cooled` toggle and all 7 queue event toggles (`on_queue_job_added`, `on_queue_job_assigned`, `on_queue_job_started`, `on_queue_job_waiting`, `on_queue_job_skipped`, `on_queue_job_failed`, `on_queue_completed`) were silently discarded. The create endpoint manually listed each field but omitted these 8 toggles, so they always defaulted to `false` regardless of user selection. Editing an existing provider worked correctly. - **Clear Plate Prompt Shown for Staged Queue Items** — The "Clear Plate & Start Next" button on the printer card appeared when all pending queue items were staged (`manual_start`/Queue Only), even though the scheduler won't auto-start them. The clear plate prompt now only appears when there are auto-dispatchable items that the scheduler will actually start after the plate is cleared. - **Ethernet Badge Always Shown on Printer Cards** — The printer card network badge always showed "Ethernet" instead of the WiFi signal indicator, even on printers without an ethernet port. The `home_flag` bit 18 was incorrectly interpreted as indicating a wired connection. Removed the faulty ethernet detection; the WiFi signal badge now displays correctly when the printer reports signal strength. - **GitHub Backup Required Cloud Login** ([#655](https://github.com/maziggy/bambuddy/issues/655)) — The GitHub backup settings card was completely blocked behind Bambu Cloud authentication, showing "Bambu Cloud login required" even though the backup feature works without it (K-profiles and app settings don't need cloud). Removed the cloud auth gate so GitHub backup can be configured and used without Bambu Cloud. The "Cloud Profiles" checkbox is disabled with a hint when not logged in. Reported by @TravisWilder. diff --git a/backend/app/api/routes/notifications.py b/backend/app/api/routes/notifications.py index 426ddd002..f40ff0205 100644 --- a/backend/app/api/routes/notifications.py +++ b/backend/app/api/routes/notifications.py @@ -133,6 +133,16 @@ async def create_notification_provider( on_ams_ht_temperature_high=provider_data.on_ams_ht_temperature_high, # Build plate detection on_plate_not_empty=provider_data.on_plate_not_empty, + # Bed cooled + on_bed_cooled=provider_data.on_bed_cooled, + # Print queue events + on_queue_job_added=provider_data.on_queue_job_added, + on_queue_job_assigned=provider_data.on_queue_job_assigned, + on_queue_job_started=provider_data.on_queue_job_started, + on_queue_job_waiting=provider_data.on_queue_job_waiting, + on_queue_job_skipped=provider_data.on_queue_job_skipped, + on_queue_job_failed=provider_data.on_queue_job_failed, + on_queue_completed=provider_data.on_queue_completed, # Quiet hours quiet_hours_enabled=provider_data.quiet_hours_enabled, quiet_hours_start=provider_data.quiet_hours_start, diff --git a/backend/app/main.py b/backend/app/main.py index c2fdf33a2..80947b8bb 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -2306,10 +2306,19 @@ async def on_print_complete(printer_id: int, data: dict): logger.info("[BED-COOL] Monitoring bed temp for printer %s (threshold: %.0f°C)", printer_id, threshold) + # Request a fresh full status so we get current bed_temper + printer_manager.request_status_update(printer_id) + max_polls = 120 # 120 * 15s = 30 min timeout - for _ in range(max_polls): + for poll_num in range(max_polls): await asyncio.sleep(15) + # Request fresh temperature data every 60s — after print completion, + # the printer may send partial MQTT updates without bed_temper, + # leaving the cached value stale at the end-of-print temperature. + if poll_num % 4 == 0: + printer_manager.request_status_update(printer_id) + # Check if printer is still connected status = printer_manager.get_status(printer_id) if status is None: @@ -2327,8 +2336,16 @@ async def on_print_complete(printer_id: int, data: dict): bed_temp = status.temperatures.get("bed") if bed_temp is None: + logger.debug( + "[BED-COOL] Printer %s: bed temp is None (keys: %s, state: %s)", + printer_id, + list(status.temperatures.keys()) if isinstance(status.temperatures, dict) else "N/A", + status.state if hasattr(status, "state") else "N/A", + ) continue + logger.debug("[BED-COOL] Printer %s: bed=%.1f°C, threshold=%.0f°C", printer_id, bed_temp, threshold) + if bed_temp <= threshold: logger.info( "[BED-COOL] Bed cooled to %.1f°C on printer %s (threshold: %.0f°C)",