Skip to content

Device Definition & Discovery Architecture

Stephan Zehrer edited this page Sep 11, 2026 · 1 revision

Device Definition & Discovery Architecture

Overview

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.

Distributed Responsibilities

+-------------------------------------------------------+
|                    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)  |
+-------------------------------------------------------+

1. iOS App (mHomeNode) — The Mobile Scout

  • 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.

2. Rust Server (HomeNodeServer) — The IP Backbone

  • 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.

Shared Specification Schema (YAML)

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.

Example 1: BLE Device Profile (qingping_cgg1.yaml)

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: "%"

Example 2: IP Device Profile (shelly_gen2_relay.yaml)

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"

Extensibility & Scripting Engine Strategy

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

Onboarding Workflow

  1. Physical Room Scan: The user opens mHomeNode on iOS while walking through the house.

  2. Fingerprint Matching: The app scans BLE, matches FDCD Service UUIDs against the YAML definitions, and presents "QingPing Sensor detected nearby" instead of an obscure MAC address.

  3. Room Assignment: The user assigns the identified sensor to "Living Room".

  4. Server Sync: The iOS app syncs the newly claimed device metadata to HomeNodeServer.

  5. Network Sweep: Simultaneously, HomeNodeServer detects new Shelly relays via mDNS on the LAN and flags them in the UI for user confirmation.

Clone this wiki locally