Skip to content

Commit 0e8e0ee

Browse files
committed
perf(api): downsample /api/history responses to keep Pi dashboard fast
1 parent 93ef8a5 commit 0e8e0ee

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

‎api/__init__.py‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
from typing import Any
1212
from zoneinfo import ZoneInfo
1313

14-
import pymysql
1514
import asyncio
15+
import math
16+
17+
import pymysql
1618
from fastapi import FastAPI, HTTPException, Query, WebSocket, WebSocketDisconnect
1719
from pydantic import BaseModel
1820
from fastapi.middleware.cors import CORSMiddleware
@@ -100,11 +102,18 @@ def api_history(
100102
"",
101103
description="Comma-separated register names (empty = all)",
102104
),
105+
max_points: int = Query(
106+
500,
107+
ge=10,
108+
le=5000,
109+
description="Maximum number of snapshot points to return; larger windows are downsampled",
110+
),
103111
):
104112
"""Return time-series data for the last N minutes.
105113
106114
Returns a list of {timestamp, registers: {name: value}} objects.
107115
If *fields* is provided, only those registers are included.
116+
Larger windows are automatically downsampled to keep responses fast.
108117
"""
109118
since = datetime.now(TZ) - timedelta(minutes=minutes)
110119
conn = _get_conn()
@@ -119,6 +128,11 @@ def api_history(
119128
if not snapshots:
120129
return {"snapshots": [], "count": 0}
121130

131+
# Downsample large windows to avoid multi-second responses on a Pi.
132+
if len(snapshots) > max_points:
133+
step = math.ceil(len(snapshots) / max_points)
134+
snapshots = snapshots[::step]
135+
122136
snap_ids = [s[0] for s in snapshots]
123137
placeholders = ",".join(["%s"] * len(snap_ids))
124138

0 commit comments

Comments
 (0)