diff --git a/CHANGELOG.md b/CHANGELOG.md index f5053b4a0..52abaa654 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ All notable changes to Bambuddy will be documented in this file. - **SpoolBuddy Updates Now Use SSH** — Replaced the fragile self-update mechanism (daemon pulls its own code via git, permission errors on `.git/`, hardcoded `main` branch) with SSH-based updates driven by the Bambuddy backend. Bambuddy now SSHes into the SpoolBuddy Pi and runs git fetch/checkout, pip install, systemctl restart, and kiosk browser restart remotely. Updates automatically use the same branch as Bambuddy. SSH key pairing is fully automatic — Bambuddy generates an ED25519 keypair and includes the public key in the device registration response; the daemon deploys it to `authorized_keys` on first connect. The install script creates the `spoolbuddy` user with a bash shell and sudoers entries for daemon and kiosk restart. A "Force Update" button allows re-deploying even when versions match. The SSH public key is also shown in SpoolBuddy Settings → Updates → SSH Setup for manual pairing if needed. - **SpoolBuddy Kiosk Shows Stale Frontend After Update** — After an update, the kiosk browser displayed the old frontend because Chromium served cached assets even after restarting. Added `--disk-cache-size=0` to the Chromium launch flags so it always loads fresh content from the Bambuddy backend. - **SpoolBuddy Kiosk Starts Before Network Is Ready** — On fresh installs, the kiosk browser launched before the network was fully up, showing a connection error for 10-15 seconds until connectivity was restored. The getty@tty1 autologin override now waits for `network-online.target` so Chromium has connectivity when it starts. -- **SpoolBuddy Update Status Stale After Restart** — After a SpoolBuddy update completed, the UI continued showing "Update complete, daemon restarting..." and the old "update available" banner because stale status was never cleared. Fixed by clearing `update_status` on device re-registration (daemon restart), and adding WebSocket handlers for `spoolbuddy_update` and `spoolbuddy_online` events so the frontend immediately refreshes device state and update check results. +- **SpoolBuddy Update Status Stale After Restart** — After a SpoolBuddy update completed, the UI permanently showed "Update complete, daemon restarting..." and a stale "update available" banner. Root cause: the SSH update set status to `"complete"` after the daemon had already restarted and re-registered, overwriting the cleared state. Fixed by letting daemon re-registration be the completion signal — it now clears any update status (`pending`/`updating`/`complete`/`error`), and the final `"complete"` write was removed. Also added WebSocket handlers for `spoolbuddy_update` and `spoolbuddy_online` events so the frontend refreshes immediately. - **Virtual Printer Proxy A1 Printing Fails** ([#757](https://github.com/maziggy/bambuddy/issues/757)) — BambuStudio could not send prints to A1 (and potentially P1S) virtual printers in proxy mode. The slicer connects to undocumented proprietary ports 2024-2026 on these models, which the proxy was not forwarding, causing BambuStudio to show an access code dialog instead of printing. Added transparent TCP pass-through proxying for ports 2024-2026. These ports are silently ignored on models that don't use them (X1C, H2C, P2S). Reported by @Utility9298. - **Spool Assignment on Empty AMS Slots** ([#784](https://github.com/maziggy/bambuddy/issues/784)) — Empty AMS slots (no physical spool detected) showed "Assign Spool" and "Configure" buttons in the hover popup. Assigning a spool to an empty slot created a stuck state because no "Unassign" button is available for empty slots. Removed both buttons from empty AMS and HT AMS slot popups. External spool holders are unaffected. Reported by @RosdasHH. diff --git a/backend/app/api/routes/spoolbuddy.py b/backend/app/api/routes/spoolbuddy.py index 5e4f72959..456388922 100644 --- a/backend/app/api/routes/spoolbuddy.py +++ b/backend/app/api/routes/spoolbuddy.py @@ -102,7 +102,7 @@ async def register_device( device.has_backlight = req.has_backlight device.last_seen = now # Clear stale update status on re-registration (daemon restarted after update) - if device.update_status in ("complete", "error"): + if device.update_status in ("pending", "updating", "complete", "error"): device.update_status = None device.update_message = None logger.info("SpoolBuddy device re-registered: %s (%s)", req.device_id, req.hostname) diff --git a/backend/app/core/config.py b/backend/app/core/config.py index f10c06e49..4e1617596 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -5,7 +5,7 @@ from pathlib import Path from pydantic_settings import BaseSettings # Application version - single source of truth -APP_VERSION = "0.2.3.b1" +APP_VERSION = "0.2.3" GITHUB_REPO = "maziggy/bambuddy" BUG_REPORT_RELAY_URL = os.environ.get("BUG_REPORT_RELAY_URL", "https://bambuddy.cool/api/bug-report") diff --git a/backend/app/services/spoolbuddy_ssh.py b/backend/app/services/spoolbuddy_ssh.py index e068627ac..5d46d5721 100644 --- a/backend/app/services/spoolbuddy_ssh.py +++ b/backend/app/services/spoolbuddy_ssh.py @@ -226,7 +226,6 @@ async def perform_ssh_update(device_id: str, ip_address: str, install_path: str return # Step 6: Restart kiosk browser to load updated frontend - await _update_progress("updating", "Restarting kiosk browser...") rc, _, stderr = await _run_ssh_command( ip_address, "sudo /usr/bin/systemctl restart getty@tty1.service", @@ -235,8 +234,6 @@ async def perform_ssh_update(device_id: str, ip_address: str, install_path: str if rc != 0: # Non-fatal — kiosk may not be set up on all devices logger.warning("SpoolBuddy %s: kiosk restart failed (non-fatal): %s", device_id, stderr[:200]) - - await _update_progress("complete", "Update complete, daemon restarting...") logger.info("SpoolBuddy %s: SSH update complete (branch=%s)", device_id, branch) except Exception as e: