summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/esp_mqtt_util.py42
-rw-r--r--src/home/mqtt/__init__.py5
-rw-r--r--src/home/mqtt/esp.py106
-rw-r--r--src/home/mqtt/mqtt.py2
-rw-r--r--src/home/mqtt/payload/__init__.py2
-rw-r--r--src/home/mqtt/payload/base_payload.py28
-rw-r--r--src/home/mqtt/payload/esp.py78
-rw-r--r--src/home/mqtt/payload/inverter.py6
-rw-r--r--src/home/mqtt/payload/relay.py90
-rw-r--r--src/home/mqtt/payload/sensors.py4
-rw-r--r--src/home/mqtt/payload/temphum.py14
-rw-r--r--src/home/mqtt/relay.py107
-rw-r--r--src/home/mqtt/temphum.py33
-rwxr-xr-xsrc/inverter_mqtt_receiver.py7
-rwxr-xr-xsrc/inverter_mqtt_sender.py6
-rwxr-xr-xsrc/polaris_kettle_bot.py6
-rwxr-xr-xsrc/polaris_kettle_util.py6
-rwxr-xr-xsrc/pump_mqtt_bot.py22
-rwxr-xr-xsrc/relay_mqtt_bot.py26
-rwxr-xr-xsrc/relay_mqtt_http_proxy.py19
-rwxr-xr-xsrc/relay_mqtt_util.py45
-rwxr-xr-xsrc/sensors_mqtt_receiver.py6
-rwxr-xr-xsrc/sensors_mqtt_sender.py6
-rwxr-xr-x[-rw-r--r--]src/temphum.py1
24 files changed, 387 insertions, 280 deletions
diff --git a/src/esp_mqtt_util.py b/src/esp_mqtt_util.py
new file mode 100755
index 0000000..263128c
--- /dev/null
+++ b/src/esp_mqtt_util.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python3
+from typing import Optional
+from argparse import ArgumentParser
+from enum import Enum
+
+from home.config import config
+from home.mqtt import MqttRelay
+from home.mqtt.esp import MqttEspBase
+from home.mqtt.temphum import MqttTempHum
+from home.mqtt.esp import MqttEspDevice
+
+mqtt_client: Optional[MqttEspBase] = None
+
+
+class NodeType(Enum):
+ RELAY = 'relay'
+ TEMPHUM = 'temphum'
+
+
+if __name__ == '__main__':
+ parser = ArgumentParser()
+ parser.add_argument('--device-id', type=str, required=True)
+ parser.add_argument('--type', type=str, required=True,
+ choices=[i.name.lower() for i in NodeType])
+
+ config.load('mqtt_util', parser=parser)
+ arg = parser.parse_args()
+
+ mqtt_node_type = NodeType(arg.type)
+ devices = MqttEspDevice(id=arg.device_id)
+
+ if mqtt_node_type == NodeType.RELAY:
+ mqtt_client = MqttRelay(devices=devices)
+ elif mqtt_node_type == NodeType.TEMPHUM:
+ mqtt_client = MqttTempHum(devices=devices)
+
+ mqtt_client.set_message_callback(lambda device_id, payload: print(payload))
+ mqtt_client.configure_tls()
+ try:
+ mqtt_client.connect_and_loop()
+ except KeyboardInterrupt:
+ mqtt_client.disconnect()
diff --git a/src/home/mqtt/__init__.py b/src/home/mqtt/__init__.py
index c9a6c6e..982e2b6 100644
--- a/src/home/mqtt/__init__.py
+++ b/src/home/mqtt/__init__.py
@@ -1,3 +1,4 @@
-from .mqtt import MQTTBase
+from .mqtt import MqttBase
from .util import poll_tick
-from .relay import MQTTRelay, MQTTRelayState, MQTTRelayDevice \ No newline at end of file
+from .relay import MqttRelay, MqttRelayState
+from .temphum import MqttTempHum \ No newline at end of file
diff --git a/src/home/mqtt/esp.py b/src/home/mqtt/esp.py
new file mode 100644
index 0000000..56ced83
--- /dev/null
+++ b/src/home/mqtt/esp.py
@@ -0,0 +1,106 @@
+import re
+import paho.mqtt.client as mqtt
+
+from .mqtt import MqttBase
+from typing import Optional, Union
+from .payload.esp import (
+ OTAPayload,
+ OTAResultPayload,
+ DiagnosticsPayload,
+ InitialDiagnosticsPayload
+)
+
+
+class MqttEspDevice:
+ id: str
+ secret: Optional[str]
+
+ def __init__(self, id: str, secret: Optional[str] = None):
+ self.id = id
+ self.secret = secret
+
+
+class MqttEspBase(MqttBase):
+ _devices: list[MqttEspDevice]
+ _message_callback: Optional[callable]
+ _ota_publish_callback: Optional[callable]
+
+ TOPIC_LEAF = 'esp'
+
+ def __init__(self,
+ devices: Union[MqttEspDevice, list[MqttEspDevice]],
+ subscribe_to_updates=True):
+ super().__init__(clean_session=True)
+ if not isinstance(devices, list):
+ devices = [devices]
+ self._devices = devices
+ self._message_callback = None
+ self._ota_publish_callback = None
+ self._subscribe_to_updates = subscribe_to_updates
+ self._ota_mid = None
+
+ def on_connect(self, client: mqtt.Client, userdata, flags, rc):
+ super().on_connect(client, userdata, flags, rc)
+
+ if self._subscribe_to_updates:
+ for device in self._devices:
+ topic = f'hk/{device.id}/{self.TOPIC_LEAF}/#'
+ self._logger.debug(f"subscribing to {topic}")
+ client.subscribe(topic, qos=1)
+
+ def on_publish(self, client: mqtt.Client, userdata, mid):
+ if self._ota_mid is not None and mid == self._ota_mid and self._ota_publish_callback:
+ self._ota_publish_callback()
+
+ def set_message_callback(self, callback: callable):
+ self._message_callback = callback
+
+ def on_message(self, client: mqtt.Client, userdata, msg):
+ try:
+ match = re.match(self.get_mqtt_topics(), msg.topic)
+ self._logger.debug(f'topic: {msg.topic}')
+ if not match:
+ return
+
+ device_id = match.group(1)
+ subtopic = match.group(2)
+
+ # try:
+ next(d for d in self._devices if d.id == device_id)
+ # except StopIteration:h
+ # return
+
+ message = None
+ if subtopic == 'stat':
+ message = DiagnosticsPayload.unpack(msg.payload)
+ elif subtopic == 'stat1':
+ message = InitialDiagnosticsPayload.unpack(msg.payload)
+ elif subtopic == 'otares':
+ message = OTAResultPayload.unpack(msg.payload)
+
+ if message and self._message_callback:
+ self._message_callback(device_id, message)
+ return True
+
+ except Exception as e:
+ self._logger.exception(str(e))
+
+ def push_ota(self,
+ device_id,
+ filename: str,
+ publish_callback: callable,
+ qos: int):
+ device = next(d for d in self._devices if d.id == device_id)
+ assert device.secret is not None, 'device secret not specified'
+
+ self._ota_publish_callback = publish_callback
+ payload = OTAPayload(secret=device.secret, filename=filename)
+ publish_result = self._client.publish(f'hk/{device.id}/{self.TOPIC_LEAF}/admin/ota',
+ payload=payload.pack(),
+ qos=qos)
+ self._ota_mid = publish_result.mid
+ self._client.loop_write()
+
+ @classmethod
+ def get_mqtt_topics(cls, additional_topics: Optional[list[str]] = None):
+ return rf'^hk/(.*?)/{cls.TOPIC_LEAF}/(stat|stat1|otares'+('|'+('|'.join(additional_topics)) if additional_topics else '')+')$' \ No newline at end of file
diff --git a/src/home/mqtt/mqtt.py b/src/home/mqtt/mqtt.py
index 9dd973b..4acd4f6 100644
--- a/src/home/mqtt/mqtt.py
+++ b/src/home/mqtt/mqtt.py
@@ -13,7 +13,7 @@ def username_and_password() -> Tuple[str, str]:
return username, password
-class MQTTBase:
+class MqttBase:
def __init__(self, clean_session=True):
self._client = mqtt.Client(client_id=config['mqtt']['client_id'],
protocol=mqtt.MQTTv311,
diff --git a/src/home/mqtt/payload/__init__.py b/src/home/mqtt/payload/__init__.py
index 9fcaf3e..eee6709 100644
--- a/src/home/mqtt/payload/__init__.py
+++ b/src/home/mqtt/payload/__init__.py
@@ -1 +1 @@
-from .base_payload import MQTTPayload \ No newline at end of file
+from .base_payload import MqttPayload \ No newline at end of file
diff --git a/src/home/mqtt/payload/base_payload.py b/src/home/mqtt/payload/base_payload.py
index 108e0c0..1abd898 100644
--- a/src/home/mqtt/payload/base_payload.py
+++ b/src/home/mqtt/payload/base_payload.py
@@ -5,7 +5,21 @@ import re
from typing import Optional, Tuple
-class MQTTPayload(abc.ABC):
+def pldstr(self) -> str:
+ attrs = []
+ for field in self.__class__.__annotations__:
+ if hasattr(self, field):
+ attr = getattr(self, field)
+ attrs.append(f'{field}={attr}')
+ if attrs:
+ attrs_s = ' '
+ attrs_s += ', '.join(attrs)
+ else:
+ attrs_s = ''
+ return f'<%s{attrs_s}>' % (self.__class__.__name__,)
+
+
+class MqttPayload(abc.ABC):
FORMAT = ''
PACKER = {}
UNPACKER = {}
@@ -70,7 +84,7 @@ class MQTTPayload(abc.ABC):
bf_number = -1
i += 1
- if issubclass(field_type, MQTTPayloadCustomField):
+ if issubclass(field_type, MqttPayloadCustomField):
kwargs[field] = field_type.unpack(data[i])
else:
kwargs[field] = cls._unpack_field(field, data[i])
@@ -87,15 +101,18 @@ class MQTTPayload(abc.ABC):
@classmethod
def _unpack_field(cls, name, val):
- if isinstance(val, MQTTPayloadCustomField):
+ if isinstance(val, MqttPayloadCustomField):
return
if cls.UNPACKER and name in cls.UNPACKER:
return cls.UNPACKER[name](val)
else:
return val
+ def __str__(self):
+ return pldstr(self)
-class MQTTPayloadCustomField(abc.ABC):
+
+class MqttPayloadCustomField(abc.ABC):
def __init__(self, **kwargs):
for field in self.__class__.__annotations__:
setattr(self, field, kwargs[field])
@@ -109,6 +126,9 @@ class MQTTPayloadCustomField(abc.ABC):
def unpack(cls, *args, **kwargs):
pass
+ def __str__(self):
+ return pldstr(self)
+
def bit_field(seq_no: int, total_bits: int, bits: int):
return type(f'MQTTPayloadBitField_{seq_no}_{total_bits}_{bits}', (object,), {
diff --git a/src/home/mqtt/payload/esp.py b/src/home/mqtt/payload/esp.py
new file mode 100644
index 0000000..171cdb9
--- /dev/null
+++ b/src/home/mqtt/payload/esp.py
@@ -0,0 +1,78 @@
+import hashlib
+
+from .base_payload import MqttPayload, MqttPayloadCustomField
+
+
+class OTAResultPayload(MqttPayload):
+ FORMAT = '=BB'
+ result: int
+ error_code: int
+
+
+class OTAPayload(MqttPayload):
+ secret: str
+ filename: str
+
+ # structure of returned data:
+ #
+ # uint8_t[len(secret)] secret;
+ # uint8_t[16] md5;
+ # *uint8_t data
+
+ def pack(self):
+ buf = bytearray(self.secret.encode())
+ m = hashlib.md5()
+ with open(self.filename, 'rb') as fd:
+ content = fd.read()
+ m.update(content)
+ buf.extend(m.digest())
+ buf.extend(content)
+ return buf
+
+ def unpack(cls, buf: bytes):
+ raise RuntimeError(f'{cls.__class__.__name__}.unpack: not implemented')
+ # secret = buf[:12].decode()
+ # filename = buf[12:].decode()
+ # return OTAPayload(secret=secret, filename=filename)
+
+
+class DiagnosticsFlags(MqttPayloadCustomField):
+ state: bool
+ config_changed_value_present: bool
+ config_changed: bool
+
+ @staticmethod
+ def unpack(flags: int):
+ # _logger.debug(f'StatFlags.unpack: flags={flags}')
+ state = flags & 0x1
+ ccvp = (flags >> 1) & 0x1
+ cc = (flags >> 2) & 0x1
+ # _logger.debug(f'StatFlags.unpack: state={state}')
+ return DiagnosticsFlags(state=(state == 1),
+ config_changed_value_present=(ccvp == 1),
+ config_changed=(cc == 1))
+
+ def __index__(self):
+ bits = 0
+ bits |= (int(self.state) & 0x1)
+ bits |= (int(self.config_changed_value_present) & 0x1) << 1
+ bits |= (int(self.config_changed) & 0x1) << 2
+ return bits
+
+
+class InitialDiagnosticsPayload(MqttPayload):
+ FORMAT = '=IBbIB'
+
+ ip: int
+ fw_version: int
+ rssi: int
+ free_heap: int
+ flags: DiagnosticsFlags
+
+
+class DiagnosticsPayload(MqttPayload):
+ FORMAT = '=bIB'
+
+ rssi: int
+ free_heap: int
+ flags: DiagnosticsFlags
diff --git a/src/home/mqtt/payload/inverter.py b/src/home/mqtt/payload/inverter.py
index 1d4099c..09388df 100644
--- a/src/home/mqtt/payload/inverter.py
+++ b/src/home/mqtt/payload/inverter.py
@@ -1,13 +1,13 @@
import struct
-from .base_payload import MQTTPayload, bit_field
+from .base_payload import MqttPayload, bit_field
from typing import Tuple
_mult_10 = lambda n: int(n*10)
_div_10 = lambda n: n/10
-class Status(MQTTPayload):
+class Status(MqttPayload):
# 46 bytes
FORMAT = 'IHHHHHHBHHHHHBHHHHHHHH'
@@ -65,7 +65,7 @@ class Status(MQTTPayload):
load_connected: bit_field(0, 16, 1)
-class Generation(MQTTPayload):
+class Generation(MqttPayload):
# 8 bytes
FORMAT = 'II'
diff --git a/src/home/mqtt/payload/relay.py b/src/home/mqtt/payload/relay.py
index 1a38201..4902991 100644
--- a/src/home/mqtt/payload/relay.py
+++ b/src/home/mqtt/payload/relay.py
@@ -1,53 +1,13 @@
-import hashlib
+from .base_payload import MqttPayload
+from .esp import (
+ OTAResultPayload,
+ OTAPayload,
+ InitialDiagnosticsPayload,
+ DiagnosticsPayload
+)
-from .base_payload import MQTTPayload, MQTTPayloadCustomField
-
-# _logger = logging.getLogger(__name__)
-
-class StatFlags(MQTTPayloadCustomField):
- state: bool
- config_changed_value_present: bool
- config_changed: bool
-
- @staticmethod
- def unpack(flags: int):
- # _logger.debug(f'StatFlags.unpack: flags={flags}')
- state = flags & 0x1
- ccvp = (flags >> 1) & 0x1
- cc = (flags >> 2) & 0x1
- # _logger.debug(f'StatFlags.unpack: state={state}')
- return StatFlags(state=(state == 1),
- config_changed_value_present=(ccvp == 1),
- config_changed=(cc == 1))
-
- def __index__(self):
- bits = 0
- bits |= (int(self.state) & 0x1)
- bits |= (int(self.config_changed_value_present) & 0x1) << 1
- bits |= (int(self.config_changed) & 0x1) << 2
- return bits
-
-
-class InitialStatPayload(MQTTPayload):
- FORMAT = '=IBbIB'
-
- ip: int
- fw_version: int
- rssi: int
- free_heap: int
- flags: StatFlags
-
-
-class StatPayload(MQTTPayload):
- FORMAT = '=bIB'
-
- rssi: int
- free_heap: int
- flags: StatFlags
-
-
-class PowerPayload(MQTTPayload):
+class PowerPayload(MqttPayload):
FORMAT = '=12sB'
PACKER = {
'state': lambda n: int(n),
@@ -60,37 +20,3 @@ class PowerPayload(MQTTPayload):
secret: str
state: bool
-
-
-class OTAResultPayload(MQTTPayload):
- FORMAT = '=BB'
- result: int
- error_code: int
-
-
-class OTAPayload(MQTTPayload):
- secret: str
- filename: str
-
- # structure of returned data:
- #
- # uint8_t[len(secret)] secret;
- # uint8_t[16] md5;
- # *uint8_t data
-
- def pack(self):
- buf = bytearray(self.secret.encode())
- m = hashlib.md5()
- with open(self.filename, 'rb') as fd:
- content = fd.read()
- m.update(content)
- buf.extend(m.digest())
- buf.extend(content)
- return buf
-
- def unpack(cls, buf: bytes):
- raise RuntimeError(f'{cls.__class__.__name__}.unpack: not implemented')
- # secret = buf[:12].decode()
- # filename = buf[12:].decode()
- # return OTAPayload(secret=secret, filename=filename)
-
diff --git a/src/home/mqtt/payload/sensors.py b/src/home/mqtt/payload/sensors.py
index 3ecc243..f99b307 100644
--- a/src/home/mqtt/payload/sensors.py
+++ b/src/home/mqtt/payload/sensors.py
@@ -1,10 +1,10 @@
-from .base_payload import MQTTPayload
+from .base_payload import MqttPayload
_mult_100 = lambda n: int(n*100)
_div_100 = lambda n: n/100
-class Temperature(MQTTPayload):
+class Temperature(MqttPayload):
FORMAT = 'IhH'
PACKER = {
'temp': _mult_100,
diff --git a/src/home/mqtt/payload/temphum.py b/src/home/mqtt/payload/temphum.py
new file mode 100644
index 0000000..5b45ecb
--- /dev/null
+++ b/src/home/mqtt/payload/temphum.py
@@ -0,0 +1,14 @@
+from .base_payload import MqttPayload
+
+two_digits_precision = lambda x: round(x, 2)
+
+
+class TempHumDataPayload(MqttPayload):
+ FORMAT = '=dd'
+ UNPACKER = {
+ 'temp': two_digits_precision,
+ 'rh': two_digits_precision
+ }
+
+ temp: float
+ rh: float
diff --git a/src/home/mqtt/relay.py b/src/home/mqtt/relay.py
index 53d43e4..a90f19c 100644
--- a/src/home/mqtt/relay.py
+++ b/src/home/mqtt/relay.py
@@ -2,83 +2,43 @@ import paho.mqtt.client as mqtt
import re
import datetime
-from .mqtt import MQTTBase
-from typing import Optional, Union
from .payload.relay import (
- InitialStatPayload,
- StatPayload,
PowerPayload,
- OTAPayload,
- OTAResultPayload
)
+from .esp import MqttEspBase
-class MQTTRelayDevice:
- id: str
- secret: Optional[str]
+class MqttRelay(MqttEspBase):
+ TOPIC_LEAF = 'relay'
- def __init__(self, id: str, secret: Optional[str] = None):
- self.id = id
- self.secret = secret
-
-
-class MQTTRelay(MQTTBase):
- _devices: list[MQTTRelayDevice]
- _message_callback: Optional[callable]
- _ota_publish_callback: Optional[callable]
-
- def __init__(self,
- devices: Union[MQTTRelayDevice, list[MQTTRelayDevice]],
- subscribe_to_updates=True):
- super().__init__(clean_session=True)
- if not isinstance(devices, list):
- devices = [devices]
- self._devices = devices
- self._message_callback = None
- self._ota_publish_callback = None
- self._subscribe_to_updates = subscribe_to_updates
- self._ota_mid = None
-
- def on_connect(self, client: mqtt.Client, userdata, flags, rc):
- super().on_connect(client, userdata, flags, rc)
-
- if self._subscribe_to_updates:
- for device in self._devices:
- topic = f'hk/{device.id}/relay/#'
- self._logger.debug(f"subscribing to {topic}")
- client.subscribe(topic, qos=1)
+ def set_power(self, device_id, enable: bool, secret=None):
+ device = next(d for d in self._devices if d.id == device_id)
+ secret = secret if secret else device.secret
- def on_publish(self, client: mqtt.Client, userdata, mid):
- if self._ota_mid is not None and mid == self._ota_mid and self._ota_publish_callback:
- self._ota_publish_callback()
+ assert secret is not None, 'device secret not specified'
- def set_message_callback(self, callback: callable):
- self._message_callback = callback
+ payload = PowerPayload(secret=secret,
+ state=enable)
+ self._client.publish(f'hk/{device.id}/{self.TOPIC_LEAF}/power',
+ payload=payload.pack(),
+ qos=1)
+ self._client.loop_write()
def on_message(self, client: mqtt.Client, userdata, msg):
+ if super().on_message(client, userdata, msg):
+ return
+
try:
- match = re.match(r'^hk/(.*?)/relay/(stat|stat1|power|otares)$', msg.topic)
- self._logger.debug(f'topic: {msg.topic}')
+ match = re.match(self.get_mqtt_topics(['power']), msg.topic)
if not match:
return
device_id = match.group(1)
subtopic = match.group(2)
- try:
- next(d for d in self._devices if d.id == device_id)
- except StopIteration:
- return
-
message = None
- if subtopic == 'stat':
- message = StatPayload.unpack(msg.payload)
- elif subtopic == 'stat1':
- message = InitialStatPayload.unpack(msg.payload)
- elif subtopic == 'power':
+ if subtopic == 'power':
message = PowerPayload.unpack(msg.payload)
- elif subtopic == 'otares':
- message = OTAResultPayload.unpack(msg.payload)
if message and self._message_callback:
self._message_callback(device_id, message)
@@ -86,37 +46,8 @@ class MQTTRelay(MQTTBase):
except Exception as e:
self._logger.exception(str(e))
- def set_power(self, device_id, enable: bool, secret=None):
- device = next(d for d in self._devices if d.id == device_id)
- secret = secret if secret else device.secret
-
- assert secret is not None, 'device secret not specified'
-
- payload = PowerPayload(secret=secret,
- state=enable)
- self._client.publish(f'hk/{device.id}/relay/power',
- payload=payload.pack(),
- qos=1)
- self._client.loop_write()
-
- def push_ota(self,
- device_id,
- filename: str,
- publish_callback: callable,
- qos: int):
- device = next(d for d in self._devices if d.id == device_id)
- assert device.secret is not None, 'device secret not specified'
-
- self._ota_publish_callback = publish_callback
- payload = OTAPayload(secret=device.secret, filename=filename)
- publish_result = self._client.publish(f'hk/{device.id}/relay/admin/ota',
- payload=payload.pack(),
- qos=qos)
- self._ota_mid = publish_result.mid
- self._client.loop_write()
-
-class MQTTRelayState:
+class MqttRelayState:
enabled: bool
update_time: datetime.datetime
rssi: int
diff --git a/src/home/mqtt/temphum.py b/src/home/mqtt/temphum.py
new file mode 100644
index 0000000..b9b2eb9
--- /dev/null
+++ b/src/home/mqtt/temphum.py
@@ -0,0 +1,33 @@
+import paho.mqtt.client as mqtt
+import re
+
+from .payload.temphum import (
+ TempHumDataPayload
+)
+from .esp import MqttEspBase
+
+
+class MqttTempHum(MqttEspBase):
+ TOPIC_LEAF = 'temphum'
+
+ def on_message(self, client: mqtt.Client, userdata, msg):
+ if super().on_message(client, userdata, msg):
+ return
+
+ try:
+ match = re.match(self.get_mqtt_topics(['data']), msg.topic)
+ if not match:
+ return
+
+ device_id = match.group(1)
+ subtopic = match.group(2)
+
+ message = None
+ if subtopic == 'data':
+ message = TempHumDataPayload.unpack(msg.payload)
+
+ if message and self._message_callback:
+ self._message_callback(device_id, message)
+
+ except Exception as e:
+ self._logger.exception(str(e))
diff --git a/src/inverter_mqtt_receiver.py b/src/inverter_mqtt_receiver.py
index a7018f2..d40647e 100755
--- a/src/inverter_mqtt_receiver.py
+++ b/src/inverter_mqtt_receiver.py
@@ -1,15 +1,14 @@
#!/usr/bin/env python3
import paho.mqtt.client as mqtt
import re
-import logging
-from home.mqtt import MQTTBase
+from home.mqtt import MqttBase
from home.mqtt.payload.inverter import Status, Generation
from home.database import InverterDatabase
from home.config import config
-class MQTTReceiver(MQTTBase):
+class MqttReceiver(MqttBase):
def __init__(self):
super().__init__(clean_session=False)
self.database = InverterDatabase()
@@ -70,6 +69,6 @@ class MQTTReceiver(MQTTBase):
if __name__ == '__main__':
config.load('inverter_mqtt_receiver')
- server = MQTTReceiver()
+ server = MqttReceiver()
server.connect_and_loop()
diff --git a/src/inverter_mqtt_sender.py b/src/inverter_mqtt_sender.py
index 74191a2..fb2a2d8 100755
--- a/src/inverter_mqtt_sender.py
+++ b/src/inverter_mqtt_sender.py
@@ -5,11 +5,11 @@ import json
import inverterd
from home.config import config
-from home.mqtt import MQTTBase, poll_tick
+from home.mqtt import MqttBase, poll_tick
from home.mqtt.payload.inverter import Status, Generation
-class MQTTClient(MQTTBase):
+class MqttClient(MqttBase):
def __init__(self):
super().__init__()
@@ -66,7 +66,7 @@ class MQTTClient(MQTTBase):
if __name__ == '__main__':
config.load('inverter_mqtt_sender')
- client = MQTTClient()
+ client = MqttClient()
client.configure_tls()
client.connect_and_loop(loop_forever=False)
client.poll_inverter() \ No newline at end of file
diff --git a/src/polaris_kettle_bot.py b/src/polaris_kettle_bot.py
index 2e5256d..088707d 100755
--- a/src/polaris_kettle_bot.py
+++ b/src/polaris_kettle_bot.py
@@ -10,7 +10,7 @@ import paho.mqtt.client as mqtt
from home.telegram import bot
from home.api.types import BotType
-from home.mqtt import MQTTBase
+from home.mqtt import MqttBase
from home.config import config
from home.util import chunks
from syncleo import (
@@ -204,7 +204,7 @@ class KettleInfo:
class KettleController(threading.Thread,
- MQTTBase,
+ MqttBase,
DeviceListener,
IncomingMessageListener,
KettleInfoListener,
@@ -224,7 +224,7 @@ class KettleController(threading.Thread,
def __init__(self):
# basic setup
- MQTTBase.__init__(self, clean_session=False)
+ MqttBase.__init__(self, clean_session=False)
threading.Thread.__init__(self)
self._logger = logging.getLogger(self.__class__.__name__)
diff --git a/src/polaris_kettle_util.py b/src/polaris_kettle_util.py
index 61c1c7d..81326dd 100755
--- a/src/polaris_kettle_util.py
+++ b/src/polaris_kettle_util.py
@@ -8,7 +8,7 @@ import paho.mqtt.client as mqtt
from typing import Optional
from argparse import ArgumentParser
from queue import SimpleQueue
-from home.mqtt import MQTTBase
+from home.mqtt import MqttBase
from home.config import config
from syncleo import (
Kettle,
@@ -21,7 +21,7 @@ logger = logging.getLogger(__name__)
control_tasks = SimpleQueue()
-class MQTTServer(MQTTBase):
+class MqttServer(MqttBase):
def __init__(self):
super().__init__(clean_session=False)
@@ -78,7 +78,7 @@ def main():
arg = config.load('polaris_kettle_util', use_cli=True, parser=parser)
if arg.mode == 'mqtt':
- server = MQTTServer()
+ server = MqttServer()
try:
server.connect_and_loop(loop_forever=True)
except KeyboardInterrupt:
diff --git a/src/pump_mqtt_bot.py b/src/pump_mqtt_bot.py
index accafcb..d3b6de4 100755
--- a/src/pump_mqtt_bot.py
+++ b/src/pump_mqtt_bot.py
@@ -8,10 +8,10 @@ from telegram import ReplyKeyboardMarkup, User
from home.config import config
from home.telegram import bot
from home.telegram._botutil import user_any_name
-from home.api.types import BotType
-from home.mqtt import MQTTRelay, MQTTRelayState, MQTTRelayDevice
-from home.mqtt.payload import MQTTPayload
-from home.mqtt.payload.relay import InitialStatPayload, StatPayload
+from home.mqtt.esp import MqttEspDevice
+from home.mqtt import MqttRelay, MqttRelayState
+from home.mqtt.payload import MqttPayload
+from home.mqtt.payload.relay import InitialDiagnosticsPayload, DiagnosticsPayload
config.load('pump_mqtt_bot')
@@ -70,8 +70,8 @@ bot.lang.en(
)
-mqtt_relay: Optional[MQTTRelay] = None
-relay_state = MQTTRelayState()
+mqtt_relay: Optional[MqttRelay] = None
+relay_state = MqttRelayState()
class UserAction(Enum):
@@ -79,10 +79,10 @@ class UserAction(Enum):
OFF = 'off'
-def on_mqtt_message(home_id, message: MQTTPayload):
- if isinstance(message, InitialStatPayload) or isinstance(message, StatPayload):
+def on_mqtt_message(home_id, message: MqttPayload):
+ if isinstance(message, InitialDiagnosticsPayload) or isinstance(message, DiagnosticsPayload):
kwargs = dict(rssi=message.rssi, enabled=message.flags.state)
- if isinstance(message, InitialStatPayload):
+ if isinstance(message, InitialDiagnosticsPayload):
kwargs['fw_version'] = message.fw_version
relay_state.update(**kwargs)
@@ -157,8 +157,8 @@ def markup(ctx: Optional[bot.Context]) -> Optional[ReplyKeyboardMarkup]:
if __name__ == '__main__':
- mqtt_relay = MQTTRelay(devices=MQTTRelayDevice(id=config['mqtt']['home_id'],
- secret=config['mqtt']['home_secret']))
+ mqtt_relay = MqttRelay(devices=MqttEspDevice(id=config['mqtt']['home_id'],
+ secret=config['mqtt']['home_secret']))
mqtt_relay.set_message_callback(on_mqtt_message)
mqtt_relay.configure_tls()
mqtt_relay.connect_and_loop(loop_forever=False)
diff --git a/src/relay_mqtt_bot.py b/src/relay_mqtt_bot.py
index 33b7e06..ebbff82 100755
--- a/src/relay_mqtt_bot.py
+++ b/src/relay_mqtt_bot.py
@@ -6,10 +6,10 @@ from functools import partial
from home.config import config
from home.telegram import bot
-from home.api.types import BotType
-from home.mqtt import MQTTRelay, MQTTRelayState, MQTTRelayDevice
-from home.mqtt.payload import MQTTPayload
-from home.mqtt.payload.relay import InitialStatPayload, StatPayload
+from home.mqtt import MqttRelay, MqttRelayState
+from home.mqtt.esp import MqttEspDevice
+from home.mqtt.payload import MqttPayload
+from home.mqtt.payload.relay import InitialDiagnosticsPayload, DiagnosticsPayload
config.load('relay_mqtt_bot')
@@ -34,8 +34,8 @@ status_emoji = {
'on': '✅',
'off': '❌'
}
-mqtt_relay: Optional[MQTTRelay] = None
-relay_states: dict[str, MQTTRelayState] = {}
+mqtt_relay: Optional[MqttRelay] = None
+relay_states: dict[str, MqttRelayState] = {}
class UserAction(Enum):
@@ -43,13 +43,13 @@ class UserAction(Enum):
OFF = 'off'
-def on_mqtt_message(home_id, message: MQTTPayload):
- if isinstance(message, InitialStatPayload) or isinstance(message, StatPayload):
+def on_mqtt_message(home_id, message: MqttPayload):
+ if isinstance(message, InitialDiagnosticsPayload) or isinstance(message, DiagnosticsPayload):
kwargs = dict(rssi=message.rssi, enabled=message.flags.state)
- if isinstance(message, InitialStatPayload):
+ if isinstance(message, InitialDiagnosticsPayload):
kwargs['fw_version'] = message.fw_version
if home_id not in relay_states:
- relay_states[home_id] = MQTTRelayState()
+ relay_states[home_id] = MqttRelayState()
relay_states[home_id].update(**kwargs)
@@ -87,8 +87,8 @@ def markup(ctx: Optional[bot.Context]) -> Optional[ReplyKeyboardMarkup]:
if __name__ == '__main__':
devices = []
for device_id, data in config['relays'].items():
- devices.append(MQTTRelayDevice(id=device_id,
- secret=data['secret']))
+ devices.append(MqttEspDevice(id=device_id,
+ secret=data['secret']))
labels = data['labels']
bot.lang.ru(**{device_id: labels['ru']})
bot.lang.en(**{device_id: labels['en']})
@@ -101,7 +101,7 @@ if __name__ == '__main__':
messages.append(f'{type_emoji}{status_emoji[action.value]} {labels[_lang]}')
bot.handler(texts=messages)(partial(enable_handler if action == UserAction.ON else disable_handler, device_id))
- mqtt_relay = MQTTRelay(devices=devices)
+ mqtt_relay = MqttRelay(devices=devices)
mqtt_relay.set_message_callback(on_mqtt_message)
mqtt_relay.configure_tls()
mqtt_relay.connect_and_loop(loop_forever=False)
diff --git a/src/relay_mqtt_http_proxy.py b/src/relay_mqtt_http_proxy.py
index 51a4e21..098facc 100755
--- a/src/relay_mqtt_http_proxy.py
+++ b/src/relay_mqtt_http_proxy.py
@@ -1,20 +1,21 @@
#!/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 home.mqtt import MqttRelay, MqttRelayState
+from home.mqtt.esp import MqttEspDevice
+from home.mqtt.payload import MqttPayload
+from home.mqtt.payload.relay import InitialDiagnosticsPayload, DiagnosticsPayload
from typing import Optional
-mqtt_relay: Optional[MQTTRelay] = None
-relay_states: dict[str, MQTTRelayState] = {}
+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):
+def on_mqtt_message(device_id, message: MqttPayload):
+ if isinstance(message, InitialDiagnosticsPayload) or isinstance(message, DiagnosticsPayload):
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] = MqttRelayState()
relay_states[device_id].update(**kwargs)
@@ -54,7 +55,7 @@ class RelayMqttHttpProxy(http.HTTPServer):
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 = MqttRelay(devices=[MqttEspDevice(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)
diff --git a/src/relay_mqtt_util.py b/src/relay_mqtt_util.py
deleted file mode 100755
index 45d2405..0000000
--- a/src/relay_mqtt_util.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python3
-from typing import Optional
-from argparse import ArgumentParser
-
-from home.config import config
-from home.mqtt import MQTTRelay, MQTTRelayDevice
-from home.mqtt.payload import MQTTPayload
-from home.mqtt.payload.relay import (
- InitialStatPayload, StatPayload, OTAResultPayload
-)
-
-mqtt_relay: Optional[MQTTRelay] = None
-
-
-def on_mqtt_message(device_id, p: MQTTPayload):
- message = None
-
- if isinstance(p, InitialStatPayload) or isinstance(p, StatPayload):
- message = f'[stat] state={"on" if p.flags.state else "off"}'
- message += f' rssi={p.rssi}'
- message += f' free_heap={p.free_heap}'
- if isinstance(p, InitialStatPayload):
- message += f' fw={p.fw_version}'
-
- elif isinstance(p, OTAResultPayload):
- message = f'[otares] result={p.result} error_code={p.error_code}'
-
- if message:
- print(message)
-
-
-if __name__ == '__main__':
- parser = ArgumentParser()
- parser.add_argument('--device-id', type=str, required=True)
-
- config.load('relay_mqtt_util', parser=parser)
- arg = parser.parse_args()
-
- mqtt_relay = MQTTRelay(devices=MQTTRelayDevice(id=arg.device_id))
- mqtt_relay.set_message_callback(on_mqtt_message)
- mqtt_relay.configure_tls()
- try:
- mqtt_relay.connect_and_loop()
- except KeyboardInterrupt:
- mqtt_relay.disconnect()
diff --git a/src/sensors_mqtt_receiver.py b/src/sensors_mqtt_receiver.py
index 9637690..a377ddd 100755
--- a/src/sensors_mqtt_receiver.py
+++ b/src/sensors_mqtt_receiver.py
@@ -2,7 +2,7 @@
import paho.mqtt.client as mqtt
import re
-from home.mqtt import MQTTBase
+from home.mqtt import MqttBase
from home.config import config
from home.mqtt.payload.sensors import Temperature
from home.api.types import TemperatureSensorLocation
@@ -16,7 +16,7 @@ def get_sensor_type(sensor: str) -> TemperatureSensorLocation:
raise ValueError(f'unexpected sensor value: {sensor}')
-class MQTTServer(MQTTBase):
+class MqttServer(MqttBase):
def __init__(self):
super().__init__(clean_session=False)
self.database = SensorsDatabase()
@@ -49,5 +49,5 @@ class MQTTServer(MQTTBase):
if __name__ == '__main__':
config.load('sensors_mqtt_receiver')
- server = MQTTServer()
+ server = MqttServer()
server.connect_and_loop()
diff --git a/src/sensors_mqtt_sender.py b/src/sensors_mqtt_sender.py
index 2cf2717..87a28ca 100755
--- a/src/sensors_mqtt_sender.py
+++ b/src/sensors_mqtt_sender.py
@@ -3,12 +3,12 @@ import time
import json
from home.util import parse_addr, MySimpleSocketClient
-from home.mqtt import MQTTBase, poll_tick
+from home.mqtt import MqttBase, poll_tick
from home.mqtt.payload.sensors import Temperature
from home.config import config
-class MQTTClient(MQTTBase):
+class MqttClient(MqttBase):
def __init__(self):
super().__init__(self)
self._home_id = config['mqtt']['home_id']
@@ -52,7 +52,7 @@ class MQTTClient(MQTTBase):
if __name__ == '__main__':
config.load('sensors_mqtt_sender')
- client = MQTTClient()
+ client = MqttClient()
client.configure_tls()
client.connect_and_loop(loop_forever=False)
client.poll()
diff --git a/src/temphum.py b/src/temphum.py
index dc0b7dd..0f90835 100644..100755
--- a/src/temphum.py
+++ b/src/temphum.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python3
from argparse import ArgumentParser
from home.temphum import SensorType, create_sensor