Coverage for src/webui.py: 0%
34 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-09-11 22:45 +0900
« prev ^ index » next coverage.py v7.9.1, created at 2025-09-11 22:45 +0900
1#!/usr/bin/env python3
2"""
3電力計のデータ収集状況を表示する Web サーバです。
5Usage:
6 webui.py [-c CONFIG] [-p PORT] [-D]
8Options:
9 -c CONFIG : 通常モードで使う設定ファイルを指定します。[default: config.yaml]
10 -p PORT : WEB サーバのポートを指定します。[default: 5000]
11 -D : デバッグモードで動作します。
12"""
14import logging
15import pathlib
16import signal
17import sys
19import flask
20import flask_cors
21import my_lib.config
22import my_lib.logger
24SCHEMA_CONFIG = "config.schema"
27def term():
28 # 子プロセスを終了
29 my_lib.proc_util.kill_child()
31 # プロセス終了
32 logging.info("Graceful shutdown completed")
33 sys.exit(0)
36def sig_handler(num, frame): # noqa: ARG001
37 logging.warning("receive signal %d", num)
39 if num in (signal.SIGTERM, signal.SIGINT):
40 term()
43def create_app(config):
44 # NOTE: アクセスログは無効にする
45 logging.getLogger("werkzeug").setLevel(logging.ERROR)
47 import my_lib.webapp.config
49 my_lib.webapp.config.URL_PREFIX = "/wattmeter-sharp/metrics"
50 my_lib.webapp.config.init(config)
52 import my_lib.webapp.base
53 import my_lib.webapp.util
55 import sharp_hems.webui.api.metrics
57 app = flask.Flask("wattmeter-sharp")
59 flask_cors.CORS(app)
61 app.config["CONFIG"] = config
63 app.register_blueprint(my_lib.webapp.base.blueprint, url_prefix=my_lib.webapp.config.URL_PREFIX)
64 app.register_blueprint(my_lib.webapp.base.blueprint_default)
65 app.register_blueprint(my_lib.webapp.util.blueprint, url_prefix=my_lib.webapp.config.URL_PREFIX)
66 app.register_blueprint(sharp_hems.webui.api.metrics.blueprint, url_prefix=my_lib.webapp.config.URL_PREFIX)
68 my_lib.webapp.config.show_handler_list(app)
70 return app
73if __name__ == "__main__":
74 import docopt
76 args = docopt.docopt(__doc__)
78 config_file = args["-c"]
79 port = args["-p"]
80 debug_mode = args["-D"]
82 my_lib.logger.init("hems.wattmeter-sharp", level=logging.DEBUG if debug_mode else logging.INFO)
84 config = my_lib.config.load(config_file, pathlib.Path(SCHEMA_CONFIG))
86 app = create_app(config)
88 signal.signal(signal.SIGTERM, sig_handler)
90 # Flaskアプリケーションを実行
91 try:
92 # NOTE: スクリプトの自動リロード停止したい場合は use_reloader=False にする
93 app.run(host="0.0.0.0", port=port, threaded=True, use_reloader=True, debug=debug_mode) # noqa: S104
94 except KeyboardInterrupt:
95 logging.info("Received KeyboardInterrupt, shutting down...")
96 sig_handler(signal.SIGINT, None)