From d8a1a041503e9bf3a2000010daa3761afab43d21 Mon Sep 17 00:00:00 2001 From: Robbie Seymour <40930716+robbie-seymour@users.noreply.github.com> Date: Wed, 19 Jul 2023 16:26:54 +1000 Subject: [PATCH] Started doing frontend refactor in relation to backend websocket. JIRA: GNS-42 --- frontend/package.json | 5 +- frontend/src/State.ts | 62 +++++++++++++++++++ frontend/src/Websocket.ts | 62 +++++++++++++++++++ .../EncounterInfo/EncounterInfo.tsx | 4 +- frontend/src/logic/backend_req.ts | 11 ++-- orch-rs/src/groundstation.rs | 16 +++-- 6 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 frontend/src/State.ts create mode 100644 frontend/src/Websocket.ts diff --git a/frontend/package.json b/frontend/package.json index 0c68032..b1dd157 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,9 +13,10 @@ "@types/node": "^16.11.66", "@types/react": "^18.0.21", "@types/react-dom": "^18.0.6", + "fast-json-patch": "^3.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-scripts": "^5.0.1", + "react-scripts": "^2.1.3", "typescript": "^4.8.4", "web-vitals": "^2.1.4" }, @@ -24,7 +25,7 @@ "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", - "lint" : "eslint --ext .js,.jsx,.ts,.tsx --fix src/" + "lint": "eslint --ext .js,.jsx,.ts,.tsx --fix src/" }, "eslintConfig": { "extends": [ diff --git a/frontend/src/State.ts b/frontend/src/State.ts new file mode 100644 index 0000000..3fa71c0 --- /dev/null +++ b/frontend/src/State.ts @@ -0,0 +1,62 @@ +export interface State { + stations: Map; + current_satellite: Satellite; + backend_status: BackendStatus; + } + export interface Satellite { + tle: string, + name: string, + norad_id: number, + ind_designator: string, + } + export interface BackendStatus { + lib_state: string, + cpu: number, + mem: number, + client_list: Array, + } + export enum GroundStationStatus { + OFFLINE, + IDLE, + TRACKING, + OVERHEAT, + FAULT, + } + + export enum AntennaType { + HELICAL, + DIPOLE, + YAGI, + PARABOLIC, + PATCH, + } + + export enum GSKinematics { + STATIC, + AZ, + AZEL, + } + + export interface GPSPosition { + latitude: String, + longitude: String, + altitude: String, + valid: boolean, + } + export interface GroundStation { + name: String, + location: GPSPosition, + orientation: PolarPoint, + signal_strength: number, + status: GroundStationStatus, + freq_response: [number, number], + antenna_type: AntennaType, + kinematics: GSKinematics, + } + export interface PolarPoint { + az: number, + el: number, + } + +//export type StateAction = GPSPosition | GroundStation | AntennaType; + \ No newline at end of file diff --git a/frontend/src/Websocket.ts b/frontend/src/Websocket.ts new file mode 100644 index 0000000..5f7a450 --- /dev/null +++ b/frontend/src/Websocket.ts @@ -0,0 +1,62 @@ +import {State} from "./State" +import {applyPatch, Operation} from "fast-json-patch" +interface Patch { + type: "Patch"; + ops: Operation[]; // from fast-json-patch +} + +interface Full { + type: "Full"; + state: State; +} + +type ServerMessage = Patch | Full; + +let websocket: WebSocket | undefined; +let state: State | undefined; + +const setupWebsocket = (onStateUpdate: (state: State) => void) => { + const uri = "ws://127.0.0.1:3333/ws"; + const connection = new WebSocket(uri); + console.log(`connecting to websocket: ${uri}`); + + connection.onopen = () => { + console.log("opened websocket"); + websocket = connection; + }; + + connection.onclose = (reason) => { + websocket = undefined; + + if (reason.code !== 1000 && reason.code !== 1001) { + console.log("closed websocket"); + + setTimeout(() => { + setupWebsocket(onStateUpdate); + }, 500); + } + }; + + connection.onerror = (error) => { + console.error("Error with websocket:", error); + connection.close(); + } + + connection.onmessage = (message) => { + const msg = JSON.parse(message.data) as ServerMessage; + + switch (msg.type) { + case "Patch": { + if (todo !== undefined) { + let {newDocument: newState} = applyPatch(todo, msg.ops, false, fals) + } + break; + } + + case "Full" : { + + break; + } + } + } +}; \ No newline at end of file diff --git a/frontend/src/components/EncounterSub/EncounterInfo/EncounterInfo.tsx b/frontend/src/components/EncounterSub/EncounterInfo/EncounterInfo.tsx index a1f79a2..a152444 100644 --- a/frontend/src/components/EncounterSub/EncounterInfo/EncounterInfo.tsx +++ b/frontend/src/components/EncounterSub/EncounterInfo/EncounterInfo.tsx @@ -2,11 +2,13 @@ // Segment responsible for displaying information about the targeted satellite // Matt -import React from 'react'; +import {useEffect} from 'react'; import { Grid, Table, TableBody, TableCell, TableContainer, TableRow, Typography } from "@mui/material" import { n2yo_radio_passes, n2yo_visual_passes } from '../../../types/n2yotypes'; import UTCtoD from '../../../logic/utility'; + + interface EncounterInfoProps { vp: n2yo_visual_passes, rp: n2yo_radio_passes diff --git a/frontend/src/logic/backend_req.ts b/frontend/src/logic/backend_req.ts index e87e611..d3e39de 100644 --- a/frontend/src/logic/backend_req.ts +++ b/frontend/src/logic/backend_req.ts @@ -61,8 +61,11 @@ export async function getWhatsUp(pos: gps_pos, search_radius: number, cat_id: nu } // Get backend status -export async function getStatus() : Promise { - return await fetch(`http://127.0.0.1:${port}/status`) - .then(res => res.json()) - .then(res => {return res as backend_status}) +export async function getStatus() { + /* + return await fetch(`http://127.0.0.1:${port}/status`) + .then(res => res.json()) + .then(res => {return res as backend_status}) + //*/ + return null } \ No newline at end of file diff --git a/orch-rs/src/groundstation.rs b/orch-rs/src/groundstation.rs index 9a773c1..92e5763 100644 --- a/orch-rs/src/groundstation.rs +++ b/orch-rs/src/groundstation.rs @@ -4,7 +4,10 @@ use crate::state; // pub name: String, // pub orientation: (f32, f32), // } - +use serial::{ + SerialPortSettings, +}; +use serialport; pub trait GroundStation { fn get_status(&self) -> state::GroundStation; // fn get_name(&self) -> String; @@ -16,7 +19,7 @@ pub trait GroundStation { // fn subsribers(&mut self) // fn subscribe(&mut self, subsriber: &dyn Fn(GroundSationStatus)); // whatever else might be needed for this? - fn get_gps(&mut self); + fn get_gps(&self); } // this stuff will probably get moved out to some sorta test module later @@ -48,8 +51,9 @@ impl GroundStation for MockGroundStation { self.orientation.1 += 0.1; self.orientation.1 %= 360.0; } - fn get_gps(&mut self) { - todo!() + fn get_gps(&self) { + let available_ports = serialport::available_ports(); + } } @@ -64,7 +68,7 @@ impl GroundStation for MobileGroundStation { todo!() } - fn get_gps(&mut self) { + fn get_gps(&self) { todo!() } } @@ -80,7 +84,7 @@ impl GroundStation for PhysicsGroundStation { todo!() } - fn get_gps(&mut self) { + fn get_gps(&self) { todo!() }