Skip to content

Homie compliance phase 1: producer wire correctness #95

Closed

Description

@dcj

Part of #91. Everything a third-party Homie 5 controller can observe from an SDK device. Line numbers refer to homieiot/convention@7edc221.

Lifecycle and teardown

  • Device.stop() publishes $state=disconnected for every device in the tree, not only the root (:280-281; the cascade at :262-267 covers only lost). Today each child's retained $state stays ready after a clean shutdown.
  • declare_lost() paired with stop(announce=False) ends in a clean MQTT disconnect with no disconnected (:281, :284). Decide the deliberate-death sequence.
  • child.delete(): update the parent first (init, $description without the child, ready), then clear the child's topics starting with $state (:635-641). Today the order is reversed.
  • delete() followed by stop() republishes $state=disconnected, re-creating a deleted device with no $description (:272, :288).
  • The Last Will carries the tree's QoS and retain; today it goes out at QoS 0 while every other $state uses QoS 2 (:45, :689-691).

$description

  • version becomes a content hash (see Homie 5 compliance: convention-compliant base layer, eBus policy above it #91). Today it is epoch milliseconds, so two documents in one millisecond share a version (:215) and every reconnect publishes a new version of an unchanged document.
  • A change happens only in init, disconnected or lost (:207). Today a change while sleeping is published directly.
  • Omit type when unset instead of "type": null for devices and nodes (:218, :305).
  • datatype is required and retained is a non-null boolean (:340, :343); today either can be emitted as null.
  • A json $format is a string, not a nested object (:395).
  • enum and color require a $format; an enum format has at least one value and no duplicates (:392-393). Warn, per the epic's policy.
  • description_extras cannot add root or parent to a root device (:220).
  • Node.add_property() / Device.add_node() outside a transition publish new values before ready (:279).

Property values

  • Refuse and log, publishing nothing, an outbound value the datatype cannot represent: non-finite floats (:99), booleans on numeric properties, integers outside 64 bits or not whole (:87-89), enum values not in $format. Floats never carry + in the exponent (:97).
  • Encoders for datetime, duration and color (:120, :132, :137-138); today these fall through to str().
  • Outbound json must be an array or object, never NaN (:150).
  • The 0x00 empty-string encoding applies only to string properties (:65-67); an empty enum, integer or json value is invalid, not 0x00.
  • Non-retained (event) properties publish non-retained at QoS 0 (:50) and are not replayed by the reconnect or structural-change republish walk (:695).
  • $alert publishes to $alert/[alert ID] and can be cleared; delete() clears alerts (:517, :289).

/set on the device

  • Ignore, with a warning, a /set the broker delivers with the retain flag set: a stale retained command replayed at subscribe (:48, :483). Needs Expose the MQTT retain flag to subscription callbacks ebus-mqtt-client#24.
  • Validate inbound payloads per datatype before the callback: json is an array or object; integers and floats follow the payload grammar; numbers are rounded to the step, then checked against min/max (:399). Invalid payloads are dropped with a warning.
  • supports_target=True is inert: warn once at construction instead of calling the $target stub on every /set, which as placed would precede the acceptance decision (:466, :470).

Metadata

  • .ebus-spec.json lists mdns-discovery under supports; the library has no mDNS code.

Activity

  1. dcj commented on Oct 8, 2026

    @dcj
    ContributorAuthor

    Done in #96 (72b5629). Every checklist item above is implemented, with the convention citations and the behavior changes listed in the CHANGELOG [Unreleased] entry. Ships in the next ebus-sdk release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions