Refactor HomeView to use energyStore for energy data Refactor HomeView
to use energyStore for energy data
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed, reactive, watch } from 'vue'
|
||||||
import { useWebSocketStore } from './websocket'
|
import { useWebSocketStore } from './websocket'
|
||||||
import { useSensorStore } from './sensor'
|
import { useSensorStore } from './sensor'
|
||||||
import { useRoomStore } from './room'
|
import { useRoomStore } from './room'
|
||||||
import { useAnalyticsStore } from './analytics'
|
import { useAnalyticsStore } from './analytics'
|
||||||
|
|
||||||
|
const MAX_HISTORY_POINTS = 100
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Energy Store - Simplified to only track energy consumption metrics
|
* Energy Store - Simplified to only track energy consumption metrics
|
||||||
* For sensor data: use useSensorStore()
|
* For sensor data: use useSensorStore()
|
||||||
@@ -20,34 +22,66 @@ export const useEnergyStore = defineStore('energy', () => {
|
|||||||
const analyticsStore = useAnalyticsStore()
|
const analyticsStore = useAnalyticsStore()
|
||||||
|
|
||||||
// Energy-specific state
|
// Energy-specific state
|
||||||
const currentConsumption = ref(0) // Current energy consumption in kWh
|
const currentConsumption = ref<number>(0) // Current energy consumption in kWh
|
||||||
const averageConsumption = ref(0) // Average energy consumption in kWh
|
const averageConsumption = ref<number>(0) // Average energy consumption in kWh
|
||||||
|
|
||||||
// Computed: Current energy value from WebSocket
|
// Track aggregated energy over time
|
||||||
const currentEnergyValue = computed(() => {
|
const energyHistory = reactive<number[]>([])
|
||||||
return websocketStore.latestMessage?.energy?.value || 0
|
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
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Computed: Average energy usage from time series
|
return totalEnergy
|
||||||
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)
|
// Update current consumption (called from components or watchers)
|
||||||
function updateCurrentConsumption(value: number) {
|
function updateCurrentConsumption(value: number): void {
|
||||||
currentConsumption.value = value
|
currentConsumption.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update average consumption (called from components or watchers)
|
// Update average consumption (called from components or watchers)
|
||||||
function updateAverageConsumption(value: number) {
|
function updateAverageConsumption(value: number): void {
|
||||||
averageConsumption.value = value
|
averageConsumption.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize data from APIs (convenience function for AnalyticsView)
|
// Initialize data from APIs (convenience function for AnalyticsView)
|
||||||
async function initializeFromApi() {
|
async function initializeFromApi(): Promise<void> {
|
||||||
await Promise.allSettled([
|
await Promise.allSettled([
|
||||||
roomStore.loadRoomsFromAPI(),
|
roomStore.loadRoomsFromAPI(),
|
||||||
sensorStore.fetchApiSensors(),
|
sensorStore.fetchApiSensors(),
|
||||||
@@ -62,6 +96,8 @@ export const useEnergyStore = defineStore('energy', () => {
|
|||||||
averageConsumption,
|
averageConsumption,
|
||||||
currentEnergyValue,
|
currentEnergyValue,
|
||||||
averageEnergyUsage,
|
averageEnergyUsage,
|
||||||
|
energyHistory,
|
||||||
|
energyTimestamps,
|
||||||
|
|
||||||
// Energy-specific actions
|
// Energy-specific actions
|
||||||
updateCurrentConsumption,
|
updateCurrentConsumption,
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ export const useRoomStore = defineStore('room', () => {
|
|||||||
const apiRooms = ref<ApiRoomInfo[]>([])
|
const apiRooms = ref<ApiRoomInfo[]>([])
|
||||||
const roomsLoading = ref<boolean>(false)
|
const roomsLoading = ref<boolean>(false)
|
||||||
const roomsLoaded = ref<boolean>(false)
|
const roomsLoaded = ref<boolean>(false)
|
||||||
const apiLoading = ref(false)
|
const apiLoading = ref<boolean>(false)
|
||||||
const apiError = ref<string | null>(null)
|
const apiError = ref<string | null>(null)
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
function updateRoomData(data: SensorReading) {
|
function updateRoomData(data: SensorReading): void {
|
||||||
const sensorStore = useSensorStore()
|
const sensorStore = useSensorStore()
|
||||||
|
|
||||||
// Validate data structure and provide fallbacks
|
// Validate data structure and provide fallbacks
|
||||||
@@ -169,7 +169,14 @@ export const useRoomStore = defineStore('room', () => {
|
|||||||
return true
|
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 sensorStore = useSensorStore()
|
||||||
const sensorsInRoom = sensorStore.getSensorsByRoom(roomName)
|
const sensorsInRoom = sensorStore.getSensorsByRoom(roomName)
|
||||||
const roomMetrics = roomsData.get(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) => ({
|
return availableRooms.value.map((room) => ({
|
||||||
name: room,
|
name: room,
|
||||||
...getRoomStats(room),
|
...getRoomStats(room),
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ export const useSensorStore = defineStore('sensor', () => {
|
|||||||
const latestReadings = reactive<Map<string, SensorReading>>(new Map())
|
const latestReadings = reactive<Map<string, SensorReading>>(new Map())
|
||||||
const sensorsData = reactive<Map<string, any>>(new Map()) // Legacy support
|
const sensorsData = reactive<Map<string, any>>(new Map()) // Legacy support
|
||||||
const recentlyUpdatedSensors = reactive<Set<string>>(new Set()) // Track recently updated sensors
|
const recentlyUpdatedSensors = reactive<Set<string>>(new Set()) // Track recently updated sensors
|
||||||
const totalReadings = ref(0) // Total number of readings across all sensors
|
const totalReadings = ref<number>(0) // Total number of readings across all sensors
|
||||||
const apiLoading = ref(false)
|
const apiLoading = ref<boolean>(false)
|
||||||
const apiError = ref<string | null>(null)
|
const apiError = ref<string | null>(null)
|
||||||
|
|
||||||
// Computed properties
|
// Computed properties
|
||||||
@@ -23,12 +23,12 @@ export const useSensorStore = defineStore('sensor', () => {
|
|||||||
|
|
||||||
const activeSensors = computed(() => {
|
const activeSensors = computed(() => {
|
||||||
return Array.from(sensorDevices.values()).filter(
|
return Array.from(sensorDevices.values()).filter(
|
||||||
sensor => sensor.status === 'active' || sensor.status === 'online'
|
(sensor) => sensor.status === 'active' || sensor.status === 'online',
|
||||||
).length
|
).length
|
||||||
})
|
})
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
function updateSensorRoom(sensorId: string, newRoom: string) {
|
function updateSensorRoom(sensorId: string, newRoom: string): void {
|
||||||
const sensor = sensorDevices.get(sensorId)
|
const sensor = sensorDevices.get(sensorId)
|
||||||
if (sensor) {
|
if (sensor) {
|
||||||
sensor.room = newRoom
|
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)
|
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
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise<boolean>((resolve) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.log(`Action ${action.name} executed successfully on ${sensor.name}`)
|
console.log(`Action ${action.name} executed successfully on ${sensor.name}`)
|
||||||
resolve(true)
|
resolve(true)
|
||||||
@@ -59,11 +59,11 @@ export const useSensorStore = defineStore('sensor', () => {
|
|||||||
return Array.from(sensorDevices.values()).filter((sensor) => sensor.type === type)
|
return Array.from(sensorDevices.values()).filter((sensor) => sensor.type === type)
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateEnergySensors(data: Sensor) {
|
function updateEnergySensors(data: SensorReading): void {
|
||||||
console.log(data)
|
console.log(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLatestReading(reading: SensorReading) {
|
function updateLatestReading(reading: SensorReading): void {
|
||||||
latestReadings.set(reading.sensor_id, reading)
|
latestReadings.set(reading.sensor_id, reading)
|
||||||
|
|
||||||
// Increment total readings count
|
// Increment total readings count
|
||||||
@@ -191,12 +191,12 @@ export const useSensorStore = defineStore('sensor', () => {
|
|||||||
console.log(result)
|
console.log(result)
|
||||||
// Check if result has a sensors property (common API pattern)
|
// Check if result has a sensors property (common API pattern)
|
||||||
if (result.sensors && Array.isArray(result.sensors)) {
|
if (result.sensors && Array.isArray(result.sensors)) {
|
||||||
let totalReadingsCount = 0
|
let totalReadingsCount: number = 0
|
||||||
|
|
||||||
result.sensors.forEach((sensor) => {
|
result.sensors.forEach((sensor) => {
|
||||||
const sensorKey = sensor._id || sensor.sensor_id
|
const sensorKey: string = sensor._id || sensor.sensor_id
|
||||||
const sensorType = sensor.sensor_type || sensor.type
|
const sensorType: string = sensor.sensor_type || sensor.type
|
||||||
const sensorName = sensor.name || ''
|
const sensorName: string = sensor.name || ''
|
||||||
|
|
||||||
// Accumulate total readings
|
// Accumulate total readings
|
||||||
if (sensor.total_readings) {
|
if (sensor.total_readings) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ interface SensorReading {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const useWebSocketStore = defineStore('websocket', () => {
|
export const useWebSocketStore = defineStore('websocket', () => {
|
||||||
const isConnected = ref(false)
|
const isConnected = ref<boolean>(false)
|
||||||
const latestMessage = ref<SensorReading | null>(null)
|
const latestMessage = ref<SensorReading | null>(null)
|
||||||
const timeSeriesData = reactive<{
|
const timeSeriesData = reactive<{
|
||||||
labels: string[]
|
labels: string[]
|
||||||
@@ -37,7 +37,7 @@ export const useWebSocketStore = defineStore('websocket', () => {
|
|||||||
let socket: WebSocket | null = null
|
let socket: WebSocket | null = null
|
||||||
const newDataBuffer: SensorReading[] = []
|
const newDataBuffer: SensorReading[] = []
|
||||||
|
|
||||||
function connect(url: string) {
|
function connect(url: string): void {
|
||||||
if (isConnected.value && socket) {
|
if (isConnected.value && socket) {
|
||||||
console.log('Already connected.')
|
console.log('Already connected.')
|
||||||
return
|
return
|
||||||
@@ -109,13 +109,13 @@ export const useWebSocketStore = defineStore('websocket', () => {
|
|||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
function disconnect() {
|
function disconnect(): void {
|
||||||
if (socket) {
|
if (socket) {
|
||||||
socket.close()
|
socket.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function processIncomingData(data: SensorReading) {
|
function processIncomingData(data: SensorReading): void {
|
||||||
// Skip non-data messages
|
// Skip non-data messages
|
||||||
if ('type' in data && (data.type === 'connection_established' || data.type === 'proxy_info')) {
|
if ('type' in data && (data.type === 'connection_established' || data.type === 'proxy_info')) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
title="Real-time Energy"
|
title="Real-time Energy"
|
||||||
:content="currentEnergyValue"
|
:content="currentEnergyValue"
|
||||||
details="kWh"
|
details="kWh"
|
||||||
:trend-data="websocketStore.timeSeriesData.datasets[0].data.slice(-8)"
|
:trend-data="energyStore.energyHistory.slice(-8)"
|
||||||
trend-direction="neutral"
|
trend-direction="neutral"
|
||||||
/>
|
/>
|
||||||
<GraphMetricCard
|
<GraphMetricCard
|
||||||
@@ -74,15 +74,13 @@ const energyStore = useEnergyStore()
|
|||||||
const websocketStore = useWebSocketStore()
|
const websocketStore = useWebSocketStore()
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
|
|
||||||
|
// Use energy store for aggregated values across all sensors
|
||||||
const currentEnergyValue = computed(() => {
|
const currentEnergyValue = computed(() => {
|
||||||
return websocketStore.latestMessage?.energy?.value.toFixed(2) || '0.00'
|
return energyStore.currentEnergyValue.toFixed(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
const averageEnergyUsage = computed(() => {
|
const averageEnergyUsage = computed(() => {
|
||||||
const data = websocketStore.timeSeriesData.datasets[0].data
|
return energyStore.averageEnergyUsage.toFixed(2)
|
||||||
if (data.length === 0) return '0.00'
|
|
||||||
const sum = data.reduce((acc, val) => acc + val, 0)
|
|
||||||
return (sum / data.length).toFixed(2)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user