Commit Graph
100 Commits
Author SHA1 Message Date
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 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 a14dcbc034 Frontend WebSocket Tests Summary
Expanded the useWebSocket.test.ts from minimal coverage to 20 comprehensive tests covering:

  WebSocket Mock Tests (6 tests)

  - Creates WebSocket with correct URL
  - Starts in CONNECTING state
  - Transitions to OPEN state
  - Can receive messages
  - Can close connection
  - Tracks all instances

  Hook Connection Tests (2 tests)

  - Connects to WebSocket on mount
  - Reports connected state when WebSocket opens

  Message Handling Tests (9 tests)

  - Updates printer status in query cache on printer_status message
  - Preserves wifi_signal when new value is null
  - Invalidates archives on print_complete message
  - Invalidates archives on archive_created message
  - Invalidates archives on archive_updated message (new handler for timelapse auto-assignment)
  - Ignores pong messages without error
  - Handles malformed JSON gracefully
  - Handles unknown message types gracefully

  sendMessage Tests (2 tests)

  - Sends JSON message when connected
  - Does not send when disconnected

  Reconnection Tests (2 tests)

  - Reconnects after connection closes
  - Cleans up on unmount

  Key Fixes

  - Fixed MSW (Mock Service Worker) conflict by:
    a. Adding addEventListener/removeEventListener to MockWebSocket class
    b. Updating MSW setup to bypass WebSocket requests
    c. Properly managing WebSocket mock lifecycle in each test

  Test Results:
  - Frontend: 137 tests passed (9 test files)
  - Backend: 346 tests passed
2025-12-12 15:52:35 +01:00
maziggy ee2b674278 Issue 1: Print Start Notification - Estimated Time Unknown
Problem: At print start, the MQTT mc_remaining_time was often 0 or unavailable because the printer hadn't fully processed the gcode yet.

  Solution: Modified the notification system to prioritize the print_time_seconds from the 3MF file parsing (which is always available after archive creation) over the
  MQTT remaining time.

  Files changed:
  - backend/app/services/notification_service.py:
    - Added optional archive_data parameter to on_print_start() method
    - Added priority logic: archive data > MQTT remaining_time > raw_data mc_remaining_time
  - backend/app/main.py:
    - Created _send_print_start_notification() helper function
    - Moved notification sending to AFTER archive creation (when print_time_seconds is available)
    - Added fallback notification sending at early return points (auto_archive disabled, file not found, etc.)

  Issue 2: Timelapse Auto-Assignment

  Problem: Timelapses couldn't be auto-assigned reliably because printer dates could be off in LAN-only mode, making timestamp matching unreliable.

  Solution: Track whether timelapse recording was active during the print via MQTT, and if so, auto-fetch the most recent timelapse file on print completion.

  Files changed:
  - backend/app/services/bambu_mqtt.py:
    - Added _timelapse_during_print instance variable
    - Track when timelapse is active during a print (in both data and xcam parsing)
    - Reset the flag on new print start
    - Include timelapse_was_active in the print complete callback data
  - backend/app/main.py:
    - Added timelapse auto-scan logic in on_print_complete()
    - If timelapse_was_active is True and status is "completed":
        - Wait 5 seconds for timelapse to finalize
      - Scan printer's timelapse directory
      - Find most recent file by mtime
      - Verify it was modified within 30 minutes of print completion
      - Download and attach to archive
      - Send WebSocket update
2025-12-12 15:35:46 +01:00
maziggy f7cde95bbb Tests Added Summary:
Backend Tests (New Files)

  1. backend/tests/integration/test_camera_api.py - 13 tests
    - Camera stop endpoint (GET and POST methods)
    - Active stream termination
    - Printer-specific stream stopping
    - Camera test endpoint
    - Camera snapshot endpoint
    - Camera stream validation
  2. backend/tests/integration/test_system_api.py - 16 tests
    - System info endpoint structure
    - App, database, storage, memory, CPU sections
    - Helper functions (format_bytes, format_uptime)
    - Archive statistics
    - Printer connection info
  3. backend/tests/unit/services/test_telemetry.py - 16 tests
    - Installation ID creation/retrieval
    - Telemetry enabled/disabled checks
    - Telemetry URL configuration
    - Heartbeat sending and rate limiting
    - Exception handling
  4. backend/tests/unit/services/test_notification_service.py (updated) - Added TestNotificationVariableFallbacks class with 9 tests
    - Duration formatting with None values
    - Print complete fallback values
    - Estimated time and remaining time fallbacks
    - Filename fallback to "Unknown"

  Frontend Tests (New Files)

  5. frontend/src/__tests__/pages/SystemInfoPage.test.tsx - 14 tests
    - Loading and error states
    - Application, database, storage, memory, CPU sections
    - Connected printers display
    - Disk usage warning/danger colors
    - Refresh button
  6. frontend/src/__tests__/components/AMSHistoryModal.test.tsx - 21 tests
    - Modal open/close behavior
    - Humidity/temperature mode switching
    - Time range selection
    - Statistics cards (current, avg, min, max)
    - Loading and error states
    - Trend calculation
  7. frontend/src/__tests__/components/NotificationProviderCard.test.tsx (updated) - Added NotificationProviderCard AMS toggles describe block with 11 tests
    - AMS humidity/temperature notification toggles
    - AMS-HT humidity/temperature notification toggles
    - Independence of AMS and AMS-HT toggles
    - Default values

  Total New Tests: ~100 tests covering:
  - Camera API endpoints
  - System info API
  - Anonymous telemetry service
  - Notification variable fallbacks
  - System Info page UI
  - AMS History modal UI
  - AMS/AMS-HT notification toggle settings

  Tests Added - Complete Summary:

  Backend Tests (4 new files, 1 updated)

  | File                                                       | Tests | Description                                                     |
  |------------------------------------------------------------|-------|-----------------------------------------------------------------|
  | tests/integration/test_camera_api.py                       | 13    | Camera stop (GET/POST), snapshot, stream, test endpoints        |
  | tests/integration/test_system_api.py                       | 16    | System info API, helper functions (format_bytes, format_uptime) |
  | tests/unit/services/test_telemetry.py                      | 16    | Installation ID, telemetry toggle, heartbeat sending            |
  | tests/unit/services/test_notification_service.py (updated) | +10   | Variable fallbacks for duration, filename, estimated_time       |

  Frontend Tests (2 new files, 1 updated)

  | File                                                                 | Tests | Description                                           |
  |----------------------------------------------------------------------|-------|-------------------------------------------------------|
  | src/__tests__/pages/SystemInfoPage.test.tsx                          | 14    | System info page UI, sections, loading/error states   |
  | src/__tests__/components/AMSHistoryModal.test.tsx                    | 21    | AMS history modal, mode switching, time ranges, stats |
  | src/__tests__/components/NotificationProviderCard.test.tsx (updated) | +11   | AMS/AMS-HT notification toggle independence           |

  Total: 101 new tests
  - Backend: 335 tests total (all passing)
  - Frontend: 124 tests total (all passing)
2025-12-12 11:15:59 +01:00
maziggy 2953d2cc3c Changed version to 0.1.5b6; uodated CHANGELOG 2025-12-12 09:36:17 +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 a7c1fe6d4f Changed version to 0.1.5b5 2025-12-11 14:49:07 +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 2e5c42b383 For multi plates files, archive card now shows cover image of printed plate 2025-12-11 12:32:18 +01:00
maziggy 5ead2296c4 Improved notification scheduler and templates 2025-12-11 12:11:31 +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 ff53e62ef8 Add comprehensive automated testing infrastructure
Backend:
  - pytest configuration with async support and coverage
  - Unit tests for notification service (23 tests)
  - Unit tests for smart plug manager (12 tests)
  - Unit tests for archive service (16 tests)
  - Integration tests for API endpoints
  - Fix: notifications now send immediately (digest is summary only)

  Frontend:
  - Vitest configuration with jsdom and coverage
  - MSW for API mocking
  - Component tests for Toggle, Button, Card, ConfirmModal (77 tests)
  - Test utilities with custom render wrapper

  CI/CD:
  - GitHub Actions workflow for automated testing
  - Backend lint, unit tests, integration tests
  - Frontend lint, type-check, unit tests, build
2025-12-11 10:03:40 +01:00
maziggy c3026632da Improved auto power off scheduler 2025-12-11 08:02:15 +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
maziggy dbcbde0b16 Improved email notification provider 2025-12-10 19:12:49 +01:00
maziggy d1518083fc ## New Features
### Projects / Print Grouping
  - Create projects to group related prints (e.g., "Voron Build" with 50 parts)
  - Track progress with target count and completion percentage
  - Assign archives to projects via edit modal or context menu
  - Project cards show archive thumbnails with clickable links
  - Color-coded project badges on archive cards
  - Filter and manage projects by status (active/completed/archived)

  ### Full-Text Search (FTS5)
  - SQLite FTS5 virtual table for efficient searching
  - Search across print_name, filename, tags, notes, designer, filament_type
  - Automatic index sync with triggers for INSERT/UPDATE/DELETE

  ### Webhooks & API Keys
  - API key authentication with granular permissions
  - Permissions: can_read_status, can_manage_queue, can_control_printer
  - Secure key generation with prefix display only after creation
  - Settings page API Keys tab for key management
  - Webhook endpoints for external integrations

  ### Failure Analysis
  - Dashboard widget showing failure rate with color coding
  - Correlate failures with conditions (filament type, printer, time)
  - Top failure reasons breakdown
  - Weekly trend visualization

  ### Archive Comparison
  - Select 2-5 archives to compare side-by-side
  - Highlight differences in print settings (yellow)
  - Success/failure correlation insights
  - Modal with close via button, X, Escape, or backdrop

  ### CSV/Excel Export
  - Export archives and statistics with current filters
  - Support for both CSV and Excel (.xlsx) formats
  - openpyxl dependency added

  ## Bug Fixes
  - Fixed context menu submenu not showing (removed overflow-hidden)
  - Fixed project card thumbnails using correct API endpoint
  - Fixed EditArchiveModal to invalidate projects query on save
  - Fixed clipboard API fallback for HTTP contexts
  - Fixed archive PATCH 500 error (FTS5 index rebuild)
  - Fixed FastAPI trailing slash routing for projects endpoint

  ## UI Improvements
  - Context menu submenu with hover/click support
  - Project badge on archive cards with project color
  - "Go to Project" context menu item for assigned archives
  - Clickable project card thumbnails linking to archives
  - Reset Layout button moved to Stats page header
2025-12-10 17:06:43 +00:00
maziggy 711140ddf9 Added mobile PWA support 2025-12-10 11:21:25 +00:00
maziggy 83fc278b75 Fixed bug where not all AMS spools were synced to Spoolman 2025-12-10 10:02:11 +00:00
maziggy 8bd404951e Changed version to 0.1.5b4 2025-12-10 08:51:21 +00:00
maziggy b4007c9594 Added embedded external links to backup/restore module 2025-12-09 12:11:19 +00:00
maziggy 36b57bbafb - External links can now be embedded into sidebar navigation 2025-12-09 12:06:58 +00:00
maziggy 69ba3e2806 Fixed a bug in notification module where newly added notification types were not saved properly 2025-12-09 11:25:32 +00:00
maziggy 50259f6dc4 Removed debug logs for backup/restore module 2025-12-09 11:19:35 +00:00
maziggy cf972f42c1 - Improved backup/restore module 2025-12-09 11:04:48 +00:00
maziggy 957ad17825 - Improved backup/restore module 2025-12-09 10:59:16 +00:00
maziggy 3f9b7e0b7f - Improved backup/restore module 2025-12-09 10:55:54 +00:00
maziggy b024880cb6 - Improved backup/restore module 2025-12-09 10:42:04 +00:00
maziggy fb6ff3130e - Improved backup/restore module 2025-12-09 10:33:22 +00:00
maziggy 6d71261de7 Renaming app to Bambuddy 2025-12-09 08:55:59 +00:00
maziggy ac4fec7de8 - Fixed bug, where switched off printers still show as active on printer page 2025-12-09 08:26:25 +00:00
maziggy a0f0892ea0 * Added user options to backup module; Fixed HTTP 500 bug 2025-12-09 08:20:27 +00:00
maziggy ce18b38264 Fixed os.path issue in update module 2025-12-08 17:58:20 +00:00
maziggy c74f24353a - Added smart plug monitoring and scheduling
- Added daily digest to notification module
2025-12-08 16:30:53 +00:00
maziggy 29aadfb774 Added template system to notification module. 2025-12-08 15:23:17 +00:00
maziggy 1a17b547dc - Added maintenance interval type clendar days
- Minor improvements to maintenance module
2025-12-08 14:52:16 +00:00
maziggy 2867401116 Add Cloud Profiles template visibility and preset diff view
Cloud Profiles (ProfilesPage.tsx):
  - Add template visibility control (showInModal flag)
    - Eye/EyeOff toggle in templates modal to show/hide templates
    - Only templates with showInModal=true appear in preset modals
    - Default new templates to showInModal=true in save dialog
  - Add preset diff/compare view with two modes:
    - Compare button in edit modal (preset vs base)
    - Compare mode on main page (two-preset comparison)
    - Side-by-side diff with added/removed/changed highlighting
    - Stats showing added/removed/changed/same counts
    - Search filter and Changes/All toggle
    - Type restriction (only compare same preset types)
  - Fix array value display (show "value" instead of ["value"])
  - Fix printer preset G-code display (format escaped \n as real newlines)
  - Fix modal overflow issues with proper flex patterns
  - Fix light theme colors for compare selection text
2025-12-08 14:03:38 +00:00
maziggy e47ef36630 sync 2025-12-08 09:56:21 +00:00
maziggy 71e15b0ed7 Add AMS humidity/temperature indicators with configurable thresholds
- Add dynamic humidity indicator with Bambu Lab style water drop icons
    - Empty drop for good (dry), half-filled for fair, full for bad (wet)
    - Configurable thresholds via Settings page

  - Add dynamic temperature indicator with thermometer icons
    - Empty for good, half-filled for fair, full for hot
    - Colors match humidity: green/gold/red

  - Add AMS Display Thresholds settings card
    - Humidity thresholds (good/fair) configurable
    - Temperature thresholds (good/fair) configurable
    - Persisted in backend settings

  - Fix AMS card stability issues
    - Add ams_extruder_map to WebSocket broadcasts
    - Cache AMS data and extruder map to prevent bouncing
    - Fix L/R nozzle indicator for dual-nozzle H2 printers

  - Fix status summary bar counting
    - Don't count printers with unknown status as offline

  - Theme-aware L/R nozzle badges (light/dark theme support)
2025-12-07 14:56:52 +00:00
maziggy e688c35719 sync 2025-12-07 14:29:54 +00:00
maziggy cef6cd593b Added Wifi signal strength to printer card 2025-12-07 11:30:19 +00:00
maziggy 06bfaa3c74 Completely removed control page and all it's related code 2025-12-07 10:19:25 +00:00
Martin Ziegler eb6d6e6ce5 Refactoring AMS module 2025-12-06 15:24:48 +01:00
Martin Ziegler ef29acda2d Refactoring AMS module 2025-12-06 08:55:06 +01:00
Martin Ziegler e44bc318ac Refactoring AMS module 2025-12-05 16:00:56 +01:00