add relay_mqtt_http_proxy
This commit is contained in:
parent
a03ec71118
commit
1d508814ca
20
doc/relay_mqtt_http_proxy.md
Normal file
20
doc/relay_mqtt_http_proxy.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
## config example
|
||||||
|
|
||||||
|
```
|
||||||
|
[mqtt]
|
||||||
|
host = "mqtt.solarmon.ru"
|
||||||
|
port = 8883
|
||||||
|
|
||||||
|
client_id = "relay_mqtt_util"
|
||||||
|
username = ""
|
||||||
|
password = ""
|
||||||
|
|
||||||
|
[relay]
|
||||||
|
devices = ['id1', 'id2']
|
||||||
|
|
||||||
|
[server]
|
||||||
|
listen = "0.0.0.0:8821"
|
||||||
|
|
||||||
|
[logging]
|
||||||
|
verbose = false
|
||||||
|
```
|
@ -86,11 +86,13 @@ class MQTTRelay(MQTTBase):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._logger.exception(str(e))
|
self._logger.exception(str(e))
|
||||||
|
|
||||||
def set_power(self, device_id, enable: bool):
|
def set_power(self, device_id, enable: bool, secret=None):
|
||||||
device = next(d for d in self._devices if d.id == device_id)
|
device = next(d for d in self._devices if d.id == device_id)
|
||||||
assert device.secret is not None, 'device secret not specified'
|
secret = secret if secret else device.secret
|
||||||
|
|
||||||
payload = PowerPayload(secret=device.secret,
|
assert secret is not None, 'device secret not specified'
|
||||||
|
|
||||||
|
payload = PowerPayload(secret=secret,
|
||||||
state=enable)
|
state=enable)
|
||||||
self._client.publish(f'hk/{device.id}/relay/power',
|
self._client.publish(f'hk/{device.id}/relay/power',
|
||||||
payload=payload.pack(),
|
payload=payload.pack(),
|
||||||
|
68
src/relay_mqtt_http_proxy.py
Normal file
68
src/relay_mqtt_http_proxy.py
Normal file
@ -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()
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user