general dashboard

This commit is contained in:
rafaeldpsilva
2025-09-02 14:19:05 +01:00
commit 0db018f939
41 changed files with 9025 additions and 0 deletions

165
src/stores/energy.ts Normal file
View File

@@ -0,0 +1,165 @@
import { defineStore } from 'pinia'
import { ref, reactive } from 'vue'
const MAX_DATA_POINTS = 100 // Keep the last 100 data points for the chart
interface SensorReading {
sensorId: string
room: string
timestamp: number
energy: {
value: number
unit: string
}
co2: {
value: number
unit: string
}
temperature?: {
value: number
unit: string
}
}
interface RoomMetrics {
room: string
sensors: string[]
energy: {
current: number
total: number
average: number
unit: string
}
co2: {
current: number
average: number
max: number
status: 'good' | 'moderate' | 'poor' | 'critical'
unit: string
}
occupancyEstimate: 'low' | 'medium' | 'high'
lastUpdated: number
}
interface LegacyEnergyData {
sensorId: string
timestamp: number
value: number
unit: string
}
export const useEnergyStore = defineStore('energy', () => {
// State
const isConnected = ref(false)
const latestMessage = ref<LegacyEnergyData | null>(null)
const timeSeriesData = reactive<{
labels: string[]
datasets: { data: number[] }[]
}>({
labels: [],
datasets: [{ data: [] }],
})
const sensorsData = reactive<Map<string, any>>(new Map()) // Legacy support
const roomsData = reactive<Map<string, RoomMetrics>>(new Map())
const latestReadings = reactive<Map<string, SensorReading>>(new Map())
let socket: WebSocket | null = null
const newDataBuffer: (LegacyEnergyData | SensorReading)[] = []
// Actions
function connect(url: string) {
if (isConnected.value) {
console.log('Already connected.')
return
}
console.log(`Connecting to WebSocket at ${url}`)
socket = new WebSocket(url)
socket.onopen = () => {
console.log('WebSocket connection established.')
isConnected.value = true
}
socket.onmessage = (event) => {
try {
const data = JSON.parse(event.data)
newDataBuffer.push(data)
} catch (error) {
console.error('Error parsing incoming data:', error)
}
}
socket.onclose = () => {
console.log('WebSocket connection closed.')
isConnected.value = false
socket = null
}
socket.onerror = (error) => {
console.error('WebSocket error:', error)
isConnected.value = false
socket = null
}
// Process the buffer at intervals
setInterval(() => {
if (newDataBuffer.length > 0) {
const data = newDataBuffer.shift() // Get the oldest data point
if (data) {
latestMessage.value = data
// Update sensor-specific data
updateSensorData(data)
// Update time series for chart (aggregate all sensors)
const newLabel = new Date(data.timestamp * 1000).toLocaleTimeString()
timeSeriesData.labels.push(newLabel)
timeSeriesData.datasets[0].data.push(data.value)
if (timeSeriesData.labels.length > MAX_DATA_POINTS) {
timeSeriesData.labels.shift()
timeSeriesData.datasets[0].data.shift()
}
}
}
}, 500) // Process every 500ms
}
function disconnect() {
if (socket) {
socket.close()
}
}
function updateSensorData(data: EnergyData) {
const existingSensor = sensorsData.get(data.sensorId)
if (existingSensor) {
// Update existing sensor
const newTotal = existingSensor.totalConsumption + data.value
const dataPoints = Math.floor((data.timestamp - existingSensor.lastUpdated) / 60) + 1 // Rough estimate
sensorsData.set(data.sensorId, {
...existingSensor,
latestValue: data.value,
totalConsumption: newTotal,
averageConsumption: newTotal / dataPoints,
lastUpdated: data.timestamp
})
} else {
// Create new sensor entry
sensorsData.set(data.sensorId, {
sensorId: data.sensorId,
latestValue: data.value,
totalConsumption: data.value,
averageConsumption: data.value,
lastUpdated: data.timestamp,
unit: data.unit
})
}
}
return { isConnected, latestMessage, timeSeriesData, sensorsData, connect, disconnect }
})