From pyhubblenetwork
Testing framework for Hubble Ready devices over Bluetooth Low Energy (BLE). Use when testing Hubble Ready device functionality, validating BLE connectivity, verifying device characteristics, testing encryption key writes, validating configuration updates, or debugging provisioning workflows. Provides structured test commands with JSON output for automated validation.
npx claudepluginhub hubblenetwork/pyhubblenetwork --plugin pyhubblenetworkThis skill is limited to using the following tools:
This testing framework provides comprehensive validation capabilities for Hubble Ready devices over Bluetooth Low Energy (BLE). It wraps the `hubblenetwork ready` CLI commands to enable systematic testing of device discovery, characteristic reads/writes, and the complete provisioning workflow.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
This testing framework provides comprehensive validation capabilities for Hubble Ready devices over Bluetooth Low Energy (BLE). It wraps the hubblenetwork ready CLI commands to enable systematic testing of device discovery, characteristic reads/writes, and the complete provisioning workflow.
The framework is designed for:
bluetooth group)bluetooth group: sudo usermod -a -G bluetooth $USERexport HUBBLE_ORG_ID="your-org-id"
export HUBBLE_API_TOKEN="your-api-token"
These are only required for the provision command which registers devices with the Hubble backend.
All test commands support --format json for structured output suitable for automated validation. Always use JSON format for testing to enable programmatic result verification.
scan)Scan for Hubble Ready devices advertising the 0xFCA7 service UUID.
Command:
hubblenetwork ready scan --format json [--timeout SECONDS]
Parameters:
--timeout (optional): Scan duration in seconds (default: 10)--format json: Required for structured outputExpected Output:
{
"devices": [
{
"address": "AA:BB:CC:DD:EE:FF",
"name": "Hubble Ready Device",
"rssi": -65
}
],
"scan_duration": 10.2
}
Validation:
devices array is not emptyCommon Test Failures:
info)Read all characteristics from a connected Hubble Ready device.
Command:
hubblenetwork ready info --format json --address <MAC> [--timeout SECONDS]
Parameters:
--address (required): Device MAC address from scan--timeout (optional): Connection timeout in seconds (default: 10)--format json: Required for structured outputExpected Output:
{
"address": "AA:BB:CC:DD:EE:FF",
"status": {
"firmware_version": "1.2.3",
"key_written": false,
"config_written": false,
"time_written": false
},
"key_info": {
"encryption_mode": "AES-256-CTR"
},
"config": {
"eid_type": "utc",
"rotation_period_seconds": 900,
"pool_size": 5
},
"time": {
"unix_timestamp": 1709424000,
"datetime": "2024-03-03T00:00:00Z"
}
}
Validation:
Common Test Failures:
All read tests require the --address flag and support --timeout.
read-status)Read firmware version and provisioning status flags.
Command:
hubblenetwork ready read-status --format json --address <MAC> [--timeout SECONDS]
Expected Output:
{
"address": "AA:BB:CC:DD:EE:FF",
"firmware_version": "1.2.3",
"key_written": false,
"config_written": false,
"time_written": false
}
Validation:
Test Scenarios:
read-key-info)Read encryption mode to determine required key size.
Command:
hubblenetwork ready read-key-info --format json --address <MAC> [--timeout SECONDS]
Expected Output:
{
"address": "AA:BB:CC:DD:EE:FF",
"encryption_mode": "AES-256-CTR"
}
Validation:
Test Note: Always read key info before testing key writes to ensure correct key size.
read-config)Read EID configuration parameters.
Command:
hubblenetwork ready read-config --format json --address <MAC> [--timeout SECONDS]
Expected Output:
{
"address": "AA:BB:CC:DD:EE:FF",
"eid_type": "utc",
"rotation_period_seconds": 900,
"pool_size": 5
}
Validation:
read-time)Read device's current Unix timestamp.
Command:
hubblenetwork ready read-time --format json --address <MAC> [--timeout SECONDS]
Expected Output:
{
"address": "AA:BB:CC:DD:EE:FF",
"unix_timestamp": 1709424000,
"datetime": "2024-03-03T00:00:00Z"
}
Validation:
abs(device_time - system_time)All write tests require the --address flag and return success confirmation.
write-key)Write base64-encoded encryption key to device.
Command:
hubblenetwork ready write-key --format json --address <MAC> --key <BASE64_KEY> [--timeout SECONDS]
Parameters:
--address (required): Device MAC address--key (required): Base64-encoded key (16 bytes for AES-128, 32 bytes for AES-256)--timeout (optional): Connection timeout in seconds (default: 10)Expected Output:
{
"address": "AA:BB:CC:DD:EE:FF",
"success": true,
"message": "Encryption key written successfully"
}
Test Workflow:
read-key-infokey_written flagKey Generation Example:
# For AES-128-CTR (16 bytes)
KEY=$(openssl rand -base64 16)
# For AES-256-CTR (32 bytes)
KEY=$(openssl rand -base64 32)
hubblenetwork ready write-key --format json --address <MAC> --key "$KEY"
Common Test Failures:
write-config)Write EID configuration to device.
Command:
hubblenetwork ready write-config --format json --address <MAC> --eid-type <TYPE> --pool-size <SIZE> [--timeout SECONDS]
Parameters:
--address (required): Device MAC address--eid-type (required): "utc" or "counter"--pool-size (required): Integer >= 1--timeout (optional): Connection timeout in seconds (default: 10)Expected Output:
{
"address": "AA:BB:CC:DD:EE:FF",
"success": true,
"message": "Configuration written successfully"
}
Test Workflow:
read-configTest Examples:
# Test UTC mode with pool size 10
hubblenetwork ready write-config --format json --address <MAC> --eid-type utc --pool-size 10
# Test counter mode with pool size 1
hubblenetwork ready write-config --format json --address <MAC> --eid-type counter --pool-size 1
Validation:
write-time)Write Unix timestamp to device (defaults to current time if not specified).
Command:
hubblenetwork ready write-time --format json --address <MAC> [--timestamp UNIX_TS] [--timeout SECONDS]
Parameters:
--address (required): Device MAC address--timestamp (optional): Unix timestamp (default: current time)--timeout (optional): Connection timeout in seconds (default: 10)Expected Output:
{
"address": "AA:BB:CC:DD:EE:FF",
"success": true,
"message": "Time written successfully",
"timestamp_written": 1709424000
}
Test Workflow:
read-timeTest Examples:
# Write current time
hubblenetwork ready write-time --format json --address <MAC>
# Write specific timestamp
hubblenetwork ready write-time --format json --address <MAC> --timestamp 1709424000
Validation:
provision)Execute complete provisioning workflow: scan → register with backend → write key/config/time.
Command:
hubblenetwork ready provision --format json [--timeout SECONDS] [--eid-type TYPE] [--pool-size SIZE]
Parameters:
--timeout (optional): Per-operation timeout (default: 10)--eid-type (optional): "utc" or "counter" (default: "utc")--pool-size (optional): Integer >= 1 (default: 5)Environment Variables Required:
HUBBLE_ORG_ID: Organization IDHUBBLE_API_TOKEN: API tokenExpected Output:
{
"success": true,
"device": {
"address": "AA:BB:CC:DD:EE:FF",
"device_id": "dev_abc123",
"name": "Hubble Ready Device"
},
"steps": {
"scan": {"success": true, "duration": 5.2},
"register": {"success": true, "duration": 0.8},
"write_key": {"success": true, "duration": 2.1},
"write_config": {"success": true, "duration": 1.9},
"write_time": {"success": true, "duration": 1.8}
},
"total_duration": 11.8
}
Test Workflow:
info command to verify all flags are trueValidation:
read-status to confirm all flags trueCommon Test Failures:
All commands support --format json which returns structured output:
{
"success": true,
"data": { /* command-specific data */ },
"duration": 2.5
}
{
"success": false,
"error": {
"type": "BleConnectionError",
"message": "Failed to connect to device",
"details": "Connection timeout after 10 seconds",
"att_error_code": 14,
"att_error_name": "Unlikely Error"
}
}
Error Fields:
type: Python exception class namemessage: Human-readable error descriptiondetails: Additional contextatt_error_code: ATT protocol error code (if applicable)att_error_name: ATT error name (if applicable)Purpose: Verify device is advertising and readable.
Steps:
Commands:
# Step 1: Scan
hubblenetwork ready scan --format json --timeout 10
# Step 2: Get address from scan output, read info
hubblenetwork ready info --format json --address <MAC>
Expected Results:
Purpose: Test encryption key write with correct key size.
Steps:
Commands:
# Step 1: Read encryption mode
hubblenetwork ready read-key-info --format json --address <MAC>
# Step 2: Generate key (example for AES-256-CTR)
KEY=$(openssl rand -base64 32)
# Step 3: Write key
hubblenetwork ready write-key --format json --address <MAC> --key "$KEY"
# Step 4: Verify
hubblenetwork ready read-status --format json --address <MAC>
Expected Results:
Purpose: Test configuration write and verify changes persist.
Steps:
Commands:
# Step 1: Read current config
hubblenetwork ready read-config --format json --address <MAC>
# Step 2: Write new config
hubblenetwork ready write-config --format json --address <MAC> --eid-type utc --pool-size 10
# Step 3: Verify changes
hubblenetwork ready read-config --format json --address <MAC>
Expected Results:
Purpose: Check device time and synchronize if drift detected.
Steps:
Commands:
# Step 1: Read device time
hubblenetwork ready read-time --format json --address <MAC>
# Step 2: If drift detected, sync time
hubblenetwork ready write-time --format json --address <MAC>
# Step 3: Verify
hubblenetwork ready read-time --format json --address <MAC>
Expected Results:
Purpose: Execute complete provisioning flow end-to-end.
Prerequisites:
Commands:
# Run complete provisioning
hubblenetwork ready provision --format json
# Verify provisioning
hubblenetwork ready info --format json --address <MAC>
Expected Results:
Symptom:
{
"success": false,
"error": {
"type": "BleScanError",
"message": "Bluetooth adapter not found"
}
}
Debugging Steps:
hciconfig (Linux) or System Preferences (macOS)Symptom:
{
"success": false,
"error": {
"type": "BleScanError",
"message": "Access denied",
"details": "org.bluez.Error.NotPermitted"
}
}
Debugging Steps:
sudo usermod -a -G bluetooth $USER, then log out and back in.Symptom:
{
"success": false,
"error": {
"type": "BleConnectionError",
"message": "Failed to connect to device",
"details": "Connection timeout after 10 seconds"
}
}
Debugging Steps:
--timeout 30ATT (Attribute Protocol) errors indicate the device rejected the operation.
ATT Error 0x0E (14): "Unlikely Error"
Device rejected the operation for internal reasons.
{
"success": false,
"error": {
"type": "BleError",
"message": "Write failed",
"att_error_code": 14,
"att_error_name": "Unlikely Error"
}
}
Debugging Steps:
ATT Error 0x0D (13): "Invalid Attribute Value Length"
Wrong data size for characteristic write.
{
"success": false,
"error": {
"type": "BleError",
"message": "Write failed",
"att_error_code": 13,
"att_error_name": "Invalid Attribute Value Length"
}
}
Debugging Steps:
echo "$KEY" | base64 -d | wc -cSymptom:
{
"success": false,
"error": {
"type": "ValueError",
"message": "Invalid key size",
"details": "Key must be 16 bytes for AES-128-CTR or 32 bytes for AES-256-CTR"
}
}
Debugging Steps:
hubblenetwork ready read-key-info --format json --address <MAC>openssl rand -base64 16 (16 bytes)openssl rand -base64 32 (32 bytes)echo "$KEY" | base64 -d | wc -cSymptom:
{
"success": false,
"error": {
"type": "BleConnectionError",
"message": "Device not found",
"details": "No device found with address AA:BB:CC:DD:EE:FF"
}
}
Debugging Steps:
All test commands should include --format json for structured output:
# ✓ Good - JSON output
hubblenetwork ready scan --format json
# ✗ Bad - Table output (hard to parse)
hubblenetwork ready scan
JSON output enables:
Default timeout is 10 seconds. Adjust based on test scenario:
# Quick scan
hubblenetwork ready scan --format json --timeout 5
# Longer scan for weak signal devices
hubblenetwork ready scan --format json --timeout 30
# Connection with BLE interference
hubblenetwork ready info --format json --address <MAC> --timeout 20
Guidelines:
Always read characteristics before writing to understand current state:
# ✓ Good - Read first, then write
hubblenetwork ready read-key-info --format json --address <MAC>
# ... determine key size from output ...
hubblenetwork ready write-key --format json --address <MAC> --key "$KEY"
# ✗ Bad - Write without reading (may use wrong key size)
hubblenetwork ready write-key --format json --address <MAC> --key "$KEY"
After write operations, always read back to verify changes persisted:
# Write config
hubblenetwork ready write-config --format json --address <MAC> --eid-type utc --pool-size 10
# Verify write succeeded
hubblenetwork ready read-config --format json --address <MAC>
# Expected: eid_type="utc", pool_size=10
When multiple devices are present, always specify --address:
# Scan to find devices
hubblenetwork ready scan --format json
# Specify device for operations
hubblenetwork ready info --format json --address AA:BB:CC:DD:EE:FF
For provisioning with multiple devices, the command will prompt for device selection unless --address is provided.
Use status flags to determine device provisioning state:
hubblenetwork ready read-status --format json --address <MAC>
Flag Interpretation:
key_written: false → Need to write encryption keyconfig_written: false → Need to write configurationtime_written: false → Need to write timetrue → Device fully provisionedFor automated testing, capture JSON output for validation:
# Capture test result
RESULT=$(hubblenetwork ready scan --format json)
# Parse with jq for validation
DEVICE_COUNT=$(echo "$RESULT" | jq '.devices | length')
if [ "$DEVICE_COUNT" -eq 0 ]; then
echo "TEST FAILED: No devices found"
exit 1
fi
echo "TEST PASSED: Found $DEVICE_COUNT device(s)"
Quick reference table for all test commands:
| Command | Purpose | Required Flags | Optional Flags |
|---|---|---|---|
scan | Find devices | --format json | --timeout |
info | Read all characteristics | --format json --address | --timeout |
read-status | Read provisioning status | --format json --address | --timeout |
read-key-info | Read encryption mode | --format json --address | --timeout |
read-config | Read EID config | --format json --address | --timeout |
read-time | Read device time | --format json --address | --timeout |
write-key | Write encryption key | --format json --address --key | --timeout |
write-config | Write EID config | --format json --address --eid-type --pool-size | --timeout |
write-time | Write device time | --format json --address | --timeout --timestamp |
provision | Full provisioning flow | --format json | --timeout --eid-type --pool-size --address |
When tests fail, use these diagnostic commands:
# Check BLE adapter status (Linux)
hciconfig
bluetoothctl show
# Check BLE permissions (Linux)
groups | grep bluetooth
# Test basic BLE scanning (Linux)
sudo hcitool lescan
# Check system Bluetooth (macOS)
system_profiler SPBluetoothDataType
Issue: "No devices found" but device is on
Issue: "Connection refused" repeatedly
Issue: Writes succeed but reads show old values
Issue: Provisioning fails at registration step
Issue: Intermittent connection failures
For implementation details and error codes:
src/hubblenetwork/cli.py (lines 852-2136)src/hubblenetwork/ready.pysrc/hubblenetwork/errors.pysrc/hubblenetwork/crypto.pyREADME.md - SDK overview and installationCLAUDE.md - Architecture and development guide.claude/skills/hubble-ready-test/examples/ - Sample JSON responsesFor issues or questions about this testing framework:
examples/ directoryThe testing framework is a documentation layer that wraps the existing CLI. It stays synchronized with the CLI automatically since it documents exact command syntax.