api: refactor ccujack state keeping

This commit is contained in:
lilly 2026-05-14 15:36:46 +02:00
commit b623082c4a
Signed by: lilly
SSH key fingerprint: SHA256:y9T5GFw2A20WVklhetIxG1+kcg/Ce0shnQmbu1LQ37g
5 changed files with 22 additions and 36 deletions

View file

@ -9,7 +9,6 @@ from fastapi.responses import RedirectResponse
from contextlib import asynccontextmanager
from simple_openid_connect.client import OpenidClient
from simple_openid_connect.data import TokenSuccessResponse, RpInitiatedLogoutRequest
from cachetools import TTLCache
from aiohttp import BasicAuth
from dooris_api import deps, models, exceptions, app_config
@ -37,12 +36,11 @@ async def lifespan(app: FastAPI):
scope=app_cfg.openid_scope,
)
app.extra["cache"] = TTLCache(maxsize=64, ttl=30 * 60)
app.extra["ccujack"] = CCUJackClient(
"https://hmdooris-ccu.ccchh.net:2122",
auth=BasicAuth("dooris", os.environ["HMDOORIS_PW"]),
)
await app.extra["ccujack"].find_locks()
yield
@ -178,7 +176,10 @@ async def logout(
):
deps.clear_auth_state(resp)
return oidc_client.initiate_logout(
RpInitiatedLogoutRequest(id_token_hint=current_user.raw_id_token, post_logout_redirect_uri=f"{app_config.get().base_url}/")
RpInitiatedLogoutRequest(
id_token_hint=current_user.raw_id_token,
post_logout_redirect_uri=f"{app_config.get().base_url}/",
)
)
@ -188,19 +189,11 @@ async def logout(
responses={status.HTTP_401_UNAUTHORIZED: {"model": models.HttpProblemDetail}},
)
async def list_locks(
ccujack: deps.CCUJackClient, cache: deps.Cache
ccujack: deps.CCUJackClient
) -> List[models.Lock]:
# discover locks from ccujack
CACHE_KEY = "ccu-find-locks"
if CACHE_KEY in cache:
locks = cache[CACHE_KEY]
else:
locks = await ccujack.find_locks()
cache[CACHE_KEY] = locks
# assemble result objects
result = []
for i_lock, lock_channels in locks:
for i_lock, lock_channels in ccujack.locks:
status_data = dict()
for i_channel, channel_params in lock_channels:
for i_param in channel_params:
@ -244,3 +237,12 @@ async def list_locks(
)
return result
@app.patch(
"/api/locks/{name}",
tags=["locks"],
responses={status.HTTP_401_UNAUTHORIZED: {"model": models.HttpProblemDetail}},
)
async def operate_lock(name: str):
pass

View file

@ -55,13 +55,17 @@ class CCUValue(BaseModel):
v: Any
LockData = List[Tuple[CCUDeviceInfo, List[Tuple[CCUChannelInfo, List[CCUParamInfo]]]]]
class CCUJackClient:
base_uri: str
locks: LockData
def __init__(self, base_uri: str, auth: BasicAuth):
self.http = ClientSession(base_url=base_uri, auth=auth, raise_for_status=True, connector=TCPConnector(ssl=False))
self.locks = None
async def find_locks(self) -> List[Tuple[CCUDeviceInfo, List[Tuple[CCUChannelInfo, List[CCUParamInfo]]]]]:
async def find_locks(self):
logger.debug("Inspecting lock devices present in CCUJack")
async with self.http.get("/device") as resp:
devices = CCUDeviceList.model_validate(await resp.json())
@ -72,7 +76,7 @@ class CCUJackClient:
if i.rel == "device"
])
return [
self.locks = [
i
for i in device_infos
if i[0].type == DEVICE_TYPE_LOCK

View file

@ -4,7 +4,6 @@ from datetime import datetime, UTC, timedelta
from fastapi import Request, Depends, Response
from simple_openid_connect.data import TokenSuccessResponse
from simple_openid_connect.client import OpenidClient
from cachetools import Cache
from dooris_api import models, exceptions
from dooris_api.ccujack import CCUJackClient
@ -124,13 +123,6 @@ def clear_auth_state(resp: Response):
CurrentUser = Annotated[Optional[models.CurrentUser], Depends(get_current_user)]
def get_cache(req: Request) -> Cache:
return req.app.extra["cache"]
Cache = Annotated[Cache, Depends(get_cache)]
def get_ccujack(req: Request) -> CCUJackClient:
return req.app.extra["ccujack"]