HA not accepting results from an MQTT topic?

So I’ve been trying to use a PIR sensor as an MQTT device, and now I’m using Python3 for that, with the following script being run in RPi’s Terminal:

#!/usr/bin/python

import RPi.GPIO as GPIO
import time
import paho.mqtt.publish as publish
GPIO.setmode(GPIO.BCM)
GPIO_PIR = 6

print "Home Security"

GPIO.setup(GPIO_PIR,GPIO.IN)      # Echo 
Current_State  = 0
Previous_State = 0
 
try:
  print "Detecting.."
  while GPIO.input(GPIO_PIR)==1:
    Current_State  = 0
 
  print "Safe"
  publish.single("ha/pir", "false", retain=True, hostname="(my IP address)")
  while True :
    Current_State = GPIO.input(GPIO_PIR)
 
    if Current_State==1 and Previous_State==0:
      print "Movement detected!"
      publish.single("ha/pir", "true", retain=True, hostname="(my IP address)")
      Previous_State=1
    elif Current_State==0 and Previous_State==1:
      print "Safe"
      publish.single("ha/pir", "false", retain=True, hostname="(my IP address)")
      Previous_State=0
 
    time.sleep(0.01)
 
except KeyboardInterrupt:
  GPIO.cleanup()

And for the configuration.yaml part, the script is the following:

mqtt:
  broker: (my IP address)
  port: 1883
  client_id: home-assistant-1
  username: "(my username)"
  password: "(my password)"

binary_sensor:
  - platform: mqtt
    state_topic: "ha/pir" 
    name: "Security"
    payload_on: "true"
    payload_off: "false"
    qos: 0
    device_class: motion

So there’re no fancy quotes in the scripts. The MQTT used is the Add-on from HA (Mosquitto broker), and at one point it did work, the Lovelace displaying the state of the MQTT PIR sensor, but now it won’t show the state of the sensor, including when I listen to the topic ha/pir in the MQTT Integration page. Where did it go wrong and what I should fix? Either way, the Python script in the Terminal worked perfectly, but the HA won’t receive its results.

Can you show what gets received in mqtt explorer ?

Sorry, I still don’t know how to use mqtt explorer (did try).

Even just going to the MQTT thing in Home Assistant and subscribing to the topic ha/pir will help.

Settings > Integrations > MQTT > Configure > “Listen to a topic”

Yeah, I tried that and didn’t get any response unlike the Python one (via Terminal), only the initial false one.

image

OK, so the first thing that jumps out at me, is that the python script does not seem to use authentication to publish the message to the MQTT server. So check if authentication is actually needed.

Home Assistant will show any and all data flowing on the topic, whether it understands it or not. The fact there is no data flowing on the topic, means it literally is not being published.

EDIT:
You will be able to verify this by opening a terminal on the Pi and sudo apt-get install mosquitto-clients and then running the command mosquitto_sub -h [broker_ip_address] -u [username] -P [password] -t \# that will show you everything flowing through every topic, if it’s very busy and you want to only see the ha/pir topic, change -t \# to -t ha/pir

OK, so far, it seems to be working when I put the Python script in the places that has the folder paho.mqtt.python (I didn’t previously), and when I separated the import part and the GPIO part and added importing paho.mqtt.client, so it’s like this currently:

import RPi.GPIO as GPIO
import time
import paho.mqtt.publish as publish
import paho.mqtt.client as mqtt

GPIO.setmode(GPIO.BCM)
GPIO_PIR = 6

But I’ll stop by again when it stopped working again (hopefully not, obviously).

Seems to be inconsistent, at time it works, at time it doesn’t, and at another time it works but not perfectly (like the indicator of MQTT device PIR will be turned on or off after 2 or 3 times the PIR changed state). What are the factors of the MQTT work here?

So far the solution I’ve found in further talk (credit: Andrew Jones) is to add the following to the Python script:

auth = { "username': '(my username)', 'password':'(my password)' }

And then (though it’s preferable to not use publish.single, as when the user connects to the MQTT server, it’ll send an update and then disconnects. But MQTT is designed for connect and stay connected) add auth=auth on the publish.single part:

publish.single("ha/pir", "false", retain=True, hostname="(my IP address)", auth=auth)