Connect a Python service to Home Assistant via MQTT
Create MQTT entities automatically
A Python script can publish measurements to a broker and describe the corresponding Home Assistant entity through MQTT Discovery. No additional sensor block is needed in configuration.yaml.
Prerequisites
- the Home Assistant MQTT integration
- a reachable broker, such as the Mosquitto add-on
- a dedicated broker account with suitable topic permissions
- a Python virtual environment on the LAN server
Port 1883 is normally unencrypted and should remain on a trusted LAN. Use TLS or a VPN across untrusted networks.
Install Paho MQTT
python3 -m venv /opt/lanserver/venv
/opt/lanserver/venv/bin/pip install paho-mqtt
Publish discovery and state
Home Assistant Core 2026.4 ignores the old MQTT object_id option. default_entity_id proposes an ID; unique_id lets Home Assistant manage the entity in its registry.
import json
import os
import paho.mqtt.client as mqtt
BROKER = "HOME-ASSISTANT-IP"
USER = os.environ["MQTT_USER"]
PASSWORD = os.environ["MQTT_PASSWORD"]
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.username_pw_set(USER, PASSWORD)
client.connect(BROKER, 1883, keepalive=60)
config_topic = "homeassistant/sensor/lanserver/temperature/config"
state_topic = "lanserver/sensor/temperature"
availability_topic = "lanserver/status"
config = {
"name": "Temperature",
"unique_id": "lanserver_temperature_01",
"default_entity_id": "sensor.lanserver_temperature",
"state_topic": state_topic,
"availability_topic": availability_topic,
"unit_of_measurement": "°C",
"device_class": "temperature",
"state_class": "measurement",
"value_template": "{{ value_json.temperature }}",
"device": {
"identifiers": ["lanserver_01"],
"name": "LAN server",
"manufacturer": "DIY"
}
}
client.loop_start()
client.publish(config_topic, json.dumps(config), qos=1, retain=True).wait_for_publish()
client.publish(availability_topic, "online", qos=1, retain=True).wait_for_publish()
client.publish(state_topic, json.dumps({"temperature": 42.5}), qos=1, retain=True).wait_for_publish()
client.disconnect()
client.loop_stop()
Credentials belong in a protected systemd environment file. Retained discovery survives a Home Assistant restart; retained state restores the last value but may be stale. Availability gives that old value context. A short timer job cannot truthfully claim that a permanent process remains online.
Schedule with systemd
# /etc/systemd/system/mqtt-sensor.service
[Unit]
Description=MQTT sensor update
[Service]
Type=oneshot
EnvironmentFile=/etc/lanserver/mqtt.env
ExecStart=/opt/lanserver/venv/bin/python /opt/lanserver/mqtt_sensor.py
# /etc/systemd/system/mqtt-sensor.timer
[Unit]
Description=Update MQTT sensor every five minutes
[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
Persistent=true
[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now mqtt-sensor.timer
Troubleshooting
Check both topics with an MQTT client, verify ACLs and exact topic spelling, inspect journalctl -u mqtt-sensor.service, and deliberately clear obsolete retained discovery messages with an empty retained payload.