75 lines
1.9 KiB
TypeScript
75 lines
1.9 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import type { ModuleSensorResponse } from "../../../types/meteo";
|
|
|
|
export type AccumulatedBucket = {
|
|
label: string;
|
|
from: string;
|
|
to: string;
|
|
total: number;
|
|
unit?: string;
|
|
};
|
|
|
|
type AccumulatedRange = "7d" | "30d" | "month" | "year";
|
|
|
|
const BACKEND_URL = "http://localhost:18450";
|
|
|
|
export function useAccumulatedHistory(
|
|
sensor: ModuleSensorResponse | null,
|
|
range: AccumulatedRange,
|
|
) {
|
|
const [buckets, setBuckets] = useState<AccumulatedBucket[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (!sensor) {
|
|
setBuckets([]);
|
|
return;
|
|
}
|
|
|
|
const sensorKey = sensor.key;
|
|
const controller = new AbortController();
|
|
|
|
async function loadAccumulated() {
|
|
try {
|
|
setLoading(true);
|
|
|
|
const params = new URLSearchParams({
|
|
key: sensorKey,
|
|
range,
|
|
});
|
|
|
|
const response = await fetch(
|
|
`${BACKEND_URL}/api/historian/accumulated?${params.toString()}`,
|
|
{ signal: controller.signal },
|
|
);
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Failed to load accumulated history");
|
|
}
|
|
|
|
const payload = (await response.json()) as AccumulatedBucket[];
|
|
setBuckets(payload);
|
|
} catch (error) {
|
|
if (controller.signal.aborted) return;
|
|
|
|
console.error("Failed to load accumulated history", error);
|
|
setBuckets([]);
|
|
} finally {
|
|
if (!controller.signal.aborted) {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
loadAccumulated();
|
|
|
|
return () => controller.abort();
|
|
}, [sensor?.key, range]);
|
|
|
|
return {
|
|
buckets,
|
|
loading,
|
|
};
|
|
}
|
|
|
|
export type { AccumulatedRange }; |