X-Git-Url: https://git.giacomolli.uk/onehouse/blobdiff_plain/9ea825d64a3efaf8679990ea652ffaad0615c24c..HEAD:/doc/mqtt.rst?ds=inline diff --git a/doc/mqtt.rst b/doc/mqtt.rst index 615116e..e0a2d62 100644 --- a/doc/mqtt.rst +++ b/doc/mqtt.rst @@ -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.