Python code to publish MQTT message to mosquitto?

I have Home Assistant, running on a Raspberry Pi, Mosquitto is installed and running, working fine with Zigbee2MQTT. All are up-to-date latest versions.

I want to push a message from a raspberry Pi that has the ability to read a kWh usage for the house. Mosquitto is configured to auto configure messages starting with “homeassistant/”. When I run the code below, it definitely connects without error to the Mosquitto broker. And it has no error publishing these messages. But, the sensor is not automatically added to HomeAssistant. I belive that I am doing something wrong with the “/config” message. I believe it is that message that is responsible for adding the sensors to HomeAssistant?

#!/usr/bin/env python3
from struct import *
from datetime import datetime
import time
import subprocess
import paho.mqtt.client as mqtt

mqtt_username = "blah"
mqtt_password =  "blah"
mqtt_host = "blah"
mqtt_port = 1883

#******************************************
# Callback function when the client successfully connects to the MQTT broker
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))

    while True:
      item1 = 1000
      item2 = 2000
      
      # Publish config??
      config_payload = {
          "name": "Power Use General",
          "state_topic": "homeassistant/sensor/house/power_use1/state",
          "state_class": "measurement",
          "unit_of_measurement": "kWh",
          "device_class": "energy",
          "value_template": "{{ value }}",
          "unique_id": "power_use",
          "device": {
            "identifiers": [
               "thesensor"
            ],
            "name": "Power Use Sensors",
            "model": "None",
            "manufacturer": "None"
          },
          "icon": "mdi:home-lightning-bolt-outline",
          "platform": "mqtt"
      }
      client.publish(topic="homeassistant/sensor/house/power_use1/config", payload=str(config_payload), qos=2, retain=False)

      # Publish State1
      topic1 = "homeassistant/sensor/house/power_use1/state"
      client.publish(topic=topic1, payload=str(item1), qos=2, retain=False)

      # Publish State2
      topic2 = "homeassistant/sensor/house/power_use2/state"
      client.publish(topic=topic2, payload=str(item2), qos=2, retain=False)
      print("Published    '{0}' to '{1}'          Published '{2}' to '{3}'".format(str(item1), topic1, str(item2), topic2))

      time.sleep(6)
#******************************************

#-------------------------------------------------------------------------------------------------------
# main function
def main():
    client = mqtt.Client()
    client.username_pw_set(mqtt_username, mqtt_password)
    client.on_connect = on_connect
    client.connect(mqtt_host, mqtt_port)
    client.loop_forever()

#---------------------------------------------------------------------------------------------------------------------------------
if __name__=="__main__":
    main()
#---------------------------------------------------------------------------------------------------------------------------------

1 Like

It won’t be added unless you are using discovery MQTT - Home Assistant

Inside the configuration for Mosquitto, the “Enable Discovery” setting is on, and the discovery prefix is “homeassistant”. It has picked up a bunch of MQTT items from other providers. It is just my published messages that are being ignored, which indicates that I am not publishing something that Mosquitto needs, and I cannot figure out what that is.

I pointed you to the docs.

Just publishing something to homeassistant/ does not configure it.

I figured it out. Fairly simple really. I was setting qos to 2. I had not defined a method to handle the callback, so the messages were never successfully getting to Mosquitto. qos=2 requires my app to acknowledge comms from HA, which I was not doing. I just set the qos to 0, and Home Assistant auto configured the entities as expected.

1 Like

I think I was confused about about the fact (1) that I was on my phone and had problems reading your conf and (2) that you were posting state under homeassistant/, which I thought was not allowed, but seems on re-reading the docs is OK.

@megapint I am not sure whether the change of qos was the one which actually fixed your issue.

This did not work for me:

When converting the dict with str, then the double quotes are replaced by single quotes which is no valid JSON:

{'name': 'Power Use General', ...}

Valid JSON would be:

{"name": "Power Use General", ...}

Using json.dumps() to convert the dictionary config_payload solves the issue because it generates a valid JSON string.

payload=json.dumps(config_payload)
1 Like