add selector for esp sensors in statistics screen

This commit is contained in:
David Senoner 2025-06-14 11:02:44 +02:00
parent 9fc7453a44
commit b57d9b7875
Signed by: kada49
GPG key ID: 92BABE6B7E63C6CA
2 changed files with 39 additions and 12 deletions

View file

@ -128,11 +128,17 @@
import * as Chart from "$lib/components/ui/chart/index.js"; import * as Chart from "$lib/components/ui/chart/index.js";
import * as Card from "$lib/components/ui/card/index.js"; import * as Card from "$lib/components/ui/card/index.js";
import * as Select from "$lib/components/ui/select/index.js"; import * as Select from "$lib/components/ui/select/index.js";
import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
import { ChevronDownIcon, Columns2 } from "@lucide/svelte";
let chartData = $state([]); let chartData = $state([]);
let newChartData = $derived(
chartData.filter((item: object) => {
if (item.sensorId === selectedESP) {
return { ...item };
}
}),
);
let timeRange = $state("90d"); let timeRange = $state("90d");
const selectedLabel = $derived.by(() => { const selectedLabel = $derived.by(() => {
@ -149,7 +155,7 @@
}); });
const filteredData = $derived( const filteredData = $derived(
chartData.filter((item) => { newChartData.filter((item) => {
const now = new Date(); const now = new Date();
let daysToSubtract = 90; let daysToSubtract = 90;
if (timeRange === "30d") { if (timeRange === "30d") {
@ -212,7 +218,9 @@
const selectedSensorConfig = $derived( const selectedSensorConfig = $derived(
sensorOptions.find((s) => s.key === selectedSensor) || sensorOptions[0], sensorOptions.find((s) => s.key === selectedSensor) || sensorOptions[0],
); );
const device = "macaddress";
let esps = $state([]);
let selectedESP = $state("Select ESP sensor");
let isLoading = $state(false); let isLoading = $state(false);
let hasError = $state(false); let hasError = $state(false);
@ -234,6 +242,10 @@
const rawData = await response.json(); const rawData = await response.json();
console.log("Raw stats data:", rawData); console.log("Raw stats data:", rawData);
const allesps = rawData.map((i: any) => {
return i.sensorId;
});
esps = allesps.filter((v: any, i: any, a: any) => a.indexOf(v) === i);
if (!rawData || rawData.length === 0) { if (!rawData || rawData.length === 0) {
console.log("No data available for statistics"); console.log("No data available for statistics");
@ -260,14 +272,14 @@
const headers = "time," + selectedSensorConfig.key; const headers = "time," + selectedSensorConfig.key;
csv += headers + "\n"; csv += headers + "\n";
chartData.forEach((obj: any) => { newChartData.forEach((obj: any) => {
csv += obj.date.toISOString() + "," + obj[selectedSensorConfig.key] + "\n"; csv += obj.date.toISOString() + "," + obj[selectedSensorConfig.key] + "\n";
}); });
const encodedUri = encodeURI(csv); const encodedUri = encodeURI(csv);
const link = document.createElement("a"); const link = document.createElement("a");
link.setAttribute("href", encodedUri); link.setAttribute("href", encodedUri);
link.setAttribute("download", device + "_" + selectedSensorConfig.key + "_data.csv"); link.setAttribute("download", selectedESP + "_" + selectedSensorConfig.key + "_data.csv");
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
@ -370,8 +382,19 @@
</Dialog.Header> </Dialog.Header>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<Select.Root type="single" bind:value={selectedESP}>
<Select.Trigger class="w-[160px] rounded-lg" aria-label="Select a sensor">
{selectedESP}
</Select.Trigger>
<Select.Content class="rounded-xl">
{#each esps as esp}
<Select.Item value={esp} class="rounded-lg">{esp}</Select.Item>
{/each}
</Select.Content>
</Select.Root>
<Select.Root type="single" bind:value={selectedSensor}> <Select.Root type="single" bind:value={selectedSensor}>
<Select.Trigger class="w-[160px] rounded-lg" aria-label="Select a value"> <Select.Trigger class="w-[160px] rounded-lg" aria-label="Select a metric">
{sensorLabel} {sensorLabel}
</Select.Trigger> </Select.Trigger>
<Select.Content class="rounded-xl"> <Select.Content class="rounded-xl">
@ -383,7 +406,7 @@
</Select.Root> </Select.Root>
<Select.Root type="single" bind:value={timeRange}> <Select.Root type="single" bind:value={timeRange}>
<Select.Trigger class="w-[160px] rounded-lg" aria-label="Select a value"> <Select.Trigger class="w-[160px] rounded-lg" aria-label="Select a time range">
{selectedLabel} {selectedLabel}
</Select.Trigger> </Select.Trigger>
<Select.Content class="rounded-xl"> <Select.Content class="rounded-xl">
@ -415,7 +438,7 @@
<p class="text-muted-foreground text-sm">Please try again later</p> <p class="text-muted-foreground text-sm">Please try again later</p>
</div> </div>
</div> </div>
{:else if chartData.length === 0} {:else if newChartData.length === 0}
<div class="flex h-[400px] items-center justify-center"> <div class="flex h-[400px] items-center justify-center">
<div class="text-center"> <div class="text-center">
<p class="mb-2 text-lg font-semibold">No data available</p> <p class="mb-2 text-lg font-semibold">No data available</p>

View file

@ -1,15 +1,19 @@
import { db } from "$lib/server/db"; import { db } from "$lib/server/db";
import * as table from "$lib/server/db/schema" import * as table from "$lib/server/db/schema"
import { eq } from "drizzle-orm";
export const GET = async () => { export const GET = async (event) => {
// Get all sensor data (like the original working version) // Get all sensor data (like the original working version)
console.log(event.locals.session.userId)
const rawData = await db.select({ const rawData = await db.select({
altitude: table.sensorData.altitude, altitude: table.sensorData.altitude,
humidity: table.sensorData.humidity, humidity: table.sensorData.humidity,
pressure: table.sensorData.pressure, pressure: table.sensorData.pressure,
temperature: table.sensorData.temperature, temperature: table.sensorData.temperature,
date: table.sensorData.time, date: table.sensorData.time,
}).from(table.sensorData); sensorId: table.sensorData.sensor,
user: table.sensors.user,
}).from(table.sensorData).innerJoin(table.sensors, eq(table.sensors.id, table.sensorData.sensor)).where(eq(table.sensors.user, event.locals.session.userId));
// Scale pressure values to be in a similar range as other sensors // Scale pressure values to be in a similar range as other sensors
// Divide by 1000 to convert from Pa to kPa (more reasonable scale) // Divide by 1000 to convert from Pa to kPa (more reasonable scale)