feat: show robots page easier - quick connected sign. Quick reload - no need for manual reloads or anything.

ref: N25B-142
This commit is contained in:
Björn Otgaar
2025-10-30 13:05:56 +01:00
parent ea17b95a53
commit 4181454a73
2 changed files with 144 additions and 158 deletions

View File

@@ -1,178 +1,38 @@
import { useEffect } from 'react'
import Logging from '../Logging/Logging';
// Define the robot type
type Robot = {
id: string;
name: string;
port: number;
};
// Define the expected arguments
type ConnectedRobotsProps = {
connectedRobots: Robot[];
setConnectedRobots: React.Dispatch<React.SetStateAction<Robot[]>>;
};
export default function ConnectedRobots({
connectedRobots, setConnectedRobots }: ConnectedRobotsProps) {
import { useEffect, useState } from 'react'
export default function ConnectedRobots() {
const [connected, setConnected] = useState<boolean | null>(null);
useEffect(() => {
const eventSource = new EventSource("http://localhost:8000/sse");
// We're excepting a stream of data like that looks like this: `data = False` or `data = True`
const eventSource = new EventSource("http://localhost:8000/robot/ping_stream");
eventSource.onmessage = (event) => {
// Receive message and parse
console.log("received message:", event.data);
try {
const data = JSON.parse(event.data);
// Example: data = { event: "robot_connected", id: "pepper_robot1", name: "Pepper", port: 1234 }
if (data.event === "robot_connected") {
// Safeguard id in request.
if (data.id === null || data.id === undefined) {
console.log(`Missing robot id in connection request.
Use format: 'data: {event = 'robot_connected', id = <id>, (optional) name = <name>, (optional) port = <port>}'.`)
return () => eventSource.close();
}
// Safeguard duplicates
if (connectedRobots.some(robot => robot.id === data.id))
console.log("connection request was sent for id: ", data.id,
" however this id was already present at current time");
// Add to connected robots while checking name and port for undefineds.
else {
const name = data.name ?? "no given name";
const port = typeof data.port === "number" ? data.port : -1;
setConnectedRobots(robots => [...robots, { id: data.id, name: name, port: port }]);
}
// Set connected to value.
try {
setConnected(data)
}
if (data.event === "robot_disconnected") {
// Safeguard id in request.
if (data.id === null || data.id === undefined) {
console.log("Missing robot id in connection request. Use format: 'data: {event = 'robot_disconnected', id = <id>}'.");
return () => eventSource.close();
}
// Filter out same ids (should only be one)
setConnectedRobots(robots => robots.filter(robot => robot.id !== data.id));
}
if (data.event === "robot_list") {
if (data.list === null || data.list === undefined) {
console.log("Missing list in robot_list request. Use format: 'data: {event = 'robot_list', list = <list>}'.");
return () => eventSource.close();
}
// Set the robot list to the one found in CB
setConnectedRobots(data.list);
catch {
console.log("couldnt extract connected from incoming ping data")
}
} catch {
console.log("Unparsable SSE message:", event.data);
console.log("Ping message not in correct format:", event.data);
}
};
return () => eventSource.close();
}, [connectedRobots]);
});
return (
<div>
<h1>Robots Connected</h1>
<h1>Is robot currently connected?</h1>
<div>
<h2>Connected Robots</h2>
<ul>
{connectedRobots.map(robot =>
// Map all the robots in an unordered list
<li key={robot.id}>
<strong>{robot.name}</strong> (ID: {robot.id}, Port: {robot.port === -1 ? "No given port" : robot.port})
</li>
)}
</ul>
</div>
<div className={"flex-col gap-lg"}>
<div className={"flex-row gap-md justify-center"}>
<button onClick={() => {
// Let's test the reload function.
const example_list = [{ id: "pepper_robot1", name: "Pepper1", port: 1234 },
{ id: "pepper_robot2", name: "Pepper2", port: 1235 },
{ id: "pepper_robot3", name: "Pepper3", port: 1236 },
{ id: "pepper_robot4", name: "Pepper4", port: 1237 }]
const example_event = `{
"event": "robot_list", "list":
[{ "id": "pepper_robot1",
"name": "Pepper1",
"port": 1234 },{
"id": "pepper_robot2",
"name": "Pepper2",
"port": 1235 },{
"id": "pepper_robot3",
"name": "Pepper3",
"port": 1236 }, {
"id": "pepper_robot4",
"name": "Pepper4",
"port": 1237 }]}`
// Now let's put it through the same steps as the event would do. :)
try {
const data = JSON.parse(example_event);
if (data.event === "robot_list") {
if (data.list === null || data.list === undefined) {
console.log("Missing list in robot_list request. Use format: 'data: {event = 'robot_list', list = <list>}'.");
return;
}
// Check if it is as expected.
if (JSON.stringify(data.list) !== JSON.stringify(example_list)) {
console.log("Dummy reload failed: list don't match.")
}
else {
console.log("Dummy reload succes!!")
}
} else {
console.log("Dummy reload failed, didn't parse to 'data.event === 'robot_list'.'")
}
} catch {
console.log("Dummy reload failed: didnt parse correctly.")
}
}}>Dummy Reload from CB</button>
<button onClick={() => {
// Example dummy robots
const connection_dummies: Robot[] = [
{ id: "pepper_robot1", name: "Pepper One", port: 8001 },
{ id: "pepper_robot2", name: "Pepper Two", port: 8002 },
{ id: "naoqi_robot1", name: "Naoqi One", port: 9001 },
{ id: "naoqi_robot2", name: "Naoqi Two", port: 9002 },
{ id: "noport1", name: "I dont have a port in my request >:)", port: -1 },
{ id: "noname1", name: "no given name", port: 2001 }
];
const randomIndex = Math.floor(Math.random() * connection_dummies.length);
const randomConnectionDummy = connection_dummies[randomIndex];
if (connectedRobots.some(robot => robot.id === randomConnectionDummy.id))
console.log("connection request was sent for id: ", randomConnectionDummy.id,
" however this id was already present at current time");
else
setConnectedRobots(robots => [...robots, randomConnectionDummy]);
}}>'Sent connected event'</button>
<button onClick={() => {
// Example disconnection bots
const disconnection_dummies = [
{ id: "pepper_robot1" },
{ id: "pepper_robot2" },
{ id: "naoqi_robot1" },
{ id: "naoqi_robot2" },
{ id: "noport1", name: "I dont have a port in my request >:)", port: -1 },
{ id: "noname1", name: "no given name", port: 2001 }
];
const randomIndex = Math.floor(Math.random() * disconnection_dummies.length);
const randomDisconnectionDummy = disconnection_dummies[randomIndex];
setConnectedRobots(robots => robots.filter(robot => robot.id !== randomDisconnectionDummy.id));
}}>'Sent disconnected event'</button>
<button onClick={() => {
setConnectedRobots([]);
}}>Reset</button>
</div>
<h2>Robot is currently: {connected == null ? "checking..." : (connected ? "connected! 🟢" : "not connected... 🔴")} </h2>
</div>
</div>
);