feat: add robot connection

ref: N25B-400
This commit is contained in:
Björn Otgaar
2026-01-08 14:01:42 +01:00
parent a1e242e391
commit 6e1eb25bbc
3 changed files with 57 additions and 6 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import styles from './MonitoringPage.module.css';
/**
@@ -155,3 +155,50 @@ export const StatusList: React.FC<StatusListProps> = ({ title, items, type }) =>
</section>
);
};
// --- Robot Connected ---
export const RobotConnected = () => {
/**
* The current connection state:
* - `true`: Robot is connected.
* - `false`: Robot is not connected.
* - `null`: Connection status is unknown (initial check in progress).
*/
const [connected, setConnected] = useState<boolean | null>(null);
useEffect(() => {
// Open a Server-Sent Events (SSE) connection to receive live ping updates.
// We're expecting 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) => {
// Expecting messages in JSON format: `true` or `false`
console.log("received message:", event.data);
try {
const data = JSON.parse(event.data);
try {
setConnected(data)
}
catch {
console.log("couldnt extract connected from incoming ping data")
}
} catch {
console.log("Ping message not in correct format:", event.data);
}
};
// Clean up the SSE connection when the component unmounts.
return () => eventSource.close();
}, []);
return (
<div>
<h3>Connection:</h3>
<p className={connected ? styles.connected : styles.disconnected }>{connected ? "● Robot is connected" : "● Robot is disconnected"}</p>
</div>
)
}

View File

@@ -53,6 +53,11 @@
font-weight: bold;
}
.disconnected {
color: red;
font-weight: bold;
}
.pausePlayInactive{
background-color: gray;
}

View File

@@ -1,7 +1,7 @@
import React from 'react';
import styles from './MonitoringPage.module.css';
import useProgramStore from "../../utils/programStore.ts";
import { GestureControls, SpeechPresets, DirectSpeechInput, StatusList } from './Components';
import { GestureControls, SpeechPresets, DirectSpeechInput, StatusList, RobotConnected } from './Components';
import { nextPhase, pauseExperiment, playExperiment, resetExperiment, resetPhase } from ".//MonitoringPageAPI.ts"
type Goal = { id?: string | number; description?: string; achieved?: boolean };
@@ -130,8 +130,7 @@ const MonitoringPage: React.FC = () => {
</div>
<div className={styles.connectionStatus}>
<h3>Connection:</h3>
<p className={styles.connected}> Robot is connected</p>
{RobotConnected()}
</div>
</header>