save
This commit is contained in:
parent
c976495222
commit
52db06e0c8
@ -6,7 +6,12 @@
|
|||||||
|
|
||||||
namespace homekit::main {
|
namespace homekit::main {
|
||||||
|
|
||||||
|
#ifndef CONFIG_TARGET_ESP01
|
||||||
|
#ifndef CONFIG_NO_RECOVERY
|
||||||
enum WorkingMode working_mode = WorkingMode::NORMAL;
|
enum WorkingMode working_mode = WorkingMode::NORMAL;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static const uint16_t recovery_boot_detection_ms = 2000;
|
static const uint16_t recovery_boot_detection_ms = 2000;
|
||||||
static const uint8_t recovery_boot_delay_ms = 100;
|
static const uint8_t recovery_boot_delay_ms = 100;
|
||||||
|
|
||||||
@ -22,8 +27,10 @@ static StopWatch blinkStopWatch;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_TARGET_ESP01
|
#ifndef CONFIG_TARGET_ESP01
|
||||||
|
#ifndef CONFIG_NO_RECOVERY
|
||||||
static DNSServer* dnsServer = nullptr;
|
static DNSServer* dnsServer = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static void onWifiConnected(const WiFiEventStationModeGotIP& event);
|
static void onWifiConnected(const WiFiEventStationModeGotIP& event);
|
||||||
static void onWifiDisconnected(const WiFiEventStationModeDisconnected& event);
|
static void onWifiDisconnected(const WiFiEventStationModeDisconnected& event);
|
||||||
@ -45,6 +52,7 @@ static void wifiConnect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_TARGET_ESP01
|
#ifndef CONFIG_TARGET_ESP01
|
||||||
|
#ifndef CONFIG_NO_RECOVERY
|
||||||
static void wifiHotspot() {
|
static void wifiHotspot() {
|
||||||
led::mcu_led->on();
|
led::mcu_led->on();
|
||||||
|
|
||||||
@ -71,13 +79,16 @@ static void waitForRecoveryPress() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
WiFi.disconnect();
|
WiFi.disconnect();
|
||||||
|
#ifndef CONFIG_NO_RECOVERY
|
||||||
#ifndef CONFIG_TARGET_ESP01
|
#ifndef CONFIG_TARGET_ESP01
|
||||||
homekit::main::waitForRecoveryPress();
|
homekit::main::waitForRecoveryPress();
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
@ -95,25 +106,31 @@ void setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_TARGET_ESP01
|
#ifndef CONFIG_TARGET_ESP01
|
||||||
|
#ifndef CONFIG_NO_RECOVERY
|
||||||
switch (working_mode) {
|
switch (working_mode) {
|
||||||
case WorkingMode::RECOVERY:
|
case WorkingMode::RECOVERY:
|
||||||
wifiHotspot();
|
wifiHotspot();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WorkingMode::NORMAL:
|
case WorkingMode::NORMAL:
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnected);
|
wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnected);
|
||||||
wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnected);
|
wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnected);
|
||||||
wifiConnect();
|
wifiConnect();
|
||||||
|
#ifndef CONFIG_NO_RECOVERY
|
||||||
#ifndef CONFIG_TARGET_ESP01
|
#ifndef CONFIG_TARGET_ESP01
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop(LoopConfig* config) {
|
void loop(LoopConfig* config) {
|
||||||
|
#ifndef CONFIG_NO_RECOVERY
|
||||||
#ifndef CONFIG_TARGET_ESP01
|
#ifndef CONFIG_TARGET_ESP01
|
||||||
if (working_mode == WorkingMode::NORMAL) {
|
if (working_mode == WorkingMode::NORMAL) {
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
if (wifi_state == WiFiConnectionState::WAITING) {
|
if (wifi_state == WiFiConnectionState::WAITING) {
|
||||||
PRINT(".");
|
PRINT(".");
|
||||||
@ -166,6 +183,7 @@ void loop(LoopConfig* config) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifndef CONFIG_NO_RECOVERY
|
||||||
#ifndef CONFIG_TARGET_ESP01
|
#ifndef CONFIG_TARGET_ESP01
|
||||||
} else {
|
} else {
|
||||||
if (dnsServer != nullptr)
|
if (dnsServer != nullptr)
|
||||||
@ -176,6 +194,7 @@ void loop(LoopConfig* config) {
|
|||||||
httpServer->loop();
|
httpServer->loop();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onWifiConnected(const WiFiEventStationModeGotIP& event) {
|
static void onWifiConnected(const WiFiEventStationModeGotIP& event) {
|
||||||
|
@ -10,8 +10,10 @@
|
|||||||
#include <homekit/config.h>
|
#include <homekit/config.h>
|
||||||
#include <homekit/logging.h>
|
#include <homekit/logging.h>
|
||||||
#ifndef CONFIG_TARGET_ESP01
|
#ifndef CONFIG_TARGET_ESP01
|
||||||
|
#ifndef CONFIG_NO_RECOVERY
|
||||||
#include <homekit/http_server.h>
|
#include <homekit/http_server.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#include <homekit/wifi.h>
|
#include <homekit/wifi.h>
|
||||||
#include <homekit/mqtt/mqtt.h>
|
#include <homekit/mqtt/mqtt.h>
|
||||||
|
|
||||||
@ -20,6 +22,7 @@
|
|||||||
namespace homekit::main {
|
namespace homekit::main {
|
||||||
|
|
||||||
#ifndef CONFIG_TARGET_ESP01
|
#ifndef CONFIG_TARGET_ESP01
|
||||||
|
#ifndef CONFIG_NO_RECOVERY
|
||||||
enum class WorkingMode {
|
enum class WorkingMode {
|
||||||
RECOVERY, // AP mode, http server with configuration
|
RECOVERY, // AP mode, http server with configuration
|
||||||
NORMAL, // MQTT client
|
NORMAL, // MQTT client
|
||||||
@ -27,6 +30,7 @@ enum class WorkingMode {
|
|||||||
|
|
||||||
extern enum WorkingMode working_mode;
|
extern enum WorkingMode working_mode;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
enum class WiFiConnectionState {
|
enum class WiFiConnectionState {
|
||||||
WAITING = 0,
|
WAITING = 0,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "homekit_main",
|
"name": "homekit_main",
|
||||||
"version": "1.0.8",
|
"version": "1.0.10",
|
||||||
"build": {
|
"build": {
|
||||||
"flags": "-I../../include"
|
"flags": "-I../../include"
|
||||||
},
|
},
|
||||||
|
59
src/home/mqtt/relay.py
Normal file
59
src/home/mqtt/relay.py
Normal file
@ -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
|
@ -54,12 +54,17 @@ def bsd_parser(product_config: dict,
|
|||||||
arg_kwargs['type'] = int
|
arg_kwargs['type'] = int
|
||||||
elif kwargs['type'] == 'int':
|
elif kwargs['type'] == 'int':
|
||||||
arg_kwargs['type'] = int
|
arg_kwargs['type'] = int
|
||||||
|
elif kwargs['type'] == 'bool':
|
||||||
|
arg_kwargs['action'] = 'store_true'
|
||||||
|
arg_kwargs['required'] = False
|
||||||
else:
|
else:
|
||||||
raise TypeError(f'unsupported type {kwargs["type"]} for define {define_name}')
|
raise TypeError(f'unsupported type {kwargs["type"]} for define {define_name}')
|
||||||
else:
|
else:
|
||||||
arg_kwargs['action'] = 'store_true'
|
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)
|
bsd_walk(product_config, f)
|
||||||
|
|
||||||
@ -76,6 +81,9 @@ def bsd_get(product_config: dict,
|
|||||||
enums.append(f'CONFIG_{define_name}')
|
enums.append(f'CONFIG_{define_name}')
|
||||||
defines[f'CONFIG_{define_name}'] = f'HOMEKIT_{attr_value.upper()}'
|
defines[f'CONFIG_{define_name}'] = f'HOMEKIT_{attr_value.upper()}'
|
||||||
return
|
return
|
||||||
|
if kwargs['type'] == 'bool':
|
||||||
|
defines[f'CONFIG_{define_name}'] = True
|
||||||
|
return
|
||||||
defines[f'CONFIG_{define_name}'] = str(attr_value)
|
defines[f'CONFIG_{define_name}'] = str(attr_value)
|
||||||
bsd_walk(product_config, f)
|
bsd_walk(product_config, f)
|
||||||
return defines, enums
|
return defines, enums
|
||||||
|
18
test/mqtt_relay_server_util.py
Executable file
18
test/mqtt_relay_server_util.py
Executable file
@ -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()
|
39
test/mqtt_relay_util.py
Executable file
39
test/mqtt_relay_util.py
Executable file
@ -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
|
||||||
|
))
|
Loading…
x
Reference in New Issue
Block a user