Get state of relay on device page

This commit is contained in:
Pierre HUBERT 2024-09-25 21:56:54 +02:00
parent 3c2fa18d9a
commit e0f0067e89
6 changed files with 70 additions and 16 deletions

View File

@ -187,7 +187,11 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()>
) )
.route( .route(
"/web_api/relays/status", "/web_api/relays/status",
web::get().to(relays_controller::get_status_all), web::get().to(relays_controller::status_all),
)
.route(
"/web_api/relay/{id}/status",
web::get().to(relays_controller::status_single),
) )
// Devices API // Devices API
.route( .route(

View File

@ -95,8 +95,18 @@ pub async fn delete(actor: WebEnergyActor, path: web::Path<RelayIDInPath>) -> Ht
} }
/// Get the status of all relays /// Get the status of all relays
pub async fn get_status_all(actor: WebEnergyActor) -> HttpResult { pub async fn status_all(actor: WebEnergyActor) -> HttpResult {
let list = actor.send(energy_actor::GetAllRelaysState).await?; let list = actor.send(energy_actor::GetAllRelaysState).await?;
Ok(HttpResponse::Ok().json(list)) Ok(HttpResponse::Ok().json(list))
} }
/// Get the state of a single relay
pub async fn status_single(actor: WebEnergyActor, path: web::Path<RelayIDInPath>) -> HttpResult {
let list = actor.send(energy_actor::GetAllRelaysState).await?;
let Some(state) = list.into_iter().find(|r| r.id == path.id) else {
return Ok(HttpResponse::NotFound().json("Relay not found!"));
};
Ok(HttpResponse::Ok().json(state))
}

View File

@ -75,4 +75,16 @@ export class RelayApi {
} }
return map; return map;
} }
/**
* Get the status of a single relay
*/
static async SingleStatus(relay: DeviceRelay): Promise<RelayStatus> {
return (
await APIClient.exec({
method: "GET",
uri: `/relay/${relay.id}/state`,
})
).data;
}
} }

View File

@ -14,9 +14,12 @@ import { EditDeviceRelaysDialog } from "../../dialogs/EditDeviceRelaysDialog";
import { DeviceRouteCard } from "./DeviceRouteCard"; import { DeviceRouteCard } from "./DeviceRouteCard";
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
import { useLoadingMessage } from "../../hooks/context_providers/LoadingMessageProvider"; import { useLoadingMessage } from "../../hooks/context_providers/LoadingMessageProvider";
import { RelayApi } from "../../api/RelayApi"; import { RelayApi, RelayStatus } from "../../api/RelayApi";
import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider"; import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider";
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
import { AsyncWidget } from "../../widgets/AsyncWidget";
import { TimeWidget } from "../../widgets/TimeWidget";
import { BoolText } from "../../widgets/BoolText";
export function DeviceRelays(p: { export function DeviceRelays(p: {
device: Device; device: Device;
@ -115,10 +118,35 @@ export function DeviceRelays(p: {
</> </>
} }
> >
<ListItemText primary={r.name} secondary={"TODO: status"} /> <ListItemText
primary={r.name}
secondary={<RelayEntryStatus relay={r} />}
/>
</ListItem> </ListItem>
))} ))}
</DeviceRouteCard> </DeviceRouteCard>
</> </>
); );
} }
function RelayEntryStatus(p: { relay: DeviceRelay }): React.ReactElement {
const [state, setState] = React.useState<RelayStatus | undefined>();
const load = async () => {
setState(await RelayApi.SingleStatus(p.relay));
};
return (
<AsyncWidget
loadKey={p.relay.id}
load={load}
errMsg="Failed to load relay status!"
build={() => (
<>
<BoolText val={state!.on} positive="ON" negative="OFF" /> for{" "}
<TimeWidget diff time={state!.for} />
</>
)}
/>
);
}

View File

@ -14,6 +14,7 @@ import React from "react";
import { DeviceRelay } from "../api/DeviceApi"; import { DeviceRelay } from "../api/DeviceApi";
import { RelayApi, RelaysStatus } from "../api/RelayApi"; import { RelayApi, RelaysStatus } from "../api/RelayApi";
import { AsyncWidget } from "../widgets/AsyncWidget"; import { AsyncWidget } from "../widgets/AsyncWidget";
import { BoolText } from "../widgets/BoolText";
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer"; import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
import { TimeWidget } from "../widgets/TimeWidget"; import { TimeWidget } from "../widgets/TimeWidget";
@ -103,15 +104,3 @@ function RelaysList(p: {
</TableContainer> </TableContainer>
); );
} }
function BoolText(p: {
val: boolean;
positive: string;
negative: string;
}): React.ReactElement {
return p.val ? (
<span style={{ color: "green" }}>{p.positive}</span>
) : (
<span style={{ color: "red" }}>{p.negative}</span>
);
}

View File

@ -0,0 +1,11 @@
export function BoolText(p: {
val: boolean;
positive: string;
negative: string;
}): React.ReactElement {
return p.val ? (
<span style={{ color: "green" }}>{p.positive}</span>
) : (
<span style={{ color: "red" }}>{p.negative}</span>
);
}