]> git.giacomolli.uk - onehouse/blobdiff - doc/mqtt.rst
Build typed MQTT publications
[onehouse] / doc / mqtt.rst
index 615116effbe9e93a709e0f2d17f1ca1851d77e77..55a9a67ebc2eaaa4992224ce7eb447a16a00029a 100644 (file)
@@ -22,3 +22,112 @@ stays unchanged on retry. Its timestamp is not the observation time.
 Measurements and online availability repeat at five-minute intervals.
 The device contact timeout is fifteen minutes. These constants do not
 run timers or implement publication suppression.
+
+********************
+ Typed publications
+********************
+
+Each operation has a ``Build`` function and a ``Parse`` function, such
+as ``BuildReported`` and ``ParseReported``. Builders accept an ID, an
+optional target, metadata, and a typed payload. They validate the same
+contract as the parsers. ``Parse`` selects the typed payload and address
+kind from an incoming topic. A caller does not split or join topics and
+does not build an envelope.
+
+A ``Publication`` contains topic, JSON bytes, QoS, and retention. It
+also supplies the expiry deadline, response topic, and correlation data
+when the operation needs them. The transport uses MQTT 5, sets the
+payload format to UTF-8 and the content type to ``application/json``,
+and derives the message expiry interval from the deadline. It rejects
+expired work before sending or processing it. The protocol package has
+no broker client or clock worker.
+
+.. list-table:: Delivery rules
+   :header-rows: 1
+
+   -  -  Operation
+      -  QoS
+      -  Retained
+
+   -  -  Descriptor, availability, reported, hub status
+      -  1
+      -  Yes
+
+   -  -  Telemetry
+      -  0
+      -  No
+
+   -  -  Events, commands, command batches, results
+      -  1
+      -  No
+
+A parser accepts a live delivery of retained-topic data with its
+retained flag false. It rejects a retained event, telemetry sample,
+command, batch, or result. Telemetry uses the same complete value
+payload as a reported snapshot. The publisher keeps the retained
+reported snapshot up to date, with QoS 1, without topic string
+operations: it uses ``BuildReported`` for the same device and
+capability.
+
+**********
+ Payloads
+**********
+
+``DescriptorPayload`` requires nonempty manufacturer, model, firmware,
+and capabilities. Optional attribution has a 2000-byte limit. Each
+capability has a unique valid ID and a valid type. Both Boolean access
+flags must be present. At least one must be true. The descriptor does
+not contain house metadata.
+
+``AvailabilityPayload`` accepts ``online`` or ``offline``. A shared
+broker connection cannot have a separate last will for every device. The
+driver reports device failures and repeats online contact evidence.
+
+``ValuePayload`` requires a JSON value and preserves complete objects.
+JSON null is a present value. The wire layer does not check
+capability-specific units, ranges, settings, or physical access.
+Commands use this payload and require an expiry. The receiver checks
+ownership, access, and expiry before it acts.
+
+``EventPayload`` is an open object of event data. Every member is
+application data, not an optional wire field. Empty objects and custom
+members are valid. This supports exact event matching, physical button
+actions, and camera motion times without discarding event details.
+Unknown fields in envelopes and in closed payloads, including nested
+capabilities, batch members, and hub diagnostics, are rejected. Nested
+application values and event data are open by definition.
+
+``BatchPayload`` holds 2 through 256 ordered commands for one device.
+Each member has a capability, metadata, and a value payload. Encoding
+inserts the member schema. The outer message ID equals the first member
+ID. Member IDs and capabilities are distinct. Every member requires its
+own expiry. A malformed member rejects the complete batch. The transport
+uses the earliest member deadline and no combined response topic. Each
+member has its own result.
+
+``ResultPayload`` accepts ``accepted``, ``completed``, ``rejected``, or
+``failed``. Rejected and failed results require a nonempty reason.
+Accepted and completed results must not have a reason. The correlation
+ID must equal the command ID in the topic. A result does not replace
+physical feedback. Duplicate detection, result ordering, and physical
+operation safety belong to the driver and core.
+
+``HubStatusPayload`` contains one Zigbee hub snapshot with a matching
+hub ID, address, status, device counts, and optional pairing and
+diagnostics. Status is ``ready`` or ``unavailable``. Hub timestamps use
+UTC. Its envelope requires expiry. ``HubStatusLifetime`` calculates two
+poll intervals plus 50 seconds. The publisher refreshes status at the
+poll interval and after reconnect. It preserves diagnostic observation
+time and stale flags. Consumers reject expired snapshots and check
+source age before using a diagnostic value. Hub status is not core
+house-state input.
+
+**************
+ Verification
+**************
+
+Unit tests cover all topic and payload forms, delivery rules, invalid
+fields and schemas, batch order and bounds, correlation, and expiry
+metadata. These tests do not verify a broker, a physical device, MQTT
+acknowledgement, reconnect behavior, publication suppression, or command
+execution.