Skip to content

feat: implement BLE notifier for JCODE devices and enhance channel no…#21

Merged
cnjack merged 1 commit into
mainfrom
feat/ble-notification
Apr 18, 2026
Merged

feat: implement BLE notifier for JCODE devices and enhance channel no…#21
cnjack merged 1 commit into
mainfrom
feat/ble-notification

Conversation

@cnjack

@cnjack cnjack commented Apr 18, 2026

Copy link
Copy Markdown
Owner

…tifications

Summary by CodeRabbit

  • New Features
    • Added Bluetooth Low Energy (BLE) support for JCODE-* IoT devices via Nordic UART Service
    • Introduced lifecycle status notifications (idle, working, approval, done states)
    • Enhanced status messages with time-aware and contextual formatting
    • Integrated BLE and WeChat for real-time status updates during operations

@cnjack cnjack merged commit 4a9a568 into main Apr 18, 2026
1 check was pending
@coderabbitai

coderabbitai Bot commented Apr 18, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0c110412-2569-435a-8acc-a924c74a0f4c

📥 Commits

Reviewing files that changed from the base of the PR and between b9e0b16 and 2c52353.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • go.mod
  • internal/channel/ble/ble.go
  • internal/channel/channel.go
  • internal/channel/channel_notifier.go
  • internal/channel/messages.go
  • internal/command/interactive.go
  • internal/command/web.go
  • internal/handler/notifying.go
  • script/poc/ble.go

📝 Walkthrough

Walkthrough

This PR introduces Bluetooth Low Energy (BLE) notification support for JCODE-* IoT devices using the Nordic UART Service. It adds lifecycle event abstractions (EventType, NotifyEvent, Notifier interface), implements a BLE-backed notifier with background connection management, creates adapters for existing Channels, and integrates both into the interactive and web handlers with structured event emission tied to agent working/approval/completion states.

Changes

Cohort / File(s) Summary
Dependency Management
go.mod
Added 8 indirect BLE and platform-specific dependencies: go-ole, dbus, winrt-go, cyw43439, seqs, cbgo, pio, and tinygo.org/x/bluetooth.
Core Notification Abstractions
internal/channel/channel.go
Introduced EventType enum (EventIdle, EventWorking, EventApproval, EventDone), NotifyEvent struct with Type, Tool, and Err fields, and Notifier interface defining Name(), Available(), Notify(event), and Close() contract.
BLE Notifier Implementation
internal/channel/ble/ble.go
New BLE-backed Notifier that discovers and connects to JCODE-* devices via Nordic UART Service. Features background connect() routine with adapter enable, scan, device discovery/connection, and service/characteristic discovery. Handles Notify() by formatting events via FormatBLE and writing to RX characteristic. Includes mutex-protected state (ready, closed, connecting guard) and error recovery with automatic reconnection attempts.
Channel Adapter
internal/channel/channel_notifier.go
New ChannelNotifier adapter wrapping a Channel as a Notifier, mapping EventWorking and EventIdle to rich text messages while ignoring EventDone and EventApproval. Availability determined by channel StateEnabled state.
Message Formatting
internal/channel/messages.go
Added FormatBLE(event) to map event types to BLE command/value pairs, RichWorking(t) and RichIdle(t) for time-variant status strings, and RichDone(summary, err, t) for completion messages with error or summary details (truncated to ~500 chars).
Lifecycle Event Emission
internal/handler/notifying.go
Extended NotifyingHandler with AddNotifier() registration and CloseNotifiers() shutdown. New notifyAll() helper fans out NotifyEvent updates to all available notifiers. Emits EventWorking on first agent text (guarded by sentWorking flag), EventApproval on approval requests, EventDone on completion, and auto-transitions to EventIdle after 5 seconds.
Command Handler Integration
internal/command/interactive.go, internal/command/web.go
Wired ble.New() and channel.NewChannelNotifier(wechatClient) into notifying handlers. Initial Notify(EventIdle) triggers background BLE discovery. Extended shutdown to call CloseNotifiers() for graceful notifier cleanup.
BLE Client POC
script/poc/ble.go
Standalone interactive BLE client program demonstrating Nordic UART Service communication. Scans for JCODE-* devices, connects, enables TX notifications, and provides REPL interface for sending heart <msg>, state commands (idle|working|attention|complete), and raw JSON to the RX characteristic.

Sequence Diagram

sequenceDiagram
    participant Agent as Agent/Handler
    participant NotifyH as NotifyingHandler
    participant BLENotif as BLE Notifier
    participant ChanNotif as Channel Notifier
    participant BLEDev as BLE Device (IoT)
    participant WeChat as WeChat Channel

    Agent->>NotifyH: OnAgentText (first call)
    NotifyH->>NotifyH: sentWorking=true, notifyAll(EventWorking)
    NotifyH->>BLENotif: Notify(EventWorking)
    NotifyH->>ChanNotif: Notify(EventWorking)
    
    BLENotif->>BLENotif: Format EventWorking → (cmd, val)
    BLENotif->>BLEDev: WriteWithoutResponse (RX char)
    
    ChanNotif->>WeChat: RichWorking(now) → SendText

    Agent->>NotifyH: OnApprovalRequest
    NotifyH->>NotifyH: notifyAll(EventApproval, Tool)
    NotifyH->>BLENotif: Notify(EventApproval)
    BLENotif->>BLEDev: WriteWithoutResponse (attention+tool)

    Agent->>NotifyH: OnApprovalResponse(Approved=true)
    NotifyH->>NotifyH: notifyAll(EventWorking)
    NotifyH->>BLENotif: Notify(EventWorking)
    NotifyH->>ChanNotif: Notify(EventWorking)

    Agent->>NotifyH: OnCompletion(EventDone)
    NotifyH->>NotifyH: notifyAll(EventDone)
    NotifyH->>BLENotif: Notify(EventDone)
    NotifyH->>ChanNotif: Notify(EventDone) [ignored]
    BLENotif->>BLEDev: WriteWithoutResponse (complete)

    NotifyH->>NotifyH: After 5s: notifyAll(EventIdle)
    NotifyH->>BLENotif: Notify(EventIdle)
    NotifyH->>ChanNotif: Notify(EventIdle)
    BLENotif->>BLEDev: WriteWithoutResponse (idle/ready)
    ChanNotif->>WeChat: RichIdle(now) → SendText
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰✨ A rabbit's tale of BLE lights,
Where Nordic chips dance through the nights,
With notifiers aplenty, event flows aligned,
And IoT devices perfectly designed!
Thump thump goes the discovery beat,
Making smart notifications complete! 🔔

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ble-notification

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant