diff --git a/package.json b/package.json index fb9ac4e..75383b6 100644 --- a/package.json +++ b/package.json @@ -68,8 +68,6 @@ "@node-rs/argon2": "^2.0.2", "@oslojs/crypto": "^1.0.1", "@oslojs/encoding": "^1.1.0", - "d3-scale": "^4.0.2", - "d3-shape": "^3.2.0", "drizzle-orm": "^0.43.1", "mqtt": "^5.13.1", "postgres": "^3.4.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c8adcf8..7918f60 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,12 +17,6 @@ importers: '@oslojs/encoding': specifier: ^1.1.0 version: 1.1.0 - d3-scale: - specifier: ^4.0.2 - version: 4.0.2 - d3-shape: - specifier: ^3.2.0 - version: 3.2.0 drizzle-orm: specifier: ^0.43.1 version: 0.43.1(postgres@3.4.5) diff --git a/src/lib/server/db/schema.js b/src/lib/server/db/schema.js index 9e7680e..0ae02ed 100644 --- a/src/lib/server/db/schema.js +++ b/src/lib/server/db/schema.js @@ -42,5 +42,4 @@ export const sensorData = pgTable("sensor_data", { humidity: real().notNull(), pressure: real().notNull(), altitude: real().notNull(), - time: timestamp().notNull().defaultNow(), }); diff --git a/src/lib/server/mqtt-devices.js b/src/lib/server/mqtt-devices.js deleted file mode 100644 index 8445506..0000000 --- a/src/lib/server/mqtt-devices.js +++ /dev/null @@ -1,42 +0,0 @@ -// src/lib/server/mqtt-devices.js -// This module provides access to MQTT device data for other parts of the application - -// We'll import the maps directly from the MQTT server module - -let connectedDevices = new Map(); -let deviceSensorData = new Map(); - -// Export the maps so the MQTT server can set them -export { connectedDevices, deviceSensorData }; - -// Clean up offline devices (not seen in last 5 minutes) -function cleanupDevices() { - const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000); - let updated = false; - - for (const [deviceId, device] of connectedDevices.entries()) { - if (device.lastSeen < fiveMinutesAgo && device.status === "online") { - connectedDevices.set(deviceId, { ...device, status: "offline" }); - updated = true; - } - } - - return updated; -} - -// Export function to get current devices -export function getCurrentDevices() { - cleanupDevices(); - return Array.from(connectedDevices.values()).map((device) => { - const sensorData = deviceSensorData.get(device.id); - return { - ...device, - sensorData: sensorData || null, - }; - }); -} - -// Export function to get sensor data for a specific device -export function getDeviceSensorData(deviceId) { - return deviceSensorData.get(deviceId) || null; -} diff --git a/src/routes/(app)/[slug]/+page.server.ts b/src/routes/(app)/[slug]/+page.server.ts index 8ce7412..4488322 100644 --- a/src/routes/(app)/[slug]/+page.server.ts +++ b/src/routes/(app)/[slug]/+page.server.ts @@ -3,74 +3,35 @@ import * as table from "$lib/server/db/schema"; import { eq } from "drizzle-orm"; import type { PageServerLoad } from "./$types"; import { connect } from "mqtt"; -import { getDeviceSensorData } from "$lib/server/mqtt-devices.js"; export const load: PageServerLoad = async ({ params }) => { - // Convert slug to number for floor lookup - const floorNumber = Number(params.slug); - - // First check if we have a saved floor configuration in the floors table - const floorData = await db.select({ - floor: table.floors.floor, - url: table.floors.url - }).from(table.floors).where(eq(table.floors.floor, floorNumber)); - - if (floorData.length > 0 && floorData[0].url && floorData[0].url !== "/") { - try { - // Try to parse the saved configuration - const config = JSON.parse(floorData[0].url); - - // Add real sensor data to devices - if (config.devices) { - config.devices = config.devices.map(device => { - const sensorData = getDeviceSensorData(device.id); - return { - ...device, - sensorData: sensorData - }; - }); - } - - return { - slug: params.slug, - floorConfig: config, - hasConfig: true - }; - } catch (e) { - console.error("Error parsing floor configuration:", e); + { + const floor_cnt = await db.select({ floor: table.plans.floor, json: table.plans.plan }).from(table.plans).where(eq(table.plans.floor, params.slug)); + if (floor_cnt.length == 0) { + await db.insert(table.plans).values({ floor: params.slug, plan: { + "regions": [ + { "start": { "x": 100, "y": 100 }, "end": { "x": 400, "y": 100 } }, + { "start": { "x": 400, "y": 100 }, "end": { "x": 400, "y": 300 } }, + { "start": { "x": 400, "y": 300 }, "end": { "x": 100, "y": 300 } }, + { "start": { "x": 100, "y": 300 }, "end": { "x": 100, "y": 100 } } + ], + "doors": [ + { "location": { "x": 240, "y": 100 }, "width": 50, "rotation": 0 } + ], + "furnitures": [ + { + "minBound": { "x": 150, "y": 150 }, + "maxBound": { "x": 200, "y": 200 }, + "equipName": "Table", + "xPlacement": 150, + "yPlacement": 150, + "rotation": 0 + } + ] + }}); } + } - - // Fallback to the old canvas drawing system - const floor_cnt = await db.select({ floor: table.plans.floor, json: table.plans.plan }).from(table.plans).where(eq(table.plans.floor, params.slug)); - if (floor_cnt.length == 0) { - await db.insert(table.plans).values({ floor: params.slug, plan: { - "regions": [ - { "start": { "x": 100, "y": 100 }, "end": { "x": 400, "y": 100 } }, - { "start": { "x": 400, "y": 100 }, "end": { "x": 400, "y": 300 } }, - { "start": { "x": 400, "y": 300 }, "end": { "x": 100, "y": 300 } }, - { "start": { "x": 100, "y": 300 }, "end": { "x": 100, "y": 100 } } - ], - "doors": [ - { "location": { "x": 240, "y": 100 }, "width": 50, "rotation": 0 } - ], - "furnitures": [ - { - "minBound": { "x": 150, "y": 150 }, - "maxBound": { "x": 200, "y": 200 }, - "equipName": "Table", - "xPlacement": 150, - "yPlacement": 150, - "rotation": 0 - } - ] - }}); - } - const floor_ = await db.select({ floor: table.plans.floor, json: table.plans.plan }).from(table.plans).where(eq(table.plans.floor, params.slug)); - return { - slug: params.slug, - floor: floor_, - hasConfig: false - }; + return { slug: params.slug, floor: floor_ }; }; diff --git a/src/routes/(app)/[slug]/+page.svelte b/src/routes/(app)/[slug]/+page.svelte index e31f282..2f90051 100644 --- a/src/routes/(app)/[slug]/+page.svelte +++ b/src/routes/(app)/[slug]/+page.svelte @@ -1,59 +1,26 @@ -
- -

Floor {data.slug}

- - {#if data.hasConfig && data.floorConfig} - -
- {#if data.floorConfig.image} -
- Floor plan - - {#if data.floorConfig.devices} - {#each data.floorConfig.devices as device} -
-
- - {device.name} -
-
-
- - - {#if deviceSensorData.get(device.id)?.temperature !== undefined} - {deviceSensorData.get(device.id).temperature.toFixed(1)}°C - {:else if device.sensorData} - {device.sensorData.temperature.toFixed(1)}°C - {:else} - --°C - {/if} - -
-
- - - {#if deviceSensorData.get(device.id)?.humidity !== undefined} - {deviceSensorData.get(device.id).humidity.toFixed(1)}% - {:else if device.sensorData} - {device.sensorData.humidity.toFixed(1)}% - {:else} - --% - {/if} - -
-
- - - {#if deviceSensorData.get(device.id)?.pressure !== undefined} - {Math.round(deviceSensorData.get(device.id).pressure)}Pa - {:else if device.sensorData} - {Math.round(device.sensorData.pressure)}Pa - {:else} - --Pa - {/if} - -
-
- - - {#if deviceSensorData.get(device.id)?.altitude !== undefined} - {deviceSensorData.get(device.id).altitude.toFixed(1)}m - {:else if device.sensorData} - {device.sensorData.altitude.toFixed(1)}m - {:else} - --m - {/if} - -
-
-
- {/each} - {/if} -
- -
-

MQTT Status: {mqttMessage}

-
- {/if} -
- {:else} - -
- {mqttMessage} - -
- {/if} - - Statistics - - - - - {#snippet child({ props })} - - {/snippet} - - - {#each table as column} - (column.visible = !value)} - > - {column.id} - - {/each} - - -
- Data for floor {data.slug} - Showing total data for the last 3 months -
- - - {selectedLabel} - - - Last 3 months - Last 30 days - Last 7 days - - -
- - - { - return v.toLocaleDateString("en-US", { - month: "short", - day: "numeric", - }); - }, - }, - - yAxis: { format: () => "" }, - }} - > - {#snippet marks({ series, getAreaProps })} - - - - - - - - - - - - {#each series as s, i (s.key)} - - {/each} - - {/snippet} - {#snippet tooltip()} - { - return v.toLocaleDateString("en-US", { - month: "long", - }); - }} - indicator="line" - /> - {/snippet} - - - - -
-
+
+

Floor {data.slug}

+ {mqttMessage} +
diff --git a/src/routes/(app)/[slug]/stats/+server.ts b/src/routes/(app)/[slug]/stats/+server.ts deleted file mode 100644 index 6356340..0000000 --- a/src/routes/(app)/[slug]/stats/+server.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { db } from "$lib/server/db"; -import * as table from "$lib/server/db/schema" - -export const GET = async () => { - const data = await db.select({ sensor: table.sensorData.sensor }).from(table.sensorData); - console.log(data); - - return new Response(JSON.stringify(data), { - headers: { - "Content-Type": "application/json" - } - }); -} diff --git a/src/routes/(app)/settings/+page.server.js b/src/routes/(app)/settings/+page.server.js index e7bdcb0..365a6b8 100644 --- a/src/routes/(app)/settings/+page.server.js +++ b/src/routes/(app)/settings/+page.server.js @@ -1,35 +1,10 @@ import { db } from "$lib/server/db"; import * as table from "$lib/server/db/schema"; -import { getCurrentDevices } from "$lib/server/mqtt-devices.js"; import { fail } from "@sveltejs/kit"; import { eq } from "drizzle-orm"; export const load = async (event) => { - // Fetch all available floors - const floors = await db - .select({ floor: table.floors.floor }) - .from(table.floors) - .orderBy(table.floors.floor); - - // Get real connected devices from MQTT - let devices = getCurrentDevices(); - - // If no real devices, provide fallback mock devices - if (devices.length === 0) { - devices = [ - { - id: "no-devices", - name: "No ESP8266 devices connected", - type: "esp8266", - status: "offline", - }, - ]; - } - - return { - floors: floors.map((f) => f.floor), - devices: devices, - }; + return {}; }; export const actions = { @@ -66,49 +41,4 @@ export const actions = { await db.delete(table.floors).where(eq(table.floors.floor, n)); }, - savefloor: async (event) => { - const formData = await event.request.formData(); - const floorNumber = formData.get("floorNumber"); - const floorPlanImage = formData.get("floorPlanImage"); - const devices = formData.get("devices"); - - const n = Number(floorNumber); - if (isNaN(n)) return fail(400, { message: "Invalid floor number!" }); - - if (!floorPlanImage || !devices) { - return fail(400, { message: "Missing floor plan or device configuration!" }); - } - - try { - const deviceData = JSON.parse(devices); - - // Check if floor exists - const exists = await db - .select({ floor: table.floors.floor }) - .from(table.floors) - .where(eq(table.floors.floor, n)); - - if (exists.length === 0) { - return fail(400, { message: `Floor ${n} does not exist! Please create it first.` }); - } - - // Update floor with configuration - // Note: In a real implementation, you would store this data properly - // For now, we'll just update the url field as a JSON string - const floorConfig = { - image: floorPlanImage, - devices: deviceData, - }; - - await db - .update(table.floors) - .set({ url: JSON.stringify(floorConfig) }) - .where(eq(table.floors.floor, n)); - - return { success: true, message: `Floor ${n} configuration saved successfully!` }; - } catch (error) { - console.error("Error saving floor configuration:", error); - return fail(500, { message: "Failed to save floor configuration!" }); - } - }, }; diff --git a/src/routes/(app)/settings/+page.svelte b/src/routes/(app)/settings/+page.svelte index 9b57069..173578d 100644 --- a/src/routes/(app)/settings/+page.svelte +++ b/src/routes/(app)/settings/+page.svelte @@ -1,6 +1,5 @@