Compare commits
No commits in common. "2349e58924b010b01f6e33160053bd34027beab8" and "7ac0a4106cdc621f7b62dab7317d7c0c6317fb9b" have entirely different histories.
2349e58924
...
7ac0a4106c
4 changed files with 11 additions and 31 deletions
|
|
@ -1,6 +1,4 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import logging
|
|
||||||
from contextvars import ContextVar
|
from contextvars import ContextVar
|
||||||
from argparse import ArgumentParser, Namespace
|
from argparse import ArgumentParser, Namespace
|
||||||
|
|
||||||
|
|
@ -74,10 +72,6 @@ def main():
|
||||||
)
|
)
|
||||||
args = argp.parse_args()
|
args = argp.parse_args()
|
||||||
|
|
||||||
# setup logging
|
|
||||||
logging.basicConfig(level=logging.DEBUG, format="[%(levelname)s] %(filename)s: %(message)s")
|
|
||||||
|
|
||||||
# setup app
|
|
||||||
app_config.set(args)
|
app_config.set(args)
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from dooris_api.app import app
|
from dooris_api.app import app
|
||||||
|
|
@ -86,7 +80,6 @@ def main():
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
app.mount("/", StaticFiles(directory=args.serve_static, html=True), name="static")
|
app.mount("/", StaticFiles(directory=args.serve_static, html=True), name="static")
|
||||||
|
|
||||||
# start webserver
|
|
||||||
config = uvicorn.Config(app, port=8000, log_level="debug")
|
config = uvicorn.Config(app, port=8000, log_level="debug")
|
||||||
server = uvicorn.Server(config)
|
server = uvicorn.Server(config)
|
||||||
server.run()
|
server.run()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
from typing import Optional, List, AsyncIterable
|
from typing import Optional, List, AsyncIterable
|
||||||
import logging
|
import logging
|
||||||
import secrets
|
import secrets
|
||||||
|
import sys
|
||||||
from datetime import datetime, UTC
|
from datetime import datetime, UTC
|
||||||
from fastapi import FastAPI, Request, Response, status
|
from fastapi import FastAPI, Request, Response, status
|
||||||
from fastapi.responses import RedirectResponse
|
from fastapi.responses import RedirectResponse
|
||||||
|
|
@ -21,6 +22,12 @@ logger = logging.getLogger(__name__)
|
||||||
async def lifespan(app: FastAPI):
|
async def lifespan(app: FastAPI):
|
||||||
app_cfg = app_config.get()
|
app_cfg = app_config.get()
|
||||||
|
|
||||||
|
root_logger = logging.getLogger("")
|
||||||
|
root_logger.setLevel(logging.INFO)
|
||||||
|
root_logger.addHandler(logging.StreamHandler(sys.stderr))
|
||||||
|
app_logger = logging.getLogger("dooris_api")
|
||||||
|
app_logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
app.extra["oidc_client"] = OpenidClient.from_issuer_url(
|
app.extra["oidc_client"] = OpenidClient.from_issuer_url(
|
||||||
url=app_cfg.openid_issuer,
|
url=app_cfg.openid_issuer,
|
||||||
authentication_redirect_uri=f"{app_cfg.base_url}/auth/login-callback",
|
authentication_redirect_uri=f"{app_cfg.base_url}/auth/login-callback",
|
||||||
|
|
@ -35,7 +42,8 @@ async def lifespan(app: FastAPI):
|
||||||
auth=BasicAuth(app_cfg.ccujack_user, app_cfg.ccujack_password),
|
auth=BasicAuth(app_cfg.ccujack_user, app_cfg.ccujack_password),
|
||||||
mqtt_conn=app_cfg.ccujack_mqtt,
|
mqtt_conn=app_cfg.ccujack_mqtt,
|
||||||
)
|
)
|
||||||
await app.extra["ccujack"].start()
|
await app.extra["ccujack"].connect_mqtt()
|
||||||
|
await app.extra["ccujack"].find_locks()
|
||||||
|
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,6 @@ class CCUJackClient:
|
||||||
locks: LockData
|
locks: LockData
|
||||||
param_values: Dict[str, Any]
|
param_values: Dict[str, Any]
|
||||||
task_process_messages: asyncio.Task
|
task_process_messages: asyncio.Task
|
||||||
task_find_locks: asyncio.Task
|
|
||||||
data_updated: asyncio.Event
|
data_updated: asyncio.Event
|
||||||
|
|
||||||
def __init__(self, base_uri: str, auth: BasicAuth, mqtt_conn: str):
|
def __init__(self, base_uri: str, auth: BasicAuth, mqtt_conn: str):
|
||||||
|
|
@ -86,16 +85,10 @@ class CCUJackClient:
|
||||||
self.locks = None
|
self.locks = None
|
||||||
self.param_values = dict()
|
self.param_values = dict()
|
||||||
self.task_process_messages = None
|
self.task_process_messages = None
|
||||||
self.task_find_locks = None
|
|
||||||
self.data_updated = asyncio.Event()
|
self.data_updated = asyncio.Event()
|
||||||
|
|
||||||
async def start(self):
|
async def connect_mqtt(self):
|
||||||
await self.mqtt.connect()
|
await self.mqtt.connect()
|
||||||
await self.find_locks()
|
|
||||||
|
|
||||||
self.task_find_locks = asyncio.get_running_loop().create_task(
|
|
||||||
self.cron(), name="ccujack-cron"
|
|
||||||
)
|
|
||||||
self.task_process_messages = asyncio.get_running_loop().create_task(
|
self.task_process_messages = asyncio.get_running_loop().create_task(
|
||||||
self.process_mqt_messages(), name="process-mqtt-messages"
|
self.process_mqt_messages(), name="process-mqtt-messages"
|
||||||
)
|
)
|
||||||
|
|
@ -123,7 +116,6 @@ class CCUJackClient:
|
||||||
# save the result
|
# save the result
|
||||||
new_locks = [i for i in device_infos if i[0].type == DEVICE_TYPE_LOCK]
|
new_locks = [i for i in device_infos if i[0].type == DEVICE_TYPE_LOCK]
|
||||||
if new_locks != self.locks:
|
if new_locks != self.locks:
|
||||||
logger.info("Found new locks, updating state")
|
|
||||||
self.locks = new_locks
|
self.locks = new_locks
|
||||||
self.data_updated.set()
|
self.data_updated.set()
|
||||||
self.data_updated.clear()
|
self.data_updated.clear()
|
||||||
|
|
@ -156,17 +148,6 @@ class CCUJackClient:
|
||||||
finally:
|
finally:
|
||||||
self.data_updated.clear()
|
self.data_updated.clear()
|
||||||
|
|
||||||
async def cron(self):
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
|
|
||||||
await asyncio.sleep(60 * 60) # 1 hour
|
|
||||||
logger.info("Running CCUJack cron")
|
|
||||||
await self.find_locks()
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception(f"Error in CCUJack cron task: {e}")
|
|
||||||
|
|
||||||
async def query_param_value(self, address: str) -> CCUValue:
|
async def query_param_value(self, address: str) -> CCUValue:
|
||||||
if address in self.param_values:
|
if address in self.param_values:
|
||||||
return self.param_values[address]
|
return self.param_values[address]
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
# https://github.com/eclipse-paho/paho.mqtt.python/blob/master/examples/loop_asyncio.py
|
# https://github.com/eclipse-paho/paho.mqtt.python/blob/master/examples/loop_asyncio.py
|
||||||
#
|
#
|
||||||
|
|
||||||
from typing import Any, Set, Iterable
|
from typing import Any, List, Set, Iterable
|
||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import socket
|
import socket
|
||||||
|
|
@ -132,7 +132,6 @@ class AsyncMqttClient:
|
||||||
self.fut_subscribe = asyncio.get_running_loop().create_future()
|
self.fut_subscribe = asyncio.get_running_loop().create_future()
|
||||||
self.client.subscribe([(i, qos) for i in to_add])
|
self.client.subscribe([(i, qos) for i in to_add])
|
||||||
await self.fut_subscribe
|
await self.fut_subscribe
|
||||||
self.active_subscriptions.update(to_add)
|
|
||||||
|
|
||||||
to_remove = self.active_subscriptions.difference(topics)
|
to_remove = self.active_subscriptions.difference(topics)
|
||||||
if to_remove:
|
if to_remove:
|
||||||
|
|
@ -140,7 +139,6 @@ class AsyncMqttClient:
|
||||||
self.fut_unsubscribe = asyncio.get_running_loop().create_future()
|
self.fut_unsubscribe = asyncio.get_running_loop().create_future()
|
||||||
self.client.unsubscribe(list(to_remove))
|
self.client.unsubscribe(list(to_remove))
|
||||||
await self.fut_unsubscribe
|
await self.fut_unsubscribe
|
||||||
self.active_subscriptions.difference_update(to_remove)
|
|
||||||
|
|
||||||
async def connect(self):
|
async def connect(self):
|
||||||
server_host, server_port = self.connection_string.rsplit(":", maxsplit=1)
|
server_host, server_port = self.connection_string.rsplit(":", maxsplit=1)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue