Add support for mqtt birth message
This commit is contained in:
+14
-8
@@ -2,11 +2,17 @@ mqtt:
|
|||||||
host: 192.168.1.1
|
host: 192.168.1.1
|
||||||
username: user
|
username: user
|
||||||
password: password
|
password: password
|
||||||
workers:
|
|
||||||
thermostat:
|
manager:
|
||||||
args:
|
topic_subcription:
|
||||||
devices:
|
update_all:
|
||||||
bedroom: 00:11:22:33:44:55
|
topic: homeassistant/status
|
||||||
topic_prefix: thermostat
|
payload: online
|
||||||
topic_subscription: thermostat/+/+/set
|
workers:
|
||||||
update_interval: 60
|
thermostat:
|
||||||
|
args:
|
||||||
|
devices:
|
||||||
|
bedroom: 00:11:22:33:44:55
|
||||||
|
topic_prefix: thermostat
|
||||||
|
topic_subscription: thermostat/+/+/set
|
||||||
|
update_interval: 60
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ else:
|
|||||||
_LOGGER.debug('Starting')
|
_LOGGER.debug('Starting')
|
||||||
|
|
||||||
mqtt = MqttClient(settings['mqtt'])
|
mqtt = MqttClient(settings['mqtt'])
|
||||||
WorkersManager.start(mqtt, settings['workers'])
|
WorkersManager().register_workers(settings['manager']).start(mqtt)
|
||||||
|
|
||||||
running = True
|
running = True
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
import paho.mqtt.publish as publish
|
import paho.mqtt.publish as publish
|
||||||
import paho.mqtt.client as mqtt
|
import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
|
|
||||||
class MqttClient:
|
class MqttClient:
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self._config = config
|
self._config = config
|
||||||
|
|
||||||
def publish(self, messages):
|
def publish(self, messages):
|
||||||
|
if messages is None:
|
||||||
|
return
|
||||||
|
|
||||||
publish.multiple(list(map(lambda m: m.as_dict, messages)),
|
publish.multiple(list(map(lambda m: m.as_dict, messages)),
|
||||||
hostname=self.hostname,
|
hostname=self.hostname,
|
||||||
auth={'username': self.username, 'password': self.password})
|
auth={'username': self.username, 'password': self.password})
|
||||||
@@ -34,6 +38,7 @@ class MqttClient:
|
|||||||
|
|
||||||
mqttc.loop_start()
|
mqttc.loop_start()
|
||||||
|
|
||||||
|
|
||||||
class MqttMessage:
|
class MqttMessage:
|
||||||
def __init__(self, topic=None, payload=None):
|
def __init__(self, topic=None, payload=None):
|
||||||
self._topic = topic
|
self._topic = topic
|
||||||
@@ -59,7 +64,7 @@ class MqttMessage:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.as_dict.__str__()
|
return self.as_dict.__str__()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ class ThermostatWorker(BaseWorker):
|
|||||||
self._reverse_modes = {v: k for k, v in self._mapped_modes.items()}
|
self._reverse_modes = {v: k for k, v in self._mapped_modes.items()}
|
||||||
|
|
||||||
def get_mapping(self, mode):
|
def get_mapping(self, mode):
|
||||||
|
if mode < 0:
|
||||||
|
return None
|
||||||
return self._mapped_modes[mode]
|
return self._mapped_modes[mode]
|
||||||
|
|
||||||
def get_reverse_mapping(self, mode):
|
def get_reverse_mapping(self, mode):
|
||||||
@@ -67,6 +69,8 @@ class ThermostatWorker(BaseWorker):
|
|||||||
_, device_name, method, _ = topic.split('/')
|
_, device_name, method, _ = topic.split('/')
|
||||||
thermostat = self.devices[device_name]
|
thermostat = self.devices[device_name]
|
||||||
|
|
||||||
|
value = value.decode('utf-8')
|
||||||
|
|
||||||
if method == STATE_AWAY:
|
if method == STATE_AWAY:
|
||||||
method = "mode"
|
method = "mode"
|
||||||
value = ModesMapper.on_off_to_mode(value)
|
value = ModesMapper.on_off_to_mode(value)
|
||||||
|
|||||||
+49
-17
@@ -20,38 +20,70 @@ class WorkersManager:
|
|||||||
_LOGGER.debug(messages)
|
_LOGGER.debug(messages)
|
||||||
return messages
|
return messages
|
||||||
|
|
||||||
@classmethod
|
def __init__(self):
|
||||||
def start(cls, mqtt, config):
|
self._mqtt_callbacks = []
|
||||||
scheduler = BackgroundScheduler()
|
self._update_commands = []
|
||||||
mqtt_callbacks = []
|
self._scheduler = BackgroundScheduler()
|
||||||
|
|
||||||
for (worker_name, worker_config) in config.items():
|
def register_workers(self, config):
|
||||||
|
for (worker_name, worker_config) in config['workers'].items():
|
||||||
module_obj = importlib.import_module("workers.%s" % worker_name)
|
module_obj = importlib.import_module("workers.%s" % worker_name)
|
||||||
klass = getattr(module_obj, "%sWorker" % worker_name.title())
|
klass = getattr(module_obj, "%sWorker" % worker_name.title())
|
||||||
|
|
||||||
if module_obj.REQUIREMENTS is not None:
|
if module_obj.REQUIREMENTS is not None:
|
||||||
cls._pip_install_helper(module_obj.REQUIREMENTS)
|
self._pip_install_helper(module_obj.REQUIREMENTS)
|
||||||
|
|
||||||
worker_obj = klass(**worker_config['args'])
|
worker_obj = klass(**worker_config['args'])
|
||||||
|
|
||||||
if 'update_interval' in worker_config:
|
if hasattr(worker_obj, 'status_update'):
|
||||||
_LOGGER.debug("Added: %s with %d seconds interval" % (worker_name, worker_config['update_interval']))
|
_LOGGER.debug("Added: %s with %d seconds interval" % (worker_name, worker_config['update_interval']))
|
||||||
_WORKERS_QUEUE.put(cls.Command(worker_obj.status_update, []))
|
command = self.Command(worker_obj.status_update, [])
|
||||||
scheduler.add_job(
|
self._update_commands.append(command)
|
||||||
lambda x: _WORKERS_QUEUE.put(cls.Command(worker_obj.status_update, [])), 'interval',
|
|
||||||
seconds=worker_config['update_interval'],
|
if 'update_interval' in worker_config:
|
||||||
args=[worker_name]
|
self._scheduler.add_job(
|
||||||
)
|
lambda x: self._queue_command(command), 'interval',
|
||||||
|
seconds=worker_config['update_interval'],
|
||||||
|
args=[worker_name]
|
||||||
|
)
|
||||||
|
|
||||||
if 'topic_subscription' in worker_config:
|
if 'topic_subscription' in worker_config:
|
||||||
_LOGGER.debug("Subscribing to: %s" % worker_config['topic_subscription'])
|
_LOGGER.debug("Subscribing to: %s" % worker_config['topic_subscription'])
|
||||||
mqtt_callbacks.append((
|
self._mqtt_callbacks.append((
|
||||||
worker_config['topic_subscription'],
|
worker_config['topic_subscription'],
|
||||||
lambda client, _ , c: _WORKERS_QUEUE.put(cls.Command(worker_obj.on_command, [c.topic, c.payload]))
|
lambda client, _ , c: self._queue_command(self.Command(worker_obj.on_command, [c.topic, c.payload]))
|
||||||
))
|
))
|
||||||
|
|
||||||
scheduler.start()
|
for (callback_name, options) in config['topic_subcription'].items():
|
||||||
mqtt.callbacks_subscription(mqtt_callbacks)
|
_LOGGER.debug("Subscribing to: %s with command: %s" % (options['topic'], callback_name))
|
||||||
|
self._mqtt_callbacks.append((
|
||||||
|
options['topic'],
|
||||||
|
lambda client, _ , c: self._queue_if_matching_payload(self.Command(getattr(self, callback_name)), c.payload, options['payload']))
|
||||||
|
)
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
def start(self, mqtt):
|
||||||
|
self._scheduler.start()
|
||||||
|
mqtt.callbacks_subscription(self._mqtt_callbacks)
|
||||||
|
self.update_all()
|
||||||
|
|
||||||
|
def _queue_if_matching_payload(self, command, payload, expected_payload):
|
||||||
|
if payload.decode('utf-8') == expected_payload:
|
||||||
|
self._queue_command(command)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mqtt_callbacks(self):
|
||||||
|
return self._mqtt_callbacks
|
||||||
|
|
||||||
|
def update_all(self):
|
||||||
|
_LOGGER.debug("Updating all workers")
|
||||||
|
for command in self._update_commands:
|
||||||
|
self._queue_command(command)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _queue_command(command):
|
||||||
|
_WORKERS_QUEUE.put(command)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _pip_install_helper(package_names):
|
def _pip_install_helper(package_names):
|
||||||
|
|||||||
Reference in New Issue
Block a user