]> git.giacomolli.uk - onehouse/blobdiff - doc/mqtt.rst
Exchange bounded M31 Modbus TCP requests
[onehouse] / doc / mqtt.rst
index 615116effbe9e93a709e0f2d17f1ca1851d77e77..e0a2d6246a23f19295d68db48162f0ababcae3da 100644 (file)
@@ -7,18 +7,130 @@ command, and message IDs use canonical uppercase ULIDs. Capabilities and
 events use lowercase ASCII letters and digits, with single internal
 hyphen or period separators. Topic builders reject invalid addresses.
 
-``Address.Topic`` and ``ParseTopic`` cover device descriptor,
-availability, reported values, telemetry, events, commands, command
-batches, results, and Zigbee hub status. Subscription helpers supply the
-core input filters, each device's command filter, and hub status filter.
-The command filter includes the reserved ``$batch`` target.
-
-``EncodeEnvelope`` and ``ParseEnvelope`` validate schema, IDs, optional
-UTC timestamps, and a required object payload. Unknown envelope fields,
-trailing JSON, unsupported schema versions, and malformed topics are
-errors. A receiver checks expiry against its own clock. The message ID
-stays unchanged on retry. Its timestamp is not the observation time.
+Private topic helpers cover device descriptor, availability, reported
+values, telemetry, events, commands, command batches, results, and
+Zigbee hub status. Subscription helpers supply the core input filters,
+each device's command filter, and hub status filter. The command filter
+includes the reserved ``$batch`` target.
+
+Private envelope helpers validate schema, IDs, optional UTC timestamps,
+and a required object payload. Unknown envelope fields, trailing JSON,
+unsupported schema versions, and malformed topics are errors. A receiver
+checks expiry against its own clock. The message ID 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 through shared typed validation. A builder
+encodes its validated payload without parsing it. Batch members use the
+same metadata and value validation without envelope encoding. Access
+flag presence checks apply to parsed JSON only. ``Parse`` selects the
+typed payload and address kind after one topic parse. 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.