48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
# tools/mqtt.py
|
|
|
|
import json
|
|
import socket
|
|
import logging
|
|
from typing import Any
|
|
|
|
from paho.mqtt.publish import single as mqtt_publish
|
|
|
|
from constants import MQTT_USERNAME, MQTT_PASSWORD, MQTT_FALLBACK_IP
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class MQTT:
|
|
def __init__(self):
|
|
self._username = MQTT_USERNAME
|
|
self._password = MQTT_PASSWORD
|
|
self.IP = self._resolve_ip()
|
|
|
|
def _resolve_ip(self) -> str:
|
|
"""Attempts to resolve the Home Assistant IP, falls back to static on failure/timeout."""
|
|
socket.setdefaulttimeout(2.0)
|
|
try:
|
|
return socket.gethostbyname("homeassistant.local")
|
|
except (socket.gaierror, socket.timeout, OSError) as e:
|
|
logger.warning(
|
|
f"Could not resolve homeassistant.local ({e}). Falling back to static IP."
|
|
)
|
|
return MQTT_FALLBACK_IP
|
|
finally:
|
|
socket.setdefaulttimeout(None)
|
|
|
|
def send(self, data: dict[str, Any], topic: str = "weather_station") -> None:
|
|
logger.debug("Sending MQTT payload to server...")
|
|
try:
|
|
mqtt_publish(
|
|
topic,
|
|
json.dumps(data),
|
|
retain=True,
|
|
hostname=self.IP,
|
|
keepalive=120,
|
|
client_id="weather-station",
|
|
auth={"password": self._password, "username": self._username},
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"MQTT data couldn't be sent: {e}")
|