From 6e1eb25bbc5c11684277a485a410ce22b504eae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Otgaar?= Date: Thu, 8 Jan 2026 14:01:42 +0100 Subject: [PATCH] feat: add robot connection ref: N25B-400 --- src/pages/MonitoringPage/Components.tsx | 51 ++++++++++++++++++- .../MonitoringPage/MonitoringPage.module.css | 5 ++ src/pages/MonitoringPage/MonitoringPage.tsx | 7 ++- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/pages/MonitoringPage/Components.tsx b/src/pages/MonitoringPage/Components.tsx index 1e21eb1..81be8a9 100644 --- a/src/pages/MonitoringPage/Components.tsx +++ b/src/pages/MonitoringPage/Components.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import styles from './MonitoringPage.module.css'; /** @@ -154,4 +154,51 @@ export const StatusList: React.FC = ({ title, items, type }) => ); -}; \ No newline at end of file +}; + + +// --- 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(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 ( +
+

Connection:

+

{connected ? "● Robot is connected" : "● Robot is disconnected"}

+
+ ) +} \ No newline at end of file diff --git a/src/pages/MonitoringPage/MonitoringPage.module.css b/src/pages/MonitoringPage/MonitoringPage.module.css index 1d76c46..b4542cb 100644 --- a/src/pages/MonitoringPage/MonitoringPage.module.css +++ b/src/pages/MonitoringPage/MonitoringPage.module.css @@ -53,6 +53,11 @@ font-weight: bold; } +.disconnected { + color: red; + font-weight: bold; +} + .pausePlayInactive{ background-color: gray; } diff --git a/src/pages/MonitoringPage/MonitoringPage.tsx b/src/pages/MonitoringPage/MonitoringPage.tsx index e6dbd25..ae34fd8 100644 --- a/src/pages/MonitoringPage/MonitoringPage.tsx +++ b/src/pages/MonitoringPage/MonitoringPage.tsx @@ -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 }; @@ -126,12 +126,11 @@ const MonitoringPage: React.FC = () => { > ⟲ - +
-

Connection:

-

● Robot is connected

+ {RobotConnected()}