summaryrefslogtreecommitdiff
path: root/src/relay_mqtt_http_proxy.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/relay_mqtt_http_proxy.py')
-rw-r--r--src/relay_mqtt_http_proxy.py68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/relay_mqtt_http_proxy.py b/src/relay_mqtt_http_proxy.py
new file mode 100644
index 0000000..ab8a138
--- /dev/null
+++ b/src/relay_mqtt_http_proxy.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+from home import http
+from home.config import config
+from home.mqtt import MQTTRelay, MQTTRelayDevice, MQTTRelayState
+from home.mqtt.payload import MQTTPayload
+from home.mqtt.payload.relay import InitialStatPayload, StatPayload
+from typing import Optional
+from home.util import parse_addr
+
+mqtt_relay: Optional[MQTTRelay] = None
+relay_states: dict[str, MQTTRelayState] = {}
+
+
+def on_mqtt_message(device_id, message: MQTTPayload):
+ if isinstance(message, InitialStatPayload) or isinstance(message, StatPayload):
+ kwargs = dict(rssi=message.rssi, enabled=message.flags.state)
+ if device_id not in relay_states:
+ relay_states[device_id] = MQTTRelayState()
+ relay_states[device_id].update(**kwargs)
+
+
+class RelayMqttHttpProxy(http.HTTPServer):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.get('/relay/{id}/on', self.relay_on)
+ self.get('/relay/{id}/off', self.relay_off)
+ self.get('/relay/{id}/toggle', self.relay_toggle)
+
+ async def _relay_on_off(self,
+ enable: Optional[bool],
+ req: http.Request):
+ device_id = req.match_info['id']
+ device_secret = req.query['secret']
+
+ if enable is None:
+ if device_id in relay_states and relay_states[device_id].ever_updated:
+ cur_state = relay_states[device_id].enabled
+ else:
+ cur_state = False
+ enable = not cur_state
+
+ mqtt_relay.set_power(device_id, enable, device_secret)
+ return self.ok()
+
+ async def relay_on(self, req: http.Request):
+ return await self._relay_on_off(True, req)
+
+ async def relay_off(self, req: http.Request):
+ return await self._relay_on_off(False, req)
+
+ async def relay_toggle(self, req: http.Request):
+ return await self._relay_on_off(None, req)
+
+
+if __name__ == '__main__':
+ config.load('relay_mqtt_http_proxy')
+
+ mqtt_relay = MQTTRelay(devices=[MQTTRelayDevice(id=device_id) for device_id in config.get('relay.devices')])
+ mqtt_relay.configure_tls()
+ mqtt_relay.set_message_callback(on_mqtt_message)
+ mqtt_relay.connect_and_loop(loop_forever=False)
+
+ proxy = RelayMqttHttpProxy(parse_addr(config.get('server.listen')))
+ try:
+ proxy.run()
+ except KeyboardInterrupt:
+ mqtt_relay.disconnect()
+