import { io, Socket } from "socket.io-client"; import { store } from "../store"; import { updateTelemetry, setTelemetryLoading, setTelemetryError, } from "../store/telemetrySlice"; import { BmsState } from "@/constants/types"; import { BASE_URL, SOCKET_BASE_URL, VECTOR_BASE_URL } from "@/constants/config"; import api from "./axiosClient"; import axios from "axios"; type TokenResponse = { success: boolean; message: string; data: { email: string; token: string; }; }; let socket: Socket | null = null; let token: string | null = null; let controllingServer: string | null = null; const fetchToken = async (): Promise => { try { const response = await api.get( `${BASE_URL}/api/v1/vec-token` ); return response.data.data.token; } catch (error) { console.error("Error fetching token:", error); throw error; } }; const fetchControllingServer = async (token: string): Promise => { const hardwareDeviceId = store.getState().user.data?.batteries[0]?.device_id; console.log("Hardware Device ID:", store.getState().user.data); // const hardwareDeviceId = "VEC16000866082076280974"; try { if (!hardwareDeviceId) throw new Error("Missing hardwareDeviceId"); const response = await axios.get( `${VECTOR_BASE_URL}/api/device-management/dashboard/get/hardwareDeviceId/${hardwareDeviceId}`, { headers: { Authorization: `Bearer ${token}`, }, } ); return response.data.trim(); } catch (error) { console.error("Error fetching controlling server:", error); throw error; } }; export const connectSocket = () => { // const hardwareDeviceId = store.getState().user.data?.batteries[0]?.battery_id; const hardwareDeviceId = "V16000866082076280974"; if (!token || !controllingServer || !hardwareDeviceId) { store.dispatch(setTelemetryError("Missing socket auth info")); return; } store.dispatch(setTelemetryLoading()); console.log("Initializing socket connection..."); socket = io( `${SOCKET_BASE_URL}/?dashboardId=deviceDashboardSocket&assetId=${hardwareDeviceId}`, { transports: ["websocket"], extraHeaders: { Authorization: `Bearer ${token}`, controllingServer: controllingServer, }, reconnection: true, } ); socket.on("connect", () => { console.log("Socket connected:", socket?.id); }); socket.on("connect_error", (error) => { console.error("Socket connection error:", error); store.dispatch(setTelemetryError("Socket connection failed")); }); socket.on("disconnect", (reason) => { console.log("Socket disconnecteddddd", reason); store.dispatch(setTelemetryError("Socket disconnected: " + reason)); }); socket.on("dataUpdate", handleSocketData); }; export const initSocket = async () => { try { //get latest telemetry as fallback option token = await fetchToken(); controllingServer = await fetchControllingServer(token); await fetchLatestTelemetry(token, controllingServer); connectSocket(); } catch (err) { console.log(err, ""); store.dispatch(setTelemetryError("Initialization failed")); } }; export const disconnectSocket = () => { if (socket) { socket.disconnect(); console.log("Socket disconnected"); } }; const handleSocketData = (data: any) => { console.log("..."); try { console.log(data.dataSeries.assetData, "dataSeries.assetData"); const SoH = data?.dataSeries?.assetData[0]?.bms[0]?.bmsSpecific?.ivecSpecific?.soh ?? null; const SoC = data?.dataSeries?.assetData?.[0]?.bms?.[0]?.batterySoc ?? null; const currentMode = data?.dataSeries?.assetData?.[0]?.bms?.[0]?.bmsSpecific?.ivecSpecific ?.ivecStatus?.currentMode ?? null; const gps = data?.dataSeries?.locationData?.gps ?? null; const totalDistance = data?.dataSeries?.systemData?.odoMeter ?? null; const lat = gps?.[1]; const lon = gps?.[2]; console.log("GPS Data:", lat, lon); let bms_state: BmsState | null = null; if (currentMode === 0) { bms_state = 0; } else if (currentMode === 1) { bms_state = -1; } else if (currentMode === 2) { bms_state = 1; } store.dispatch( updateTelemetry({ SoH, SoC, chargingState: bms_state, lat, lon, loading: false, error: null, totalDistance, }) ); } catch (err) { console.error("Error handling socket data:", err); store.dispatch(setTelemetryError("Data parsing failed")); } }; const fetchLatestTelemetry = async ( token: string, controllingServer: string ) => { try { const hardwareDeviceId = store.getState().user.data?.batteries[0]?.device_id; if (!hardwareDeviceId || !token || !controllingServer) throw new Error("Missing hardwareDeviceId"); const response = await axios.post( "https://vec-tr.ai/api/dashboard/getLastTelemetry", { deviceId: hardwareDeviceId }, // body { headers: { Authorization: `Bearer ${token}`, controllingServer: controllingServer, "Content-Type": "application/json", }, } ); if (response.data?.success && response.data?.data?.length > 0) { const telemetry = response.data.data[0]; const SoH = telemetry?.assetData?.[0]?.bms?.[0]?.bmsSpecific?.ivecSpecific?.soh ?? null; const SoC = telemetry?.assetData?.[0]?.bms?.[0]?.batterySoc ?? null; const currentMode = telemetry?.assetData?.[0]?.bms?.[0]?.bmsSpecific?.ivecSpecific ?.ivecStatus?.currentMode ?? null; const gps = telemetry?.locationData?.gps ?? null; const totalDistance = telemetry?.systemData?.odoMeter ?? null; const lat = gps?.[1]; const lon = gps?.[2]; let bms_state: BmsState | null = null; if (currentMode === 0) { bms_state = 0; } else if (currentMode === 1) { bms_state = -1; } else if (currentMode === 2) { bms_state = 1; } store.dispatch( updateTelemetry({ SoH, SoC, chargingState: bms_state, lat, lon, loading: false, error: null, totalDistance, }) ); } else { store.dispatch(setTelemetryError("No telemetry data found")); } } catch (error) { console.error("Error fetching latest telemetry:", error); store.dispatch(setTelemetryError("Failed to fetch latest telemetry")); } };