diff options
author | Evgeny Zinoviev <me@ch1p.io> | 2023-05-31 22:27:46 +0300 |
---|---|---|
committer | Evgeny Zinoviev <me@ch1p.io> | 2023-05-31 22:27:46 +0300 |
commit | 52db06e0c81bf7f5ec75da40250ddb700d333db2 (patch) | |
tree | 730c0db16580a42487cf46b60cdb346571beee3b | |
parent | c976495222858c4921454c9294ff73794ae56277 (diff) |
save
-rw-r--r-- | platformio/common/libs/main/homekit/main.cpp | 21 | ||||
-rw-r--r-- | platformio/common/libs/main/homekit/main.h | 4 | ||||
-rw-r--r-- | platformio/common/libs/main/library.json | 2 | ||||
-rw-r--r-- | src/home/mqtt/relay.py | 59 | ||||
-rwxr-xr-x | src/pio_ini.py | 10 | ||||
-rwxr-xr-x | test/mqtt_relay_server_util.py | 18 | ||||
-rwxr-xr-x | test/mqtt_relay_util.py | 39 |
7 files changed, 150 insertions, 3 deletions
diff --git a/platformio/common/libs/main/homekit/main.cpp b/platformio/common/libs/main/homekit/main.cpp index fd08925..816c764 100644 --- a/platformio/common/libs/main/homekit/main.cpp +++ b/platformio/common/libs/main/homekit/main.cpp @@ -6,7 +6,12 @@ namespace homekit::main { +#ifndef CONFIG_TARGET_ESP01 +#ifndef CONFIG_NO_RECOVERY enum WorkingMode working_mode = WorkingMode::NORMAL; +#endif +#endif + static const uint16_t recovery_boot_detection_ms = 2000; static const uint8_t recovery_boot_delay_ms = 100; @@ -22,8 +27,10 @@ static StopWatch blinkStopWatch; #endif #ifndef CONFIG_TARGET_ESP01 +#ifndef CONFIG_NO_RECOVERY static DNSServer* dnsServer = nullptr; #endif +#endif static void onWifiConnected(const WiFiEventStationModeGotIP& event); static void onWifiDisconnected(const WiFiEventStationModeDisconnected& event); @@ -45,6 +52,7 @@ static void wifiConnect() { } #ifndef CONFIG_TARGET_ESP01 +#ifndef CONFIG_NO_RECOVERY static void wifiHotspot() { led::mcu_led->on(); @@ -71,13 +79,16 @@ static void waitForRecoveryPress() { } } #endif +#endif void setup() { WiFi.disconnect(); +#ifndef CONFIG_NO_RECOVERY #ifndef CONFIG_TARGET_ESP01 homekit::main::waitForRecoveryPress(); #endif +#endif #ifdef DEBUG Serial.begin(115200); @@ -95,6 +106,7 @@ void setup() { } #ifndef CONFIG_TARGET_ESP01 +#ifndef CONFIG_NO_RECOVERY switch (working_mode) { case WorkingMode::RECOVERY: wifiHotspot(); @@ -102,19 +114,24 @@ void setup() { case WorkingMode::NORMAL: #endif +#endif wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnected); wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnected); wifiConnect(); +#ifndef CONFIG_NO_RECOVERY #ifndef CONFIG_TARGET_ESP01 break; } #endif +#endif } void loop(LoopConfig* config) { +#ifndef CONFIG_NO_RECOVERY #ifndef CONFIG_TARGET_ESP01 if (working_mode == WorkingMode::NORMAL) { #endif +#endif if (wifi_state == WiFiConnectionState::WAITING) { PRINT("."); led::mcu_led->blink(2, 50); @@ -166,6 +183,7 @@ void loop(LoopConfig* config) { } #endif } +#ifndef CONFIG_NO_RECOVERY #ifndef CONFIG_TARGET_ESP01 } else { if (dnsServer != nullptr) @@ -176,6 +194,7 @@ void loop(LoopConfig* config) { httpServer->loop(); } #endif +#endif } static void onWifiConnected(const WiFiEventStationModeGotIP& event) { @@ -191,4 +210,4 @@ static void onWifiDisconnected(const WiFiEventStationModeDisconnected& event) { wifiTimer.once(2, wifiConnect); } -}
\ No newline at end of file +} diff --git a/platformio/common/libs/main/homekit/main.h b/platformio/common/libs/main/homekit/main.h index a503dd0..78a0695 100644 --- a/platformio/common/libs/main/homekit/main.h +++ b/platformio/common/libs/main/homekit/main.h @@ -10,8 +10,10 @@ #include <homekit/config.h> #include <homekit/logging.h> #ifndef CONFIG_TARGET_ESP01 +#ifndef CONFIG_NO_RECOVERY #include <homekit/http_server.h> #endif +#endif #include <homekit/wifi.h> #include <homekit/mqtt/mqtt.h> @@ -20,6 +22,7 @@ namespace homekit::main { #ifndef CONFIG_TARGET_ESP01 +#ifndef CONFIG_NO_RECOVERY enum class WorkingMode { RECOVERY, // AP mode, http server with configuration NORMAL, // MQTT client @@ -27,6 +30,7 @@ enum class WorkingMode { extern enum WorkingMode working_mode; #endif +#endif enum class WiFiConnectionState { WAITING = 0, diff --git a/platformio/common/libs/main/library.json b/platformio/common/libs/main/library.json index 04eedab..728d4f8 100644 --- a/platformio/common/libs/main/library.json +++ b/platformio/common/libs/main/library.json @@ -1,6 +1,6 @@ { "name": "homekit_main", - "version": "1.0.8", + "version": "1.0.10", "build": { "flags": "-I../../include" }, diff --git a/src/home/mqtt/relay.py b/src/home/mqtt/relay.py new file mode 100644 index 0000000..cf657f7 --- /dev/null +++ b/src/home/mqtt/relay.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +import paho.mqtt.client as mqtt +import re +import logging + +from .mqtt import MQTTBase + + +class MQTTRelayClient(MQTTBase): + _home_id: str + + def __init__(self, home_id: str): + super().__init__(clean_session=True) + self._home_id = home_id + + def on_connect(self, client: mqtt.Client, userdata, flags, rc): + super().on_connect(client, userdata, flags, rc) + + topic = f'home/{self._home_id}/#' + self._logger.info(f"subscribing to {topic}") + + client.subscribe(topic, qos=1) + + def on_message(self, client: mqtt.Client, userdata, msg): + try: + match = re.match(r'^home/(.*?)/relay/(stat|power)(?:/(.+))?$', msg.topic) + self._logger.info(f'topic: {msg.topic}') + if not match: + return + + name = match.group(1) + subtopic = match.group(2) + + if name != self._home_id: + return + + if subtopic == 'stat': + stat_name, stat_value = match.group(3).split('/') + self._logger.info(f'stat: {stat_name} = {stat_value}') + + except Exception as e: + self._logger.exception(str(e)) + + +class MQTTRelayController(MQTTBase): + _home_id: str + + def __init__(self, home_id: str): + super().__init__(clean_session=True) + self._home_id = home_id + + def set_power(self, enable: bool): + self._client.publish(f'home/{self._home_id}/relay/power', + payload=int(enable), + qos=1) + self._client.loop_write() + + def send_stat(self, stat: dict): + pass diff --git a/src/pio_ini.py b/src/pio_ini.py index 19dd707..920c3e5 100755 --- a/src/pio_ini.py +++ b/src/pio_ini.py @@ -54,12 +54,17 @@ def bsd_parser(product_config: dict, arg_kwargs['type'] = int elif kwargs['type'] == 'int': arg_kwargs['type'] = int + elif kwargs['type'] == 'bool': + arg_kwargs['action'] = 'store_true' + arg_kwargs['required'] = False else: raise TypeError(f'unsupported type {kwargs["type"]} for define {define_name}') else: arg_kwargs['action'] = 'store_true' - parser.add_argument(f'--{define_name}', required=True, **arg_kwargs) + if 'required' not in arg_kwargs: + arg_kwargs['required'] = True + parser.add_argument(f'--{define_name}', **arg_kwargs) bsd_walk(product_config, f) @@ -76,6 +81,9 @@ def bsd_get(product_config: dict, enums.append(f'CONFIG_{define_name}') defines[f'CONFIG_{define_name}'] = f'HOMEKIT_{attr_value.upper()}' return + if kwargs['type'] == 'bool': + defines[f'CONFIG_{define_name}'] = True + return defines[f'CONFIG_{define_name}'] = str(attr_value) bsd_walk(product_config, f) return defines, enums diff --git a/test/mqtt_relay_server_util.py b/test/mqtt_relay_server_util.py new file mode 100755 index 0000000..e6c5255 --- /dev/null +++ b/test/mqtt_relay_server_util.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +import sys +import os.path +sys.path.extend([ + os.path.realpath( + os.path.join(os.path.dirname(os.path.join(__file__)), '..') + ) +]) + +from src.home.config import config +from src.home.mqtt.relay import MQTTRelayClient + + +if __name__ == '__main__': + config.load('test_mqtt_relay_server') + relay = MQTTRelayClient('test') + relay.configure_tls() + relay.connect_and_loop() diff --git a/test/mqtt_relay_util.py b/test/mqtt_relay_util.py new file mode 100755 index 0000000..c1096cc --- /dev/null +++ b/test/mqtt_relay_util.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +import sys +import os.path +sys.path.extend([ + os.path.realpath( + os.path.join(os.path.dirname(os.path.join(__file__)), '..') + ) +]) + +from argparse import ArgumentParser +from src.home.config import config +from src.home.mqtt.relay import MQTTRelayController + + +if __name__ == '__main__': + parser = ArgumentParser() + parser.add_argument('--on', action='store_true') + parser.add_argument('--off', action='store_true') + parser.add_argument('--stat', action='store_true') + + config.load('test_mqtt_relay', parser=parser) + arg = parser.parse_args() + + relay = MQTTRelayController('test') + relay.configure_tls() + relay.connect_and_loop(loop_forever=False) + + if arg.on: + relay.set_power(True) + + elif arg.off: + relay.set_power(False) + + elif arg.stat: + relay.send_stat(dict( + state=False, + signal=-59, + fw_v=1.0 + ))
\ No newline at end of file |