add selector for esp sensors in statistics screen
This commit is contained in:
parent
9fc7453a44
commit
b57d9b7875
2 changed files with 39 additions and 12 deletions
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue