Skip to content

Commit 0d6f7a7

Browse files
committed
introduce time_cached for low-level APIs
1 parent 88f4f01 commit 0d6f7a7

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

franklinwh/client.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
"""
66

77
from __future__ import annotations
8-
from collections.abc import Callable
98

109
import asyncio
10+
from collections.abc import Callable
1111
from dataclasses import dataclass
1212
from enum import Enum
1313
import hashlib
@@ -19,6 +19,7 @@
1919
import httpx
2020

2121
from .api import DEFAULT_URL_BASE
22+
from .timed_cache import time_cached
2223

2324

2425
class AccessoryType(Enum):
@@ -599,19 +600,22 @@ def set_value(keys, value):
599600
return json.loads(data)
600601

601602
# Sends a 203 which is a high level status
603+
@time_cached()
602604
async def _status(self):
603605
payload = self._build_payload(203, {"opt": 1, "refreshData": 1})
604606
data = (await self._mqtt_send(payload))["result"]["dataArea"]
605607
return json.loads(data)
606608

607609
# Sends a 311 which appears to be a more specific switch command
610+
@time_cached()
608611
async def _switch_status(self):
609612
payload = self._build_payload(311, {"opt": 0, "order": self.gateway})
610613
data = (await self._mqtt_send(payload))["result"]["dataArea"]
611614
return json.loads(data)
612615

613616
# Sends a 353 which grabs real-time smart-circuit load information
614617
# https://github.com/richo/homeassistant-franklinwh/issues/27#issuecomment-2714422732
618+
@time_cached()
615619
async def _switch_usage(self):
616620
payload = self._build_payload(353, {"opt": 0, "order": self.gateway})
617621
data = (await self._mqtt_send(payload))["result"]["dataArea"]
@@ -739,6 +743,7 @@ async def set_grid_status(self, status: GridStatus, soc: int = 5):
739743
}
740744
await self._post(url, json.dumps(payload))
741745

746+
@time_cached()
742747
async def get_composite_info(self):
743748
"""Get composite information about the FranklinWH gateway."""
744749
url = self.url_base + "hes-gateway/terminal/getDeviceCompositeInfo"

franklinwh/timed_cache.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""Cache a function result for a specified time."""
2+
3+
import asyncio
4+
from datetime import datetime, timedelta
5+
from functools import wraps
6+
7+
__cache = {}
8+
__lock = asyncio.Lock()
9+
10+
11+
def time_cached(ttl: timedelta = timedelta(seconds=2)):
12+
"""Decorator to cache function results for a specified time-to-live (TTL)."""
13+
14+
def wrapper(func):
15+
@wraps(func)
16+
async def wrapped(*args, **kwargs):
17+
async with __lock:
18+
now = datetime.now()
19+
for key, value in __cache.copy().items():
20+
if now > value[0]:
21+
del __cache[key]
22+
key = (func.__name__, args, frozenset(kwargs.items()))
23+
if key not in __cache:
24+
__cache[key] = (now + ttl, await func(*args, **kwargs))
25+
return __cache[key][1]
26+
27+
setattr(wrapped, "clear", __cache.clear)
28+
return wrapped
29+
30+
return wrapper

0 commit comments

Comments
 (0)