diff --git a/examples/simple_producer/src/main.rs b/examples/simple_producer/src/main.rs index 963c469..294c001 100644 --- a/examples/simple_producer/src/main.rs +++ b/examples/simple_producer/src/main.rs @@ -66,7 +66,6 @@ impl Telemetry { tokio::time::sleep(Duration::from_secs(1)).await; } } - () }); Ok(Self { @@ -140,13 +139,13 @@ async fn main() -> Result<(), Box> { tokio::time::sleep_until(next_time).await; sin_tlm_handle.publish( Value::Float32( - (f32::TAU() * (index as f32) / (1000.0_f32)).sin() + (index as f32) / (1000.0_f32) + (f32::TAU() * (index as f32) / (1000.0_f32)).sin() ), chrono::Utc::now(), ).await?; cos_tlm_handle.publish( Value::Float64( - (f64::TAU() * (index as f64) / (1000.0_f64)).cos() + (index as f64) / (1000.0_f64) + (f64::TAU() * (index as f64) / (1000.0_f64)).cos() ), chrono::Utc::now(), ).await?; diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 14949a0..a78fb6f 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -4,4 +4,4 @@ import { RouterView } from 'vue-router' \ No newline at end of file + diff --git a/frontend/src/assets/main.scss b/frontend/src/assets/main.scss index 9162fa4..fd419f3 100644 --- a/frontend/src/assets/main.scss +++ b/frontend/src/assets/main.scss @@ -1,4 +1,3 @@ - $light-gray: #d0d1d0; $dark-gray: #303031; diff --git a/frontend/src/components/Axis.vue b/frontend/src/components/Axis.vue deleted file mode 100644 index db10217..0000000 --- a/frontend/src/components/Axis.vue +++ /dev/null @@ -1,183 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend/src/components/Graph.vue b/frontend/src/components/Graph.vue deleted file mode 100644 index 373d07f..0000000 --- a/frontend/src/components/Graph.vue +++ /dev/null @@ -1,107 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend/src/components/GraphAxis.vue b/frontend/src/components/GraphAxis.vue new file mode 100644 index 0000000..58946b0 --- /dev/null +++ b/frontend/src/components/GraphAxis.vue @@ -0,0 +1,303 @@ + + + + + diff --git a/frontend/src/components/Line.vue b/frontend/src/components/Line.vue deleted file mode 100644 index 6714659..0000000 --- a/frontend/src/components/Line.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend/src/components/SvgGraph.vue b/frontend/src/components/SvgGraph.vue new file mode 100644 index 0000000..257625c --- /dev/null +++ b/frontend/src/components/SvgGraph.vue @@ -0,0 +1,141 @@ + + + + + diff --git a/frontend/src/components/TelemetryLine.vue b/frontend/src/components/TelemetryLine.vue new file mode 100644 index 0000000..6f22910 --- /dev/null +++ b/frontend/src/components/TelemetryLine.vue @@ -0,0 +1,120 @@ + + + + + diff --git a/frontend/src/composables/telemetry.ts b/frontend/src/composables/telemetry.ts index c4eb6f8..54f117f 100644 --- a/frontend/src/composables/telemetry.ts +++ b/frontend/src/composables/telemetry.ts @@ -1,28 +1,29 @@ import { ref, toValue, watchEffect } from 'vue' -import { type MaybeRefOrGetter } from '@vue/reactivity' +import { type MaybeRefOrGetter } from 'vue' export interface TelemetryDefinition { - uuid: string; - name: string; - data_type: string; + uuid: string + name: string + data_type: string } export function useTelemetry(name: MaybeRefOrGetter) { - const data = ref(null); - const error = ref(null); + const data = ref(null) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const error = ref(null) - watchEffect(async () => { - const name_value = toValue(name); + watchEffect(async () => { + const name_value = toValue(name) - try { - const res = await fetch(`/api/tlm/${name_value}`); - data.value = await res.json(); - error.value = null; - } catch (e) { - data.value = null; - error.value = e; - } - }); + try { + const res = await fetch(`/api/tlm/${name_value}`) + data.value = await res.json() + error.value = null + } catch (e) { + data.value = null + error.value = e + } + }) - return { data, error }; + return { data, error } } diff --git a/frontend/src/composables/ticker.ts b/frontend/src/composables/ticker.ts index baf832b..81b27cc 100644 --- a/frontend/src/composables/ticker.ts +++ b/frontend/src/composables/ticker.ts @@ -1,19 +1,19 @@ import { onMounted, onUnmounted, ref, shallowRef } from 'vue' export function useNow(update_ms: number) { - const handle = shallowRef(undefined); - const now = ref(Date.now()); + const handle = shallowRef(undefined) + const now = ref(Date.now()) - onMounted(() => { - handle.value = setInterval(() => { - now.value = Date.now(); - }, update_ms); - }); - onUnmounted(() => { - if (handle.value) { - clearInterval(handle.value); - } - }); + onMounted(() => { + handle.value = setInterval(() => { + now.value = Date.now() + }, update_ms) + }) + onUnmounted(() => { + if (handle.value) { + clearInterval(handle.value) + } + }) - return now; + return now } diff --git a/frontend/src/composables/websocket.ts b/frontend/src/composables/websocket.ts index 6245d2e..722a9e9 100644 --- a/frontend/src/composables/websocket.ts +++ b/frontend/src/composables/websocket.ts @@ -1,121 +1,138 @@ -import { computed, onMounted, onUnmounted, ref, type Ref, shallowRef, watch } from 'vue' +import { + computed, + type MaybeRefOrGetter, + onMounted, + onUnmounted, + ref, + type Ref, + shallowRef, + toValue, + watch, +} from 'vue' +import type { TelemetryDefinition } from '@/composables/telemetry' export interface TelemetryDataItem { - value: any; - timestamp: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value: any + timestamp: string } interface TlmValue { - uuid: string; - value: TelemetryDataItem; + uuid: string + value: TelemetryDataItem } export class WebsocketHandle { - websocket: WebSocket | null; - should_be_connected: boolean; - connected: Ref; - on_telem_value: Mapvoid>>; + websocket: WebSocket | null + should_be_connected: boolean + connected: Ref + on_telem_value: Map void>> - constructor() { - this.websocket = null; - this.should_be_connected = false; - this.connected = ref(false); - this.on_telem_value = new Map(); + constructor() { + this.websocket = null + this.should_be_connected = false + this.connected = ref(false) + this.on_telem_value = new Map() + } + + connect() { + this.should_be_connected = true + if (this.websocket != null) { + return } - connect() { - this.should_be_connected = true; - if (this.websocket != null) { - return; + this.websocket = new WebSocket( + location.protocol.replace('http', 'ws') + '//' + location.host + '/ws', + ) + this.websocket.addEventListener('open', () => { + this.connected.value = true + }) + this.websocket.addEventListener('close', () => { + if (this.should_be_connected) { + this.disconnect() + setTimeout(() => { + this.connect() + }, 1000) + } + }) + this.websocket.addEventListener('error', () => { + if (this.should_be_connected) { + this.disconnect() + setTimeout(() => { + this.connect() + }, 1000) + } + }) + this.websocket.addEventListener('message', event => { + const message = JSON.parse(event.data) + if (message['TlmValue']) { + const tlm_value = message['TlmValue'] as TlmValue + const listeners = this.on_telem_value.get(tlm_value.uuid) + if (listeners) { + listeners.forEach(listener => { + listener(tlm_value.value) + }) } + } + }) + } - this.websocket = new WebSocket(location.protocol.replace("http", "ws") + "//" + location.host + "/ws"); - this.websocket.addEventListener("open", (event) => { - this.connected.value = true; - }); - this.websocket.addEventListener("close", (event) => { - if (this.should_be_connected) { - this.disconnect(); - setTimeout(() => { - this.connect(); - }, 1000); - } - }); - this.websocket.addEventListener("error", (event) => { - if (this.should_be_connected) { - this.disconnect(); - setTimeout(() => { - this.connect(); - }, 1000); - } - }); - this.websocket.addEventListener("message", (event) => { - const message = JSON.parse(event.data); - if (message["TlmValue"]) { - const tlm_value = message["TlmValue"] as TlmValue; - const listeners = this.on_telem_value.get(tlm_value.uuid); - if (listeners) { - listeners.forEach((listener) => { - listener(tlm_value.value); - }); - } - } - }); + disconnect() { + this.should_be_connected = false + if (this.websocket == null) { + return } - disconnect() { - this.should_be_connected = false; - if (this.websocket == null) { - return; + this.connected.value = false + this.websocket.close() + this.websocket = null + this.on_telem_value.clear() + } + + listen_to_telemetry(telemetry: MaybeRefOrGetter) { + const value_result = ref(null) + + const uuid = computed(() => { + const tlm = toValue(telemetry) + if (tlm) { + return tlm.uuid + } + return null + }) + + watch([uuid, this.connected], ([uuid_value, connected]) => { + if (connected && uuid_value) { + this.websocket?.send( + JSON.stringify({ + RegisterTlmListener: { + uuid: uuid_value, + }, + }), + ) + if (!this.on_telem_value.has(uuid_value)) { + this.on_telem_value.set(uuid_value, []) } + this.on_telem_value.get(uuid_value)?.push(value => { + value_result.value = value + }) + } + }) - this.connected.value = false; - this.websocket.close(); - this.websocket = null; - this.on_telem_value.clear(); - } - - listen_to_telemetry(telemetry: Ref) { - const value_result = ref(null); - - const uuid = computed(() => { - if (telemetry.value) { - return telemetry.value.uuid; - } - return null; - }); - - watch([uuid, this.connected], ([uuid_value, connected]) => { - if (connected && uuid_value) { - this.websocket?.send(JSON.stringify({ - "RegisterTlmListener": { - uuid: uuid_value - } - })); - if (!this.on_telem_value.has(uuid_value)) { - this.on_telem_value.set(uuid_value, []); - } - this.on_telem_value.get(uuid_value)?.push((value) => { - value_result.value = value; - }); - } - }); - - return value_result; - } + return value_result + } } export const WEBSOCKET_SYMBOL = Symbol() export function useWebsocket() { - const handle = shallowRef(new WebsocketHandle()); + const handle = shallowRef(new WebsocketHandle()) - onMounted(() => { - handle.value.connect(); - }); - onUnmounted(() => { - handle.value.disconnect(); - }) + onMounted(() => { + handle.value.connect() + }) + onUnmounted(() => { + handle.value.disconnect() + }) - return handle; + return handle } diff --git a/frontend/src/graph/axis.ts b/frontend/src/graph/axis.ts index 0633fcd..3b799a7 100644 --- a/frontend/src/graph/axis.ts +++ b/frontend/src/graph/axis.ts @@ -1,12 +1,20 @@ -import type { MaybeRefOrGetter } from '@vue/reactivity' import type { Ref } from 'vue' +export enum AxisSide { + Right, + Left, + Hidden, +} + +export enum AxisType { + Linear, + Logarithmic, +} + export const AXIS_DATA = Symbol() export interface AxisData { - min_y: MaybeRefOrGetter; - max_y: MaybeRefOrGetter; - axis_update_watch: Ref; - max_y_callback: (y: number) => void; - min_y_callback: (y: number) => void; - y_map: (y: number) => number; + axis_update_watch: Ref + max_y_callback: (y: number) => void + min_y_callback: (y: number) => void + y_map: (y: number) => number } diff --git a/frontend/src/graph/graph.ts b/frontend/src/graph/graph.ts index 9e74480..6e1e876 100644 --- a/frontend/src/graph/graph.ts +++ b/frontend/src/graph/graph.ts @@ -1,12 +1,12 @@ -import type { MaybeRefOrGetter } from '@vue/reactivity' +import type { MaybeRefOrGetter } from 'vue' export const GRAPH_DATA = Symbol() export interface GraphData { - border: MaybeRefOrGetter; - min_x: MaybeRefOrGetter; - max_x: MaybeRefOrGetter; - width: MaybeRefOrGetter; - height: MaybeRefOrGetter; - x_map: (x: number) => number; + border_top_bottom: MaybeRefOrGetter + min_x: MaybeRefOrGetter + max_x: MaybeRefOrGetter + width: MaybeRefOrGetter + height: MaybeRefOrGetter + x_map: (x: number) => number } diff --git a/frontend/src/views/HomeView.vue b/frontend/src/views/HomeView.vue index 7a112ca..197f6a7 100644 --- a/frontend/src/views/HomeView.vue +++ b/frontend/src/views/HomeView.vue @@ -1,25 +1,28 @@ - + diff --git a/server/src/telemetry.rs b/server/src/telemetry.rs index 795f68c..e7d7473 100644 --- a/server/src/telemetry.rs +++ b/server/src/telemetry.rs @@ -14,7 +14,7 @@ fn tlm_data_type_serialzier(tlm_data_type: &TelemetryDataType, serializer: S) struct TlmDataTypeVisitor; -impl<'de> Visitor<'de> for TlmDataTypeVisitor { +impl Visitor<'_> for TlmDataTypeVisitor { type Value = TelemetryDataType; fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { @@ -95,7 +95,7 @@ impl TelemetryManagementService { definition: TelemetryDefinition { uuid: uuid.clone(), name: telemetry_definition_request.name.clone(), - data_type: telemetry_definition_request.data_type().clone(), + data_type: telemetry_definition_request.data_type(), }, data: tokio::sync::watch::channel(None).0 }); @@ -104,11 +104,9 @@ impl TelemetryManagementService { } pub async fn get_by_name(&self, name: &String) -> Option { - let Some(uuid) = ({ + let uuid = { let uuid_lock = self.uuid_mapping.lock().await; - uuid_lock.get(name).map(|inner| inner.clone()) - }) else { - return None; + uuid_lock.get(name).cloned()? }; self.get_by_uuid(&uuid).await @@ -116,6 +114,6 @@ impl TelemetryManagementService { pub async fn get_by_uuid(&self, uuid: &String) -> Option { let tlm_lock = self.tlm_mapping.lock().await; - tlm_lock.get(uuid).map(|inner| inner.clone()) + tlm_lock.get(uuid).cloned() } }