Skip to content

MQTT integration

John edited this page Jun 3, 2023 · 5 revisions

MQTT integration

In order to support discovery features of MQTT tools such as Home Assistant, an MQTT integration configuration can be activated with the --mqttint option.

Such a configuration file allows flexible construction of MQTT topics and payloads depending on message and field definitions as well as global status topics.

ebusd uses it as instructions of how to announce the syntax of its global topic and all message related topics it sends. This way, another backend or a user interface can pick up what is going to be expected as available topics together with their semantics.

Currently, the following integration configurations are distributed with ebusd:

In order to use the Home Assistant MQTT Discovery integration, ebusd needs to be run with the following additional arguments (replace <BROKERHOST> with the host name of the broker):

ebusd ... \
  --mqtthost <BROKERHOST> --mqttport 1883 \
  --mqttint=/etc/ebusd/mqtt-hassio.cfg \
  --mqttjson

This configuration uses the default topic prefix ebusd for publishing the data and homeassistant for publishing to the HA discovery.

On HA, ebusd itself as well as each circuit detected will appear as device in the Heating area. This can be changed directly in the integration file /etc/ebusd/mqtt-hassio.cfg) or by passing another argument to ebusd like this--mqttvar="area=My Area".

All automatically sent messages (due to e.g. controllers on the bus) as well as all messages with a poll priority will feed data to HA.

When appending |^w to the filter-direction in the integration file, some writable number entities will also be sent to HA. This is not enabled by default, as the values are really changed at once when playing around with them in the HA UI, so use with care.

When using HA supervisor, this ebusd HA Addon might ease the setup.

Unfortunately, IoT hub does not support dynamic, message-based configuration of devices. Instead, it only accepts a single definition per device. Therefore, the MQTT integration feature of ebusd cannot be used, but some documentation is kept here.

In order to send MQTT data to IoT hub, ebusd needs to be run with the following additional arguments:

ebusd ... \
  --mqtthost <HUBNAME>.azure-devices.net --mqttport 8883 \
  --mqttclientid <DEVICENAME> \
  --mqttuser '<HUBNAME>.azure-devices.net/<DEVICENAME>/?api-version=2018-06-30' \
  --mqttpass 'SharedAccessSignature sr=<HUBNAME>.azure-devices.net%2Fdevices%2F<DEVICENAME>&sig=<SIG>&se=<SE>' \
  --mqtttopic 'devices/<DEVICENAME>/messages/events/circuit=%circuit&name=%name&$.ct=application%%2Fjson' \
  --mqttglobal 'devices/<DEVICENAME>/messages/events/circuit=global&$.ct=application%%2Fjson' \
  --mqttversion 3.1.1 \
  --mqttca ./IoTHubRootCA_Baltimore.pem \
  --mqttjson

The following have to be replaced with actual values:

  • <HUBNAME> with the name of the hub
  • <DEVICENAME> with the name of the device created on the hub before (e.g. ebusd)
  • <SIG> and <SE> with the actual secrets from the generated SAS token (better replace the whole string instead of only the parts). See here how to get that token.
  • the certificate file needs to be available locally, it can be downloaded here:
    IoTHubRootCA_Baltimore.pem

Some more info can be found here: Using MQTT with Azure IoTHub without SDK

With this setup and using "ebusd" instead of <DEVICENAME>, the status of ebusd ("global" topic) would arrive at the hub like this:

{
  "event": {
    "origin": "ebusd",
    ...
    "properties": {
      ...
      "application": {
        "circuit": "global"
      }
    },
    "payload": true
  }
}

and data for the circuit "broadcast" and message "datetime" would arrive at the hub like this:

{
  "event": {
    "origin": "ebusd",
    ...
    "properties": {
      ...
      "application": {
        "circuit": "broadcast",
        "name": "datetime"
      }
    },
    "payload": {
      "outsidetemp": {"value": 5.125},
      "time": {"value": "14:22:02"},
      "date": {"value": "05.02.2022"}      
    }
  }
}

By using the circuit=%circuit&name=%name part of the "property bag" in the topic, these values get assigned to the message on the hub in the event.properties.application.circuit and event.properties.application.name JSON paths and this can be used for further message routing in Azure.

Alternatively, ebusd supports moving the circuit and message name to the payload by removing "%name" from the topic, i.e. use --mqtttopic 'devices/<DEVICENAME>/messages/events/$.ct=application%%2Fjson#' instead (note the final # as hint for ebusd to not append defaults). The data of the example above is then reformatted to this (note the missing event.properties.application part):

{
  "event": {
    "origin": "ebusd",
    ...
    "properties": {
      ...
    },
    "payload": {
      "circuit": "broadcast",
      "name": "datetime",
      "fields": {
        "outsidetemp": {"value": 5.125},
        "time": {"value": "14:22:02"},
        "date": {"value": "05.02.2022"}
      }
    }
  }
}