Display relay status on relays page

This commit is contained in:
Pierre HUBERT 2024-09-09 21:27:15 +02:00
parent 7cac6aeb35
commit a97614ce44
3 changed files with 52 additions and 5 deletions

View File

@ -45,6 +45,14 @@ export interface UpdatedInfo {
enabled: boolean; enabled: boolean;
} }
export interface DeviceState {
id: string;
last_ping: number;
online: boolean;
}
export type DevicesState = Map<string, DeviceState>;
export function DeviceURL(d: Device): string { export function DeviceURL(d: Device): string {
return `/dev/${encodeURIComponent(d.id)}`; return `/dev/${encodeURIComponent(d.id)}`;
} }
@ -74,6 +82,22 @@ export class DeviceApi {
).data; ).data;
} }
/**
* Get the state of devices
*/
static async DevicesState(): Promise<DevicesState> {
const devs: DeviceState[] = (
await APIClient.exec({
uri: "/devices/state",
method: "GET",
})
).data;
const m = new Map();
devs.forEach((d) => m.set(d.id, d));
return m;
}
/** /**
* Validate a device * Validate a device
*/ */

View File

@ -13,7 +13,7 @@ import {
} from "@mui/material"; } from "@mui/material";
import React from "react"; import React from "react";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import { Device, DeviceApi, DeviceURL } from "../api/DeviceApi"; import { Device, DeviceApi, DevicesState, DeviceURL } from "../api/DeviceApi";
import { AsyncWidget } from "../widgets/AsyncWidget"; import { AsyncWidget } from "../widgets/AsyncWidget";
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer"; import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
import { TimeWidget } from "../widgets/TimeWidget"; import { TimeWidget } from "../widgets/TimeWidget";
@ -22,14 +22,17 @@ export function DevicesRoute(): React.ReactElement {
const loadKey = React.useRef(1); const loadKey = React.useRef(1);
const [list, setList] = React.useState<Device[] | undefined>(); const [list, setList] = React.useState<Device[] | undefined>();
const [states, setStates] = React.useState<DevicesState | undefined>();
const load = async () => { const load = async () => {
setList(await DeviceApi.ValidatedList()); setList(await DeviceApi.ValidatedList());
setStates(await DeviceApi.DevicesState());
}; };
const reload = () => { const reload = () => {
loadKey.current += 1; loadKey.current += 1;
setList(undefined); setList(undefined);
setStates(undefined);
}; };
return ( return (
@ -45,10 +48,16 @@ export function DevicesRoute(): React.ReactElement {
> >
<AsyncWidget <AsyncWidget
loadKey={loadKey.current} loadKey={loadKey.current}
ready={!!list} ready={!!list && !!states}
errMsg="Failed to load the list of validated devices!" errMsg="Failed to load the list of validated devices!"
load={load} load={load}
build={() => <ValidatedDevicesList onReload={reload} list={list!} />} build={() => (
<ValidatedDevicesList
onReload={reload}
list={list!}
states={states!}
/>
)}
/> />
</SolarEnergyRouteContainer> </SolarEnergyRouteContainer>
); );
@ -56,6 +65,7 @@ export function DevicesRoute(): React.ReactElement {
function ValidatedDevicesList(p: { function ValidatedDevicesList(p: {
list: Device[]; list: Device[];
states: DevicesState;
onReload: () => void; onReload: () => void;
}): React.ReactElement { }): React.ReactElement {
const navigate = useNavigate(); const navigate = useNavigate();
@ -75,6 +85,7 @@ function ValidatedDevicesList(p: {
<TableCell>Max number of relays</TableCell> <TableCell>Max number of relays</TableCell>
<TableCell>Created</TableCell> <TableCell>Created</TableCell>
<TableCell>Updated</TableCell> <TableCell>Updated</TableCell>
<TableCell>Status</TableCell>
<TableCell></TableCell> <TableCell></TableCell>
</TableRow> </TableRow>
</TableHead> </TableHead>
@ -97,6 +108,15 @@ function ValidatedDevicesList(p: {
<TableCell> <TableCell>
<TimeWidget time={dev.time_update} /> <TimeWidget time={dev.time_update} />
</TableCell> </TableCell>
<TableCell align="center">
{p.states.get(dev.id)!.online ? (
<strong>Online</strong>
) : (
<em>Offline</em>
)}
<br />
<TimeWidget diff time={p.states.get(dev.id)!.last_ping} />
</TableCell>
<TableCell> <TableCell>
<Tooltip title="Open device page"> <Tooltip title="Open device page">
<Link to={DeviceURL(dev)}> <Link to={DeviceURL(dev)}>

View File

@ -55,11 +55,14 @@ export function timeDiffFromNow(t: number): string {
return timeDiff(t, time()); return timeDiff(t, time());
} }
export function TimeWidget(p: { time?: number }): React.ReactElement { export function TimeWidget(p: {
time?: number;
diff?: boolean;
}): React.ReactElement {
if (!p.time) return <></>; if (!p.time) return <></>;
return ( return (
<Tooltip title={formatDate(p.time)} arrow> <Tooltip title={formatDate(p.time)} arrow>
<span>{timeDiffFromNow(p.time)}</span> <span>{p.diff ? timeDiff(0, p.time) : timeDiffFromNow(p.time)}</span>
</Tooltip> </Tooltip>
); );
} }