Add shutter actions

This commit is contained in:
Nicolas Duhamel 2021-03-31 16:13:52 +02:00
parent 12f47d0e56
commit 1c0f931aa0

View File

@ -3,6 +3,7 @@ import threading
import queue import queue
import logging import logging
import concurrent.futures import concurrent.futures
from typing import Union, Callable
import pebble import pebble
@ -172,8 +173,9 @@ class WaitForTopic(threading.Thread, mqtt.Client):
def __init__(self, def __init__(self,
config: Configuration, config: Configuration,
topic: str, topic: str,
payload: str=None, payload: Union[str, Callable[[str],bool]],
logger: logging.Logger=None): logger: logging.Logger=None):
""" payload: str or function stop if payload is received or function return True, the function must have this signature func(payload: str) -> bool """
threading.Thread.__init__(self) threading.Thread.__init__(self)
mqtt.Client.__init__(self) mqtt.Client.__init__(self)
@ -181,7 +183,11 @@ class WaitForTopic(threading.Thread, mqtt.Client):
self.configuration = config self.configuration = config
self.topic = topic self.topic = topic
self.payload = payload
if callable(payload):
self.check_payload = payload
else:
self.check_payload = lambda x: x == payload
self.daemon = True self.daemon = True
@ -209,9 +215,10 @@ class WaitForTopic(threading.Thread, mqtt.Client):
self.logger.error('Invaliad topic: %s', topic) self.logger.error('Invaliad topic: %s', topic)
return return
if self.payload and payload != self.payload: if self.check_payload(payload):
return self.__run = False
def stop(self):
self.__run = False self.__run = False
def run(self): def run(self):
@ -275,23 +282,50 @@ class Publish(Action):
if self.check_response: if self.check_response:
checker.join(timeout=self.check_response['timeout']) checker.join(timeout=self.check_response['timeout'])
if checker.is_alive(): #timeout occur if checker.is_alive(): #timeout occur
checker.stop()
return self.failed() return self.failed()
return self.ok() return self.ok()
class Shutter(Action): class TasmotaShutter(Action):
TOPIC_FORMAT = "cmnd/tasmota/shutter/{shutter_name}/{action}"
TOPIC_CHECK_FORMAT = "stat/tasmota/shutter/{shutter_name}/SHUTTER1"
ACTION_OPEN = 'ShutterOpen'
ACTION_CLOSE = 'ShutterClose'
def __init__(self, shutter_name: str): def __init__(self, shutter_name: str):
Action.__init__(self) Action.__init__(self)
pass self.shutter_name = shutter_name
self.action = None
def Close(self): def Close(self):
self.action = self.ACTION_CLOSE
return self return self
def Open(self): def Open(self):
self.action = self.ACTION_OPEN
return self return self
def run(self): def run(self):
if self.action is None:
raise RuntimeError('No action specified')
topic = self.TOPIC_FORMAT.format(
shutter_name = self.shutter_name,
action = self.action
)
self.proxy.threaded_publish(topic, qos=1, retain=False)
checker = WaitForTopic(self.proxy.configuration,
self.TOPIC_CHECK_FORMAT.format(shutter_name = self.shutter_name),
payload= '100' if self.action == self.ACTION_OPEN else '0')
checker.join(timeout=30)
if checker.is_alive():
return self.failed()
return self.ok() return self.ok()
class Sleep(Scene): class Sleep(Scene):
@ -300,6 +334,10 @@ class Sleep(Scene):
Publish('cmnd/tasmota/screen/Screen/POWER').Payload('OFF').Qos(2)\ Publish('cmnd/tasmota/screen/Screen/POWER').Payload('OFF').Qos(2)\
.CheckResponse('stat/tasmota/screen/Screen/POWER', 'OFF', 3), .CheckResponse('stat/tasmota/screen/Screen/POWER', 'OFF', 3),
Publish('cmnd/tasmota/light/LivingroomFireplace/POWER').Payload('OFF').Qos(2), Publish('cmnd/tasmota/light/LivingroomFireplace/POWER').Payload('OFF').Qos(2),
TasmotaShutter('Bedroom1x1').Close(),
TasmotaShutter('Bedroom1x2').Close(),
TasmotaShutter('Staircase1').Close(),
TasmotaShutter('Bathroom').Close(),
] ]
WATCH = [ WATCH = [