Show current consumption chart
This commit is contained in:
		@@ -2,9 +2,9 @@ import { APIClient } from "./ApiClient";
 | 
			
		||||
 | 
			
		||||
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({
 | 
			
		||||
      method: "GET",
 | 
			
		||||
      uri: "/energy/curr_consumption",
 | 
			
		||||
@@ -12,6 +12,18 @@ export class EnergyApi {
 | 
			
		||||
    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
 | 
			
		||||
   */
 | 
			
		||||
@@ -22,4 +34,16 @@ export class EnergyApi {
 | 
			
		||||
    });
 | 
			
		||||
    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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,12 +26,6 @@ export function CachedConsumptionWidget(): React.ReactElement {
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <StatCard
 | 
			
		||||
      title="Cached consumption"
 | 
			
		||||
      data={[]}
 | 
			
		||||
      interval="Current data"
 | 
			
		||||
      trend="neutral"
 | 
			
		||||
      value={val?.toString() ?? "Loading"}
 | 
			
		||||
    />
 | 
			
		||||
    <StatCard title="Cached consumption" value={val?.toString() ?? "Loading"} />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,14 @@ export function CurrConsumptionWidget(): React.ReactElement {
 | 
			
		||||
  const snackbar = useSnackbar();
 | 
			
		||||
 | 
			
		||||
  const [val, setVal] = React.useState<undefined | number>();
 | 
			
		||||
  const [history, setHistory] = React.useState<number[] | undefined>();
 | 
			
		||||
 | 
			
		||||
  const refresh = async () => {
 | 
			
		||||
    try {
 | 
			
		||||
      const s = await EnergyApi.CurrConsumption();
 | 
			
		||||
      const s = await EnergyApi.GridConsumption();
 | 
			
		||||
      const history = await EnergyApi.GridConsumptionHistory();
 | 
			
		||||
      setVal(s);
 | 
			
		||||
      setHistory(history);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.error(e);
 | 
			
		||||
      snackbar("Failed to refresh current consumption!");
 | 
			
		||||
@@ -19,7 +22,6 @@ export function CurrConsumptionWidget(): React.ReactElement {
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  React.useEffect(() => {
 | 
			
		||||
    refresh();
 | 
			
		||||
    const i = setInterval(() => refresh(), 3000);
 | 
			
		||||
 | 
			
		||||
    return () => clearInterval(i);
 | 
			
		||||
@@ -28,9 +30,8 @@ export function CurrConsumptionWidget(): React.ReactElement {
 | 
			
		||||
  return (
 | 
			
		||||
    <StatCard
 | 
			
		||||
      title="Current consumption"
 | 
			
		||||
      data={[]}
 | 
			
		||||
      interval="Current data"
 | 
			
		||||
      trend="neutral"
 | 
			
		||||
      data={history ?? []}
 | 
			
		||||
      interval="Last day"
 | 
			
		||||
      value={val?.toString() ?? "Loading"}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
 
 | 
			
		||||
@@ -11,24 +11,25 @@ import { areaElementClasses } from "@mui/x-charts/LineChart";
 | 
			
		||||
export type StatCardProps = {
 | 
			
		||||
  title: string;
 | 
			
		||||
  value: string;
 | 
			
		||||
  interval: string;
 | 
			
		||||
  trend: "up" | "down" | "neutral";
 | 
			
		||||
  data: number[];
 | 
			
		||||
  interval?: string;
 | 
			
		||||
  trend?: "up" | "down" | "neutral";
 | 
			
		||||
  data?: number[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function getDaysInMonth(month: number, year: number) {
 | 
			
		||||
  const date = new Date(year, month, 0);
 | 
			
		||||
  const monthName = date.toLocaleDateString("en-US", {
 | 
			
		||||
    month: "short",
 | 
			
		||||
  });
 | 
			
		||||
  const daysInMonth = date.getDate();
 | 
			
		||||
  const days = [];
 | 
			
		||||
  let i = 1;
 | 
			
		||||
  while (days.length < daysInMonth) {
 | 
			
		||||
    days.push(`${monthName} ${i}`);
 | 
			
		||||
    i += 1;
 | 
			
		||||
function last24Hours(): string[] {
 | 
			
		||||
  let res: Array<string> = [];
 | 
			
		||||
 | 
			
		||||
  for (let index = 0; index < 3600 * 24; index += 60 * 10) {
 | 
			
		||||
    const date = new Date();
 | 
			
		||||
    date.setTime(date.getTime() - index * 1000);
 | 
			
		||||
    res.push(date.getHours() + "h" + date.getMinutes());
 | 
			
		||||
  }
 | 
			
		||||
  return days;
 | 
			
		||||
 | 
			
		||||
  res.reverse();
 | 
			
		||||
 | 
			
		||||
  console.log(res);
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function AreaGradient({ color, id }: { color: string; id: string }) {
 | 
			
		||||
@@ -50,7 +51,6 @@ export default function StatCard({
 | 
			
		||||
  data,
 | 
			
		||||
}: StatCardProps) {
 | 
			
		||||
  const theme = useTheme();
 | 
			
		||||
  const daysInWeek = getDaysInMonth(4, 2024);
 | 
			
		||||
 | 
			
		||||
  const trendColors = {
 | 
			
		||||
    up:
 | 
			
		||||
@@ -73,8 +73,8 @@ export default function StatCard({
 | 
			
		||||
    neutral: "default" as const,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const color = labelColors[trend];
 | 
			
		||||
  const chartColor = trendColors[trend];
 | 
			
		||||
  const color = labelColors[trend ?? "neutral"];
 | 
			
		||||
  const chartColor = trendColors[trend ?? "neutral"];
 | 
			
		||||
  const trendValues = { up: "+25%", down: "-25%", neutral: "+5%" };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
@@ -95,31 +95,38 @@ export default function StatCard({
 | 
			
		||||
              <Typography variant="h4" component="p">
 | 
			
		||||
                {value}
 | 
			
		||||
              </Typography>
 | 
			
		||||
              <Chip size="small" color={color} label={trendValues[trend]} />
 | 
			
		||||
              {trend && (
 | 
			
		||||
                <Chip size="small" color={color} label={trendValues[trend]} />
 | 
			
		||||
              )}
 | 
			
		||||
            </Stack>
 | 
			
		||||
            <Typography variant="caption" sx={{ color: "text.secondary" }}>
 | 
			
		||||
              {interval}
 | 
			
		||||
            </Typography>
 | 
			
		||||
          </Stack>
 | 
			
		||||
          <Box sx={{ width: "100%", height: 50 }}>
 | 
			
		||||
            <SparkLineChart
 | 
			
		||||
              colors={[chartColor]}
 | 
			
		||||
              data={data}
 | 
			
		||||
              area
 | 
			
		||||
              showHighlight
 | 
			
		||||
              showTooltip
 | 
			
		||||
              xAxis={{
 | 
			
		||||
                scaleType: "band",
 | 
			
		||||
                data: daysInWeek, // Use the correct property 'data' for xAxis
 | 
			
		||||
              }}
 | 
			
		||||
              sx={{
 | 
			
		||||
                [`& .${areaElementClasses.root}`]: {
 | 
			
		||||
                  fill: `url(#area-gradient-${value})`,
 | 
			
		||||
                },
 | 
			
		||||
              }}
 | 
			
		||||
            >
 | 
			
		||||
              <AreaGradient color={chartColor} id={`area-gradient-${value}`} />
 | 
			
		||||
            </SparkLineChart>
 | 
			
		||||
            {data && interval && (
 | 
			
		||||
              <SparkLineChart
 | 
			
		||||
                colors={[chartColor]}
 | 
			
		||||
                data={data}
 | 
			
		||||
                area
 | 
			
		||||
                showHighlight
 | 
			
		||||
                showTooltip
 | 
			
		||||
                xAxis={{
 | 
			
		||||
                  scaleType: "band",
 | 
			
		||||
                  data: last24Hours(),
 | 
			
		||||
                }}
 | 
			
		||||
                sx={{
 | 
			
		||||
                  [`& .${areaElementClasses.root}`]: {
 | 
			
		||||
                    fill: `url(#area-gradient-${value})`,
 | 
			
		||||
                  },
 | 
			
		||||
                }}
 | 
			
		||||
              >
 | 
			
		||||
                <AreaGradient
 | 
			
		||||
                  color={chartColor}
 | 
			
		||||
                  id={`area-gradient-${value}`}
 | 
			
		||||
                />
 | 
			
		||||
              </SparkLineChart>
 | 
			
		||||
            )}
 | 
			
		||||
          </Box>
 | 
			
		||||
        </Stack>
 | 
			
		||||
      </CardContent>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user