summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/mqtt_node_util.py53
-rw-r--r--include/pio/libs/mqtt/homekit/mqtt/mqtt.cpp2
-rw-r--r--include/pio/libs/mqtt/library.json2
-rw-r--r--include/pio/libs/temphum/library.json2
-rw-r--r--include/py/homekit/mqtt/_config.py9
-rw-r--r--include/py/homekit/mqtt/_wrapper.py21
-rw-r--r--include/py/homekit/mqtt/module/ota.py2
-rw-r--r--include/py/homekit/mqtt/module/relay.py3
-rw-r--r--include/py/homekit/pio/products.py10
9 files changed, 85 insertions, 19 deletions
diff --git a/bin/mqtt_node_util.py b/bin/mqtt_node_util.py
index cf451fd..68d3bd1 100755
--- a/bin/mqtt_node_util.py
+++ b/bin/mqtt_node_util.py
@@ -7,12 +7,37 @@ from typing import Optional
from argparse import ArgumentParser, ArgumentError
from homekit.config import config
-from homekit.mqtt import MqttNode, MqttWrapper, get_mqtt_modules
-from homekit.mqtt import MqttNodesConfig
+from homekit.mqtt import MqttNode, MqttWrapper, get_mqtt_modules, MqttNodesConfig
+from homekit.mqtt.module.relay import MqttRelayModule
+from homekit.mqtt.module.ota import MqttOtaModule
mqtt_node: Optional[MqttNode] = None
mqtt: Optional[MqttWrapper] = None
+relay_module: Optional[MqttOtaModule] = None
+relay_val = None
+
+ota_module: Optional[MqttRelayModule] = None
+ota_val = False
+
+no_wait = False
+stop_loop = False
+
+
+def on_mqtt_connect():
+ global stop_loop
+
+ if relay_module:
+ relay_module.switchpower(relay_val == 1)
+
+ if ota_val:
+ if not os.path.exists(arg.push_ota):
+ raise OSError(f'--push-ota: file \"{arg.push_ota}\" does not exists')
+ ota_module.push_ota(arg.push_ota, 1)
+
+ if no_wait:
+ stop_loop = True
+
if __name__ == '__main__':
nodes_config = MqttNodesConfig()
@@ -25,16 +50,22 @@ if __name__ == '__main__':
help='send relay state')
parser.add_argument('--legacy-relay', action='store_true')
parser.add_argument('--push-ota', type=str, metavar='OTA_FILENAME',
- help='push OTA, receives path to firmware.bin')
+ help='push OTA, receives path to firmware.bin (not .elf!)')
+ parser.add_argument('--no-wait', action='store_true',
+ help='execute command and exit')
config.load_app(parser=parser, no_config=True)
arg = parser.parse_args()
+ if arg.no_wait:
+ no_wait = True
+
if arg.switch_relay is not None and 'relay' not in arg.modules:
raise ArgumentError(None, '--relay is only allowed when \'relay\' module included in --modules')
mqtt = MqttWrapper(randomize_client_id=True,
client_id='mqtt_node_util')
+ mqtt.add_connect_callback(on_mqtt_connect)
mqtt_node = MqttNode(node_id=arg.node_id,
node_secret=nodes_config.get_node(arg.node_id)['password'])
@@ -42,6 +73,8 @@ if __name__ == '__main__':
# must-have modules
ota_module = mqtt_node.load_module('ota')
+ ota_val = arg.push_ota
+
mqtt_node.load_module('diagnostics')
if arg.modules:
@@ -51,18 +84,16 @@ if __name__ == '__main__':
kwargs['legacy_topics'] = True
module_instance = mqtt_node.load_module(m, **kwargs)
if m == 'relay' and arg.switch_relay is not None:
- module_instance.switchpower(arg.switch_relay == 1)
+ relay_module = module_instance
+ relay_val = arg.switch_relay
try:
mqtt.connect_and_loop(loop_forever=False)
-
- if arg.push_ota:
- if not os.path.exists(arg.push_ota):
- raise OSError(f'--push-ota: file \"{arg.push_ota}\" does not exists')
- ota_module.push_ota(arg.push_ota, 1)
-
- while True:
+ while not stop_loop:
sleep(0.1)
except KeyboardInterrupt:
+ pass
+
+ finally:
mqtt.disconnect()
diff --git a/include/pio/libs/mqtt/homekit/mqtt/mqtt.cpp b/include/pio/libs/mqtt/homekit/mqtt/mqtt.cpp
index aa769a5..83764ca 100644
--- a/include/pio/libs/mqtt/homekit/mqtt/mqtt.cpp
+++ b/include/pio/libs/mqtt/homekit/mqtt/mqtt.cpp
@@ -119,7 +119,7 @@ void Mqtt::reconnect() {
void Mqtt::disconnect() {
// TODO test how this works???
reconnectTimer.detach();
- client.disconnect();
+ client.disconnect(true);
}
void Mqtt::loop() {
diff --git a/include/pio/libs/mqtt/library.json b/include/pio/libs/mqtt/library.json
index f3f2504..6238c21 100644
--- a/include/pio/libs/mqtt/library.json
+++ b/include/pio/libs/mqtt/library.json
@@ -1,6 +1,6 @@
{
"name": "homekit_mqtt",
- "version": "1.0.11",
+ "version": "1.0.12",
"build": {
"flags": "-I../../include"
}
diff --git a/include/pio/libs/temphum/library.json b/include/pio/libs/temphum/library.json
index 329b7ca..4cf5c63 100644
--- a/include/pio/libs/temphum/library.json
+++ b/include/pio/libs/temphum/library.json
@@ -1,6 +1,6 @@
{
"name": "homekit_temphum",
- "version": "1.0.3",
+ "version": "1.0.4",
"build": {
"flags": "-I../../include"
}
diff --git a/include/py/homekit/mqtt/_config.py b/include/py/homekit/mqtt/_config.py
index 9ba9443..4916d8a 100644
--- a/include/py/homekit/mqtt/_config.py
+++ b/include/py/homekit/mqtt/_config.py
@@ -105,11 +105,16 @@ class MqttNodesConfig(ConfigUnit):
'relay': {
'type': 'dict',
'schema': {
- 'device_type': {'type': 'string', 'allowed': ['lamp', 'pump', 'solenoid'], 'required': True},
+ 'device_type': {'type': 'string', 'allowed': ['lamp', 'pump', 'solenoid', 'cooler'], 'required': True},
'legacy_topics': {'type': 'boolean'}
}
},
- 'password': {'type': 'string'}
+ 'password': {'type': 'string'},
+ 'defines': {
+ 'type': 'dict',
+ 'keysrules': {'type': 'string'},
+ 'valuesrules': {'type': ['string', 'integer']}
+ }
}
}
}
diff --git a/include/py/homekit/mqtt/_wrapper.py b/include/py/homekit/mqtt/_wrapper.py
index 3c2774c..5fc33fe 100644
--- a/include/py/homekit/mqtt/_wrapper.py
+++ b/include/py/homekit/mqtt/_wrapper.py
@@ -7,6 +7,8 @@ from ..util import strgen
class MqttWrapper(Mqtt):
_nodes: list[MqttNode]
+ _connect_callbacks: list[callable]
+ _disconnect_callbacks: list[callable]
def __init__(self,
client_id: str,
@@ -18,17 +20,30 @@ class MqttWrapper(Mqtt):
super().__init__(clean_session=clean_session,
client_id=client_id)
self._nodes = []
+ self._connect_callbacks = []
+ self._disconnect_callbacks = []
self._topic_prefix = topic_prefix
def on_connect(self, client: mqtt.Client, userdata, flags, rc):
super().on_connect(client, userdata, flags, rc)
for node in self._nodes:
node.on_connect(self)
+ for f in self._connect_callbacks:
+ try:
+ f()
+ except Exception as e:
+ self._logger.exception(e)
def on_disconnect(self, client: mqtt.Client, userdata, rc):
super().on_disconnect(client, userdata, rc)
for node in self._nodes:
node.on_disconnect()
+ for f in self._disconnect_callbacks:
+ try:
+ f()
+ except Exception as e:
+ self._logger.exception(e)
+
def on_message(self, client: mqtt.Client, userdata, msg):
try:
@@ -40,6 +55,12 @@ class MqttWrapper(Mqtt):
except Exception as e:
self._logger.exception(str(e))
+ def add_connect_callback(self, f: callable):
+ self._connect_callbacks.append(f)
+
+ def add_disconnect_callback(self, f: callable):
+ self._disconnect_callbacks.append(f)
+
def add_node(self, node: MqttNode):
self._nodes.append(node)
if self._connected:
diff --git a/include/py/homekit/mqtt/module/ota.py b/include/py/homekit/mqtt/module/ota.py
index cd34332..2f9b216 100644
--- a/include/py/homekit/mqtt/module/ota.py
+++ b/include/py/homekit/mqtt/module/ota.py
@@ -74,4 +74,4 @@ class MqttOtaModule(MqttModule):
if not self._initialized:
self._ota_request = (filename, qos)
else:
- self.do_push_ota(filename, qos)
+ self.do_push_ota(self._mqtt_node_ref.secret, filename, qos)
diff --git a/include/py/homekit/mqtt/module/relay.py b/include/py/homekit/mqtt/module/relay.py
index e968031..5cbe09b 100644
--- a/include/py/homekit/mqtt/module/relay.py
+++ b/include/py/homekit/mqtt/module/relay.py
@@ -69,8 +69,7 @@ class MqttRelayModule(MqttModule):
mqtt.subscribe_module(self._get_switch_topic(), self)
mqtt.subscribe_module('relay/status', self)
- def switchpower(self,
- enable: bool):
+ def switchpower(self, enable: bool):
payload = MqttPowerSwitchPayload(secret=self._mqtt_node_ref.secret,
state=enable)
self._mqtt_node_ref.publish(self._get_switch_topic(),
diff --git a/include/py/homekit/pio/products.py b/include/py/homekit/pio/products.py
index a0e7a1f..3d5034f 100644
--- a/include/py/homekit/pio/products.py
+++ b/include/py/homekit/pio/products.py
@@ -3,6 +3,7 @@ import logging
from io import StringIO
from collections import OrderedDict
+from ..mqtt import MqttNodesConfig
_logger = logging.getLogger(__name__)
@@ -37,6 +38,13 @@ def platformio_ini(product_config: dict,
debug=False,
debug_network=False) -> str:
node_id = build_specific_defines['CONFIG_NODE_ID']
+ if node_id not in MqttNodesConfig().get_nodes().keys():
+ raise ValueError(f'node id "{node_id}" is not specified in the config!')
+
+ try:
+ node_defines = MqttNodesConfig().get_node(node_id)['defines']
+ except KeyError:
+ node_defines = None
# defines
defines = {
@@ -63,6 +71,8 @@ def platformio_ini(product_config: dict,
if build_specific_defines:
for k, v in build_specific_defines.items():
defines[k] = v
+ if node_defines:
+ defines = {**defines, **node_defines}
defines = OrderedDict(sorted(defines.items(), key=lambda t: t[0]))
# libs