diff --git a/src/services/api.ts b/src/services/api.ts index 6d97559..9f212e9 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -76,6 +76,7 @@ export interface SensorReading { } export interface SensorInfo { + name: string sensor_id: string sensor_type: SensorType room?: string @@ -211,13 +212,49 @@ class ApiClient { this.baseUrl = baseUrl } - private getAuthHeaders(): Record { + private shouldIncludeAuth(endpoint: string): boolean { + // Endpoints that do NOT require authentication + const publicEndpoints = [ + '/health', + '/api/v1/tokens/generate', + '/api/v1/tokens/validate', + '/api/v1/ingestion/', + ] + + // Special case: token save, revoke operations might need auth depending on backend implementation + // For now, let's include auth for them to be safe + return !publicEndpoints.some((publicPath) => endpoint.startsWith(publicPath)) + } + + private getAuthHeaders(endpoint: string): Record { + // Only include auth headers for endpoints that require authentication + if (!this.shouldIncludeAuth(endpoint)) { + return {} + } + // Dynamically get auth headers to avoid circular imports try { + // Try to get from window first (for when store is exposed) const authStore = (window as any).__AUTH_STORE__ if (authStore && typeof authStore.getAuthHeader === 'function') { return authStore.getAuthHeader() } + + // Fallback: try to access the auth store directly + // This requires the auth store to be initialized + const token = localStorage.getItem('dashboard_auth_token') + if (token) { + // Check if token is still valid + const expiry = localStorage.getItem('dashboard_token_expiry') + if (expiry) { + const expiryTime = new Date(expiry).getTime() + const currentTime = new Date().getTime() + + if (currentTime < expiryTime) { + return { Authorization: `Bearer ${token}` } + } + } + } } catch (error) { console.warn('Could not get auth headers:', error) } @@ -227,7 +264,7 @@ class ApiClient { private async request(endpoint: string, options: RequestInit = {}): Promise { const url = `${this.baseUrl}${endpoint}` - const authHeaders = this.getAuthHeaders() + const authHeaders = this.getAuthHeaders(endpoint) const config: RequestInit = { headers: { 'Content-Type': 'application/json', @@ -270,7 +307,7 @@ class ApiClient { }) } - const authHeaders = this.getAuthHeaders() + const authHeaders = this.getAuthHeaders(endpoint) const response = await fetch(url.toString(), { method: 'GET', headers: { diff --git a/src/services/authApi.ts b/src/services/authApi.ts index d75db17..9cfc959 100644 --- a/src/services/authApi.ts +++ b/src/services/authApi.ts @@ -1,18 +1,16 @@ -/** - * Authentication API Service - * Handles JWT token generation and validation - */ import { apiClient } from './api' export interface TokenRequest { name: string list_of_resources: string[] + data_aggregation?: boolean + time_aggregation?: boolean + embargo?: number + exp_hours?: number } export interface TokenResponse { token: string - expires_at: string - resources: string[] } export interface TokenValidation { @@ -26,6 +24,10 @@ export const authApi = { return apiClient.post('/api/v1/tokens/generate', request) }, + async saveToken(token: string): Promise<{ token: string; datetime: string; active: boolean }> { + return apiClient.post<{ token: string; datetime: string; active: boolean }>('/api/v1/tokens/save', { token }) + }, + async validateToken(token: string): Promise { return apiClient.post('/api/v1/tokens/validate', { token }) }, diff --git a/src/services/roomsApi.ts b/src/services/roomsApi.ts index 56b7bcd..da1eb07 100644 --- a/src/services/roomsApi.ts +++ b/src/services/roomsApi.ts @@ -1,20 +1,14 @@ -/** - * Rooms API Service - * Handles room-related API calls - */ import { apiClient, type RoomInfo, type RoomData } from './api' export const roomsApi = { - /** - * Get list of all rooms with sensor counts and latest metrics - */ + async getRoomNames(): Promise<{ rooms: string[] }> { + return apiClient.get<{ rooms: string[] }>('/api/v1/rooms/names') + }, + async getRooms(): Promise { return apiClient.get('/api/v1/rooms') }, - /** - * Get historical data for a specific room - */ async getRoomData( roomName: string, params?: { diff --git a/src/services/sensorsApi.ts b/src/services/sensorsApi.ts index 8850267..48b5293 100644 --- a/src/services/sensorsApi.ts +++ b/src/services/sensorsApi.ts @@ -14,7 +14,7 @@ export const sensorsApi = { sensor_type?: SensorType status?: SensorStatus }): Promise { - return apiClient.get('/api/v1/sensors', params) + return apiClient.get('/api/v1/sensors/get', params) }, async getSensor(sensorId: string): Promise { diff --git a/src/stores/auth.ts b/src/stores/auth.ts index 0810bfb..a7f10fc 100644 --- a/src/stores/auth.ts +++ b/src/stores/auth.ts @@ -1,6 +1,24 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' -import { authApi, type TokenRequest, type TokenResponse } from '@/services/authApi' +import { authApi, type TokenRequest } from '@/services/authApi' + +// Helper function to decode JWT token payload (without verification) +function decodeJwtPayload(token: string) { + try { + const base64Url = token.split('.')[1] + const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/') + const jsonPayload = decodeURIComponent( + atob(base64) + .split('') + .map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)) + .join(''), + ) + return JSON.parse(jsonPayload) + } catch (error) { + console.error('Failed to decode JWT payload:', error) + return null + } +} const TOKEN_STORAGE_KEY = 'dashboard_auth_token' const TOKEN_EXPIRY_KEY = 'dashboard_token_expiry' @@ -53,30 +71,35 @@ export const useAuthStore = defineStore('auth', () => { try { const request: TokenRequest = { name, - list_of_resources: [ - 'sensors', - 'rooms', - 'analytics', - 'health', - 'data', - 'export', - 'events' - ] + list_of_resources: ['sensors', 'rooms', 'analytics', 'health', 'data', 'export', 'events'], + data_aggregation: true, + time_aggregation: true, + embargo: 0, + exp_hours: 24, } const response = await authApi.generateToken(request) + // Save token to backend database immediately after generation + await authApi.saveToken(response.token) + + // Decode the JWT to get expiration and resources + const payload = decodeJwtPayload(response.token) + if (!payload) { + throw new Error('Failed to decode token payload') + } + // Store token data token.value = response.token - tokenExpiry.value = response.expires_at - tokenResources.value = response.resources || request.list_of_resources + tokenExpiry.value = new Date(payload.exp * 1000).toISOString() + tokenResources.value = payload.list_of_resources || request.list_of_resources // Persist to localStorage localStorage.setItem(TOKEN_STORAGE_KEY, response.token) - localStorage.setItem(TOKEN_EXPIRY_KEY, response.expires_at) + localStorage.setItem(TOKEN_EXPIRY_KEY, tokenExpiry.value) localStorage.setItem(TOKEN_RESOURCES_KEY, JSON.stringify(tokenResources.value)) - console.log('Authentication successful, token expires at:', response.expires_at) + console.log('Authentication successful, token expires at:', tokenExpiry.value) return true } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to generate token' @@ -123,7 +146,7 @@ export const useAuthStore = defineStore('auth', () => { localStorage.removeItem(TOKEN_RESOURCES_KEY) } - function loadTokenFromStorage() { + async function loadTokenFromStorage() { const storedToken = localStorage.getItem(TOKEN_STORAGE_KEY) const storedExpiry = localStorage.getItem(TOKEN_EXPIRY_KEY) const storedResources = localStorage.getItem(TOKEN_RESOURCES_KEY) @@ -159,7 +182,7 @@ export const useAuthStore = defineStore('auth', () => { async function ensureAuthenticated(): Promise { // Try to load from storage first - if (loadTokenFromStorage() && isAuthenticated.value) { + if ((await loadTokenFromStorage()) && isAuthenticated.value) { return true } @@ -175,8 +198,10 @@ export const useAuthStore = defineStore('auth', () => { return {} } - // Initialize on store creation - loadTokenFromStorage() + // Initialize on store creation (async) + loadTokenFromStorage().catch(error => { + console.warn('Failed to load token from storage:', error) + }) return { // State @@ -196,6 +221,6 @@ export const useAuthStore = defineStore('auth', () => { clearToken, loadTokenFromStorage, ensureAuthenticated, - getAuthHeader + getAuthHeader, } -}) \ No newline at end of file +}) diff --git a/src/stores/energy.ts b/src/stores/energy.ts index ee4e324..34d5a73 100644 --- a/src/stores/energy.ts +++ b/src/stores/energy.ts @@ -207,7 +207,10 @@ export const useEnergyStore = defineStore('energy', () => { const data = newDataBuffer.shift() // Get the oldest data point if (data) { // Skip non-data messages (connection establishment, proxy info, etc.) - if (data.type && (data.type === 'connection_established' || data.type === 'proxy_info')) { + if ( + 'type' in data && + (data.type === 'connection_established' || data.type === 'proxy_info') + ) { console.log('Received system message:', data.type) return } @@ -339,6 +342,331 @@ export const useEnergyStore = defineStore('energy', () => { return 'critical' } + // Sensor management functions + function updateSensorRoom(sensorId: string, newRoom: string) { + const sensor = sensorDevices.get(sensorId) + if (sensor) { + sensor.room = newRoom + sensorDevices.set(sensorId, { ...sensor }) + } + } + + async function executeSensorAction(sensorId: string, actionId: string, parameters?: any) { + const sensor = sensorDevices.get(sensorId) + if (!sensor) return false + + const action = sensor.capabilities.actions.find((a) => a.id === actionId) + if (!action) return false + + // Simulate API call to device + console.log(`Executing action ${actionId} on sensor ${sensorId}`, parameters) + + // Here you would make the actual API call to control the device + // For now, we'll simulate a successful action + return new Promise((resolve) => { + setTimeout(() => { + console.log(`Action ${action.name} executed successfully on ${sensor.name}`) + resolve(true) + }, 1000) + }) + } + + function getSensorsByRoom(room: string): SensorDevice[] { + return Array.from(sensorDevices.values()).filter((sensor) => sensor.room === room) + } + + function getSensorsByType(type: SensorDevice['type']): SensorDevice[] { + return Array.from(sensorDevices.values()).filter((sensor) => sensor.type === type) + } + + // Room management functions + const loadRoomsFromAPI = async (): Promise => { + if (roomsLoading.value || roomsLoaded.value) { + return // Already loading or loaded + } + + roomsLoading.value = true + + try { + // Use the API client which handles authentication properly + const data = await roomsApi.getRoomNames() + if (data.rooms && Array.isArray(data.rooms)) { + availableRooms.value = data.rooms.sort() + roomsLoaded.value = true + return + } + + // If no rooms found, use empty list + console.warn('No rooms found in API response, starting with empty list') + availableRooms.value = [] + roomsLoaded.value = true + } catch (error) { + console.error('Error loading rooms:', error) + // Start with empty list on error + availableRooms.value = [] + roomsLoaded.value = true + } finally { + roomsLoading.value = false + } + } + + function addRoom(roomName: string): boolean { + if (!roomName.trim()) return false + + // Check if room already exists + if (availableRooms.value.includes(roomName.trim())) { + return false + } + + // Add room to available rooms list + availableRooms.value.push(roomName.trim()) + availableRooms.value.sort() // Keep rooms sorted alphabetically + + console.log(`Added new room: ${roomName}`) + return true + } + + function removeRoom(roomName: string): boolean { + const index = availableRooms.value.indexOf(roomName) + if (index === -1) return false + + // Check if any sensors are assigned to this room + const sensorsInRoom = Array.from(sensorDevices.values()).filter( + (sensor) => sensor.room === roomName, + ) + if (sensorsInRoom.length > 0) { + // Reassign sensors to 'Unassigned' + sensorsInRoom.forEach((sensor) => { + sensor.room = '' + sensorDevices.set(sensor.id, { ...sensor }) + }) + } + + // Remove room data + roomsData.delete(roomName) + + // Remove from available rooms + availableRooms.value.splice(index, 1) + + console.log(`Removed room: ${roomName}`) + return true + } + + function getRoomStats(roomName: string) { + const sensorsInRoom = getSensorsByRoom(roomName) + const roomMetrics = roomsData.get(roomName) + + return { + sensorCount: sensorsInRoom.length, + sensorTypes: [...new Set(sensorsInRoom.map((s) => s.type))], + hasMetrics: !!roomMetrics, + energyConsumption: roomMetrics?.energy.current || 0, + co2Level: roomMetrics?.co2.current || 0, + lastUpdated: roomMetrics?.lastUpdated || null, + } + } + + function getAllRoomsWithStats() { + return availableRooms.value.map((room) => ({ + name: room, + ...getRoomStats(room), + })) + } + + // API Integration Functions + async function handleApiCall(apiCall: () => Promise): Promise { + apiLoading.value = true + apiError.value = null + + try { + const result = await apiCall() + return result + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred' + + if (errorMessage.includes('401') || errorMessage.includes('Authorization')) { + console.warn('Authentication error detected, attempting to re-authenticate...') + + // Try to get fresh auth token + try { + const authStore = (window as any).__AUTH_STORE__ + if (authStore && typeof authStore.ensureAuthenticated === 'function') { + const authSuccess = await authStore.ensureAuthenticated() + if (authSuccess) { + console.log('Re-authentication successful, retrying API call...') + // Retry the original API call + try { + const retryResult = await apiCall() + return retryResult + } catch (retryError) { + const retryErrorMessage = + retryError instanceof Error ? retryError.message : 'Retry failed' + apiError.value = retryErrorMessage + console.error('API retry failed:', retryErrorMessage) + return null + } + } + } + } catch (authError) { + console.error('Re-authentication failed:', authError) + } + } + + apiError.value = errorMessage + console.error('API call failed:', errorMessage) + return null + } finally { + apiLoading.value = false + } + } + + // Helper function to transform API sensor to expected format + function transformApiSensor(apiSensor: any) { + return { + id: apiSensor.sensor_id, + sensor_id: apiSensor.sensor_id, + name: apiSensor.name || apiSensor.sensor_id, + type: apiSensor.sensor_type, + sensor_type: apiSensor.sensor_type, + room: apiSensor.room, + status: apiSensor.status === 'active' ? 'online' : apiSensor.status, + location: apiSensor.location, + // Add capabilities based on sensor type + capabilities: { + monitoring: [apiSensor.sensor_type], + actions: [], // API sensors don't have actions yet + }, + // Add metadata + metadata: { + created_at: apiSensor.created_at, + updated_at: apiSensor.updated_at, + manufacturer: apiSensor.manufacturer, + model: apiSensor.model, + }, + } + } + + // Sensors API functions + async function fetchApiSensors(params?: { room?: string; sensor_type?: any; status?: any }) { + const result = await handleApiCall(() => sensorsApi.getSensors(params)) + if (result.sensors) { + result.sensors.forEach((sensor) => { + sensorDevices.set(sensor.id, sensor) + }) + } + return result + } + + async function fetchApiSensorData( + sensorId: string, + params?: { start_time?: number; end_time?: number; limit?: number; offset?: number }, + ) { + return handleApiCall(() => sensorsApi.getSensorData(sensorId, params)) + } + + async function updateApiSensorMetadata(sensorId: string, metadata: Record) { + return handleApiCall(() => sensorsApi.updateSensorMetadata(sensorId, metadata)) + } + + async function deleteApiSensor(sensorId: string) { + return handleApiCall(() => sensorsApi.deleteSensor(sensorId)) + } + + async function exportApiData(params: { + start_time: number + end_time: number + sensor_ids?: string + format?: 'json' | 'csv' + }) { + return handleApiCall(() => sensorsApi.exportData(params)) + } + + // Rooms API functions + async function fetchApiRooms() { + const result = await handleApiCall(() => roomsApi.getRooms()) + if (result) { + apiRooms.value = result + // Update available rooms from API data + const roomNames = result.map((room) => room.room).filter((name) => name) + if (roomNames.length > 0) { + availableRooms.value = [...new Set([...availableRooms.value, ...roomNames])].sort() + } + } + return result + } + + async function fetchApiRoomData( + roomName: string, + params?: { start_time?: number; end_time?: number; limit?: number }, + ) { + return handleApiCall(() => roomsApi.getRoomData(roomName, params)) + } + + // Analytics API functions + async function fetchAnalyticsSummary(hours: number = 24) { + const result = await handleApiCall(() => analyticsApi.getAnalyticsSummary(hours)) + if (result) { + analyticsData.value.summary = result + } + return result + } + + async function fetchEnergyTrends(hours: number = 168) { + const result = await handleApiCall(() => analyticsApi.getEnergyTrends(hours)) + if (result) { + analyticsData.value.trends = result + } + return result + } + + async function fetchRoomComparison(hours: number = 24) { + const result = await handleApiCall(() => analyticsApi.getRoomComparison(hours)) + if (result) { + analyticsData.value.roomComparison = result + } + return result + } + + async function fetchSystemEvents(params?: { + severity?: string + event_type?: string + hours?: number + limit?: number + }) { + return handleApiCall(() => analyticsApi.getEvents(params)) + } + + // Health API functions + async function fetchSystemStatus() { + const result = await handleApiCall(() => healthApi.getStatus()) + if (result) { + systemStatus.value = result + } + return result + } + + async function fetchHealthStatus() { + const result = await handleApiCall(() => healthApi.getHealth()) + if (result) { + healthStatus.value = result + } + return result + } + + // Initialize data from APIs + async function initializeFromApi() { + await Promise.allSettled([ + loadRoomsFromAPI(), // Load room names first + fetchApiSensors(), + fetchApiRooms(), + fetchAnalyticsSummary(), + fetchSystemStatus(), + fetchHealthStatus(), + ]) + } + + // Initialize mock sensors on store creation + // Initialize mock sensor devices function initializeMockSensors() { const mockSensors: SensorDevice[] = [ @@ -470,322 +798,7 @@ export const useEnergyStore = defineStore('energy', () => { sensorDevices.set(sensor.id, sensor) }) } - - // Sensor management functions - function updateSensorRoom(sensorId: string, newRoom: string) { - const sensor = sensorDevices.get(sensorId) - if (sensor) { - sensor.room = newRoom - sensorDevices.set(sensorId, { ...sensor }) - } - } - - async function executeSensorAction(sensorId: string, actionId: string, parameters?: any) { - const sensor = sensorDevices.get(sensorId) - if (!sensor) return false - - const action = sensor.capabilities.actions.find((a) => a.id === actionId) - if (!action) return false - - // Simulate API call to device - console.log(`Executing action ${actionId} on sensor ${sensorId}`, parameters) - - // Here you would make the actual API call to control the device - // For now, we'll simulate a successful action - return new Promise((resolve) => { - setTimeout(() => { - console.log(`Action ${action.name} executed successfully on ${sensor.name}`) - resolve(true) - }, 1000) - }) - } - - function getSensorsByRoom(room: string): SensorDevice[] { - return Array.from(sensorDevices.values()).filter((sensor) => sensor.room === room) - } - - function getSensorsByType(type: SensorDevice['type']): SensorDevice[] { - return Array.from(sensorDevices.values()).filter((sensor) => sensor.type === type) - } - - // Room management functions - const loadRoomsFromAPI = async (): Promise => { - if (roomsLoading.value || roomsLoaded.value) { - return // Already loading or loaded - } - - roomsLoading.value = true - - try { - // Try to load from microservices API first - const response = await fetch('/api/v1/rooms/names') - - if (response.ok) { - const data = await response.json() - if (data.rooms && Array.isArray(data.rooms)) { - availableRooms.value = data.rooms.sort() - roomsLoaded.value = true - console.log('Loaded rooms from microservices API:', data.rooms.length) - return - } - } - - // Fallback: try direct sensor service connection - const directResponse = await fetch('http://localhost:8007/rooms/names') - - if (directResponse.ok) { - const data = await directResponse.json() - if (data.rooms && Array.isArray(data.rooms)) { - availableRooms.value = data.rooms.sort() - roomsLoaded.value = true - console.log('Loaded rooms from sensor service:', data.rooms.length) - return - } - } - - // If both fail, use empty list and log warning - console.warn('Failed to load rooms from API, starting with empty list') - availableRooms.value = [] - roomsLoaded.value = true - } catch (error) { - console.error('Error loading rooms:', error) - // Start with empty list on error - availableRooms.value = [] - roomsLoaded.value = true - } finally { - roomsLoading.value = false - } - } - - function addRoom(roomName: string): boolean { - if (!roomName.trim()) return false - - // Check if room already exists - if (availableRooms.value.includes(roomName.trim())) { - return false - } - - // Add room to available rooms list - availableRooms.value.push(roomName.trim()) - availableRooms.value.sort() // Keep rooms sorted alphabetically - - console.log(`Added new room: ${roomName}`) - return true - } - - function removeRoom(roomName: string): boolean { - const index = availableRooms.value.indexOf(roomName) - if (index === -1) return false - - // Check if any sensors are assigned to this room - const sensorsInRoom = Array.from(sensorDevices.values()).filter( - (sensor) => sensor.room === roomName, - ) - if (sensorsInRoom.length > 0) { - // Reassign sensors to 'Unassigned' - sensorsInRoom.forEach((sensor) => { - sensor.room = '' - sensorDevices.set(sensor.id, { ...sensor }) - }) - } - - // Remove room data - roomsData.delete(roomName) - - // Remove from available rooms - availableRooms.value.splice(index, 1) - - console.log(`Removed room: ${roomName}`) - return true - } - - function getRoomStats(roomName: string) { - const sensorsInRoom = getSensorsByRoom(roomName) - const roomMetrics = roomsData.get(roomName) - - return { - sensorCount: sensorsInRoom.length, - sensorTypes: [...new Set(sensorsInRoom.map((s) => s.type))], - hasMetrics: !!roomMetrics, - energyConsumption: roomMetrics?.energy.current || 0, - co2Level: roomMetrics?.co2.current || 0, - lastUpdated: roomMetrics?.lastUpdated || null, - } - } - - function getAllRoomsWithStats() { - return availableRooms.value.map((room) => ({ - name: room, - ...getRoomStats(room), - })) - } - - // API Integration Functions - async function handleApiCall(apiCall: () => Promise): Promise { - apiLoading.value = true - apiError.value = null - - try { - const result = await apiCall() - return result - } catch (error) { - const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred' - - if (errorMessage.includes('401') || errorMessage.includes('Authorization')) { - console.warn('Authentication error detected, attempting to re-authenticate...') - - // Try to get fresh auth token - try { - const authStore = (window as any).__AUTH_STORE__ - if (authStore && typeof authStore.ensureAuthenticated === 'function') { - const authSuccess = await authStore.ensureAuthenticated() - if (authSuccess) { - console.log('Re-authentication successful, retrying API call...') - // Retry the original API call - try { - const retryResult = await apiCall() - return retryResult - } catch (retryError) { - const retryErrorMessage = - retryError instanceof Error ? retryError.message : 'Retry failed' - apiError.value = retryErrorMessage - console.error('API retry failed:', retryErrorMessage) - return null - } - } - } - } catch (authError) { - console.error('Re-authentication failed:', authError) - } - } - - apiError.value = errorMessage - console.error('API call failed:', errorMessage) - return null - } finally { - apiLoading.value = false - } - } - - // Sensors API functions - async function fetchApiSensors(params?: { room?: string; sensor_type?: any; status?: any }) { - const result = await handleApiCall(() => sensorsApi.getSensors(params)) - if (result) { - apiSensors.value = result - } - return result - } - - async function fetchApiSensorData( - sensorId: string, - params?: { start_time?: number; end_time?: number; limit?: number; offset?: number }, - ) { - return handleApiCall(() => sensorsApi.getSensorData(sensorId, params)) - } - - async function updateApiSensorMetadata(sensorId: string, metadata: Record) { - return handleApiCall(() => sensorsApi.updateSensorMetadata(sensorId, metadata)) - } - - async function deleteApiSensor(sensorId: string) { - return handleApiCall(() => sensorsApi.deleteSensor(sensorId)) - } - - async function exportApiData(params: { - start_time: number - end_time: number - sensor_ids?: string - format?: 'json' | 'csv' - }) { - return handleApiCall(() => sensorsApi.exportData(params)) - } - - // Rooms API functions - async function fetchApiRooms() { - const result = await handleApiCall(() => roomsApi.getRooms()) - if (result) { - apiRooms.value = result - // Update available rooms from API data - const roomNames = result.map((room) => room.room).filter((name) => name) - if (roomNames.length > 0) { - availableRooms.value = [...new Set([...availableRooms.value, ...roomNames])].sort() - } - } - return result - } - - async function fetchApiRoomData( - roomName: string, - params?: { start_time?: number; end_time?: number; limit?: number }, - ) { - return handleApiCall(() => roomsApi.getRoomData(roomName, params)) - } - - // Analytics API functions - async function fetchAnalyticsSummary(hours: number = 24) { - const result = await handleApiCall(() => analyticsApi.getAnalyticsSummary(hours)) - if (result) { - analyticsData.value.summary = result - } - return result - } - - async function fetchEnergyTrends(hours: number = 168) { - const result = await handleApiCall(() => analyticsApi.getEnergyTrends(hours)) - if (result) { - analyticsData.value.trends = result - } - return result - } - - async function fetchRoomComparison(hours: number = 24) { - const result = await handleApiCall(() => analyticsApi.getRoomComparison(hours)) - if (result) { - analyticsData.value.roomComparison = result - } - return result - } - - async function fetchSystemEvents(params?: { - severity?: string - event_type?: string - hours?: number - limit?: number - }) { - return handleApiCall(() => analyticsApi.getEvents(params)) - } - - // Health API functions - async function fetchSystemStatus() { - const result = await handleApiCall(() => healthApi.getStatus()) - if (result) { - systemStatus.value = result - } - return result - } - - async function fetchHealthStatus() { - const result = await handleApiCall(() => healthApi.getHealth()) - if (result) { - healthStatus.value = result - } - return result - } - - // Initialize data from APIs - async function initializeFromApi() { - await Promise.allSettled([ - loadRoomsFromAPI(), // Load room names first - fetchApiSensors(), - fetchApiRooms(), - fetchAnalyticsSummary(), - fetchSystemStatus(), - fetchHealthStatus(), - ]) - } - - // Initialize mock sensors on store creation - initializeMockSensors() + //initializeMockSensors() // Load rooms from API on store initialization loadRoomsFromAPI() diff --git a/src/views/SensorManagementView.vue b/src/views/SensorManagementView.vue index 35618cf..4cc88bd 100644 --- a/src/views/SensorManagementView.vue +++ b/src/views/SensorManagementView.vue @@ -24,15 +24,6 @@
- +