]> git.giacomolli.uk - onehouse/blob - doc/mqtt.rst
Poll and command shared Alamo thermostats
[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 through shared typed validation. A builder
34 encodes its validated payload without parsing it. Batch members use the
35 same metadata and value validation without envelope encoding. Access
36 flag presence checks apply to parsed JSON only. ``Parse`` selects the
37 typed payload and address kind after one topic parse. A caller does not
38 split or join topics and does not build an envelope.
39
40 A ``Publication`` contains topic, JSON bytes, QoS, and retention. It
41 also supplies the expiry deadline, response topic, and correlation data
42 when the operation needs them. The transport uses MQTT 5, sets the
43 payload format to UTF-8 and the content type to ``application/json``,
44 and derives the message expiry interval from the deadline. It rejects
45 expired work before sending or processing it. The protocol package has
46 no broker client or clock worker.
47
48 .. list-table:: Delivery rules
49 :header-rows: 1
50
51 - - Operation
52 - QoS
53 - Retained
54
55 - - Descriptor, availability, reported, hub status
56 - 1
57 - Yes
58
59 - - Telemetry
60 - 0
61 - No
62
63 - - Events, commands, command batches, results
64 - 1
65 - No
66
67 A parser accepts a live delivery of retained-topic data with its
68 retained flag false. It rejects a retained event, telemetry sample,
69 command, batch, or result. Telemetry uses the same complete value
70 payload as a reported snapshot. The publisher keeps the retained
71 reported snapshot up to date, with QoS 1, without topic string
72 operations: it uses ``BuildReported`` for the same device and
73 capability.
74
75 **********
76 Payloads
77 **********
78
79 ``DescriptorPayload`` requires nonempty manufacturer, model, firmware,
80 and capabilities. Optional attribution has a 2000-byte limit. Each
81 capability has a unique valid ID and a valid type. Both Boolean access
82 flags must be present. At least one must be true. The descriptor does
83 not contain house metadata.
84
85 ``AvailabilityPayload`` accepts ``online`` or ``offline``. A shared
86 broker connection cannot have a separate last will for every device. The
87 driver reports device failures and repeats online contact evidence.
88
89 ``ValuePayload`` requires a JSON value and preserves complete objects.
90 JSON null is a present value. The wire layer does not check
91 capability-specific units, ranges, settings, or physical access.
92 Commands use this payload and require an expiry. The receiver checks
93 ownership, access, and expiry before it acts.
94
95 ``EventPayload`` is an open object of event data. Every member is
96 application data, not an optional wire field. Empty objects and custom
97 members are valid. This supports exact event matching, physical button
98 actions, and camera motion times without discarding event details.
99 Unknown fields in envelopes and in closed payloads, including nested
100 capabilities, batch members, and hub diagnostics, are rejected. Nested
101 application values and event data are open by definition.
102
103 ``BatchPayload`` holds 2 through 256 ordered commands for one device.
104 Each member has a capability, metadata, and a value payload. Encoding
105 inserts the member schema. The outer message ID equals the first member
106 ID. Member IDs and capabilities are distinct. Every member requires its
107 own expiry. A malformed member rejects the complete batch. The transport
108 uses the earliest member deadline and no combined response topic. Each
109 member has its own result.
110
111 ``ResultPayload`` accepts ``accepted``, ``completed``, ``rejected``, or
112 ``failed``. Rejected and failed results require a nonempty reason.
113 Accepted and completed results must not have a reason. The correlation
114 ID must equal the command ID in the topic. A result does not replace
115 physical feedback. Duplicate detection, result ordering, and physical
116 operation safety belong to the driver and core.
117
118 ``HubStatusPayload`` contains one Zigbee hub snapshot with a matching
119 hub ID, address, status, device counts, and optional pairing and
120 diagnostics. Status is ``ready`` or ``unavailable``. Hub timestamps use
121 UTC. Its envelope requires expiry. ``HubStatusLifetime`` calculates two
122 poll intervals plus 50 seconds. The publisher refreshes status at the
123 poll interval and after reconnect. It preserves diagnostic observation
124 time and stale flags. Consumers reject expired snapshots and check
125 source age before using a diagnostic value. Hub status is not core
126 house-state input.
127
128 **************
129 Verification
130 **************
131
132 Unit tests cover all topic and payload forms, delivery rules, invalid
133 fields and schemas, batch order and bounds, correlation, and expiry
134 metadata. These tests do not verify a broker, a physical device, MQTT
135 acknowledgement, reconnect behavior, publication suppression, or command
136 execution.