Support partial sensor readings and improve room metrics aggregation
- Allow room and card components to handle rooms with missing energy or CO2 data - Update RoomMetrics type to make energy and co2 fields optional - Track which sensors provide energy or CO2 data per room - Aggregate room metrics only from available data (partial readings) - Update AirQualityCard and RoomMetricsCard to safely access optional fields - Set MAX_HISTORY_POINTS to 48 in energy store - Improve robustness of API room fetching and data mapping - Update CLAUDE.md with new partial reading support and data flow details
This commit is contained in:
@@ -13,9 +13,9 @@
|
||||
<h3 class="font-medium text-gray-900">{{ room.room }}</h3>
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- CO2 Status Indicator -->
|
||||
<div
|
||||
<div
|
||||
class="w-3 h-3 rounded-full"
|
||||
:class="getCO2StatusColor(room.co2.status)"
|
||||
:class="getCO2StatusColor(room.co2!.status)"
|
||||
></div>
|
||||
<!-- Occupancy Indicator -->
|
||||
<div class="flex items-center gap-1 text-xs text-gray-500">
|
||||
@@ -32,15 +32,15 @@
|
||||
<!-- Energy -->
|
||||
<div class="bg-blue-50 rounded p-2">
|
||||
<div class="text-blue-600 font-medium">Energy</div>
|
||||
<div class="text-blue-900">{{ room.energy.current.toFixed(2) }} {{ room.energy.unit }}</div>
|
||||
<div class="text-blue-600 text-xs">Total: {{ room.energy.total.toFixed(2) }}</div>
|
||||
<div class="text-blue-900">{{ room.energy!.current.toFixed(2) }} {{ room.energy!.unit }}</div>
|
||||
<div class="text-blue-600 text-xs">Total: {{ room.energy!.total.toFixed(2) }}</div>
|
||||
</div>
|
||||
|
||||
<!-- CO2 -->
|
||||
<div class="rounded p-2" :class="getCO2BackgroundColor(room.co2.status)">
|
||||
<div class="font-medium" :class="getCO2TextColor(room.co2.status)">CO2</div>
|
||||
<div :class="getCO2TextColor(room.co2.status)">{{ Math.round(room.co2.current) }} {{ room.co2.unit }}</div>
|
||||
<div class="text-xs" :class="getCO2TextColor(room.co2.status)">{{ room.co2.status.toUpperCase() }}</div>
|
||||
<div class="rounded p-2" :class="getCO2BackgroundColor(room.co2!.status)">
|
||||
<div class="font-medium" :class="getCO2TextColor(room.co2!.status)">CO2</div>
|
||||
<div :class="getCO2TextColor(room.co2!.status)">{{ Math.round(room.co2!.current) }} {{ room.co2!.unit }}</div>
|
||||
<div class="text-xs" :class="getCO2TextColor(room.co2!.status)">{{ room.co2!.status.toUpperCase() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -77,18 +77,19 @@ import { useRoomStore } from '@/stores/room'
|
||||
const roomStore = useRoomStore()
|
||||
|
||||
const roomsList = computed(() => {
|
||||
return Array.from(roomStore.roomsData.values()).sort((a, b) =>
|
||||
a.room.localeCompare(b.room)
|
||||
)
|
||||
return Array.from(roomStore.roomsData.values())
|
||||
.filter(room => room.energy && room.co2) // Only show rooms with both metrics
|
||||
.sort((a, b) => a.room.localeCompare(b.room))
|
||||
})
|
||||
|
||||
const totalEnergy = computed(() => {
|
||||
return roomsList.value.reduce((sum, room) => sum + room.energy.current, 0)
|
||||
return roomsList.value.reduce((sum, room) => sum + (room.energy?.current || 0), 0)
|
||||
})
|
||||
|
||||
const averageCO2 = computed(() => {
|
||||
if (roomsList.value.length === 0) return 0
|
||||
return roomsList.value.reduce((sum, room) => sum + room.co2.current, 0) / roomsList.value.length
|
||||
const total = roomsList.value.reduce((sum, room) => sum + (room.co2?.current || 0), 0)
|
||||
return total / roomsList.value.length
|
||||
})
|
||||
|
||||
const getCO2StatusColor = (status: string) => {
|
||||
|
||||
Reference in New Issue
Block a user