HTTP OTA Updates via MQTT
This guide shows how to set up a workflow where the compiled firmware is uploaded to a webserver and an OTA update from this file is triggered using MQTT.
HTTP Server Setup
Section titled “HTTP Server Setup”We need a webserver that we can upload the firmware to and that can serve it to the ESPHome devices.
Here’s an example configuration for Caddy using the WebDAV module:
firmware.example.com { root * /var/www/firmware
@put method PUT handle @put { basicauth { uploader <hashed-upload-password> } webdav }
handle { basicauth { device <hashed-device-password> } file_server }}Replace <hashed-upload-password> and <hashed-device-password> with the output of caddy hash-password.
Publish Script
Section titled “Publish Script”We also need a script that uploads the compiled firmware. Since ESPHome installations have Python
available, we use a Python script. Create publish.py in the config directory:
import hashlibimport osimport paho.mqtt.publish as mqttimport requests
firmware_url = f"https://firmware.example.com/{os.environ['ESPHOME_DEVICE_NAME']}.bin"
firmware_data = open(os.environ["ESPHOME_FIRMWARE_BIN"], "rb").read()
upload_auth = ("uploader", "upload-password")requests.put(firmware_url, data=firmware_data, auth=upload_auth).raise_for_status()requests.put(firmware_url + ".md5", data=hashlib.md5(firmware_data).hexdigest(), auth=upload_auth).raise_for_status()
mqtt.single( topic=f"{os.environ['ESPHOME_MQTT_TOPIC_PREFIX']}/ota/url", payload=firmware_url, hostname=os.environ["ESPHOME_MQTT_BROKER"], port=int(os.environ["ESPHOME_MQTT_PORT"]), auth={ "username": os.environ["ESPHOME_MQTT_USERNAME"], "password": os.environ["ESPHOME_MQTT_PASSWORD"], },)ESPHome Configuration
Section titled “ESPHome Configuration”Now that we can publish the firmware file and the MQTT message, we just need to register the script and start the OTA process when the MQTT message arrives:
substitutions: node_name: mydevice
esphome: name: ${node_name} publish_shell_command: python3 publish.py
http_request: username: device password: !secret firmware_password
ota: - platform: http_request
mqtt: broker: 192.168.1.2 username: esphome password: !secret mqtt_password topic_prefix: esphome/${node_name} on_message: - topic: esphome/${node_name}/ota/url then: - ota.http_request.flash: url: !lambda 'return x;' md5_url: !lambda 'return x + ".md5";'Once configured, the Publish button appears in the ESPHome dashboard install dialog for any
device that has publish_shell_command set. Clicking it compiles the firmware and runs the
publish script automatically.
You can also trigger the same workflow from the command line:
esphome upload mydevice.yaml --device PUBLISH