fix: Use MAC address for BLE disconnect decision after climb changes#653
fix: Use MAC address for BLE disconnect decision after climb changes#653marcodejongh merged 14 commits intomainfrom
Conversation
Implements local queue storage on ESP32 with optimistic UI updates for responsive button navigation. Key changes: Backend: - Add ControllerQueueItem and ControllerQueueSync GraphQL types - Add queueItemUuid field to LedUpdate for reconciliation - Update navigateQueue mutation to accept queueItemUuid (direct nav) - Send ControllerQueueSync on initial connection and queue changes ESP32 Firmware: - Add LocalQueueItem struct and queue storage (up to 150 items) - Implement optimistic navigation with immediate display updates - Handle ControllerQueueSync events to maintain local queue state - Navigate using queueItemUuid instead of direction for reliability - Reconcile optimistic updates with backend LedUpdate responses This fixes erratic navigation when the same climb appears multiple times in the queue, and enables fast-skipping through the queue. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a climb was loaded via Bluetooth from the official Kilter app, the ESP32 display wasn't receiving metadata updates because the backend was skipping LedUpdate events sent to the same controller that initiated them. This fix: - Adds clientId field to LedUpdate GraphQL type - Backend now always sends LedUpdate with clientId (MAC address of controller) - ESP32 compares incoming clientId with its own MAC address - If clientId matches own MAC: self-initiated change, keep BLE client connected - If clientId differs: web user took over, disconnect BLE client Also handles unknown climbs (drafts/unsynced) gracefully by displaying "Unknown Climb" with navigation context so users can navigate back. The MAC address is automatically detected - no manual configuration needed. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Claude Review❌ Do not merge - Missing required files will cause build failure. Critical Issues
Minor Issues
Documentation
|
- Use pServer->start() instead of ble_gatts_start() directly to set NimBLE's internal m_gattsStarted flag - Move UUID/advertising config to begin() to avoid duplicate registration - Use BLE.startAdvertising() in proxy mode for consistent state management Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add AuroraProtocol::encodeLedCommands() to encode LED data into Aurora protocol packets for transmission to the board - Add GraphQL LED update callback to notify when websocket updates arrive - In proxy mode, encode and forward LED updates to the real board via BLE This enables the web interface to control the physical board when running through the ESP32 proxy. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude Review❌ Do not merge - Missing files will cause build failures: Critical Issues
Other Issues
Documentation
|
- Fix race condition where handleScanComplete and handleBoardFound both tried to connect, causing state to flip back to CONNECTING - Set state to CONNECTING before calling stopScan() to prevent handleScanComplete from initiating duplicate connection - Split BLE writes into 20-byte chunks to match board's MTU and the TypeScript client implementation (MAX_BLUETOOTH_MESSAGE_SIZE) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude Review✅ Ready to merge - No significant issues found. The PR implements MAC address-based client identification for ESP32 BLE disconnect decisions, which is a cleaner approach than the previous controller ID system. The code is well-structured with good separation between navigation helpers, grade colors, and subscriptions. Minor observations (non-blocking):
|
Claude Review✅ Ready to merge - Minor issues noted below, but nothing blocking. Issues
Test CoverageThe new tests ( DocumentationNo documentation updates needed - this PR adds embedded/backend features without changing documented systems in |
- Add atomic flag to prevent BLE proxy scan/connect race condition between handleBoardFound and handleScanComplete callbacks - Document hardcoded BLE delays (100ms, 200ms, 500ms) with explanations - Add grade-colors.test.ts (32 tests for grade color utilities) - Add navigation-helpers.test.ts (17 tests for navigation helpers) - Add navigate-queue.test.ts (15 tests for navigateQueue mutation) - Update test setup to include esp32_controllers table - Fix controller.test.ts to create test users for FK constraints Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace blocking delay() calls in BLE proxy with state-machine-based non-blocking timers for WAIT_BEFORE_CONNECT and WAIT_BEFORE_ADVERTISE - Remove unused BYTES_PER_LED variable from aurora_protocol.cpp - Fix native embedded test mock issues: - Add macAddress() method to MockWiFi - Add start() method to NimBLEServer mock - Fix min/max templates to return by value instead of reference This addresses review feedback about blocking delays and test failures. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude Review✅ Ready to merge - Minor issues noted below, but nothing blocking. Issues Found
Test CoverageThe PR includes comprehensive tests for:
Test coverage is appropriate for the new functionality. |
- Remove unused controllerId destructure in subscriptions.ts (use controller.id from DB query instead) - Add pinMode initialization for button pins in setup() to ensure proper INPUT_PULLUP configuration before digitalRead calls Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude Review✅ Ready to merge - This is a well-structured feature PR adding MAC address-based BLE disconnect decisions and ESP32 display/navigation support. Tests are included for the new backend functionality. A few minor issues noted below. Issues
Documentation CheckNo documentation updates needed - this PR extends the ESP32 controller functionality which is not currently documented in |
…tion Backend: - Fix async IIFE race condition in subscriptions by using event queue to ensure QueueSync arrives before LedUpdate at ESP32 - Rename newIndex to targetIndex in navigateQueue for clarity - Add tests for concurrent navigation and error handling Embedded: - Use static buffer for queue sync to prevent heap fragmentation - Add hexToRgb565Fast() helper to avoid String allocations - Improve heap allocation error logging with size and free heap info Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude Review✅ Ready to merge - Minor issues noted below, but nothing blocking. Issues
Test Coverage
Documentation
|
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reset connectionInitiated flag on all BLE proxy failure paths (empty scan results, target not found, proxy disabled) - Reduce verbose logging in controller subscriptions - Document ControllerQueueSync event, clientId field, and navigateQueue mutation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude Review✅ Ready to merge - Well-structured feature with good test coverage. Minor issues noted below, but nothing blocking. Issues
Documentation✅ Documentation updated appropriately in
Test Coverage✅ Good test coverage added:
The tests appropriately mock dependencies and verify event publishing behavior. |
- BLE client now calls connectCallback(false) when connect() fails synchronously, so the proxy gets notified and can transition to RECONNECTING state instead of being stuck in CONNECTING - Add debug logging in scanner to help diagnose board detection issues Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude Review✅ Ready to merge - No significant issues found. SummaryThis PR adds MAC address-based client identification to fix ESP32 display not receiving metadata updates when climbs are loaded via Bluetooth. The changes are well-structured with good test coverage. DocumentationThe Test CoverageNew test files provide good coverage:
Tests cover the main scenarios including direct navigation via queueItemUuid, direction-based fallback, edge cases (empty queue, boundaries), and authorization requirements. Minor Notes (non-blocking)
|
Removed temporary diagnostic logging that was added to debug board detection issues. The name is now only fetched after confirming the device is an Aurora board, which is more efficient. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude Review✅ Ready to merge - Minor issues noted below, but nothing blocking. Issues
Documentation✅ Test Coverage✅ Good test coverage:
|
Summary
Problem
When a climb was loaded via Bluetooth, the backend was skipping
LedUpdateevents to the controller that initiated them. This prevented the ESP32 display from showing climb metadata (name, grade, navigation context) for BLE-loaded climbs.Solution
clientIdfield toLedUpdateGraphQL typeLedUpdatewithclientIdset to the controller's MAC addressclientIdwith its own MAC address:Test plan
🤖 Generated with Claude Code