Remove redundant comments and improve code formatting

This commit is contained in:
rafaeldpsilva
2025-09-23 15:24:04 +01:00
parent a3d266d735
commit 6510468768
5 changed files with 102 additions and 141 deletions

View File

@@ -1,8 +1,3 @@
/**
* API Service Layer for Energy Monitoring Dashboard
* Handles all backend API communications
*/
// Base configuration // Base configuration
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000' const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000'

View File

@@ -22,26 +22,17 @@ export interface TokenValidation {
} }
export const authApi = { export const authApi = {
/**
* Generate a new JWT token for the dashboard
*/
async generateToken(request: TokenRequest): Promise<TokenResponse> { async generateToken(request: TokenRequest): Promise<TokenResponse> {
return apiClient.post<TokenResponse>('/api/v1/tokens/generate', request) return apiClient.post<TokenResponse>('/api/v1/tokens/generate', request)
}, },
/**
* Validate an existing token
*/
async validateToken(token: string): Promise<TokenValidation> { async validateToken(token: string): Promise<TokenValidation> {
return apiClient.post<TokenValidation>('/api/v1/tokens/validate', { token }) return apiClient.post<TokenValidation>('/api/v1/tokens/validate', { token })
}, },
/**
* Revoke a token
*/
async revokeToken(token: string): Promise<{ message: string }> { async revokeToken(token: string): Promise<{ message: string }> {
return apiClient.post<{ message: string }>('/api/v1/tokens/revoke', { token }) return apiClient.post<{ message: string }>('/api/v1/tokens/revoke', { token })
} },
} }
export default authApi export default authApi

View File

@@ -1,7 +1,3 @@
/**
* Sensors API Service
* Handles sensor-related API calls
*/
import { import {
apiClient, apiClient,
type SensorInfo, type SensorInfo,
@@ -13,9 +9,6 @@ import {
} from './api' } from './api'
export const sensorsApi = { export const sensorsApi = {
/**
* Get all sensors with optional filtering
*/
async getSensors(params?: { async getSensors(params?: {
room?: string room?: string
sensor_type?: SensorType sensor_type?: SensorType
@@ -24,16 +17,10 @@ export const sensorsApi = {
return apiClient.get<SensorInfo[]>('/api/v1/sensors', params) return apiClient.get<SensorInfo[]>('/api/v1/sensors', params)
}, },
/**
* Get detailed information about a specific sensor
*/
async getSensor(sensorId: string): Promise<SensorInfo> { async getSensor(sensorId: string): Promise<SensorInfo> {
return apiClient.get<SensorInfo>(`/api/v1/sensors/${sensorId}`) return apiClient.get<SensorInfo>(`/api/v1/sensors/${sensorId}`)
}, },
/**
* Get historical data for a specific sensor
*/
async getSensorData( async getSensorData(
sensorId: string, sensorId: string,
params?: { params?: {
@@ -46,16 +33,10 @@ export const sensorsApi = {
return apiClient.get<DataResponse>(`/api/v1/sensors/${sensorId}/data`, params) return apiClient.get<DataResponse>(`/api/v1/sensors/${sensorId}/data`, params)
}, },
/**
* Advanced data query with multiple filters
*/
async queryData(query: DataQuery): Promise<DataResponse> { async queryData(query: DataQuery): Promise<DataResponse> {
return apiClient.post<DataResponse>('/api/v1/data/query', query) return apiClient.post<DataResponse>('/api/v1/data/query', query)
}, },
/**
* Update sensor metadata
*/
async updateSensorMetadata( async updateSensorMetadata(
sensorId: string, sensorId: string,
metadata: Record<string, any>, metadata: Record<string, any>,
@@ -63,9 +44,6 @@ export const sensorsApi = {
return apiClient.put<{ message: string }>(`/api/v1/sensors/${sensorId}/metadata`, metadata) return apiClient.put<{ message: string }>(`/api/v1/sensors/${sensorId}/metadata`, metadata)
}, },
/**
* Delete sensor and all its data
*/
async deleteSensor(sensorId: string): Promise<{ async deleteSensor(sensorId: string): Promise<{
message: string message: string
readings_deleted: number readings_deleted: number
@@ -74,9 +52,6 @@ export const sensorsApi = {
return apiClient.delete(`/api/v1/sensors/${sensorId}`) return apiClient.delete(`/api/v1/sensors/${sensorId}`)
}, },
/**
* Export sensor data for specified time range
*/
async exportData(params: { async exportData(params: {
start_time: number start_time: number
end_time: number end_time: number

View File

@@ -1,9 +1,9 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref, reactive } from 'vue' import { ref, reactive } from 'vue'
import { import {
sensorsApi, sensorsApi,
roomsApi, roomsApi,
analyticsApi, analyticsApi,
healthApi, healthApi,
type SensorInfo as ApiSensorInfo, type SensorInfo as ApiSensorInfo,
type RoomInfo as ApiRoomInfo, type RoomInfo as ApiRoomInfo,
@@ -11,7 +11,7 @@ import {
type EnergyTrends, type EnergyTrends,
type RoomComparison, type RoomComparison,
type SystemStatus, type SystemStatus,
type HealthCheck type HealthCheck,
} from '@/services' } from '@/services'
const MAX_DATA_POINTS = 100 // Keep the last 100 data points for the chart const MAX_DATA_POINTS = 100 // Keep the last 100 data points for the chart
@@ -104,7 +104,7 @@ export const useEnergyStore = defineStore('energy', () => {
labels: [], labels: [],
datasets: [{ data: [] }], datasets: [{ data: [] }],
}) })
const sensorsData = reactive<Map<string, any>>(new Map()) // Legacy support const sensorsData = reactive<Map<string, any>>(new Map()) // Legacy support
const roomsData = reactive<Map<string, RoomMetrics>>(new Map()) const roomsData = reactive<Map<string, RoomMetrics>>(new Map())
const latestReadings = reactive<Map<string, SensorReading>>(new Map()) const latestReadings = reactive<Map<string, SensorReading>>(new Map())
@@ -123,7 +123,7 @@ export const useEnergyStore = defineStore('energy', () => {
}>({ }>({
summary: null, summary: null,
trends: null, trends: null,
roomComparison: null roomComparison: null,
}) })
const systemStatus = ref<SystemStatus | null>(null) const systemStatus = ref<SystemStatus | null>(null)
const healthStatus = ref<HealthCheck | null>(null) const healthStatus = ref<HealthCheck | null>(null)
@@ -252,18 +252,18 @@ export const useEnergyStore = defineStore('energy', () => {
function updateSensorData(data: LegacyEnergyData) { function updateSensorData(data: LegacyEnergyData) {
const existingSensor = sensorsData.get(data.sensorId) const existingSensor = sensorsData.get(data.sensorId)
if (existingSensor) { if (existingSensor) {
// Update existing sensor // Update existing sensor
const newTotal = existingSensor.totalConsumption + data.value const newTotal = existingSensor.totalConsumption + data.value
const dataPoints = Math.floor((data.timestamp - existingSensor.lastUpdated) / 60) + 1 // Rough estimate const dataPoints = Math.floor((data.timestamp - existingSensor.lastUpdated) / 60) + 1 // Rough estimate
sensorsData.set(data.sensorId, { sensorsData.set(data.sensorId, {
...existingSensor, ...existingSensor,
latestValue: data.value, latestValue: data.value,
totalConsumption: newTotal, totalConsumption: newTotal,
averageConsumption: newTotal / dataPoints, averageConsumption: newTotal / dataPoints,
lastUpdated: data.timestamp lastUpdated: data.timestamp,
}) })
} else { } else {
// Create new sensor entry // Create new sensor entry
@@ -273,7 +273,7 @@ export const useEnergyStore = defineStore('energy', () => {
totalConsumption: data.value, totalConsumption: data.value,
averageConsumption: data.value, averageConsumption: data.value,
lastUpdated: data.timestamp, lastUpdated: data.timestamp,
unit: data.unit unit: data.unit,
}) })
} }
} }
@@ -281,10 +281,10 @@ export const useEnergyStore = defineStore('energy', () => {
function updateRoomData(data: SensorReading) { function updateRoomData(data: SensorReading) {
// Store latest reading // Store latest reading
latestReadings.set(data.sensorId, data) latestReadings.set(data.sensorId, data)
// Get or create room metrics // Get or create room metrics
let roomMetrics = roomsData.get(data.room) let roomMetrics = roomsData.get(data.room)
if (!roomMetrics) { if (!roomMetrics) {
roomMetrics = { roomMetrics = {
room: data.room, room: data.room,
@@ -292,7 +292,7 @@ export const useEnergyStore = defineStore('energy', () => {
energy: { current: 0, total: 0, average: 0, unit: data.energy.unit }, energy: { current: 0, total: 0, average: 0, unit: data.energy.unit },
co2: { current: 0, average: 0, max: 0, status: 'good', unit: data.co2.unit }, co2: { current: 0, average: 0, max: 0, status: 'good', unit: data.co2.unit },
occupancyEstimate: 'low', occupancyEstimate: 'low',
lastUpdated: data.timestamp lastUpdated: data.timestamp,
} }
roomsData.set(data.room, roomMetrics) roomsData.set(data.room, roomMetrics)
} }
@@ -303,15 +303,17 @@ export const useEnergyStore = defineStore('energy', () => {
} }
// Recalculate room metrics from all sensors in the room // Recalculate room metrics from all sensors in the room
const roomSensors = Array.from(latestReadings.values()).filter(reading => reading.room === data.room) const roomSensors = Array.from(latestReadings.values()).filter(
(reading) => reading.room === data.room,
)
// Energy calculations // Energy calculations
roomMetrics.energy.current = roomSensors.reduce((sum, sensor) => sum + sensor.energy.value, 0) roomMetrics.energy.current = roomSensors.reduce((sum, sensor) => sum + sensor.energy.value, 0)
roomMetrics.energy.total += data.energy.value // Accumulate total roomMetrics.energy.total += data.energy.value // Accumulate total
roomMetrics.energy.average = roomMetrics.energy.total / roomSensors.length roomMetrics.energy.average = roomMetrics.energy.total / roomSensors.length
// CO2 calculations // CO2 calculations
const co2Values = roomSensors.map(sensor => sensor.co2.value) const co2Values = roomSensors.map((sensor) => sensor.co2.value)
roomMetrics.co2.current = co2Values.reduce((sum, val) => sum + val, 0) / co2Values.length roomMetrics.co2.current = co2Values.reduce((sum, val) => sum + val, 0) / co2Values.length
roomMetrics.co2.max = Math.max(roomMetrics.co2.max, ...co2Values) roomMetrics.co2.max = Math.max(roomMetrics.co2.max, ...co2Values)
roomMetrics.co2.average = (roomMetrics.co2.average + roomMetrics.co2.current) / 2 roomMetrics.co2.average = (roomMetrics.co2.average + roomMetrics.co2.current) / 2
@@ -349,13 +351,13 @@ export const useEnergyStore = defineStore('energy', () => {
lastSeen: Date.now() / 1000, lastSeen: Date.now() / 1000,
capabilities: { capabilities: {
monitoring: ['energy'], monitoring: ['energy'],
actions: [] actions: [],
}, },
metadata: { metadata: {
location: 'Wall mounted', location: 'Wall mounted',
model: 'EM-100', model: 'EM-100',
firmware: '2.1.0' firmware: '2.1.0',
} },
}, },
{ {
id: 'sensor_2', id: 'sensor_2',
@@ -367,16 +369,28 @@ export const useEnergyStore = defineStore('energy', () => {
capabilities: { capabilities: {
monitoring: ['temperature', 'co2'], monitoring: ['temperature', 'co2'],
actions: [ actions: [
{ id: 'temp_adjust', name: 'Adjust Temperature', type: 'adjust', icon: '🌡️', parameters: { min: 18, max: 28, step: 0.5 } }, {
{ id: 'fan_speed', name: 'Fan Speed', type: 'adjust', icon: '💨', parameters: { min: 0, max: 5, step: 1 } }, id: 'temp_adjust',
{ id: 'power_toggle', name: 'Power', type: 'toggle', icon: '⚡' } name: 'Adjust Temperature',
] type: 'adjust',
icon: '🌡️',
parameters: { min: 18, max: 28, step: 0.5 },
},
{
id: 'fan_speed',
name: 'Fan Speed',
type: 'adjust',
icon: '💨',
parameters: { min: 0, max: 5, step: 1 },
},
{ id: 'power_toggle', name: 'Power', type: 'toggle', icon: '⚡' },
],
}, },
metadata: { metadata: {
location: 'Ceiling mounted', location: 'Ceiling mounted',
model: 'HVAC-200', model: 'HVAC-200',
firmware: '3.2.1' firmware: '3.2.1',
} },
}, },
{ {
id: 'sensor_3', id: 'sensor_3',
@@ -388,16 +402,28 @@ export const useEnergyStore = defineStore('energy', () => {
capabilities: { capabilities: {
monitoring: ['energy'], monitoring: ['energy'],
actions: [ actions: [
{ id: 'brightness', name: 'Brightness', type: 'adjust', icon: '💡', parameters: { min: 0, max: 100, step: 5 } }, {
id: 'brightness',
name: 'Brightness',
type: 'adjust',
icon: '💡',
parameters: { min: 0, max: 100, step: 5 },
},
{ id: 'power_toggle', name: 'Power', type: 'toggle', icon: '⚡' }, { id: 'power_toggle', name: 'Power', type: 'toggle', icon: '⚡' },
{ id: 'scene', name: 'Scene', type: 'adjust', icon: '🎨', parameters: { options: ['Work', 'Meeting', 'Presentation', 'Relax'] } } {
] id: 'scene',
name: 'Scene',
type: 'adjust',
icon: '🎨',
parameters: { options: ['Work', 'Meeting', 'Presentation', 'Relax'] },
},
],
}, },
metadata: { metadata: {
location: 'Ceiling grid', location: 'Ceiling grid',
model: 'SL-300', model: 'SL-300',
firmware: '1.5.2' firmware: '1.5.2',
} },
}, },
{ {
id: 'sensor_4', id: 'sensor_4',
@@ -408,16 +434,14 @@ export const useEnergyStore = defineStore('energy', () => {
lastSeen: Date.now() / 1000, lastSeen: Date.now() / 1000,
capabilities: { capabilities: {
monitoring: ['co2', 'temperature', 'humidity'], monitoring: ['co2', 'temperature', 'humidity'],
actions: [ actions: [{ id: 'calibrate', name: 'Calibrate', type: 'trigger', icon: '⚙️' }],
{ id: 'calibrate', name: 'Calibrate', type: 'trigger', icon: '⚙️' }
]
}, },
metadata: { metadata: {
location: 'Wall mounted', location: 'Wall mounted',
model: 'CO2-150', model: 'CO2-150',
firmware: '2.0.3', firmware: '2.0.3',
battery: 85 battery: 85,
} },
}, },
{ {
id: 'sensor_5', id: 'sensor_5',
@@ -431,18 +455,18 @@ export const useEnergyStore = defineStore('energy', () => {
actions: [ actions: [
{ id: 'record_toggle', name: 'Recording', type: 'toggle', icon: '📹' }, { id: 'record_toggle', name: 'Recording', type: 'toggle', icon: '📹' },
{ id: 'ptz_control', name: 'Pan/Tilt/Zoom', type: 'trigger', icon: '🎥' }, { id: 'ptz_control', name: 'Pan/Tilt/Zoom', type: 'trigger', icon: '🎥' },
{ id: 'night_mode', name: 'Night Mode', type: 'toggle', icon: '🌙' } { id: 'night_mode', name: 'Night Mode', type: 'toggle', icon: '🌙' },
] ],
}, },
metadata: { metadata: {
location: 'Corner ceiling', location: 'Corner ceiling',
model: 'SEC-400', model: 'SEC-400',
firmware: '4.1.0' firmware: '4.1.0',
} },
} },
] ]
mockSensors.forEach(sensor => { mockSensors.forEach((sensor) => {
sensorDevices.set(sensor.id, sensor) sensorDevices.set(sensor.id, sensor)
}) })
} }
@@ -460,12 +484,12 @@ export const useEnergyStore = defineStore('energy', () => {
const sensor = sensorDevices.get(sensorId) const sensor = sensorDevices.get(sensorId)
if (!sensor) return false if (!sensor) return false
const action = sensor.capabilities.actions.find(a => a.id === actionId) const action = sensor.capabilities.actions.find((a) => a.id === actionId)
if (!action) return false if (!action) return false
// Simulate API call to device // Simulate API call to device
console.log(`Executing action ${actionId} on sensor ${sensorId}`, parameters) console.log(`Executing action ${actionId} on sensor ${sensorId}`, parameters)
// Here you would make the actual API call to control the device // Here you would make the actual API call to control the device
// For now, we'll simulate a successful action // For now, we'll simulate a successful action
return new Promise((resolve) => { return new Promise((resolve) => {
@@ -477,11 +501,11 @@ export const useEnergyStore = defineStore('energy', () => {
} }
function getSensorsByRoom(room: string): SensorDevice[] { function getSensorsByRoom(room: string): SensorDevice[] {
return Array.from(sensorDevices.values()).filter(sensor => sensor.room === room) return Array.from(sensorDevices.values()).filter((sensor) => sensor.room === room)
} }
function getSensorsByType(type: SensorDevice['type']): SensorDevice[] { function getSensorsByType(type: SensorDevice['type']): SensorDevice[] {
return Array.from(sensorDevices.values()).filter(sensor => sensor.type === type) return Array.from(sensorDevices.values()).filter((sensor) => sensor.type === type)
} }
// Room management functions // Room management functions
@@ -523,7 +547,6 @@ export const useEnergyStore = defineStore('energy', () => {
console.warn('Failed to load rooms from API, starting with empty list') console.warn('Failed to load rooms from API, starting with empty list')
availableRooms.value = [] availableRooms.value = []
roomsLoaded.value = true roomsLoaded.value = true
} catch (error) { } catch (error) {
console.error('Error loading rooms:', error) console.error('Error loading rooms:', error)
// Start with empty list on error // Start with empty list on error
@@ -553,23 +576,25 @@ export const useEnergyStore = defineStore('energy', () => {
function removeRoom(roomName: string): boolean { function removeRoom(roomName: string): boolean {
const index = availableRooms.value.indexOf(roomName) const index = availableRooms.value.indexOf(roomName)
if (index === -1) return false if (index === -1) return false
// Check if any sensors are assigned to this room // Check if any sensors are assigned to this room
const sensorsInRoom = Array.from(sensorDevices.values()).filter(sensor => sensor.room === roomName) const sensorsInRoom = Array.from(sensorDevices.values()).filter(
(sensor) => sensor.room === roomName,
)
if (sensorsInRoom.length > 0) { if (sensorsInRoom.length > 0) {
// Reassign sensors to 'Unassigned' // Reassign sensors to 'Unassigned'
sensorsInRoom.forEach(sensor => { sensorsInRoom.forEach((sensor) => {
sensor.room = '' sensor.room = ''
sensorDevices.set(sensor.id, { ...sensor }) sensorDevices.set(sensor.id, { ...sensor })
}) })
} }
// Remove room data // Remove room data
roomsData.delete(roomName) roomsData.delete(roomName)
// Remove from available rooms // Remove from available rooms
availableRooms.value.splice(index, 1) availableRooms.value.splice(index, 1)
console.log(`Removed room: ${roomName}`) console.log(`Removed room: ${roomName}`)
return true return true
} }
@@ -577,21 +602,21 @@ export const useEnergyStore = defineStore('energy', () => {
function getRoomStats(roomName: string) { function getRoomStats(roomName: string) {
const sensorsInRoom = getSensorsByRoom(roomName) const sensorsInRoom = getSensorsByRoom(roomName)
const roomMetrics = roomsData.get(roomName) const roomMetrics = roomsData.get(roomName)
return { return {
sensorCount: sensorsInRoom.length, sensorCount: sensorsInRoom.length,
sensorTypes: [...new Set(sensorsInRoom.map(s => s.type))], sensorTypes: [...new Set(sensorsInRoom.map((s) => s.type))],
hasMetrics: !!roomMetrics, hasMetrics: !!roomMetrics,
energyConsumption: roomMetrics?.energy.current || 0, energyConsumption: roomMetrics?.energy.current || 0,
co2Level: roomMetrics?.co2.current || 0, co2Level: roomMetrics?.co2.current || 0,
lastUpdated: roomMetrics?.lastUpdated || null lastUpdated: roomMetrics?.lastUpdated || null,
} }
} }
function getAllRoomsWithStats() { function getAllRoomsWithStats() {
return availableRooms.value.map(room => ({ return availableRooms.value.map((room) => ({
name: room, name: room,
...getRoomStats(room) ...getRoomStats(room),
})) }))
} }
@@ -606,7 +631,6 @@ export const useEnergyStore = defineStore('energy', () => {
} catch (error) { } catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred' const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'
// Handle authentication errors
if (errorMessage.includes('401') || errorMessage.includes('Authorization')) { if (errorMessage.includes('401') || errorMessage.includes('Authorization')) {
console.warn('Authentication error detected, attempting to re-authenticate...') console.warn('Authentication error detected, attempting to re-authenticate...')
@@ -622,7 +646,8 @@ export const useEnergyStore = defineStore('energy', () => {
const retryResult = await apiCall() const retryResult = await apiCall()
return retryResult return retryResult
} catch (retryError) { } catch (retryError) {
const retryErrorMessage = retryError instanceof Error ? retryError.message : 'Retry failed' const retryErrorMessage =
retryError instanceof Error ? retryError.message : 'Retry failed'
apiError.value = retryErrorMessage apiError.value = retryErrorMessage
console.error('API retry failed:', retryErrorMessage) console.error('API retry failed:', retryErrorMessage)
return null return null
@@ -652,8 +677,8 @@ export const useEnergyStore = defineStore('energy', () => {
} }
async function fetchApiSensorData( async function fetchApiSensorData(
sensorId: string, sensorId: string,
params?: { start_time?: number; end_time?: number; limit?: number; offset?: number } params?: { start_time?: number; end_time?: number; limit?: number; offset?: number },
) { ) {
return handleApiCall(() => sensorsApi.getSensorData(sensorId, params)) return handleApiCall(() => sensorsApi.getSensorData(sensorId, params))
} }
@@ -681,7 +706,7 @@ export const useEnergyStore = defineStore('energy', () => {
if (result) { if (result) {
apiRooms.value = result apiRooms.value = result
// Update available rooms from API data // Update available rooms from API data
const roomNames = result.map(room => room.room).filter(name => name) const roomNames = result.map((room) => room.room).filter((name) => name)
if (roomNames.length > 0) { if (roomNames.length > 0) {
availableRooms.value = [...new Set([...availableRooms.value, ...roomNames])].sort() availableRooms.value = [...new Set([...availableRooms.value, ...roomNames])].sort()
} }
@@ -690,8 +715,8 @@ export const useEnergyStore = defineStore('energy', () => {
} }
async function fetchApiRoomData( async function fetchApiRoomData(
roomName: string, roomName: string,
params?: { start_time?: number; end_time?: number; limit?: number } params?: { start_time?: number; end_time?: number; limit?: number },
) { ) {
return handleApiCall(() => roomsApi.getRoomData(roomName, params)) return handleApiCall(() => roomsApi.getRoomData(roomName, params))
} }
@@ -750,12 +775,12 @@ export const useEnergyStore = defineStore('energy', () => {
// Initialize data from APIs // Initialize data from APIs
async function initializeFromApi() { async function initializeFromApi() {
await Promise.allSettled([ await Promise.allSettled([
loadRoomsFromAPI(), // Load room names first loadRoomsFromAPI(), // Load room names first
fetchApiSensors(), fetchApiSensors(),
fetchApiRooms(), fetchApiRooms(),
fetchAnalyticsSummary(), fetchAnalyticsSummary(),
fetchSystemStatus(), fetchSystemStatus(),
fetchHealthStatus() fetchHealthStatus(),
]) ])
} }
@@ -765,19 +790,19 @@ export const useEnergyStore = defineStore('energy', () => {
// Load rooms from API on store initialization // Load rooms from API on store initialization
loadRoomsFromAPI() loadRoomsFromAPI()
return { return {
// WebSocket state // WebSocket state
isConnected, isConnected,
latestMessage, latestMessage,
timeSeriesData, timeSeriesData,
sensorsData, sensorsData,
roomsData, roomsData,
latestReadings, latestReadings,
sensorDevices, sensorDevices,
availableRooms, availableRooms,
roomsLoading, roomsLoading,
roomsLoaded, roomsLoaded,
// API state // API state
apiSensors, apiSensors,
apiRooms, apiRooms,
@@ -788,7 +813,7 @@ export const useEnergyStore = defineStore('energy', () => {
apiError, apiError,
// WebSocket functions // WebSocket functions
connect, connect,
disconnect, disconnect,
getCO2Status, getCO2Status,
updateSensorRoom, updateSensorRoom,
@@ -815,6 +840,6 @@ export const useEnergyStore = defineStore('energy', () => {
fetchSystemEvents, fetchSystemEvents,
fetchSystemStatus, fetchSystemStatus,
fetchHealthStatus, fetchHealthStatus,
initializeFromApi initializeFromApi,
} }
}) })

View File

@@ -58,21 +58,17 @@ const DEFAULT_SETTINGS: AppSettings = {
} }
export const useSettingsStore = defineStore('settings', () => { export const useSettingsStore = defineStore('settings', () => {
// State
const settings = reactive<AppSettings>({ ...DEFAULT_SETTINGS }) const settings = reactive<AppSettings>({ ...DEFAULT_SETTINGS })
const isLoading = ref(false) const isLoading = ref(false)
const lastSaved = ref<Date | null>(null) const lastSaved = ref<Date | null>(null)
// Local storage key
const STORAGE_KEY = 'dashboard-settings' const STORAGE_KEY = 'dashboard-settings'
// Load settings from localStorage
function loadSettings() { function loadSettings() {
try { try {
const stored = localStorage.getItem(STORAGE_KEY) const stored = localStorage.getItem(STORAGE_KEY)
if (stored) { if (stored) {
const parsed = JSON.parse(stored) const parsed = JSON.parse(stored)
// Merge with defaults to handle new settings
Object.assign(settings, { ...DEFAULT_SETTINGS, ...parsed }) Object.assign(settings, { ...DEFAULT_SETTINGS, ...parsed })
console.log('Settings loaded from localStorage') console.log('Settings loaded from localStorage')
} }
@@ -82,7 +78,6 @@ export const useSettingsStore = defineStore('settings', () => {
} }
} }
// Save settings to localStorage
function saveSettings() { function saveSettings() {
try { try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(settings)) localStorage.setItem(STORAGE_KEY, JSON.stringify(settings))
@@ -93,13 +88,11 @@ export const useSettingsStore = defineStore('settings', () => {
} }
} }
// Reset to default settings
function resetToDefaults() { function resetToDefaults() {
Object.assign(settings, DEFAULT_SETTINGS) Object.assign(settings, DEFAULT_SETTINGS)
saveSettings() saveSettings()
} }
// Update specific setting
function updateSetting(path: string, value: any) { function updateSetting(path: string, value: any) {
const keys = path.split('.') const keys = path.split('.')
let current: any = settings let current: any = settings
@@ -112,7 +105,6 @@ export const useSettingsStore = defineStore('settings', () => {
saveSettings() saveSettings()
} }
// Get setting value by path
function getSetting(path: string): any { function getSetting(path: string): any {
const keys = path.split('.') const keys = path.split('.')
let current: any = settings let current: any = settings
@@ -125,16 +117,13 @@ export const useSettingsStore = defineStore('settings', () => {
return current return current
} }
// Export settings
function exportSettings(): string { function exportSettings(): string {
return JSON.stringify(settings, null, 2) return JSON.stringify(settings, null, 2)
} }
// Import settings
function importSettings(settingsJson: string): boolean { function importSettings(settingsJson: string): boolean {
try { try {
const imported = JSON.parse(settingsJson) const imported = JSON.parse(settingsJson)
// Validate structure
if (typeof imported === 'object' && imported !== null) { if (typeof imported === 'object' && imported !== null) {
Object.assign(settings, { ...DEFAULT_SETTINGS, ...imported }) Object.assign(settings, { ...DEFAULT_SETTINGS, ...imported })
saveSettings() saveSettings()
@@ -147,7 +136,6 @@ export const useSettingsStore = defineStore('settings', () => {
} }
} }
// Theme helpers
function applyTheme() { function applyTheme() {
const root = document.documentElement const root = document.documentElement
@@ -156,13 +144,11 @@ export const useSettingsStore = defineStore('settings', () => {
} else if (settings.theme === 'light') { } else if (settings.theme === 'light') {
root.classList.remove('dark') root.classList.remove('dark')
} else { } else {
// System theme
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
root.classList.toggle('dark', prefersDark) root.classList.toggle('dark', prefersDark)
} }
} }
// WebSocket URL validation
function isValidWebSocketUrl(url: string): boolean { function isValidWebSocketUrl(url: string): boolean {
try { try {
const parsed = new URL(url) const parsed = new URL(url)
@@ -172,7 +158,6 @@ export const useSettingsStore = defineStore('settings', () => {
} }
} }
// Notification permission handling
async function requestNotificationPermission(): Promise<boolean> { async function requestNotificationPermission(): Promise<boolean> {
if (!('Notification' in window)) { if (!('Notification' in window)) {
return false return false
@@ -190,21 +175,17 @@ export const useSettingsStore = defineStore('settings', () => {
return permission === 'granted' return permission === 'granted'
} }
// Initialize store
function initialize() { function initialize() {
loadSettings() loadSettings()
applyTheme() applyTheme()
// Watch for theme changes
watch(() => settings.theme, applyTheme, { immediate: true }) watch(() => settings.theme, applyTheme, { immediate: true })
// Watch for system theme changes
if (settings.theme === 'system') { if (settings.theme === 'system') {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
mediaQuery.addEventListener('change', applyTheme) mediaQuery.addEventListener('change', applyTheme)
} }
// Auto-save on changes (debounced)
let saveTimeout: number | undefined let saveTimeout: number | undefined
watch( watch(
settings, settings,
@@ -216,7 +197,6 @@ export const useSettingsStore = defineStore('settings', () => {
) )
} }
// Get available languages
function getAvailableLanguages() { function getAvailableLanguages() {
return [ return [
{ code: 'en', name: 'English', nativeName: 'English' }, { code: 'en', name: 'English', nativeName: 'English' },
@@ -226,7 +206,6 @@ export const useSettingsStore = defineStore('settings', () => {
] ]
} }
// Get theme options
function getThemeOptions() { function getThemeOptions() {
return [ return [
{ value: 'system', label: 'System Default', icon: '🔄' }, { value: 'system', label: 'System Default', icon: '🔄' },
@@ -235,7 +214,6 @@ export const useSettingsStore = defineStore('settings', () => {
] ]
} }
// Get navigation mode options
function getNavigationModeOptions() { function getNavigationModeOptions() {
return [ return [
{ {
@@ -260,12 +238,10 @@ export const useSettingsStore = defineStore('settings', () => {
} }
return { return {
// State
settings, settings,
isLoading, isLoading,
lastSaved, lastSaved,
// Actions
loadSettings, loadSettings,
saveSettings, saveSettings,
resetToDefaults, resetToDefaults,
@@ -278,7 +254,6 @@ export const useSettingsStore = defineStore('settings', () => {
requestNotificationPermission, requestNotificationPermission,
initialize, initialize,
// Getters
getAvailableLanguages, getAvailableLanguages,
getThemeOptions, getThemeOptions,
getNavigationModeOptions, getNavigationModeOptions,