87 lines
2.1 KiB
TypeScript
87 lines
2.1 KiB
TypeScript
import { defineStore } from "pinia";
|
|
|
|
export interface PrinterTelemetry {
|
|
printerId: string;
|
|
farmId: string;
|
|
state: "idle" | "printing" | "paused" | "error" | "offline";
|
|
nozzleTempC: number;
|
|
bedTempC: number;
|
|
progressPct: number;
|
|
updatedAt: string;
|
|
}
|
|
|
|
interface TelemetryState {
|
|
socket: WebSocket | null;
|
|
connected: boolean;
|
|
printers: Record<string, PrinterTelemetry>;
|
|
reconnectAttempt: number;
|
|
}
|
|
|
|
export const useTelemetryStore = defineStore("telemetry", {
|
|
state: (): TelemetryState => ({
|
|
socket: null,
|
|
connected: false,
|
|
printers: {},
|
|
reconnectAttempt: 0,
|
|
}),
|
|
|
|
getters: {
|
|
printerList: (state) => Object.values(state.printers),
|
|
},
|
|
|
|
actions: {
|
|
connect() {
|
|
if (this.socket) return;
|
|
|
|
const config = useRuntimeConfig();
|
|
const client = useSupabaseClient();
|
|
|
|
client.auth.getSession().then(({ data }) => {
|
|
const token = data.session?.access_token ?? "";
|
|
const url = `${config.public.wsBase}/ws/telemetry?token=${encodeURIComponent(token)}`;
|
|
this.open(url);
|
|
});
|
|
},
|
|
|
|
open(url: string) {
|
|
const socket = new WebSocket(url);
|
|
|
|
socket.onopen = () => {
|
|
this.connected = true;
|
|
this.reconnectAttempt = 0;
|
|
};
|
|
|
|
socket.onmessage = (event) => {
|
|
try {
|
|
const payload = JSON.parse(event.data) as { type: string; data: PrinterTelemetry };
|
|
if (payload.type === "printer.telemetry") {
|
|
this.printers[payload.data.printerId] = payload.data;
|
|
}
|
|
} catch {
|
|
// Ignore malformed frames rather than crashing the UI.
|
|
}
|
|
};
|
|
|
|
socket.onclose = () => {
|
|
this.connected = false;
|
|
this.socket = null;
|
|
const delay = Math.min(30_000, 1_000 * 2 ** this.reconnectAttempt);
|
|
this.reconnectAttempt += 1;
|
|
setTimeout(() => this.connect(), delay);
|
|
};
|
|
|
|
socket.onerror = () => {
|
|
socket.close();
|
|
};
|
|
|
|
this.socket = socket;
|
|
},
|
|
|
|
disconnect() {
|
|
this.socket?.close();
|
|
this.socket = null;
|
|
this.connected = false;
|
|
},
|
|
},
|
|
});
|