/install ble-device-control
BLE Device Control Skill
IMPORTANT: Read this document before executing any airctl command.
Guidelines:
- Consult the Command Reference below first. All common airctl commands and their syntax are documented here.
- Follow the Decision Tree to determine which workflow to execute. Do not skip steps.
- If a command is not found in this document, verify it with
airctl --helpbefore using it.- Check prerequisites first before any BLE operation.
- Validate all user-provided inputs before passing them to airctl commands. See Input Validation below.
Input Validation
All user-provided inputs must be validated before being used in airctl commands to prevent shell injection. Apply these validation rules:
Device Address — Must match MAC address format: XX:XX:XX:XX:XX:XX where each XX is a hexadecimal pair.
- Valid regex:
^[0-9A-Fa-f]{2}(:[0-9A-Fa-f]{2}){5}$ - Example valid:
AA:BB:CC:DD:EE:FF - If invalid: reject the input and ask the user to provide a valid address.
Device Alias — Must contain only alphanumeric characters and underscores. No hyphens, spaces, or special characters.
- Valid regex:
^[A-Za-z0-9_]+$ - Example valid:
my_sensor,heart_rate - If invalid: replace hyphens with underscores, remove spaces and special characters, then confirm with the user.
UUID — Must match standard BLE UUID format: 4-digit short or 8-4-4-4-12 full format.
- Valid regex:
^[0-9A-Fa-f]{4}$or^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$ - Example valid:
2A19,00002A19-0000-1000-8000-00805F9B34FB - Both short and full UUID formats are supported in all commands.
- If invalid: reject the input and ask the user to provide a valid UUID.
Handle — Must be a positive integer.
- Valid regex:
^[1-9][0-9]*$ - Example valid:
10,74 - If invalid: reject the input.
Write Data — Must use one of the documented data format prefixes with only allowed characters.
hex:prefix: followed by hexadecimal characters only (0-9A-Fa-f). Valid regex:^hex:[0-9A-Fa-f]+$text:prefix: followed by printable ASCII characters. Valid regex:^text:[\x20-\x7E]+$base64:prefix: followed by Base64 characters. Valid regex:^base64:[A-Za-z0-9+/=]+$- No prefix: treated as hex, same rules as
hex:. - If invalid: reject the input and ask the user to provide properly formatted data.
Device Name (for scan filter) — Must contain only printable characters. No shell metacharacters.
- Disallowed characters:
` $ | ; & \x3C > ( ) { } [ ] \ ! # - If disallowed characters found: reject the input and ask the user to provide a clean device name.
Prerequisites
This skill requires the airctl CLI tool.
Provenance:
| Field | Value |
|---|---|
| Source Code | https://github.com/skinapi2025/AirCtl |
| License | MIT |
| Author | skinapi2025 |
Verify airctl is installed:
airctl --version
If airctl is not installed, ask the user to install it before proceeding. Provide the following installation command for the user to review and execute:
pip install git+https://github.com/skinapi2025/AirCtl.git
Note: Do NOT automatically run
pip installwithout user confirmation. The user should verify the package source and approve the installation.
After installation, verify the package origin:
pip show airctl
Confirm that the output shows Home-page: https://github.com/skinapi2025/AirCtl or Author: skinapi2025.
Decision Tree
Follow this decision tree to determine which workflow to execute. Start from the top and follow the FIRST matching path:
User mentions Bluetooth/BLE device operation?
│
├─ YES → What does the user want?
│ │
│ ├─ "Connect and keep connection" / "maintain connection"
│ │ → Follow Workflow 4 (Connect + Keep Alive)
│ │
│ ├─ "Connect" (without keep-alive)
│ │ → Follow Workflow 1 (Connect by Name)
│ │
│ ├─ "Read" a characteristic value
│ │ → Follow Workflow 2 (Read Characteristic)
│ │
│ ├─ "Write" to a characteristic
│ │ → Follow Workflow 3 (Write Characteristic)
│ │
│ ├─ "Scan" / "Find" / "Discover" devices
│ │ → Run: `airctl ble scan -t 10`
│ │
│ ├─ "Subscribe" / "Notify" / "Monitor"
│ │ → Follow Workflow 4 Step 3 (Subscribe)
│ │
│ ├─ "Disconnect"
│ │ → Run: `airctl ble disconnect \x3Caddress>`
│ │
│ ├─ "Battery" / "Heart rate" / "Device info"
│ │ → Use Device Profile commands: `airctl device battery/heart-rate/device-info \x3Caddress>`
│ │
│ └─ Other BLE operation
│ → Look up the command in the Command Reference section below
│
└─ NO → This skill may not be relevant
Workflow 1: Connect by Name
When user says: "connect to Heart Rate device"
Execute these steps IN ORDER:
Step 1: Scan for the device:
airctl ble scan -t 10 -n "Heart Rate"
Step 2: Parse the JSON output to extract the device address field. Validate the address format (see Input Validation).
Step 3: Connect using the validated address:
airctl ble connect \x3Caddress> -a \x3Calias>
IMPORTANT: Use underscores (
_) in aliases, never hyphens (-). Validate alias format before use.
Workflow 2: Read Characteristic
When user says: "read Body Sensor Location from Heart Rate device"
Execute these steps IN ORDER:
Step 1: Check if device is already connected:
airctl ble list
Step 2: If NOT connected, scan and connect:
airctl ble scan -t 10 -n "Heart Rate"
airctl ble connect \x3Caddress> -a heart_rate
Step 3: List characteristics to find the UUID:
airctl ble characteristics heart_rate
Step 4: Parse the JSON output to find the target characteristic UUID. Validate the UUID format (see Input Validation).
Step 5: Read the characteristic using the validated UUID:
airctl ble read heart_rate -u \x3Cuuid> -f hex
Workflow 3: Write Characteristic
When user says: "write 0x01 to Alert Level"
Execute these steps IN ORDER:
Step 1: Check if device is already connected:
airctl ble list
Step 2: If NOT connected, scan and connect first (see Workflow 1)
Step 3: Validate the UUID and data format (see Input Validation), then write:
airctl ble write \x3Caddress> -u \x3Cuuid> -d "\x3Cdata>"
Workflow 4: Connect + Keep Alive
When user says: "connect to Heart Rate and keep connection" or "connect and maintain connection"
Execute these steps IN ORDER. Do not skip any step:
Step 1: Scan and Connect
airctl ble scan -t 10 -n "Heart Rate"
Parse JSON to get address, validate it, then:
airctl ble connect \x3Caddress> -a heart_rate
Step 2: Get Characteristics
airctl ble characteristics heart_rate
Step 3: Analyze and Choose Keep-Alive Strategy
Parse the characteristics JSON. Each characteristic has a properties array. Follow this priority:
Priority 1 — If ANY characteristic has "notify" or "indicate" in properties:
airctl ble notify subscribe heart_rate -u \x3Cnotifiable_uuid>
This is the best keep-alive method. The device pushes data and keeps the connection active.
Priority 2 — If NO notifiable characteristic, find a read-only one (has "read" but NO "write"):
airctl ble task start-read heart_rate -u \x3Creadable_uuid> -i 5
Read-only characteristics are safe for periodic reads without side effects.
Priority 3 — If only read-write characteristics exist, pick one known to be safe:
airctl ble task start-read heart_rate -u \x3Creadable_uuid> -i 5
Use caution — reading may have side effects on some devices.
Workflow 5: LLM Snapshot Polling
When an AI agent needs to monitor BLE events without streaming:
Step 1: Subscribe to notifications (returns immediately):
airctl ble notify subscribe \x3Caddress> -u \x3Cuuid>
Step 2: Poll for recent events using snapshot query (returns immediately):
airctl ble events --last 5
Step 3: Repeat step 2 as needed to check for new events.
Alternative: Use periodic read tasks with result snapshots:
airctl ble task start-read \x3Caddress> -u 2A19 -i 5
# Returns: {"task_id": "abc123", "type": "periodic_read"}
airctl ble task result abc123 --last 5
# Returns: {"task_id": "abc123", "results": [...], "count": 5}
Command Reference
All common airctl commands are documented below. If you need a command not listed here, verify it with airctl --help or airctl ble --help.
Daemon
airctl daemon status
airctl daemon start
airctl daemon stop
airctl daemon restart
The daemon starts automatically for BLE operations. Use these only for troubleshooting.
BLE Scan
airctl ble scan -t 10
airctl ble scan -n "Heart Rate"
airctl ble scan --service-uuids 180D,180F
Scan output (JSON):
{"devices": [{"address": "AA:BB:CC:DD:EE:FF", "name": "Heart Rate", "rssi": -45, "service_uuids": ["180D"]}], "count": 1}
BLE Connect / Disconnect / List
airctl ble connect \x3Caddress> [-t 30] [-a alias]
airctl ble disconnect \x3Caddress>
airctl ble list
BLE GATT Exploration
airctl ble services \x3Caddress>
airctl ble characteristics \x3Caddress>
airctl ble characteristics \x3Caddress> -s \x3Cservice_uuid>
Characteristics output (JSON):
{"characteristics": [{"uuid": "2A37", "handle": 10, "properties": ["notify", "read"], "service_uuid": "180D"}]}
BLE Read
airctl ble read \x3Caddress> -u \x3Cuuid> [-f hex|base64|text]
airctl ble read \x3Caddress> -H \x3Chandle> [-f hex|base64|text]
Both short UUID (2A19) and full UUID (00002a19-0000-1000-8000-00805f9b34fb) are supported.
BLE Write
airctl ble write \x3Caddress> -u \x3Cuuid> -d "hex:010203"
airctl ble write \x3Caddress> -H \x3Chandle> -d "hex:010203"
airctl ble write \x3Caddress> -u \x3Cuuid> -d "hex:01" --response
Data format prefixes: hex: (e.g., hex:010203), text: (e.g., text:hello), base64: (e.g., base64:AQID), or no prefix (treated as hex).
BLE Notifications
airctl ble notify subscribe \x3Caddress> -u \x3Cuuid>
airctl ble notify unsubscribe \x3Caddress> -u \x3Cuuid>
BLE Event Snapshots (LLM-friendly)
airctl ble events --last 5 # Last 5 events (returns immediately)
airctl ble events --last 10 --address \x3Caddr> # Filter by device address
airctl ble events --last 5 --type notification # Filter by event type
airctl ble events --last 5 -h # Human-readable output
Event types: device_connected, device_disconnected, notification, periodic_read, periodic_write, periodic_scan, task_error
Important: Without
--last,airctl ble eventsstreams continuously and never returns. Always use--last Nfor LLM/agent usage.
BLE Background Tasks
airctl ble task start-read \x3Caddress> -u \x3Cuuid> -i 5
airctl ble task start-read \x3Caddress> -H \x3Chandle> -i 5
airctl ble task start-write \x3Caddress> -u \x3Cuuid> -d "hex:01" -i 10
airctl ble task start-scan -i 30 -t 5
airctl ble task list
airctl ble task stop \x3Ctask_id>
airctl ble task result \x3Ctask_id> --last 5 # Query task results (snapshot)
Device Profiles
airctl device battery \x3Caddress> # Battery percentage (0x180F)
airctl device device-info \x3Caddress> # Device info (0x180A)
airctl device heart-rate \x3Caddress> # Heart rate (0x180D)
airctl device heart-rate \x3Caddress> --subscribe
airctl device heart-rate \x3Caddress> --duration 60
Configuration
airctl config list
airctl config alias set \x3Caddress> \x3Cname>
airctl config alias list
airctl config alias remove \x3Cname>
airctl config preset list
airctl config preset get uart
airctl config preset set \x3Cname> --service \x3Cuuid> --char \x3Cuuid>
airctl config preset remove \x3Cname>
Common GATT UUIDs
| UUID | Name | Description |
|---|---|---|
| 180D | Heart Rate | Heart Rate service |
| 180F | Battery | Battery service |
| 180A | Device Information | Device info service |
| 2A37 | Heart Rate Measurement | Heart rate data (notify) |
| 2A38 | Body Sensor Location | Sensor position (read) |
| 2A19 | Battery Level | Battery percentage (read) |
| 2A06 | Alert Level | Alert control (write) |
| 2A29 | Manufacturer Name | Device manufacturer (read) |
Error Handling
| Error | Cause | Solution |
|---|---|---|
| "Insufficient Authentication" | Device requires pairing | Pair the device with your system first |
| "Characteristic not found" | Wrong UUID | Run airctl ble characteristics to verify, or use -H handle |
| "Device not connected" | Not connected yet | Run airctl ble connect first |
| "Daemon not running" | Daemon stopped | Run airctl daemon start or let it auto-start |
| "Command not found" | airctl not installed or outdated | Verify with airctl --version, reinstall if needed |
| "Device disconnected unexpectedly" | BLE device dropped connection | Reconnect with airctl ble connect, use periodic read task to keep alive |
Platform Requirements
- Windows: Windows 10 v16299+, Bluetooth adapter
- Linux: BlueZ 5.55+, Bluetooth adapter
- macOS: macOS 10.15+, Bluetooth adapter
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install ble-device-control - 安装完成后,直接呼叫该 Skill 的名称或使用
/ble-device-control触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
ble-device-control 是什么?
Control BLE devices via airctl CLI. MUST invoke when user mentions Bluetooth, BLE, device scan, connect, read, write, or notify. ALWAYS read this skill BEFOR... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 142 次。
如何安装 ble-device-control?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install ble-device-control」即可一键安装,无需额外配置。
ble-device-control 是免费的吗?
是的,ble-device-control 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。
ble-device-control 支持哪些平台?
ble-device-control 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 ble-device-control?
由 skinapi(@skinapi2025)开发并维护,当前版本 v1.0.4。