Show current consumption chart

This commit is contained in:
Pierre HUBERT 2024-09-26 22:37:43 +02:00
parent 2e72634abf
commit 903f1fa8ce
4 changed files with 77 additions and 51 deletions

View File

@ -2,9 +2,9 @@ import { APIClient } from "./ApiClient";
export class EnergyApi { export class EnergyApi {
/** /**
* Get current house consumption * Get current grid consumption
*/ */
static async CurrConsumption(): Promise<number> { static async GridConsumption(): Promise<number> {
const data = await APIClient.exec({ const data = await APIClient.exec({
method: "GET", method: "GET",
uri: "/energy/curr_consumption", uri: "/energy/curr_consumption",
@ -12,6 +12,18 @@ export class EnergyApi {
return data.data.consumption; return data.data.consumption;
} }
/**
* Get grid consumption history
*/
static async GridConsumptionHistory(): Promise<number[]> {
return (
await APIClient.exec({
method: "GET",
uri: "/energy/curr_consumption/history",
})
).data;
}
/** /**
* Get current cached consumption * Get current cached consumption
*/ */
@ -22,4 +34,16 @@ export class EnergyApi {
}); });
return data.data.consumption; return data.data.consumption;
} }
/**
* Get relays consumption history
*/
static async RelaysConsumptionHistory(): Promise<number[]> {
return (
await APIClient.exec({
method: "GET",
uri: "/energy/relays_consumption/history",
})
).data;
}
} }

View File

@ -26,12 +26,6 @@ export function CachedConsumptionWidget(): React.ReactElement {
}); });
return ( return (
<StatCard <StatCard title="Cached consumption" value={val?.toString() ?? "Loading"} />
title="Cached consumption"
data={[]}
interval="Current data"
trend="neutral"
value={val?.toString() ?? "Loading"}
/>
); );
} }

View File

@ -7,11 +7,14 @@ export function CurrConsumptionWidget(): React.ReactElement {
const snackbar = useSnackbar(); const snackbar = useSnackbar();
const [val, setVal] = React.useState<undefined | number>(); const [val, setVal] = React.useState<undefined | number>();
const [history, setHistory] = React.useState<number[] | undefined>();
const refresh = async () => { const refresh = async () => {
try { try {
const s = await EnergyApi.CurrConsumption(); const s = await EnergyApi.GridConsumption();
const history = await EnergyApi.GridConsumptionHistory();
setVal(s); setVal(s);
setHistory(history);
} catch (e) { } catch (e) {
console.error(e); console.error(e);
snackbar("Failed to refresh current consumption!"); snackbar("Failed to refresh current consumption!");
@ -19,7 +22,6 @@ export function CurrConsumptionWidget(): React.ReactElement {
}; };
React.useEffect(() => { React.useEffect(() => {
refresh();
const i = setInterval(() => refresh(), 3000); const i = setInterval(() => refresh(), 3000);
return () => clearInterval(i); return () => clearInterval(i);
@ -28,9 +30,8 @@ export function CurrConsumptionWidget(): React.ReactElement {
return ( return (
<StatCard <StatCard
title="Current consumption" title="Current consumption"
data={[]} data={history ?? []}
interval="Current data" interval="Last day"
trend="neutral"
value={val?.toString() ?? "Loading"} value={val?.toString() ?? "Loading"}
/> />
); );

View File

@ -11,24 +11,25 @@ import { areaElementClasses } from "@mui/x-charts/LineChart";
export type StatCardProps = { export type StatCardProps = {
title: string; title: string;
value: string; value: string;
interval: string; interval?: string;
trend: "up" | "down" | "neutral"; trend?: "up" | "down" | "neutral";
data: number[]; data?: number[];
}; };
function getDaysInMonth(month: number, year: number) { function last24Hours(): string[] {
const date = new Date(year, month, 0); let res: Array<string> = [];
const monthName = date.toLocaleDateString("en-US", {
month: "short", for (let index = 0; index < 3600 * 24; index += 60 * 10) {
}); const date = new Date();
const daysInMonth = date.getDate(); date.setTime(date.getTime() - index * 1000);
const days = []; res.push(date.getHours() + "h" + date.getMinutes());
let i = 1;
while (days.length < daysInMonth) {
days.push(`${monthName} ${i}`);
i += 1;
} }
return days;
res.reverse();
console.log(res);
return res;
} }
function AreaGradient({ color, id }: { color: string; id: string }) { function AreaGradient({ color, id }: { color: string; id: string }) {
@ -50,7 +51,6 @@ export default function StatCard({
data, data,
}: StatCardProps) { }: StatCardProps) {
const theme = useTheme(); const theme = useTheme();
const daysInWeek = getDaysInMonth(4, 2024);
const trendColors = { const trendColors = {
up: up:
@ -73,8 +73,8 @@ export default function StatCard({
neutral: "default" as const, neutral: "default" as const,
}; };
const color = labelColors[trend]; const color = labelColors[trend ?? "neutral"];
const chartColor = trendColors[trend]; const chartColor = trendColors[trend ?? "neutral"];
const trendValues = { up: "+25%", down: "-25%", neutral: "+5%" }; const trendValues = { up: "+25%", down: "-25%", neutral: "+5%" };
return ( return (
@ -95,31 +95,38 @@ export default function StatCard({
<Typography variant="h4" component="p"> <Typography variant="h4" component="p">
{value} {value}
</Typography> </Typography>
<Chip size="small" color={color} label={trendValues[trend]} /> {trend && (
<Chip size="small" color={color} label={trendValues[trend]} />
)}
</Stack> </Stack>
<Typography variant="caption" sx={{ color: "text.secondary" }}> <Typography variant="caption" sx={{ color: "text.secondary" }}>
{interval} {interval}
</Typography> </Typography>
</Stack> </Stack>
<Box sx={{ width: "100%", height: 50 }}> <Box sx={{ width: "100%", height: 50 }}>
<SparkLineChart {data && interval && (
colors={[chartColor]} <SparkLineChart
data={data} colors={[chartColor]}
area data={data}
showHighlight area
showTooltip showHighlight
xAxis={{ showTooltip
scaleType: "band", xAxis={{
data: daysInWeek, // Use the correct property 'data' for xAxis scaleType: "band",
}} data: last24Hours(),
sx={{ }}
[`& .${areaElementClasses.root}`]: { sx={{
fill: `url(#area-gradient-${value})`, [`& .${areaElementClasses.root}`]: {
}, fill: `url(#area-gradient-${value})`,
}} },
> }}
<AreaGradient color={chartColor} id={`area-gradient-${value}`} /> >
</SparkLineChart> <AreaGradient
color={chartColor}
id={`area-gradient-${value}`}
/>
</SparkLineChart>
)}
</Box> </Box>
</Stack> </Stack>
</CardContent> </CardContent>