Files
switchbot-mqtt/mqtt.py
Georgi Gardev 59adecf024 Initial commit
2023-11-17 11:19:22 +02:00

83 lines
2.5 KiB
Python

# Based on
# https://github.com/martijnversluis/switchbot2mqtt/
import json
import logging
import random
import time
import json
from paho.mqtt import client as mqtt_client
from switchbot import trigger_device
FIRST_RECONNECT_DELAY = 1
RECONNECT_RATE = 2
MAX_RECONNECT_COUNT = 12
MAX_RECONNECT_DELAY = 60
class Config:
def __init__(self, **config):
self.broker = config.get("broker")
self.port = config.get("port", None)
self.topic_prefix = config.get("topic_prefix")
self.client_id = config.get("client_id", f'switchbot2mqtt-{random.randint(0, 1000)}')
self.username = config.get("username", None)
self.password = config.get("password", None)
class MqttListener:
def __init__(self, **config):
self.running = True
self.config = Config(**config)
def run(self):
logging.info("Connecting...")
self.connect()
logging.info("Connected! Starting...")
self.client.loop_forever()
def connect(self):
self.client = mqtt_client.Client(self.config.client_id)
self.client.username_pw_set(self.config.username, self.config.password)
self.client.on_connect = self.on_connect
self.client.on_disconnect = self.on_disconnect
self.client.connect(self.config.broker, self.config.port)
def on_connect(self, client, userdata, flags, rc):
if rc == 0 and client.is_connected():
logging.info("Connected to MQTT Broker!")
client.subscribe(f'{self.config.topic_prefix}/#')
client.on_message = self.on_message
else:
logging.error(f'Failed to connect, return code {rc}')
def on_disconnect(self, client, userdata, rc):
logging.info("Disconnected with result code: %s", rc)
reconnect_count = 0
reconnect_delay = FIRST_RECONNECT_DELAY
while reconnect_count < MAX_RECONNECT_COUNT:
logging.info("Reconnecting in %d seconds...", reconnect_delay)
time.sleep(reconnect_delay)
try:
client.reconnect()
logging.info("Reconnected successfully!")
return
except Exception as err:
logging.error("%s. Reconnect failed. Retrying...", err)
reconnect_delay *= RECONNECT_RATE
reconnect_delay = min(reconnect_delay, MAX_RECONNECT_DELAY)
reconnect_count += 1
logging.info("Reconnect failed after %s attempts. Exiting...", reconnect_count)
self.running = False
def on_message(self, client, userdata, msg):
logging.debug(f"Received from `{msg.topic}` topic")
mac_address = msg.topic[(len(self.config.topic_prefix)+1):]
logging.info(f"Execute for {mac_address}")
trigger_device(mac_address, "Bot", "Press")