MQTT entities showing correct data but erroring "This entity is unavailable"

I have a Pico W running a python script publishing sensor readings from a BME280 to MQTT. I am running both homeassistant and moquitto in docker containers on my raspberry pi.

I have confirmed that the MQTT connection is working and that data is being received, as when I go to settings > devices and services > MQTT > entities, the topics are displayed as follows:

This “entity is unavailable” error message is always showing. This is also causing (I think) neither of these ‘states’ to show up in the developer tools > states list, and when I add these entities to a dashboard, they only show the same error message (I cannot post another image as I am a new user).

I am at a complete loss as I have been troubleshooting this for countless hours to no avail…

My python file is as follows:

from machine import Pin, I2C
from time import sleep
import network
from umqtt.simple import MQTTClient
import config
import BME280
import json  # Import json to format the configuration messages

# Constants for MQTT Topics
MQTT_TOPIC_TEMPERATURE_CONFIG = 'homeassistant/sensor/pico_temperature/config'
MQTT_TOPIC_PRESSURE_CONFIG = 'homeassistant/sensor/pico_pressure/config'

# State topics for sensor readings
MQTT_TOPIC_TEMPERATURE_STATE = 'homeassistant/sensor/pico_temperature/state'
MQTT_TOPIC_PRESSURE_STATE = 'homeassistant/sensor/pico_pressure/state'

# MQTT Parameters
MQTT_SERVER = config.mqtt_server
MQTT_PORT = 1883  # Set to your MQTT port, usually 1883
MQTT_USER = config.mqtt_username
MQTT_PASSWORD = config.mqtt_password
MQTT_CLIENT_ID = b"raspberrypi_picow"
MQTT_KEEPALIVE = 100
MQTT_SSL = False   # set to False if using local Mosquitto MQTT broker

# Initialize I2C communication
i2c = I2C(id=1, scl=Pin(19), sda=Pin(18), freq=10000)

# Initialize BME280 sensor
bme = BME280.BME280(i2c=i2c, addr=0x76)

def get_sensor_readings():
    temp = float(bme.temperature[:-1])  # Get temperature and convert to float
    pres = float(bme.pressure[:-3])     # Get pressure and convert to float
    return temp, pres

def initialize_wifi(ssid, password):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    # Connect to the network
    wlan.connect(ssid, password)

    # Wait for Wi-Fi connection
    connection_timeout = 10
    while connection_timeout > 0:
        if wlan.status() >= 3:
            break
        connection_timeout -= 1
        print('Waiting for Wi-Fi connection...')
        sleep(1)

    # Check if connection is successful
    if wlan.status() != 3:
        return False
    else:
        print('Connection successful!')
        network_info = wlan.ifconfig()
        print('IP address:', network_info[0])
        return True

def connect_mqtt():
    try:
        client = MQTTClient(client_id=MQTT_CLIENT_ID,
                            server=MQTT_SERVER,
                            port=MQTT_PORT,
                            user=MQTT_USER,
                            password=MQTT_PASSWORD,
                            keepalive=MQTT_KEEPALIVE,
                            ssl=MQTT_SSL)
                            
        client.connect()
        return client
    except Exception as e:
        print('Error connecting to MQTT:', e)
        raise  # Re-raise the exception to see the full traceback

def publish_sensor_config(client):
    # Device information
    device_info = {
        "identifiers": ["pico_w_sensor"],
        "name": "Raspberry Pi Pico W",
        "manufacturer": "Raspberry Pi",
        "model": "Pico W"
    }

    # Configuration for temperature sensor
    temperature_config = {
        "name": "Pico Temperature",
        "state_topic": MQTT_TOPIC_TEMPERATURE_STATE,
        "unit_of_measurement": "°C",
        "device_class": "temperature",
        "unique_id": "pico_temperature_1",
        "device": device_info
    }
    client.publish(MQTT_TOPIC_TEMPERATURE_CONFIG, json.dumps(temperature_config).encode('utf-8'), retain=True)

    # Configuration for pressure sensor
    pressure_config = {
        "name": "Pico Pressure",
        "state_topic": MQTT_TOPIC_PRESSURE_STATE,
        "unit_of_measurement": "hPa",
        "device_class": "pressure",
        "unique_id": "pico_pressure_1",
        "device": device_info
    }
    client.publish(MQTT_TOPIC_PRESSURE_CONFIG, json.dumps(pressure_config).encode('utf-8'), retain=True)

def publish_sensor_readings(client, temperature, pressure):
    client.publish(MQTT_TOPIC_TEMPERATURE_STATE, str(temperature), retain=True)
    client.publish(MQTT_TOPIC_PRESSURE_STATE, str(pressure), retain=True)



try:
    if not initialize_wifi(config.wifi_ssid, config.wifi_password):
        print('Error connecting to the network... exiting program')
    else:
        client = connect_mqtt()
        if client:
            # Publish sensor configurations
            publish_sensor_config(client)
            while True:
                # Read sensor data
                temperature, pressure = get_sensor_readings()

                # Publish sensor readings
                publish_sensor_readings(client, temperature, pressure)

                # Delay 10 seconds
                sleep(10)
        else:
            print("Failed to connect to MQTT broker.")

except Exception as e:
    print('Error:', e)

My docker-compose.yaml file contains:

version: '3.0'

services:
  portainer:
    container_name: portainer
    image: portainer/portainer-ce
    restart: always
    ports:
      - "9000:9000/tcp"
    environment:
      - TZ=Europe/London
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /opt/portainer:/data
  homeassistant:
    container_name: homeassistant
    image: "ghcr.io/home-assistant/home-assistant:stable"
    volumes:
      - /opt/homeassistant/config:/config
      - /etc/localtime:/etc/localtime:ro
    restart: unless-stopped
    privileged: true
    network_mode: host
  mosquitto:
    image: eclipse-mosquitto
    container_name: mosquitto
    volumes:
      - /opt/mosquitto:/mosquitto
      - /opt/mosquitto/data:/mosquitto/data
      - /opt/mosquitto/log:/mosquitto/log
    ports:
      - 1883:1883
      - 9001:9001

My home assistant is using the discovery prefix homeassistant and configuration.yaml contains:


# Loads default set of integrations. Do not remove.
default_config:

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

mqtt:
  sensor:
    - name: "Pico Temperature"
      state_topic: "homeassistant/sensor/pico_temperature/state"
      value_template: "{{ value | float }}"
      unit_of_measurement: "°C"
      device_class: "temperature"
      state_class: "measurement"  # This indicates the sensor is a numeric value

    - name: "Pico Pressure"
      state_topic: "homeassistant/sensor/pico_pressure/state"
      value_template: "{{ value | float }}"
      unit_of_measurement: "hPa"
      device_class: "pressure"
      state_class: "measurement"  # Same as above


Any help would be greatly appreciated, please let me know if anymore information is required!

Your python program publishes MQTT Discovery configurations for both sensors AND you’re defining the two sensors manually in configuration.yaml. You do one or the other, not both.

Remove the MQTT configurations for the two sensors from configuration.yaml. Your python program’s use of MQTT Discovery should be able to do the job alone.

The two sensors will be sensor.pico_temperature and sensor.pico_humidity.

Hi,
Thank you so much for responding.
Strangely enough, it all just magically started working after a week straight of troubleshooting… Just my luck.
I’ll take your advice on board though! thanks again.

1 Like