About to push
This commit is contained in:
+58
@@ -49,6 +49,30 @@ def create_app() -> Flask:
|
||||
collect_interval_seconds=config.collect_interval_seconds,
|
||||
)
|
||||
|
||||
@app.get("/devices/<device_id>")
|
||||
def device_detail(device_id: str) -> str:
|
||||
tz = ZoneInfo(config.app_timezone)
|
||||
selected_date_text = request.args.get("date") or datetime.now(tz).date().isoformat()
|
||||
selected_date = date.fromisoformat(selected_date_text)
|
||||
start_utc, end_utc = local_date_range_to_utc(selected_date, selected_date, tz)
|
||||
|
||||
with SessionLocal() as session:
|
||||
device = session.get(Device, device_id)
|
||||
if device is None or device.device_type not in SENSOR_DEVICE_TYPES:
|
||||
return render_template("not_found.html"), 404
|
||||
readings = load_device_readings(session, device_id, start_utc, end_utc)
|
||||
|
||||
return render_template(
|
||||
"device.html",
|
||||
device=device,
|
||||
date=selected_date_text,
|
||||
readings=readings,
|
||||
stats=stats_by_device(readings).get(device_id),
|
||||
chart_json=json.dumps(chart_payload(readings, tz)),
|
||||
timezone=config.app_timezone,
|
||||
local_readings=readings_for_display(readings, tz),
|
||||
)
|
||||
|
||||
@app.get("/reports")
|
||||
def reports() -> str:
|
||||
tz = ZoneInfo(config.app_timezone)
|
||||
@@ -147,6 +171,25 @@ def load_readings(session: Session, start_utc: datetime, end_utc: datetime) -> l
|
||||
return list(session.scalars(stmt))
|
||||
|
||||
|
||||
def load_device_readings(
|
||||
session: Session,
|
||||
device_id: str,
|
||||
start_utc: datetime,
|
||||
end_utc: datetime,
|
||||
) -> list[Reading]:
|
||||
stmt = (
|
||||
select(Reading)
|
||||
.options(joinedload(Reading.device))
|
||||
.where(
|
||||
Reading.device_id == device_id,
|
||||
Reading.recorded_at >= start_utc,
|
||||
Reading.recorded_at < end_utc,
|
||||
)
|
||||
.order_by(Reading.recorded_at)
|
||||
)
|
||||
return list(session.scalars(stmt))
|
||||
|
||||
|
||||
def latest_by_device(session: Session) -> dict[str, Reading]:
|
||||
subquery = (
|
||||
select(Reading.device_id, func.max(Reading.recorded_at).label("latest_at"))
|
||||
@@ -204,6 +247,21 @@ def chart_payload(readings: list[Reading], tz: ZoneInfo) -> list[dict[str, objec
|
||||
return list(series.values())
|
||||
|
||||
|
||||
def readings_for_display(readings: list[Reading], tz: ZoneInfo) -> list[dict[str, object]]:
|
||||
rows = []
|
||||
for reading in readings:
|
||||
local_time = reading.recorded_at.replace(tzinfo=timezone.utc).astimezone(tz)
|
||||
rows.append(
|
||||
{
|
||||
"timestamp": local_time.strftime("%Y-%m-%d %H:%M"),
|
||||
"temperature": reading.temperature,
|
||||
"humidity": reading.humidity,
|
||||
"battery": reading.battery,
|
||||
}
|
||||
)
|
||||
return rows
|
||||
|
||||
|
||||
def report_rows(
|
||||
session: Session,
|
||||
start_utc: datetime,
|
||||
|
||||
Reference in New Issue
Block a user