Commit Graph
1847 Commits
Author SHA1 Message Date
MartinNYHC 459b781fe8 Add firmware version input to bug report template 2025-12-28 08:57:27 +01:00
MartinNYHC 017e36a0a6 Add firmware version input to bug report template
Added input field for specifying printer firmware version in bug report template.
2025-12-28 08:55:28 +01:00
maziggy 49b9fb854b - Fixed bug in notification module where notifictions were sent although printer is offline 2025-12-27 18:48:14 +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 a66500b605 Fixed bug in mock_state 2025-12-27 15:46:13 +01:00
maziggy 11a6bb282a Key Discovery
A1/P1 printers don't support RTSP - they use a custom chamber image protocol on port 6000:
  - SSL/TLS connection
  - 80-byte binary auth payload (magic + "bblp" + access code)
  - 16-byte header with payload size + JPEG data

  Changes Made

  backend/app/services/camera.py

  - Added supports_rtsp() - detects X1/H2/P2 (RTSP) vs A1/P1 (chamber image)
  - Added is_chamber_image_model() - inverse check
  - Added _create_chamber_auth_payload() - builds 80-byte auth
  - Added _create_ssl_context() - SSL for self-signed certs
  - Added read_chamber_image_frame() - single frame capture
  - Added generate_chamber_image_stream() - persistent connection
  - Added read_next_chamber_frame() - read from stream
  - Updated capture_camera_frame() - uses correct protocol per model

  backend/app/api/routes/camera.py

  - Added generate_chamber_mjpeg_stream() - MJPEG from chamber protocol
  - Renamed generate_mjpeg_stream() → generate_rtsp_mjpeg_stream()
  - Updated camera_stream endpoint - chooses protocol based on model
  - Updated stop_camera_stream - cleans up both stream types
  - Added tracking for _active_chamber_streams

  Protocol Matrix

  | Model                       | Protocol      | Port |
  |-----------------------------|---------------|------|
  | X1, X1C, X1E, H2C, H2D, P2S | RTSP          | 322  |
  | A1, A1MINI, P1P, P1S        | Chamber Image | 6000 |
2025-12-25 07:44:53 +01:00
maziggy 01989b7182 - Fix A1/P1 camera streaming with extended timeouts and lower FPS cap
- Removed deprecated -stimeout option (renamed to -timeout in ffmpeg 5.0+).
2025-12-24 13:43:35 +01:00
maziggy 7622d2ae5c - 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
  - Fix A1/P1 camera streaming with extended timeouts and lower FPS cap
2025-12-24 08:41:23 +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
maziggyandClaude Opus 4.5 288a495041 - Fix dual nozzle temperature display for H2D printers
- Use extruder_info[0].temp for right nozzle instead of nozzle_temper field which incorrectly mirrors left nozzle
- Gate dual nozzle parsing with has_h2d_extruder_info to prevent single nozzle printers showing two temps
- Add nozzle_heating calculation for single nozzle printers

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 13:07:06 +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 3ffe032635 - Fix total print hours to include all prints 2025-12-21 09:56:34 +01:00
MartinNYHC 77f21bf6f8 Merge pull request #27 from maziggy/0.1.5-final
Release Notes for 0.1.5

  Highlights

  This release focuses on stability improvements and bug fixes, with major fixes for browser freezing and UI responsiveness issues.

  Bug Fixes

  - Browser freeze on print completion - Fixed a critical issue where the browser would freeze when a print completed with the camera stream open. The fix uses buffered camera frames instead of spawning duplicate ffmpeg processes.
  - Printer status "timelapse" effect - Fixed an issue where navigating to the printer page after a print completed showed metrics animating slowly from mid-print values to the final state. Printer status messages now bypass the throttled queue for immediate updates.
  - Timelapse auto-download - Complete rewrite with retry mechanism and support for multiple storage paths.
  - Timelapse detection for H2D - Fixed detection using the correct ipcam.timelapse field instead of xcam.timelapse.
  - Reprint from archive - Fixed bug where the print button sent the slicer source file instead of the sliced gcode.
  - Import shadowing bugs - Fixed ArchiveService import shadowing causing "cannot access local variable" errors.

  New Features

  - Failure reason detection - Automatically detects failure reasons from HMS errors (filament runout, layer shift, clogged nozzle)
  - Hide failed prints filter - Toggle to hide failed/aborted prints with localStorage persistence
  - Docker test suite - Comprehensive tests for build, backend, frontend, and integration
  - Pre-commit hooks - Ruff linter and formatter for code quality
  - Code quality tests - Static analysis to catch import shadowing bugs automatically

  Changes

  - Timelapse viewer default playback speed changed from 0.5x to 2x
  - Archive badges now show "cancelled" for aborted prints
  - WebSocket throttle reduced to 100ms for smoother updates
  - Added ffmpeg to Docker image

  Upgrading

  cd bambuddy && git pull && docker compose up -d --build

  Or use the auto-update feature in Settings.
v0.1.5-final
2025-12-19 08:32:10 +01:00
maziggy 866f4835a3 0.1.6b 2025-12-19 08:31:18 +01:00
maziggy 5e771b70c9 Release Notes for 0.1.5
Highlights

  This release focuses on stability improvements and bug fixes, with major fixes for browser freezing and UI responsiveness issues.

  Bug Fixes

  - Browser freeze on print completion - Fixed a critical issue where the browser would freeze when a print completed with the camera stream open. The fix uses buffered camera frames instead of spawning duplicate ffmpeg processes.
  - Printer status "timelapse" effect - Fixed an issue where navigating to the printer page after a print completed showed metrics animating slowly from mid-print values to the final state. Printer status messages now bypass the throttled queue for immediate updates.
  - Timelapse auto-download - Complete rewrite with retry mechanism and support for multiple storage paths.
  - Timelapse detection for H2D - Fixed detection using the correct ipcam.timelapse field instead of xcam.timelapse.
  - Reprint from archive - Fixed bug where the print button sent the slicer source file instead of the sliced gcode.
  - Import shadowing bugs - Fixed ArchiveService import shadowing causing "cannot access local variable" errors.

  New Features

  - Failure reason detection - Automatically detects failure reasons from HMS errors (filament runout, layer shift, clogged nozzle)
  - Hide failed prints filter - Toggle to hide failed/aborted prints with localStorage persistence
  - Docker test suite - Comprehensive tests for build, backend, frontend, and integration
  - Pre-commit hooks - Ruff linter and formatter for code quality
  - Code quality tests - Static analysis to catch import shadowing bugs automatically

  Changes

  - Timelapse viewer default playback speed changed from 0.5x to 2x
  - Archive badges now show "cancelled" for aborted prints
  - WebSocket throttle reduced to 100ms for smoother updates
  - Added ffmpeg to Docker image

  Upgrading

  cd bambuddy && git pull && docker compose up -d --build

  Or use the auto-update feature in Settings.
2025-12-19 08:28:13 +01:00
maziggy 34193c2d89 Uodated .gitignore 2025-12-18 19:53:40 +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
maziggy bc23db0149 Fixed version number parsing in update module 2025-12-14 17:00:00 +01:00
maziggy b5df62922c Updated version to 0.1.5 2025-12-14 10:25:02 +01:00
MartinNYHC dcfa9797b6 Merge pull request #25 from maziggy/0.1.5-final
Updated CHANGELOG
v0.1.5b7
2025-12-14 10:23:38 +01:00
maziggy a668b5245a Updated CHANGELOG 2025-12-14 10:22:51 +01:00
MartinNYHC d1df2bb8c5 Merge pull request #24 from maziggy/0.1.5-final
This release focuses on stability improvements, particularly around timelapse handling and Docker support.

  Bug Fixes

  - Timelapse auto-download - Complete rewrite with retry mechanism (5s, 10s, 20s delays) and support for multiple FTP paths. Now works reliably with printers in LAN-only mode that have incorrect clocks.
  - Browser tab crash - Fixed rapid re-render cascade that could crash the browser tab on print completion
  - Timelapse detection for H2D - Fixed detection for H2D printers which send timelapse status in ipcam.timelapse instead of xcam.timelapse
  - Reprint from archive - Fixed critical bug where the print button sent the slicer source file instead of the sliced gcode file
  - Import shadowing bugs - Fixed "cannot access local variable" errors in archive service

  New Features

  - Automatic failure reason detection - Automatically detects and records failure reasons from HMS error codes (filament runout, layer shift, clogged nozzle)
  - Hide failed prints filter - New toggle to hide failed/aborted prints from the archive view (persists across sessions)
  - Docker test suite - Comprehensive automated tests for Docker builds

  Improvements

  - Timelapse viewer default speed changed to 2x
  - Archive badges now show "cancelled" for user-stopped prints
  - WebSocket messages optimized (smaller payloads)
  - Pre-commit hooks added for code quality (ruff)

  Docker

  - Added ffmpeg for video processing
  - Fixed build warnings
  - Comprehensive Docker documentation added to README
2025-12-14 10:20:20 +01:00
maziggy 357dfe8036 Updated CHANGELOG 2025-12-14 10:19:09 +01:00
maziggy 88bd020dc9 Improved Docker support; Added Docker test suite 2025-12-14 10:16:33 +01:00
maziggy 40e31f4b3d Added Docker section to README 2025-12-14 10:15:16 +01:00
maziggyandClaude Opus 4.5 dc92816515 Fix i18next warning in frontend tests
- Initialize i18n in test setup to suppress 'NO_I18NEXT_INSTANCE' warning
- Update AMSHistoryModal tests to use actual translated text

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 09:54:36 +01:00
maziggy 76795b5fe2 Fixed bug where print button sent slicer source file instesf of sliced gcode file 2025-12-14 09:50:12 +01:00
maziggyandClaude Opus 4.5 6cd9cb7033 Fixed docker build warnings
- Added DEBIAN_FRONTEND=noninteractive to suppress debconf warnings
- Added --root-user-action=ignore to pip install
- Added ffmpeg to Docker image
- Increased chunkSizeWarningLimit to 3000 for Vite build

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 09:36:19 +01:00
maziggy 58c98b1075 Added docker test suite
Test Summary:
  - Build tests: 3 passed (image build, backend imports, static files)
  - Backend unit tests: 378 passed (9 docker tests excluded)
  - Frontend unit tests: 137 passed
  - Integration tests: 9 passed (health, API endpoints, persistence, WebSocket)

  Changes made to fix the Docker test suite:
  1. Added curl to the production Dockerfile for integration tests
  2. Removed deprecated version attribute from docker-compose.test.yml
  3. Added --pull flag to all build commands to ensure fresh images
  4. Added explicit build step before starting integration container
  5. Fixed WebSocket test to accept 200 as a valid response
  6. Excluded docker-marked tests from backend unit test runs (-m "not docker")
2025-12-14 09:15:49 +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 4b8e6ca797 1. Timelapse detection fixed - bambu_mqtt.py:1320-1329
- H2D sends timelapse status in ipcam.timelapse field, not xcam.timelapse
  - Added parsing for timelapse from ipcam data
  - Added test to prevent regression

  2. Systemd service updated - /etc/systemd/system/bambuddy.service
  - Now runs as claude user instead of root
  - Added ExecStartPre commands with + prefix (runs as root) to:
    - Create logs and archive directories if missing
    - Fix ownership to claude:claude before service starts

  The service restarted successfully with the permission fixes running at startup. On the next print with timelapse enabled, both the snapshot and timelapse should be captured automatically.
2025-12-13 10:59:58 +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 c317ff1085 1. Pre-commit Hook Configuration (.pre-commit-config.yaml)
- Ruff linter and formatter - Fast Python linter with auto-fix
  - Standard hooks - trailing whitespace, end-of-file, YAML/JSON checks, large file detection, merge conflict detection, debug statements, private key detection
  - Custom hook - Runs import shadowing tests before commit

  2. Ruff Configuration (pyproject.toml)

  - Python 3.11+ target
  - 120 character line length
  - Checks: pycodestyle, Pyflakes, isort, flake8-bugbear, comprehensions, pyupgrade, unused arguments, simplify
  - Sensible ignores for FastAPI patterns (Depends, unused route args)

  3. New Test Files

  backend/tests/unit/test_code_quality.py (5 tests)
  - Import shadowing detection using AST analysis
  - Catches the exact bug that broke archive creation
  - Tests all Python files in main, services, and routes

  backend/tests/unit/test_log_error_detection.py (13 tests)
  - MQTT message processing (status, xcam, AMS, HMS)
  - Print lifecycle (start to complete, failure handling)
  - Service imports verification
  - Edge cases (empty messages, unknown fields, null values)

  backend/tests/integration/test_print_lifecycle.py (6 tests)
  - Print start callback logic
  - Print complete callback logic
  - Timelapse tracking (same-message detection, completion callback)
  - Callback error handling
  - Import shadowing verification
2025-12-13 09:57:04 +01:00
maziggy ae55884858 1. ArchiveService import shadowing bug (main.py:978) - Local import was shadowing module-level import, causing "cannot access local variable" error
2. Timelapse race condition (bambu_mqtt.py) - xcam data was parsed before _was_running was set, so timelapse wasn't detected at print start
  3. Added exception handling (printer_manager.py) - _schedule_async now logs exceptions instead of swallowing them silently
  4. Added debug logging (main.py) - [CALLBACK] logs at key decision points to help debug future issues
  5. Added code quality tests (test_code_quality.py) - Static analysis to catch import shadowing bugs automatically
2025-12-13 09:39:14 +01:00
maziggy 3fe49f6af5 1. Timelapse Race Condition Fix (bambu_mqtt.py)
Problem: xcam data was parsed BEFORE _was_running was set to True, so timelapse detection failed when both arrived in the same message.

  Fix: Added timelapse detection at two critical points:

  # Lines 1375-1381: When entering RUNNING state
  if self.state.state == "RUNNING" and current_file:
      if not self._was_running:
          if self.state.timelapse:
              self._timelapse_during_print = True
              logger.info(f"[{self.serial_number}] Timelapse detected when entering RUNNING state")

  # Lines 1391-1399: When print start detected
  if self.state.timelapse:
      self._timelapse_during_print = True
      logger.info(f"[{self.serial_number}] Timelapse detected at print start")

  2. Callback Error Handling (main.py + printer_manager.py)

  Problem: The on_print_complete callback was hanging silently - no logs after "Found archive".

  Fixes:
  - Added try/except wrapper around "Update archive status" section (line 749-767)
  - Added [CALLBACK] log messages at start and end of callback
  - Added exception handler to _schedule_async in printer_manager.py to log any exceptions from async callbacks

  3. New Integration Tests (test_bambu_mqtt.py)

  Added TestRealisticMessageFlow class with 5 new tests that simulate real MQTT message sequences:

  1. test_timelapse_detected_at_print_start_in_same_message - The critical race condition test
  2. test_timelapse_not_detected_when_disabled
  3. test_timelapse_detected_when_enabled_after_print_start
  4. test_print_complete_includes_timelapse_flag_full_flow - Full lifecycle test
  5. test_print_failed_includes_timelapse_flag

  These tests process messages through _process_message() with proper {"print": {...}} wrapping, matching real MQTT flow.

  Files Modified:

  - backend/app/services/bambu_mqtt.py - Timelapse race condition fix
  - backend/app/main.py - Error handling + logging for on_print_complete
  - backend/app/services/printer_manager.py - Exception capture in _schedule_async
  - backend/tests/unit/services/test_bambu_mqtt.py - New integration tests

  Next Steps

  You should restart the application to apply these changes. The next print will show:
  - [CALLBACK] on_print_complete started for printer X
  - [ARCHIVE] Updating archive X status...
  - [ENERGY], [PHOTO], [AUTO-OFF] logs (if those features trigger)
  - [CALLBACK] on_print_complete finished for printer X, archive X
2025-12-13 09:16:58 +01:00
maziggy 9ba4ef6355 Fix docker build 2025-12-12 16:48:12 +01:00
maziggy 7262896a2b Uodated Dockerfile 2025-12-12 16:25:48 +01:00
maziggy 80c39df7e9 Fixed bug in Dockerfile 2025-12-12 16:20:55 +01:00