initial graph

This commit is contained in:
2024-12-02 23:30:05 -08:00
parent 8e4a94f8c5
commit 3eafc20e9d
12 changed files with 367 additions and 145 deletions

View File

@@ -1,13 +1,28 @@
import { ref } from 'vue'
import { ref, toValue, watchEffect } from 'vue'
import { type MaybeRefOrGetter } from '@vue/reactivity'
export function useTelemetry(name: string) {
const data = ref<any | null>(null);
const error = ref<any | null>(null);
fetch(`/api/tlm/${name}`)
.then((res) => res.json())
.then((json) => (data.value = json))
.catch((err) => (error.value = err));
return { data, error };
export interface TelemetryDefinition {
uuid: string;
name: string;
data_type: string;
}
export function useTelemetry(name: MaybeRefOrGetter<string>) {
const data = ref<TelemetryDefinition | null>(null);
const error = ref<any | null>(null);
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;
}
});
return { data, error };
}

View File

@@ -0,0 +1,19 @@
import { onMounted, onUnmounted, ref, shallowRef } from 'vue'
export function useNow(update_ms: number) {
const handle = shallowRef<number | undefined>(undefined);
const now = ref(Date.now());
onMounted(() => {
handle.value = setInterval(() => {
now.value = Date.now();
}, update_ms);
});
onUnmounted(() => {
if (handle.value) {
clearInterval(handle.value);
}
});
return now;
}

View File

@@ -1,112 +1,121 @@
import { computed, onMounted, onUnmounted, ref, type Ref, shallowRef, watch } from 'vue'
class WebsocketHandle {
websocket: WebSocket | null;
should_be_connected: boolean;
connected: Ref<boolean>;
on_telem_value: Map<string, Array<(value: any)=>void>>;
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;
}
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 uuid = message["TlmValue"]["uuid"];
if (uuid) {
const listeners = this.on_telem_value.get(uuid);
if (listeners) {
listeners.forEach((listener) => {
listener(message["TlmValue"]["value"]);
});
}
}
}
});
}
disconnect() {
this.should_be_connected = false;
if (this.websocket == null) {
return;
}
this.websocket.close();
this.websocket = null;
this.connected.value = false;
this.on_telem_value.clear();
}
listen_to_telemetry(telemetry: Ref<any>) {
const value_result = ref(null);
const uuid = computed(() => {
if (telemetry.value) {
return telemetry.value.uuid;
}
return null;
});
watch([uuid, this.connected], () => {
if (this.connected) {
let uuid_value = 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;
}
export interface TelemetryDataItem {
value: any;
timestamp: string;
}
interface TlmValue {
uuid: string;
value: TelemetryDataItem;
}
export class WebsocketHandle {
websocket: WebSocket | null;
should_be_connected: boolean;
connected: Ref<boolean>;
on_telem_value: Map<string, Array<(value: TelemetryDataItem)=>void>>;
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;
}
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;
}
this.connected.value = false;
this.websocket.close();
this.websocket = null;
this.on_telem_value.clear();
}
listen_to_telemetry(telemetry: Ref<any>) {
const value_result = ref<TelemetryDataItem | null>(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;
}
}
export const WEBSOCKET_SYMBOL = Symbol()
export function useWebsocket() {
const handle = shallowRef<WebsocketHandle>(new WebsocketHandle());
const handle = shallowRef<WebsocketHandle>(new WebsocketHandle());
onMounted(() => {
handle.value.connect();
});
onUnmounted(() => {
handle.value.disconnect();
})
onMounted(() => {
handle.value.connect();
});
onUnmounted(() => {
handle.value.disconnect();
})
return handle;
return handle;
}