mirror of
https://github.com/esphome/esphome.git
synced 2025-03-14 06:38:17 +00:00
68 lines
1.9 KiB
Python
68 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
import binascii
|
|
import json
|
|
import os
|
|
import threading
|
|
|
|
from esphome import mqtt
|
|
|
|
from ..core import DASHBOARD
|
|
from ..entries import EntryState
|
|
|
|
|
|
class MqttStatusThread(threading.Thread):
|
|
"""Status thread to get the status of the devices via MQTT."""
|
|
|
|
def run(self) -> None:
|
|
"""Run the status thread."""
|
|
dashboard = DASHBOARD
|
|
entries = dashboard.entries
|
|
current_entries = entries.async_all()
|
|
|
|
config = mqtt.config_from_env()
|
|
topic = "esphome/discover/#"
|
|
|
|
def on_message(client, userdata, msg):
|
|
nonlocal current_entries
|
|
|
|
payload = msg.payload.decode(errors="backslashreplace")
|
|
if len(payload) > 0:
|
|
data = json.loads(payload)
|
|
if "name" not in data:
|
|
return
|
|
for entry in current_entries:
|
|
if entry.name == data["name"]:
|
|
entries.async_set_state(entry, EntryState.ONLINE)
|
|
return
|
|
|
|
def on_connect(client, userdata, flags, return_code):
|
|
client.publish("esphome/discover", None, retain=False)
|
|
|
|
mqttid = str(binascii.hexlify(os.urandom(6)).decode())
|
|
|
|
client = mqtt.prepare(
|
|
config,
|
|
[topic],
|
|
on_message,
|
|
on_connect,
|
|
None,
|
|
None,
|
|
f"esphome-dashboard-{mqttid}",
|
|
)
|
|
client.loop_start()
|
|
|
|
while not dashboard.stop_event.wait(2):
|
|
current_entries = entries.async_all()
|
|
# will be set to true on on_message
|
|
for entry in current_entries:
|
|
if entry.no_mdns:
|
|
entries.async_set_state(entry, EntryState.OFFLINE)
|
|
|
|
client.publish("esphome/discover", None, retain=False)
|
|
dashboard.mqtt_ping_request.wait()
|
|
dashboard.mqtt_ping_request.clear()
|
|
|
|
client.disconnect()
|
|
client.loop_stop()
|