summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorEvgeny Zinoviev <me@ch1p.io>2023-09-13 09:34:49 +0300
committerEvgeny Sorokin <me@ch1p.io>2024-01-13 00:57:00 +0000
commit7058d0f5063dc9b065248d0a906cf874788caecf (patch)
tree26468a5d5a7f8c05804911b3fbf649d952bfd8f1 /bin
parent57955b596485ecce1ffd4395e23c078358cc5ddd (diff)
save
Diffstat (limited to 'bin')
-rwxr-xr-xbin/mqtt_node_util.py56
-rw-r--r--bin/web_kbn.py117
2 files changed, 161 insertions, 12 deletions
diff --git a/bin/mqtt_node_util.py b/bin/mqtt_node_util.py
index cf451fd..5587739 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()
@@ -23,18 +48,23 @@ if __name__ == '__main__':
help='mqtt modules to include')
parser.add_argument('--switch-relay', choices=[0, 1], type=int,
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')
+ 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,27 +72,29 @@ 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:
for m in arg.modules:
kwargs = {}
- if m == 'relay' and arg.legacy_relay:
+ if m == 'relay' and MqttNodesConfig().node_uses_legacy_relay_power_payload(arg.node_id):
kwargs['legacy_topics'] = True
+ if m == 'temphum' and MqttNodesConfig().node_uses_legacy_temphum_data_payload(arg.node_id):
+ kwargs['legacy_payload'] = 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/bin/web_kbn.py b/bin/web_kbn.py
new file mode 100644
index 0000000..8b4ca6f
--- /dev/null
+++ b/bin/web_kbn.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+import asyncio
+import jinja2
+import aiohttp_jinja2
+import os
+import __py_include
+
+from io import StringIO
+from typing import Optional
+from homekit.config import config, AppConfigUnit
+from homekit.util import homekit_path
+from aiohttp import web
+from homekit import http
+from homekit.modem import ModemsConfig
+
+
+class WebKbnConfig(AppConfigUnit):
+ NAME = 'web_kbn'
+
+ @classmethod
+ def schema(cls) -> Optional[dict]:
+ return {
+ 'listen_addr': cls._addr_schema(required=True),
+ 'assets_public_path': {'type': 'string'}
+ }
+
+
+STATIC_FILES = [
+ 'bootstrap.min.css',
+ 'bootstrap.min.js',
+ 'polyfills.js',
+ 'app.js',
+ 'app.css'
+]
+
+
+def get_js_link(file, version) -> str:
+ if version:
+ file += f'?version={version}'
+ return f'<script src="{config.app_config["assets_public_path"]}/{file}" type="text/javascript"></script>'
+
+
+def get_css_link(file, version) -> str:
+ if version:
+ file += f'?version={version}'
+ return f'<link rel="stylesheet" type="text/css" href="{config.app_config["assets_public_path"]}/{file}">'
+
+
+def get_head_static() -> str:
+ buf = StringIO()
+ for file in STATIC_FILES:
+ v = 1
+ try:
+ q_ind = file.index('?')
+ v = file[q_ind+1:]
+ file = file[:file.index('?')]
+ except ValueError:
+ pass
+
+ if file.endswith('.js'):
+ buf.write(get_js_link(file, v))
+ else:
+ buf.write(get_css_link(file, v))
+ return buf.getvalue()
+
+
+class WebSite(http.HTTPServer):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ aiohttp_jinja2.setup(
+ self.app,
+ loader=jinja2.FileSystemLoader(homekit_path('web', 'kbn_templates'))
+ )
+
+ self.app.router.add_static('/assets/', path=homekit_path('web', 'kbn_assets'))
+
+ self.get('/main.cgi', self.get_index)
+ self.get('/modems.cgi', self.get_modems)
+
+ async def render_page(self,
+ req: http.Request,
+ template_name: str,
+ title: Optional[str] = None,
+ context: Optional[dict] = None):
+ if context is None:
+ context = {}
+ context = {
+ **context,
+ 'head_static': get_head_static()
+ }
+ if title is not None:
+ context['title'] = title
+ response = aiohttp_jinja2.render_template(template_name+'.j2', req, context=context)
+ return response
+
+ async def get_index(self, req: http.Request):
+ return await self.render_page(req, 'index',
+ title="Home web site")
+
+ async def get_modems(self, req: http.Request):
+ mc = ModemsConfig()
+ print(mc)
+ return await self.render_page(req, 'modems',
+ title='Состояние модемов',
+ context=dict(modems=ModemsConfig()))
+
+
+if __name__ == '__main__':
+ config.load_app(WebKbnConfig)
+
+ loop = asyncio.get_event_loop()
+ # print(config.app_config)
+
+ print(config.app_config['listen_addr'].host)
+ server = WebSite(config.app_config['listen_addr'])
+ server.run()