Display relays status
This commit is contained in:
		@@ -360,3 +360,34 @@ impl Handler<GetDevicesState> for EnergyActor {
 | 
				
			|||||||
            .collect()
 | 
					            .collect()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Serialize)]
 | 
				
			||||||
 | 
					pub struct ResRelayState {
 | 
				
			||||||
 | 
					    pub id: DeviceRelayID,
 | 
				
			||||||
 | 
					    on: bool,
 | 
				
			||||||
 | 
					    r#for: usize,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Get the state of all relays
 | 
				
			||||||
 | 
					#[derive(Message)]
 | 
				
			||||||
 | 
					#[rtype(result = "Vec<ResRelayState>")]
 | 
				
			||||||
 | 
					pub struct GetAllRelaysState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Handler<GetAllRelaysState> for EnergyActor {
 | 
				
			||||||
 | 
					    type Result = Vec<ResRelayState>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn handle(&mut self, _msg: GetAllRelaysState, _ctx: &mut Context<Self>) -> Self::Result {
 | 
				
			||||||
 | 
					        let mut list = vec![];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for d in &self.devices.relays_list() {
 | 
				
			||||||
 | 
					            let state = self.engine.relay_state(d.id);
 | 
				
			||||||
 | 
					            list.push(ResRelayState {
 | 
				
			||||||
 | 
					                id: d.id,
 | 
				
			||||||
 | 
					                on: state.is_on(),
 | 
				
			||||||
 | 
					                r#for: state.state_for(),
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        list
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,6 +39,10 @@ impl RelayState {
 | 
				
			|||||||
    fn is_off(&self) -> bool {
 | 
					    fn is_off(&self) -> bool {
 | 
				
			||||||
        !self.on
 | 
					        !self.on
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn state_for(&self) -> usize {
 | 
				
			||||||
 | 
					        (time_secs() - self.since as u64) as usize
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RelaysState = HashMap<DeviceRelayID, RelayState>;
 | 
					type RelaysState = HashMap<DeviceRelayID, RelayState>;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -185,6 +185,10 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()>
 | 
				
			|||||||
                "/web_api/relay/{id}",
 | 
					                "/web_api/relay/{id}",
 | 
				
			||||||
                web::delete().to(relays_controller::delete),
 | 
					                web::delete().to(relays_controller::delete),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					            .route(
 | 
				
			||||||
 | 
					                "/web_api/relays/status",
 | 
				
			||||||
 | 
					                web::get().to(relays_controller::get_status_all),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
            // Devices API
 | 
					            // Devices API
 | 
				
			||||||
            .route(
 | 
					            .route(
 | 
				
			||||||
                "/devices_api/utils/time",
 | 
					                "/devices_api/utils/time",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,3 +93,10 @@ pub async fn delete(actor: WebEnergyActor, path: web::Path<RelayIDInPath>) -> Ht
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Ok(HttpResponse::Accepted().finish())
 | 
					    Ok(HttpResponse::Accepted().finish())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Get the status of all relays
 | 
				
			||||||
 | 
					pub async fn get_status_all(actor: WebEnergyActor) -> HttpResult {
 | 
				
			||||||
 | 
					    let list = actor.send(energy_actor::GetAllRelaysState).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().json(list))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,14 @@
 | 
				
			|||||||
import { APIClient } from "./ApiClient";
 | 
					import { APIClient } from "./ApiClient";
 | 
				
			||||||
import { Device, DeviceRelay } from "./DeviceApi";
 | 
					import { Device, DeviceRelay } from "./DeviceApi";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface RelayStatus {
 | 
				
			||||||
 | 
					  id: string;
 | 
				
			||||||
 | 
					  on: boolean;
 | 
				
			||||||
 | 
					  for: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type RelaysStatus = Map<string, RelayStatus>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class RelayApi {
 | 
					export class RelayApi {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Get the full list of relays
 | 
					   * Get the full list of relays
 | 
				
			||||||
@@ -49,4 +57,22 @@ export class RelayApi {
 | 
				
			|||||||
      uri: `/relay/${relay.id}`,
 | 
					      uri: `/relay/${relay.id}`,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Get the status of all relays
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  static async GetRelaysStatus(): Promise<RelaysStatus> {
 | 
				
			||||||
 | 
					    const data: any[] = (
 | 
				
			||||||
 | 
					      await APIClient.exec({
 | 
				
			||||||
 | 
					        method: "GET",
 | 
				
			||||||
 | 
					        uri: `/relays/status`,
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    ).data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const map = new Map();
 | 
				
			||||||
 | 
					    for (let r of data) {
 | 
				
			||||||
 | 
					      map.set(r.id, r);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return map;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,17 +12,20 @@ import {
 | 
				
			|||||||
} from "@mui/material";
 | 
					} from "@mui/material";
 | 
				
			||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
import { DeviceRelay } from "../api/DeviceApi";
 | 
					import { DeviceRelay } from "../api/DeviceApi";
 | 
				
			||||||
import { RelayApi } from "../api/RelayApi";
 | 
					import { RelayApi, RelaysStatus } from "../api/RelayApi";
 | 
				
			||||||
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";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function RelaysListRoute(): React.ReactElement {
 | 
					export function RelaysListRoute(): React.ReactElement {
 | 
				
			||||||
  const loadKey = React.useRef(1);
 | 
					  const loadKey = React.useRef(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [list, setList] = React.useState<DeviceRelay[] | undefined>();
 | 
					  const [list, setList] = React.useState<DeviceRelay[] | undefined>();
 | 
				
			||||||
 | 
					  const [status, setStatus] = React.useState<RelaysStatus | undefined>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const load = async () => {
 | 
					  const load = async () => {
 | 
				
			||||||
    setList(await RelayApi.GetList());
 | 
					    setList(await RelayApi.GetList());
 | 
				
			||||||
 | 
					    setStatus(await RelayApi.GetRelaysStatus());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list?.sort((a, b) => b.priority - a.priority);
 | 
					    list?.sort((a, b) => b.priority - a.priority);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@@ -48,7 +51,9 @@ export function RelaysListRoute(): React.ReactElement {
 | 
				
			|||||||
        ready={!!list}
 | 
					        ready={!!list}
 | 
				
			||||||
        errMsg="Failed to load the list of relays!"
 | 
					        errMsg="Failed to load the list of relays!"
 | 
				
			||||||
        load={load}
 | 
					        load={load}
 | 
				
			||||||
        build={() => <RelaysList onReload={reload} list={list!} />}
 | 
					        build={() => (
 | 
				
			||||||
 | 
					          <RelaysList onReload={reload} list={list!} status={status!} />
 | 
				
			||||||
 | 
					        )}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
    </SolarEnergyRouteContainer>
 | 
					    </SolarEnergyRouteContainer>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
@@ -56,6 +61,7 @@ export function RelaysListRoute(): React.ReactElement {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function RelaysList(p: {
 | 
					function RelaysList(p: {
 | 
				
			||||||
  list: DeviceRelay[];
 | 
					  list: DeviceRelay[];
 | 
				
			||||||
 | 
					  status: RelaysStatus;
 | 
				
			||||||
  onReload: () => void;
 | 
					  onReload: () => void;
 | 
				
			||||||
}): React.ReactElement {
 | 
					}): React.ReactElement {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@@ -78,15 +84,18 @@ function RelaysList(p: {
 | 
				
			|||||||
            >
 | 
					            >
 | 
				
			||||||
              <TableCell>{row.name}</TableCell>
 | 
					              <TableCell>{row.name}</TableCell>
 | 
				
			||||||
              <TableCell>
 | 
					              <TableCell>
 | 
				
			||||||
                {row.enabled ? (
 | 
					                <BoolText val={row.enabled} positive="YES" negative="NO" />
 | 
				
			||||||
                  <span style={{ color: "green" }}>YES</span>
 | 
					 | 
				
			||||||
                ) : (
 | 
					 | 
				
			||||||
                  <span style={{ color: "red" }}>NO</span>
 | 
					 | 
				
			||||||
                )}
 | 
					 | 
				
			||||||
              </TableCell>
 | 
					              </TableCell>
 | 
				
			||||||
              <TableCell>{row.priority}</TableCell>
 | 
					              <TableCell>{row.priority}</TableCell>
 | 
				
			||||||
              <TableCell>{row.consumption}</TableCell>
 | 
					              <TableCell>{row.consumption}</TableCell>
 | 
				
			||||||
              <TableCell>TODO</TableCell>
 | 
					              <TableCell>
 | 
				
			||||||
 | 
					                <BoolText
 | 
				
			||||||
 | 
					                  val={p.status.get(row.id)!.on}
 | 
				
			||||||
 | 
					                  positive="ON"
 | 
				
			||||||
 | 
					                  negative="OFF"
 | 
				
			||||||
 | 
					                />{" "}
 | 
				
			||||||
 | 
					                for <TimeWidget diff time={p.status.get(row.id)!.for} />
 | 
				
			||||||
 | 
					              </TableCell>
 | 
				
			||||||
            </TableRow>
 | 
					            </TableRow>
 | 
				
			||||||
          ))}
 | 
					          ))}
 | 
				
			||||||
        </TableBody>
 | 
					        </TableBody>
 | 
				
			||||||
@@ -94,3 +103,15 @@ 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>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user