]> git.giacomolli.uk - onehouse/blob - doc/mqtt.rst
1f5fa4a6ce1d912916922588a84c7b466e95756a
[onehouse] / doc / mqtt.rst
1 ###############
2 MQTT contract
3 ###############
4
5 The ``protocol`` package defines schema 1 under ``onehouse/v1``. Device,
6 command, and message IDs use canonical uppercase ULIDs. Capabilities and
7 events use lowercase ASCII letters and digits, with single internal
8 hyphen or period separators. Topic builders reject invalid addresses.
9
10 Private topic helpers cover device descriptor, availability, reported
11 values, telemetry, events, commands, command batches, results, and
12 Zigbee hub status. Subscription helpers supply the core input filters,
13 each device's command filter, and hub status filter. The command filter
14 includes the reserved ``$batch`` target.
15
16 Private envelope helpers validate schema, IDs, optional UTC timestamps,
17 and a required object payload. Unknown envelope fields, trailing JSON,
18 unsupported schema versions, and malformed topics are errors. A receiver
19 checks expiry against its own clock. The message ID stays unchanged on
20 retry. Its timestamp is not the observation time.
21
22 Measurements and online availability repeat at five-minute intervals.
23 The device contact timeout is fifteen minutes. These constants do not
24 run timers or implement publication suppression.
25
26 ********************
27 Typed publications
28 ********************
29
30 Each operation has a ``Build`` function and a ``Parse`` function, such
31 as ``BuildReported`` and ``ParseReported``. Builders accept an ID, an
32 optional target, metadata, and a typed payload. They validate the same
33 contract as the parsers. ``Parse`` selects the typed payload and address
34 kind from an incoming topic. A caller does not split or join topics and
35 does not build an envelope.
36
37 A ``Publication`` contains topic, JSON bytes, QoS, and retention. It
38 also supplies the expiry deadline, response topic, and correlation data
39 when the operation needs them. The transport uses MQTT 5, sets the
40 payload format to UTF-8 and the content type to ``application/json``,
41 and derives the message expiry interval from the deadline. It rejects
42 expired work before sending or processing it. The protocol package has
43 no broker client or clock worker.
44
45 .. list-table:: Delivery rules
46 :header-rows: 1
47
48 - - Operation
49 - QoS
50 - Retained
51
52 - - Descriptor, availability, reported, hub status
53 - 1
54 - Yes
55
56 - - Telemetry
57 - 0
58 - No
59
60 - - Events, commands, command batches, results
61 - 1
62 - No
63
64 A parser accepts a live delivery of retained-topic data with its
65 retained flag false. It rejects a retained event, telemetry sample,
66 command, batch, or result. Telemetry uses the same complete value
67 payload as a reported snapshot. The publisher keeps the retained
68 reported snapshot up to date, with QoS 1, without topic string
69 operations: it uses ``BuildReported`` for the same device and
70 capability.
71
72 **********
73 Payloads
74 **********
75
76 ``DescriptorPayload`` requires nonempty manufacturer, model, firmware,
77 and capabilities. Optional attribution has a 2000-byte limit. Each
78 capability has a unique valid ID and a valid type. Both Boolean access
79 flags must be present. At least one must be true. The descriptor does
80 not contain house metadata.
81
82 ``AvailabilityPayload`` accepts ``online`` or ``offline``. A shared
83 broker connection cannot have a separate last will for every device. The
84 driver reports device failures and repeats online contact evidence.
85
86 ``ValuePayload`` requires a JSON value and preserves complete objects.
87 JSON null is a present value. The wire layer does not check
88 capability-specific units, ranges, settings, or physical access.
89 Commands use this payload and require an expiry. The receiver checks
90 ownership, access, and expiry before it acts.
91
92 ``EventPayload`` is an open object of event data. Every member is
93 application data, not an optional wire field. Empty objects and custom
94 members are valid. This supports exact event matching, physical button
95 actions, and camera motion times without discarding event details.
96 Unknown fields in envelopes and in closed payloads, including nested
97 capabilities, batch members, and hub diagnostics, are rejected. Nested
98 application values and event data are open by definition.
99
100 ``BatchPayload`` holds 2 through 256 ordered commands for one device.
101 Each member has a capability, metadata, and a value payload. Encoding
102 inserts the member schema. The outer message ID equals the first member
103 ID. Member IDs and capabilities are distinct. Every member requires its
104 own expiry. A malformed member rejects the complete batch. The transport
105 uses the earliest member deadline and no combined response topic. Each
106 member has its own result.
107
108 ``ResultPayload`` accepts ``accepted``, ``completed``, ``rejected``, or
109 ``failed``. Rejected and failed results require a nonempty reason.
110 Accepted and completed results must not have a reason. The correlation
111 ID must equal the command ID in the topic. A result does not replace
112 physical feedback. Duplicate detection, result ordering, and physical
113 operation safety belong to the driver and core.
114
115 ``HubStatusPayload`` contains one Zigbee hub snapshot with a matching
116 hub ID, address, status, device counts, and optional pairing and
117 diagnostics. Status is ``ready`` or ``unavailable``. Hub timestamps use
118 UTC. Its envelope requires expiry. ``HubStatusLifetime`` calculates two
119 poll intervals plus 50 seconds. The publisher refreshes status at the
120 poll interval and after reconnect. It preserves diagnostic observation
121 time and stale flags. Consumers reject expired snapshots and check
122 source age before using a diagnostic value. Hub status is not core
123 house-state input.
124
125 **************
126 Verification
127 **************
128
129 Unit tests cover all topic and payload forms, delivery rules, invalid
130 fields and schemas, batch order and bounds, correlation, and expiry
131 metadata. These tests do not verify a broker, a physical device, MQTT
132 acknowledgement, reconnect behavior, publication suppression, or command
133 execution.