Get state of relay on device page
This commit is contained in:
		@@ -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(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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} />
 | 
				
			||||||
 | 
					        </>
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								central_frontend/src/widgets/BoolText.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								central_frontend/src/widgets/BoolText.tsx
									
									
									
									
									
										Normal 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>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user