MQTT Topics¶
gas2mqtt publishes device state, health information, and errors to a set of MQTT topics
under the gas2mqtt/ prefix. One topic accepts inbound commands.
Topic Overview¶
| Topic | Dir | Payload | Retain | QoS |
|---|---|---|---|---|
gas2mqtt/gas_counter/state |
outbound | Gas counter JSON | yes | 1 |
gas2mqtt/gas_counter/set |
inbound | Set consumption JSON | — | — |
gas2mqtt/gas_counter/availability |
outbound | "online" / "offline" |
yes | 1 |
gas2mqtt/temperature/state |
outbound | Temperature JSON | yes | 1 |
gas2mqtt/temperature/availability |
outbound | "online" / "offline" |
yes | 1 |
gas2mqtt/magnetometer/state ¹ |
outbound | Raw magnetometer JSON | yes | 1 |
gas2mqtt/magnetometer/availability ¹ |
outbound | "online" / "offline" |
yes | 1 |
gas2mqtt/status |
outbound | Heartbeat JSON + LWT "offline" |
yes | 1 |
gas2mqtt/error |
outbound | Error JSON | no | 1 |
¹ Only active when GAS2MQTT_ENABLE_DEBUG_DEVICE=true.
Payload Schemas¶
Gas Counter¶
Topic: gas2mqtt/gas_counter/state
Published on every trigger event (not every poll). Includes the optional
consumption_m3 field when consumption tracking is enabled.
| Field | Type | Description |
|---|---|---|
counter |
integer | Cumulative tick count (wraps at 65536) |
trigger |
string | "OPEN" or "CLOSED" — current trigger state |
consumption_m3 |
float | Cumulative gas in m³ (optional) |
Temperature¶
Topic: gas2mqtt/temperature/state
Polled at the configured temperature_interval (default: every 5 minutes) but only
published when the PT1-filtered value changes by more than 0.05 °C (cosalette
OnChange publish strategy). This suppresses duplicate readings when the temperature is
stable.
| Field | Type | Description |
|---|---|---|
temperature |
float | PT1-filtered temperature in °C |
Magnetometer (Debug)¶
Topic: gas2mqtt/magnetometer/state
Only published when GAS2MQTT_ENABLE_DEBUG_DEVICE=true. Published at poll_interval.
| Field | Type | Description |
|---|---|---|
bx |
integer | Magnetic field strength, X axis |
by |
integer | Magnetic field strength, Y axis |
bz |
integer | Magnetic field strength, Z axis |
Availability¶
Topics: gas2mqtt/{device}/availability
Each device publishes its availability status. The cosalette framework manages these automatically.
Status (Heartbeat)¶
Topic: gas2mqtt/status
Periodic heartbeat published by the cosalette health reporter. Also used as the Last
Will and Testament (LWT) — the broker publishes "offline" if gas2mqtt disconnects
unexpectedly.
{
"status": "online",
"uptime": 3600.0,
"version": "1.0.0",
"devices": {
"gas_counter": { "status": "online" },
"temperature": { "status": "online" },
"magnetometer": { "status": "online" }
}
}
Error¶
Topic: gas2mqtt/error
Published (not retained) when a device encounters an error. The cosalette framework deduplicates consecutive identical errors.
{
"type": "OSError",
"message": "I2C bus read failed",
"device": "gas_counter",
"timestamp": 1700000000.0
}
!!! info "Per-device error topics" In addition to the global error topic, cosalette
publishes device-specific errors to gas2mqtt/{device}/error (e.g.,
gas2mqtt/gas_counter/error). These have the same payload format.
Inbound Commands¶
Set Consumption¶
Topic: gas2mqtt/gas_counter/set
Set the cumulative consumption counter to an absolute value. Requires
GAS2MQTT_ENABLE_CONSUMPTION_TRACKING=true.
After receiving a valid command, gas2mqtt publishes an updated state to
gas2mqtt/gas_counter/state.
!!! warning "Consumption tracking must be enabled" Commands sent when
enable_consumption_tracking is false are logged as warnings and ignored.
Framework Topics¶
Alongside the gas2mqtt-specific topics above, cosalette itself publishes two framework-owned topics. Both are always on — no setting disables them — retained, QoS 1, and republished byte-identically on every broker connect.
| Topic | Payload | Retain | QoS |
|---|---|---|---|
gas2mqtt/_meta/registry |
Canonical AsyncAPI 3.0.0 document | yes | 1 |
gas2mqtt/_meta/state_model_drift |
state_model drift snapshot JSON |
yes | 1 |
Registry (gas2mqtt/_meta/registry)¶
The canonical AsyncAPI document describing every channel gas2mqtt publishes and subscribes to. Inbound command channels are stripped from the published copy so the command surface is not exposed to anyone who can subscribe on a shared broker.
State Model Drift (gas2mqtt/_meta/state_model_drift)¶
A machine-readable snapshot of state_model declaration drift (ADR-069): a handler
whose state_model= argument disagrees with its return type annotation. The topic is
published even when there is no drift — a clean app publishes drift_count: 0 rather
than omitting the topic, so "no drift" is distinguishable from "never ran a version
that publishes this topic".
| Field | Type | Description |
|---|---|---|
schema_version |
integer | Envelope version; bumped only on an incompatible payload change |
drift_count |
integer | Number of handlers with a declaration/annotation conflict |
entries[].handler |
string | Registered handler name |
entries[].archetype |
string | "telemetry" or "command" |
entries[].kind |
string | Drift kind — currently only "annotation_conflict" |
entries[].declared_model |
string | The state_model= class name declared on the handler |
entries[].effective_annotation |
string | The handler's actual return type annotation |
Fleet-wide scraping
One subscription across a whole broker distinguishes a healthy app from one that predates this topic:
An app publishing drift_count: 0 is healthy. An app with no retained message
on this topic at all has not been upgraded past cosalette 0.9.0.
ACL guidance¶
Both topics disclose handler names, channel addresses, and payload schemas. If you
run a production broker ACL file, protect _meta/# the same way you protect
_meta/registry. Every mosquitto.conf shipped in this repo is
dev-only (allow_anonymous true, no ACL file), so there is nothing to change
in-repo — this note only applies if you deploy your own broker ACLs.
Topic Naming Convention¶
gas2mqtt follows the cosalette topic convention:
| Segment | Value |
|---|---|
prefix |
App name — gas2mqtt by default |
device |
Device name: gas_counter, temperature, magnetometer |
channel |
state, set, availability, or error |
Global topics (status, error) omit the device segment: