Refactor HomeView to use energyStore for energy data Refactor HomeView

to use energyStore for energy data
This commit is contained in:
rafaeldpsilva
2025-10-01 12:57:09 +01:00
parent 6ee4801071
commit cb659c93bb
5 changed files with 90 additions and 41 deletions

View File

@@ -1,10 +1,12 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { ref, computed, reactive, watch } from 'vue'
import { useWebSocketStore } from './websocket'
import { useSensorStore } from './sensor'
import { useRoomStore } from './room'
import { useAnalyticsStore } from './analytics'
const MAX_HISTORY_POINTS = 100
/**
* Energy Store - Simplified to only track energy consumption metrics
* For sensor data: use useSensorStore()
@@ -20,34 +22,66 @@ export const useEnergyStore = defineStore('energy', () => {
const analyticsStore = useAnalyticsStore()
// Energy-specific state
const currentConsumption = ref(0) // Current energy consumption in kWh
const averageConsumption = ref(0) // Average energy consumption in kWh
const currentConsumption = ref<number>(0) // Current energy consumption in kWh
const averageConsumption = ref<number>(0) // Average energy consumption in kWh
// Computed: Current energy value from WebSocket
const currentEnergyValue = computed(() => {
return websocketStore.latestMessage?.energy?.value || 0
// Track aggregated energy over time
const energyHistory = reactive<number[]>([])
const energyTimestamps = reactive<string[]>([])
// Computed: Current total energy value - sum of all sensor readings
const currentEnergyValue = computed<number>(() => {
// Sum energy values from all sensors' latest readings
let totalEnergy: number = 0
const readings = Array.from(sensorStore.latestReadings.values())
readings.forEach((reading) => {
if (reading.energy?.value) {
totalEnergy += reading.energy.value
}
})
return totalEnergy
})
// Computed: Average energy usage from time series
const averageEnergyUsage = computed(() => {
const data = websocketStore.timeSeriesData.datasets[0].data
if (data.length === 0) return 0
const sum = data.reduce((acc, val) => acc + val, 0)
return sum / data.length
// Computed: Average energy usage from history
const averageEnergyUsage = computed<number>(() => {
if (energyHistory.length === 0) return 0
const sum: number = energyHistory.reduce((acc: number, val: number) => acc + val, 0)
return sum / energyHistory.length
})
// Watch for changes in sensor readings and update history
watch(
() => sensorStore.latestReadings.size,
() => {
const currentTotal: number = currentEnergyValue.value
const timestamp: string = new Date().toLocaleTimeString()
// Add to history
energyHistory.push(currentTotal)
energyTimestamps.push(timestamp)
// Keep only the latest MAX_HISTORY_POINTS
if (energyHistory.length > MAX_HISTORY_POINTS) {
energyHistory.shift()
energyTimestamps.shift()
}
}
)
// Update current consumption (called from components or watchers)
function updateCurrentConsumption(value: number) {
function updateCurrentConsumption(value: number): void {
currentConsumption.value = value
}
// Update average consumption (called from components or watchers)
function updateAverageConsumption(value: number) {
function updateAverageConsumption(value: number): void {
averageConsumption.value = value
}
// Initialize data from APIs (convenience function for AnalyticsView)
async function initializeFromApi() {
async function initializeFromApi(): Promise<void> {
await Promise.allSettled([
roomStore.loadRoomsFromAPI(),
sensorStore.fetchApiSensors(),
@@ -62,6 +96,8 @@ export const useEnergyStore = defineStore('energy', () => {
averageConsumption,
currentEnergyValue,
averageEnergyUsage,
energyHistory,
energyTimestamps,
// Energy-specific actions
updateCurrentConsumption,

View File

@@ -30,11 +30,11 @@ export const useRoomStore = defineStore('room', () => {
const apiRooms = ref<ApiRoomInfo[]>([])
const roomsLoading = ref<boolean>(false)
const roomsLoaded = ref<boolean>(false)
const apiLoading = ref(false)
const apiLoading = ref<boolean>(false)
const apiError = ref<string | null>(null)
// Actions
function updateRoomData(data: SensorReading) {
function updateRoomData(data: SensorReading): void {
const sensorStore = useSensorStore()
// Validate data structure and provide fallbacks
@@ -169,7 +169,14 @@ export const useRoomStore = defineStore('room', () => {
return true
}
function getRoomStats(roomName: string) {
function getRoomStats(roomName: string): {
sensorCount: number
sensorTypes: string[]
hasMetrics: boolean
energyConsumption: number
co2Level: number
lastUpdated: number | null
} {
const sensorStore = useSensorStore()
const sensorsInRoom = sensorStore.getSensorsByRoom(roomName)
const roomMetrics = roomsData.get(roomName)
@@ -184,7 +191,15 @@ export const useRoomStore = defineStore('room', () => {
}
}
function getAllRoomsWithStats() {
function getAllRoomsWithStats(): Array<{
name: string
sensorCount: number
sensorTypes: string[]
hasMetrics: boolean
energyConsumption: number
co2Level: number
lastUpdated: number | null
}> {
return availableRooms.value.map((room) => ({
name: room,
...getRoomStats(room),

View File

@@ -14,8 +14,8 @@ export const useSensorStore = defineStore('sensor', () => {
const latestReadings = reactive<Map<string, SensorReading>>(new Map())
const sensorsData = reactive<Map<string, any>>(new Map()) // Legacy support
const recentlyUpdatedSensors = reactive<Set<string>>(new Set()) // Track recently updated sensors
const totalReadings = ref(0) // Total number of readings across all sensors
const apiLoading = ref(false)
const totalReadings = ref<number>(0) // Total number of readings across all sensors
const apiLoading = ref<boolean>(false)
const apiError = ref<string | null>(null)
// Computed properties
@@ -23,12 +23,12 @@ export const useSensorStore = defineStore('sensor', () => {
const activeSensors = computed(() => {
return Array.from(sensorDevices.values()).filter(
sensor => sensor.status === 'active' || sensor.status === 'online'
(sensor) => sensor.status === 'active' || sensor.status === 'online',
).length
})
// Actions
function updateSensorRoom(sensorId: string, newRoom: string) {
function updateSensorRoom(sensorId: string, newRoom: string): void {
const sensor = sensorDevices.get(sensorId)
if (sensor) {
sensor.room = newRoom
@@ -36,14 +36,14 @@ export const useSensorStore = defineStore('sensor', () => {
}
}
async function executeSensorAction(sensorId: string, actionId: string) {
async function executeSensorAction(sensorId: string, actionId: string): Promise<boolean> {
const sensor = sensorDevices.get(sensorId)
if (!sensor) return false
const action = sensor.capabilities.actions.find((a) => a.id === actionId)
if (!action) return false
return new Promise((resolve) => {
return new Promise<boolean>((resolve) => {
setTimeout(() => {
console.log(`Action ${action.name} executed successfully on ${sensor.name}`)
resolve(true)
@@ -59,11 +59,11 @@ export const useSensorStore = defineStore('sensor', () => {
return Array.from(sensorDevices.values()).filter((sensor) => sensor.type === type)
}
function updateEnergySensors(data: Sensor) {
function updateEnergySensors(data: SensorReading): void {
console.log(data)
}
function updateLatestReading(reading: SensorReading) {
function updateLatestReading(reading: SensorReading): void {
latestReadings.set(reading.sensor_id, reading)
// Increment total readings count
@@ -191,12 +191,12 @@ export const useSensorStore = defineStore('sensor', () => {
console.log(result)
// Check if result has a sensors property (common API pattern)
if (result.sensors && Array.isArray(result.sensors)) {
let totalReadingsCount = 0
let totalReadingsCount: number = 0
result.sensors.forEach((sensor) => {
const sensorKey = sensor._id || sensor.sensor_id
const sensorType = sensor.sensor_type || sensor.type
const sensorName = sensor.name || ''
const sensorKey: string = sensor._id || sensor.sensor_id
const sensorType: string = sensor.sensor_type || sensor.type
const sensorName: string = sensor.name || ''
// Accumulate total readings
if (sensor.total_readings) {

View File

@@ -24,7 +24,7 @@ interface SensorReading {
}
export const useWebSocketStore = defineStore('websocket', () => {
const isConnected = ref(false)
const isConnected = ref<boolean>(false)
const latestMessage = ref<SensorReading | null>(null)
const timeSeriesData = reactive<{
labels: string[]
@@ -37,7 +37,7 @@ export const useWebSocketStore = defineStore('websocket', () => {
let socket: WebSocket | null = null
const newDataBuffer: SensorReading[] = []
function connect(url: string) {
function connect(url: string): void {
if (isConnected.value && socket) {
console.log('Already connected.')
return
@@ -109,13 +109,13 @@ export const useWebSocketStore = defineStore('websocket', () => {
}, 500)
}
function disconnect() {
function disconnect(): void {
if (socket) {
socket.close()
}
}
function processIncomingData(data: SensorReading) {
function processIncomingData(data: SensorReading): void {
// Skip non-data messages
if ('type' in data && (data.type === 'connection_established' || data.type === 'proxy_info')) {
return

View File

@@ -26,7 +26,7 @@
title="Real-time Energy"
:content="currentEnergyValue"
details="kWh"
:trend-data="websocketStore.timeSeriesData.datasets[0].data.slice(-8)"
:trend-data="energyStore.energyHistory.slice(-8)"
trend-direction="neutral"
/>
<GraphMetricCard
@@ -74,15 +74,13 @@ const energyStore = useEnergyStore()
const websocketStore = useWebSocketStore()
const settingsStore = useSettingsStore()
// Use energy store for aggregated values across all sensors
const currentEnergyValue = computed(() => {
return websocketStore.latestMessage?.energy?.value.toFixed(2) || '0.00'
return energyStore.currentEnergyValue.toFixed(2)
})
const averageEnergyUsage = computed(() => {
const data = websocketStore.timeSeriesData.datasets[0].data
if (data.length === 0) return '0.00'
const sum = data.reduce((acc, val) => acc + val, 0)
return (sum / data.length).toFixed(2)
return energyStore.averageEnergyUsage.toFixed(2)
})
onMounted(() => {