Repository navigation
Device Definition & Discovery Architecture
As Smart Home environments scale, managing network-attached and Bluetooth Low Energy (BLE) devices creates significant complexity—often referred to as IoT Sprawl. Unidentified IP addresses in local subnets and dozens of cryptic BLE MAC addresses make device onboarding confusing and error-prone.
The HomeNode project addresses this challenge by decoupling device-specific driver logic (discovery fingerprinting, payload parsing, and command execution) from core applications. Using a shared, cross-platform specification format (YAML/JSON), both the Rust Server (HomeNodeServer) and the iOS Client (mHomeNode) consume identical device definitions without code duplication.
+-------------------------------------------------------+
| mHomeNode (iOS) |
| - Mobile BLE Scout (RSSI proximity detection) |
| - Room-level physical device assignment |
| - Quick local scanning & Apple Home Interface |
+---------------------------+---------------------------+
|
Sync / REST API
|
+---------------------------v---------------------------+
| HomeNodeServer (Rust) |
| - 24/7 Background Network Discovery (mDNS, UPnP) |
| - Long-term state management |
| - IP-based execution engine (Shelly, Tasmota, REST) |
+-------------------------------------------------------+
Primary Scope: Bluetooth Low Energy (BLE) scanning & Apple Home integration.
Key Role: BLE signals have a limited physical range (~10–15 m). Carrying an iPhone through rooms allows users to identify unnamed BLE sensors instantly via Received Signal Strength Indicator (RSSI) proximity and map them visually to specific physical locations.
Primary Scope: Local Area Network (LAN/Wi-Fi) management.
Key Role: Runs continuously on Linux/Unix hardware. Conducts background discovery using mDNS/Bonjour, UPnP, and HTTP probing to catalog network-attached devices like Shelly relays, Tasmota devices, or smart plugs.
To allow instant support for new devices without recompiling binaries or waiting for App Store updates, device capabilities and fingerprinting rules are defined in declarative YAML files.
Both Rust (serde_json / serde_yaml) and Swift (Codable) parse these definitions natively.
Used by the iOS app to match cryptic BLE Advertisement data to a human-readable sensor name and decode payload bytes into metrics.
id: qingping_cgg1
name: "QingPing Bluetooth Temp & RH Sensor"
connection: ble
Identification rules during active/passive BLE scans
match:
service_uuids:
- "FDCD"
manufacturer_data:
company_id: "088B"
Byte offsets for parsing payload data
parse:
temperature:
bytes: [8, 9]
type: int16_le
scale: 0.1
unit: "°C"
humidity:
bytes: [10, 11]
type: uint16_le
scale: 0.1
unit: "%"
Used by the Rust server to discover devices via mDNS, probe HTTP endpoints, and trigger state changes.
id: shelly_gen2_relay
name: "Shelly Gen2 Switch"
connection: ip_http
Fingerprinting rules for network discovery
match:
mdns_service: "_http._tcp.local"
http_probe:
path: "/shelly"
contains_json:
app: "Shelly"
Metric reading configuration
metrics:
power:
path: "/rpc/Switch.GetStatus?id=0"
json_pointer: "/apower"
unit: "W"
Executable commands
actions:
turn_on:
method: GET
path: "/rpc/Switch.Set?id=0&on=true"
turn_off:
method: GET
path: "/rpc/Switch.Set?id=0&on=false"
| Phase | Strategy | Scope & Benefits |
|---|---|---|
| Phase 1 | Declarative Definitions (JSON/YAML) | Handles ~80% of standard devices (Shelly REST APIs, standard BLE GATT/Advertisement parsers). Zero runtime overhead, maximum security, native parsing on both Rust and Swift. |
| Phase 2 | Embedded Scripting (WASM / Lua) | Extends support to complex devices requiring multi-step handshakes, custom cryptographic signatures, or bitwise decoding beyond declarative byte offsets.- Rust Engine: wasmtime / wasmer or mlua- Swift Engine: JavaScriptCore / WebKit WASM or C-bridged Lua |
Physical Room Scan: The user opens
mHomeNodeon iOS while walking through the house.Fingerprint Matching: The app scans BLE, matches
FDCDService UUIDs against the YAML definitions, and presents "QingPing Sensor detected nearby" instead of an obscure MAC address.Room Assignment: The user assigns the identified sensor to "Living Room".
Server Sync: The iOS app syncs the newly claimed device metadata to
HomeNodeServer.Network Sweep: Simultaneously,
HomeNodeServerdetects new Shelly relays via mDNS on the LAN and flags them in the UI for user confirmation.
(c) Stephan Zehrer 2025