Files
lambdaiot-core/docs/DEVICE_DISCOVERY_SPEC.md

7.1 KiB

Device Discovery Specification

This specification defines the format and protocol that microcontroller-based IoT devices must follow to register themselves with the Lambda IoT Core system.

Overview

At boot, each device must submit a single JSON message containing:

  • Device information (name, description, location)
  • List of sensors
  • List of actors (actuators)

All UUIDs are deterministically generated based on the device's MAC address to ensure consistency across reboots.

UUID Generation

Device UUID

Generate a UUID v5 using:

  • Namespace: 6ba7b810-9dad-11d1-80b4-00c04fd430c8 (DNS namespace)
  • Name: Device MAC address in lowercase, no separators (e.g., aabbccddeeff)

Sensor UUID

Generate a UUID v5 using:

  • Namespace: Device UUID
  • Name: sensor-{N} where N is the 0-based sensor index

Actor UUID

Generate a UUID v5 using:

  • Namespace: Device UUID
  • Name: actor-{N} where N is the 0-based actor index

Discovery Message Format

MQTT Topic

Devices must publish to: {MQTT_TOPIC}/discovery

Where {MQTT_TOPIC} is the configured MQTT topic (e.g., lambdaiot, resulting in lambdaiot/discovery)

Message Structure

{
  "mac_address": "aa:bb:cc:dd:ee:ff",
  "device": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Living Room Sensor",
    "description": "Multi-sensor device for home monitoring",
    "location": "Living Room",
    "status_id": 1
  },
  "sensors": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "name": "Temperature",
      "type": "DHT22",
      "data_type_id": 2
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "name": "Humidity",
      "type": "DHT22",
      "data_type_id": 2
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440003",
      "name": "Motion",
      "type": "PIR",
      "data_type_id": 1
    }
  ],
  "actors": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440004",
      "name": "LED",
      "type": "RGB_LED",
      "data_type_id": 1
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440005",
      "name": "Fan",
      "type": "PWM_FAN",
      "data_type_id": 2
    }
  ]
}

Field Definitions

Device Object

Field Type Required Description
id UUID string Yes Deterministic UUID v5 based on MAC
name String Yes Human-readable device name
description String No Device description
location String No Physical location (e.g., "Living Room")
status_id Integer Yes Status code: 1=ok, 2=pending, 3=lost, 4=disabled

Sensor/Actor Object

Field Type Required Description
id UUID string Yes Deterministic UUID v5 (device UUID + "sensor-N" or "actor-N")
name String Yes Human-readable sensor/actor name
type String Yes Hardware type (e.g., "DHT22", "PIR", "RGB_LED")
data_type_id Integer Yes Data type: 1=bool, 2=float

Root Object

Field Type Required Description
mac_address String Yes Device MAC address (lowercase with colons)
device Object Yes Device information
sensors Array Yes Array of sensor objects (can be empty)
actors Array Yes Array of actor objects (can be empty)

Behavior

On First Boot

  1. Device generates deterministic UUIDs based on its MAC address
  2. Device publishes discovery message to {MQTT_TOPIC}/discovery
  3. Backend receives message, creates device record with status_id=1 (ok)
  4. Sensors and actors are created

On Subsequent Boots

  1. Device uses same deterministic UUIDs (based on MAC)
  2. Device publishes discovery message again
  3. Backend detects existing device by UUID
  4. Device details (name, description, location) are updated
  5. Sensors/actors are synchronized:
    • New sensors/actors are added
    • Existing sensors/actors with same ID but different properties are updated
    • Sensors/actors no longer in the message are deleted
  6. Device status is set to ok (1)

Conflict Resolution

  • If a device UUID already exists, it is updated rather than creating a duplicate
  • Sensors and actors are matched by UUID, not by position
  • Removing a sensor/actor from the discovery message will delete it from the database

UUID Collision Handling

Devices with different MACs will generate different UUIDs. If two devices somehow share the same MAC (misconfiguration), they will overwrite each other's records. This is acceptable as MAC duplication is a network configuration error.

Data Type Codes

Code Type Description
1 bool Boolean value (true/false or 0/1)
2 float Floating-point numeric value

Status Codes

Code Status Description
1 ok Device is functioning normally
2 pending Device is initializing
3 lost Device has not checked in recently
4 disabled Device has been administratively disabled

Example Device Implementations

Minimal Device (1 sensor, no actors)

{
  "mac_address": "aa:bb:cc:dd:ee:ff",
  "device": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Temperature Sensor",
    "description": "",
    "location": "",
    "status_id": 1
  },
  "sensors": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "name": "Temp",
      "type": "DHT22",
      "data_type_id": 2
    }
  ],
  "actors": []
}

Complex Device (3 sensors, 2 actors)

{
  "mac_address": "11:22:33:44:55:66",
  "device": {
    "id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
    "name": "Greenhouse Controller",
    "description": "Automated greenhouse monitoring and control",
    "location": "Greenhouse A",
    "status_id": 1
  },
  "sensors": [
    {
      "id": "6ba7b812-9dad-11d1-80b4-00c04fd430c8",
      "name": "Temperature",
      "type": "DHT22",
      "data_type_id": 2
    },
    {
      "id": "6ba7b813-9dad-11d1-80b4-00c04fd430c8",
      "name": "Humidity",
      "type": "DHT22",
      "data_type_id": 2
    },
    {
      "id": "6ba7b814-9dad-11d1-80b4-00c04fd430c8",
      "name": "Soil Moisture",
      "type": "Capacitive",
      "data_type_id": 2
    }
  ],
  "actors": [
    {
      "id": "6ba7b815-9dad-11d1-80b4-00c04fd430c8",
      "name": "Irrigation Pump",
      "type": "Relay",
      "data_type_id": 1
    },
    {
      "id": "6ba7b816-9dad-11d1-80b4-00c04fd430c8",
      "name": "Ventilation Fan",
      "type": "PWM",
      "data_type_id": 2
    }
  ]
}

Notes for Device Developers

  • Always use the same UUID generation algorithm to ensure consistency
  • Preserve sensor/actor order to maintain deterministic IDs
  • If hardware changes (sensors added/removed), rearrange the array to maintain backward compatibility, or accept that indices will shift
  • Include sufficient description and location information for users to identify devices
  • Set status_id to 1 (ok) on successful boot
  • Consider publishing discovery message periodically (e.g., every 5 minutes) as a heartbeat
  • Use MQTT QoS 1 (at-least-once) for discovery messages