Commit Graph
139 Commits
Author SHA1 Message Date
maziggy fd3919574b - Major fixes for skip objects feature 2026-01-01 18:31:59 +01:00
maziggy 2dcd1a2ef2 - Enhanced skip objects feature with visual improvements and better UX
- Skip Objects Modal:
    - Object ID markers overlaid on preview image (grid layout)
    - Large prominent ID badges to match printer display
    - Info banner explaining to match IDs with printer screen
    - Layer warning when skip unavailable (layer <= 1)
    - Red badge on button showing skipped count
    - Preview image now shown when paused (not just running)
    - Close with ESC key or click outside modal
    - Full light/dark theme support

  - Backend:
    - Extract object positions from 3MF (include_positions=True)
    - API returns x/y coordinates for objects (when available)
    - Parse s_obj from printer MQTT for skipped state persistence
    - Cover URL available in PAUSE/PAUSED states

  - Tests:
    - Added test for objects with position data
2026-01-01 18:01:41 +01:00
maziggy fe250b9b7f - Added frontnend/backend tests for printer controls 2026-01-01 16:02:25 +01:00
maziggy 079e9fc2cc - Camera popup window:
- Auto-resize to fit video resolution on first open
  - Persist window size and position to localStorage
  - Restore saved window state for subsequent opens
2026-01-01 12:29:25 +01:00
maziggy d3686a1b60 - Fixed maintenance interval display on status page 2026-01-01 12:21:12 +01:00
maziggy ccdb084f23 - Refactored printer card's AMS section for better experience 2026-01-01 12:08:55 +01:00
maziggy 01bc211616 - Slicer Protocol:
- Add utils/slicer.ts with OS detection for protocol handler
  - Windows: bambustudio://, macOS/Linux: bambustudioopen://
  - Update all usages in ArchivesPage.tsx and ModelViewerModal.tsx
2026-01-01 07:52:47 +01:00
maziggy bca1a80172 * Add customizable theme system with style, background, and accent options
Implement comprehensive theme customization with independent settings for
  dark and light modes:

  - Style layer: Classic (clean shadows), Glow (accent-colored glow effects),
    Vibrant (dramatic deep shadows)
  - Background layer: Neutral, Warm, Cool (light mode); plus OLED, Slate,
    Forest (dark mode only)
  - Accent colors: Green, Teal, Blue, Orange, Purple, Red

  All combinations work independently (e.g., Glow + Forest + Teal). Settings
  sync across devices via database and show toast confirmations on change.

  Backend:
  - Add 6 new settings fields (dark_style, dark_background, dark_accent,
    light_style, light_background, light_accent)
  - Add integration test for theme settings API

  Frontend:
  - Refactor index.css with 3-layer CSS variable system
  - Update ThemeContext for dual-mode theme management
  - Add Appearance section to Settings page with 6 dropdowns
  - Update components for new ThemeContext API
2025-12-31 15:44:52 +01:00
maziggy 297c3212fa Housekeeping 2025-12-31 12:24:17 +01:00
maziggy 9f665a9382 Housekeeping 2025-12-31 11:36:53 +01:00
maziggy 0291f09649 - Fixed bug where add smart plug modal doesn't scroll on lower resolution screens (https://github.com/maziggy/bambuddy/issues/34) 2025-12-30 12:22:22 +01:00
maziggy 88487f8f46 Bottom sidebar layout fix 2025-12-30 09:28:32 +01:00
maziggy a322b8fad4 Minor bugfixes in queueing module 2025-12-29 16:00:49 +01:00
maziggy 88e84ca45a - Add Virtual Printer feature - emulate Bambu printer on network
- Virtual printer appears in Bambu Studio/Orca Slicer via SSDP discovery
  - Secure TLS/MQTT communication with auto-generated certificates
  - Queue mode (pending uploads) or auto-start mode
  - Configurable access code for authentication
  - Docker support with network_mode: host and certificate persistence
  - Fix backup/restore for virtual printer settings (auto-save no longer overwrites)
2025-12-29 15:52:48 +01:00
maziggy 3cba1c0989 - Fix AMS filament matching in reprint modal
- Add fuzzy color matching for filament comparison
    Colors within RGB threshold of 40 are considered a match, fixing
    cases where 3MF and printer report slightly different hex values
    for the same filament color (e.g., beige #F5F5DC vs #FCECD6)

  - Add POST /printers/{id}/refresh-status endpoint
    Sends MQTT pushall command to request fresh AMS data from printer

  - Improve Re-read button in filament check section
    - Now triggers backend refresh before refetching status
    - More prominent styling with text label and border
    - 500ms delay after pushall to allow printer to respond

  - Add AMS slot labels to matched filament display
    Shows location like "PLA (AMS-B Slot 3)" instead of just "PLA"

  - Add color hex tooltips on filament color circles
2025-12-29 10:03:51 +01:00
maziggy a008be96ee - All archive page filters are now persitent 2025-12-29 09:16:28 +01:00
maziggy e97d697d90 - Archive card: fixed a cache bug, where wrong cover image was shown 2025-12-29 09:05:10 +01:00
maziggy 0bcedd2c16 - Add Tasmota device discovery and switchbar quick access
- Features:
    - Tasmota device discovery: Auto-detect network and scan for Tasmota devices
      in Add Smart Plug modal. Supports devices with/without authentication.
    - Switchbar: Quick access widget in sidebar footer for controlling smart plugs
      from anywhere in the app. Shows real-time status and power consumption.
2025-12-28 15:02:42 +01:00
maziggy b3ef6ccb32 - Add AMS filament preview for reprints and file type badges
- AMS Filament Preview:
    - Add GET /archives/{id}/filament-requirements endpoint to extract
      filament data from archived 3MF slice_info.config
    - Show filament comparison in reprint modal when printer is selected
    - Compare both filament type AND color with visual indicators:
      - Green checkmark: Type and color match
      - Yellow warning: Same type, different color
      - Orange warning: Different type or empty slot
    - Handle AMS-HT units (id >= 128) and virtual tray (slot 254)
    - Normalize color formats between API (RRGGBBAA) and 3MF (#RRGGBB)

- File Type Badge:
  - Archive cards show GCODE (green) or SOURCE (orange) badge
  - Helps users identify which files have print data vs source-only
  - Badge appears next to printer name in card content area

- Camera Stream Stability:
  - Increase ffmpeg read timeout from 10s to 30s
  - Add ffmpeg RTSP options: -timeout, -buffer_size, -max_delay
  - Add frontend auto-reconnection with exponential backoff (2s-30s)
  - Show reconnection UI with countdown and attempt counter
2025-12-28 13:50:29 +01:00
maziggy 530a7a4608 - Fix camera stream stopping after a few minutes
- Backend:
    - Increase ffmpeg stdout read timeout from 10s to 30s
    - Add ffmpeg RTSP stability options: -timeout, -buffer_size, -max_delay
  - Frontend:
    - Add auto-reconnection with exponential backoff (2s→30s max)
    - Show reconnection UI with countdown and attempt counter
    - Maximum 5 reconnection attempts before showing error
    - "Reconnect now" button to skip countdown
    - Reset reconnection state on manual refresh or mode switch
2025-12-28 13:16:14 +01:00
maziggy b1be35ba8c - Add timelapse editor with trim, speed adjustment, and music overlay
- Add TimelapseEditorModal component with visual timeline scrubber
  - Add timelapse processing endpoints (info, thumbnails, process)
  - Add TimelapseProcessor service using FFmpeg for video processing
  - Support trim (start/end), speed (0.25x-4x), and audio overlay
  - Add Edit button to TimelapseViewer
  - Fix browser caching with timestamp query parameter
  - Change default timelapse playback speed from 2x to 1x
2025-12-28 13:06:30 +01:00
maziggy db5cb86d3a - Project page enhancements and bug fixes
- Add filament color swatches to project cards showing colors from assigned archives
  - Add "Hide done" toggle to filter completed BOM items
  - Include projects in backup/restore (with BOM items and attachments)
  - Add file type validation for project attachments
  - Enhance project card design with gradients, shadows, and glow effects
  - Improve layout spacing on project list and detail pages
  - Replace browser confirm dialogs with styled confirmation modals
  - Fix attachment uploads not persisting (SQLAlchemy JSON column mutation)
2025-12-28 12:04:33 +01:00
maziggy 8acc91d3cd - Add subnet scanning for printer discovery in Docker environments
- Detect Docker environment automatically via /.dockerenv and cgroup
  - Show subnet input field in Add Printer dialog when running in Docker
  - Scan IP range for Bambu printer ports (8883 MQTT, 990 FTPS)
  - Query SSDP to get printer name/serial/model from discovered IPs
  - Map raw SSDP model codes to friendly names (BL-P001→X1C, O1D→H2D)
2025-12-28 09:40:47 +01:00
maziggy e9193276a6 Summary of Fixes
1. "Unknown Status (255)" bug

  File: backend/app/services/printer_manager.py:291-293

  Problem: A1/P1 printers send stg_cur=255 when idle (unlike X1 which uses -1). The code treated 255 as a valid stage number and returned "Unknown stage (255)".

  Fix: Changed the condition from if state.stg_cur >= 0: to if 0 <= state.stg_cur < 255: so that 255 is now treated as "no calibration stage" (same as -1).

  2. AMS humidity/temp displaced on mobile

  File: frontend/src/pages/PrintersPage.tsx:1164-1212

  Problem: The AMS row used a rigid horizontal flex layout that didn't adapt to narrow mobile screens, causing humidity/temperature indicators to be displaced.

  Fix:
  - Added flex-wrap to allow wrapping on very narrow screens
  - Added ml-auto to humidity/temp section to keep it right-aligned
  - Added max-w-[60px] sm:max-w-none to truncate long filament names on mobile
  - Changed gap from fixed gap-3 to responsive gap-2 sm:gap-3

  Tests Added

  4 new unit tests for get_derived_status_name:
  - test_stg_cur_255_returns_none - Verifies A1/P1 idle state
  - test_stg_cur_negative_one_returns_none_when_idle - Verifies X1 idle state
  - test_valid_stage_returns_name - Verifies valid stages work
  - test_stg_cur_zero_returns_printing - Verifies printing state

  All 382 tests pass.
2025-12-27 15:53:37 +01:00
maziggy 929c4c8cd6 - Fix total print hours calculation in set_total_hours to include all
prints (not just completed), matching get_printer_total_hours behavior
  - Add option to keep or delete archives when deleting a printer
  - Custom maintenance types no longer auto-assign to all printers
  - Add UI to manually assign/remove custom maintenance types per printer
  - Add backend endpoints for assigning types to printers and removing items
  - Exclude static/assets from large file pre-commit check
2025-12-23 09:00:36 +01:00
maziggy ef68804fa9 - Added printer auto discovery to add printer modal 2025-12-21 11:23:20 +01:00
maziggy 0da5de0f46 - Printer cards now shows heater states 2025-12-21 10:48:50 +01:00
maziggy 0200f69ba3 - Show detailed printer status stages on printer cards
- Add getStatusDisplay() helper in frontend to format status nicely
  - Add get_derived_status_name() in backend to compute status from:
    - stg_cur calibration stages (bed leveling, vibration comp, etc.)
    - Temperature data when stg_cur unavailable (heating heatbed/nozzle)
  - Include stg_cur and stg_cur_name in WebSocket broadcasts
  - Update broadcast status key to detect heating phase changes

  Printer cards now show: "Heating heatbed", "Heating nozzle", "Preparing",
  "Auto bed leveling", "Cleaning nozzle tip", and 60+ other stage names
  instead of just "Printing" or "Idle".
2025-12-21 10:24:26 +01:00
maziggy 9f0debc5a7 Fix printer status "timelapse" effect after print completion
When navigating to the printer page after a print completed, status
metrics would animate slowly from mid-print values to final state.

Root cause: The message queue processed messages one at a time with 16ms
delays. If 50+ status updates queued during a print, they took 800ms+ to
process, causing multiple throttle windows and the visual "timelapse".

Solution: Handle printer_status messages directly without queueing.
They're already throttled (100ms) so don't need queue rate limiting.
Other message types still use the queue.
2025-12-17 15:03:27 +01:00
maziggyandClaude Opus 4.5 a7319f0e70 Fix browser freeze on print completion with camera stream open
Root cause: When a print completed with the camera stream popup open,
spawning a second ffmpeg process for finish photo capture caused a
conflict that froze the browser tab and video window.

Solution: Buffer the last frame from active camera streams. When
capturing finish photo, use the buffered frame if a stream is active
instead of spawning a new ffmpeg process.

Backend changes:
- camera.py: Added _last_frames buffer and get_buffered_frame() helper
- main.py: Photo capture uses buffered frame when stream is active
- main.py: Moved slow operations to background tasks (energy calc,
  photo capture, smart plug, notifications, maintenance)
- archive.py: Fixed sync file write blocking event loop (asyncio.to_thread)
- printers.py: Added debug endpoint to simulate print completion

Frontend changes:
- useWebSocket.ts: Throttled printer status updates (100ms) to prevent
  UI overload from rapid WebSocket messages
- useWebSocket.ts: Debounced archive invalidations (3s) to prevent
  cascade of re-renders on print completion
- useWebSocket.test.ts: Updated tests for throttled/debounced handlers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 18:45:03 +01:00
maziggy e248b41fad Fixed bug where layer slider in gcode viewer was broken 2025-12-16 12:35:53 +01:00
maziggy c8b9a8e3d6 Summary of Changes
Backend (backend/app/api/routes/archives.py):
  - Added filament_colors extraction from slice_info.config in 3MF files
  - Maps filament IDs (1-based) to tool numbers (0-based)

  Frontend (frontend/src/components/GcodeViewer.tsx):
  1. Multi-color support: Pass extrusionColor as array of CSS color strings for multi-color prints
  2. Bambu T-command filtering: Filter out special Bambu commands (T255, T1000, T1001, T65535, T65279) that corrupt tool state
  3. Initial tool: Prepend T0 to ensure initial tool is set correctly
  4. Disable gradient: Set disableGradient: true for multi-color to preserve actual filament colors (the gradient was turning black into gray/white)
  5. Disable topLayerColor: Don't set topLayerColor for multi-color (it overrides per-tool colors)

  Key fixes for Bambu G-code compatibility:
  - Bambu uses special T commands (T1000, T65535, etc.) that aren't real tool changes
  - The gcode-preview library's brightness gradient was modifying colors based on layer index

  Commit message suggestion:
  Add multi-color filament support to G-code viewer

  - Extract filament colors from 3MF slice_info.config
  - Pass color array to gcode-preview for tool-based coloring
  - Filter Bambu special T commands (T1000, T65535, etc.)
  - Disable gradient to preserve actual filament colors
2025-12-16 12:30:58 +01:00
maziggy 5cd366ceac Fix browser tab crash on print completion (debounced invalidations)
When a print completes, multiple WebSocket messages are sent rapidly
  (print_complete, archive_updated, etc.). Each was immediately invalidating
  the archives query, causing a cascade of rapid re-renders that crashed
  the browser tab.

  Added debounced query invalidation to useWebSocket.ts:
  - Multiple invalidation requests within 100ms are coalesced into one
  - Uses requestAnimationFrame to avoid blocking the main thread
  - Properly cleans up timeouts on unmount
2025-12-16 10:26:30 +01:00
maziggy 99b504079b Fixed bug in archive card context menu 2025-12-16 08:26:02 +01:00
maziggy 0bb76024fd Fix printer card flicker when disconnecting
- Cache connected state in ref to prevent flicker when status
    briefly becomes undefined during query refetches
  - Use cached value for shouldHide calculation instead of raw status
2025-12-15 14:03:26 +01:00
maziggy f22acedc7d Update HMS error handling with comprehensive database and unknown filtering
- Replace manual error database with 853 codes from ha-bambulab
    (Source: https://github.com/greghesp/ha-bambulab)
  - Filter out unknown HMS error codes from display
    (Printers sometimes send duplicate/undocumented codes for same error)
  - Update HMS badge count to only show known errors
  - Export filterKnownHMSErrors helper for reuse across components
2025-12-15 13:50:13 +01:00
maziggyandClaude Opus 4.5 3a8cdba1e3 Improve HMS error descriptions and wiki links
- Add ~80 HMS error code descriptions covering:
  - 0300 series: temperature, fan, motor, force sensor, build plate errors
  - 0500 series: storage, network, module communication, camera errors
  - 0700 series: AMS communication, filament, hotend matching errors
  - 0C00 series: toolhead camera, lidar, AI detection errors
  - 1200 series: external spool errors
- Fix 0500_0400_0002_0043 description (toolhead camera dirty, not file system)
- Always link to HMS home page (wiki.bambulab.com/en/hms/home) instead of
  specific error pages that may not exist

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 09:46:19 +01:00
maziggy adcefd3a5b Issue 1: Aborted prints showing "Unknown" in failure analysis
- The failure analysis service was only querying status == "failed"
  - Changed all queries to include both failed AND aborted: status.in_(["failed", "aborted"])
  - File: backend/app/services/failure_analysis.py

  Issue 2: Cannot clear failed flag in edit mode
  - Added status field to ArchiveUpdate schema (backend)
  - Added status to API client type (frontend)
  - Added status dropdown to EditArchiveModal with options: Completed, Failed, Cancelled, Printing
  - When status changes to "completed", failure_reason is automatically cleared
  - File changes:
    - backend/app/schemas/archive.py - added status field
    - frontend/src/api/client.ts - added status to updateArchive type
    - frontend/src/components/EditArchiveModal.tsx - added status dropdown
2025-12-15 08:50:17 +01:00
maziggyandClaude Opus 4.5 ca2bd6bf57 Fix timelapse auto-download and browser tab crash on print completion
1. Timelapse auto-download rewrite (main.py)
   - New retry mechanism with short delays (5s, 10s, 20s)
   - Grabs most recent file directly without mtime comparison
   - Works with printers that have wrong clock (LAN-only mode)
   - Checks multiple paths: /timelapse, /timelapse/video, /record, /recording

2. Browser tab crash fix (PrintersPage.tsx)
   - Throttled query cache subscription using requestAnimationFrame
   - Prevents rapid re-render cascade on print completion events

3. WebSocket optimization (main.py)
   - Removed large raw_data field from print_complete message
   - Only sends necessary fields: status, filename, subtask_name, timelapse_was_active

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 08:46:38 +01:00
maziggy e85e5fa33e Backend changes:
1. bambu_mqtt.py: Added hms_errors to the completion callback data, which includes the HMS error codes when a print fails
  2. archive.py: Updated update_archive_status() to accept an optional failure_reason parameter
  3. main.py: Added auto-detection of failure reasons:
    - status == "aborted" → failure_reason = "User cancelled"
    - status == "failed" with HMS errors → maps module codes to reasons:
        - Module 0x07 (Filament) → "Filament runout"
      - Module 0x0C (Motion Controller) → "Layer shift"
      - Module 0x05 (Nozzle) → "Clogged nozzle"

  Frontend changes:

  1. ArchivesPage.tsx:
    - Badge now shows "cancelled" for aborted prints, "failed" for failed prints
    - "Failed Prints" collection and "Hide Failed" filter now include both failed and aborted statuses
  2. EditArchiveModal.tsx: Failure reason field now shows for both failed and aborted prints

  New tests added:
  - test_hms_errors_included_in_failed_completion_callback
  - test_aborted_status_when_cancelled

  The HMS error module mapping is basic and can be expanded as you observe more failure types. The actual Bambu HMS error codes are documented in their wiki - we can add
  more mappings as needed.
2025-12-13 10:13:54 +01:00
maziggy f5cec45dbf 1. Timelapse viewer default speed changed to 2x
- frontend/src/components/TimelapseViewer.tsx:17 - Changed from 0.5 to 2

  2. Archive page: hide failed prints filter with persistence
  - Added hideFailed state initialized from localStorage.getItem('archiveHideFailed')
  - Added localStorage persistence via useEffect
  - Added "Hide Failed" toggle button (red styling when active) next to the Favorites button
  - Filter is automatically bypassed when viewing the "Failed Prints" collection
  - "Reset" button also clears this filter

  The filter state persists across page refreshes and browser sessions via localStorage.
2025-12-13 10:04:15 +01:00
maziggy 80c39df7e9 Fixed bug in Dockerfile 2025-12-12 16:20:55 +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 7048bafff3 Added anonymous stats 2025-12-11 13:35:59 +01:00
maziggy 77a66ea867 Added system info page 2025-12-11 12:45:38 +01:00
maziggy 5efb7ab2c8 Improved archive card context menu 2025-12-11 12:26:37 +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 0dc76746b4 Add AMS humidity/temperature history tracking with charts
- Add database model for storing AMS sensor history (humidity, temperature)
  - Record sensor data every 5 minutes via background task
  - Add API endpoint to retrieve history with min/max/avg statistics
  - Create AMSHistoryModal component with Recharts line charts
  - Make humidity/temperature indicators clickable to open history
  - Support time range selection (6h, 24h, 48h, 7d)
  - Show threshold reference lines on charts (Good/Fair levels)
  - Add configurable data retention (default 30 days) in Settings
  - Auto-cleanup old data daily
  - Fix dark theme styling in modal using inline styles
  - Add Escape key to close modal
2025-12-10 19:45:38 +01:00