diff --git a/server/prisma/db.sqlite-journal b/server/prisma/db.sqlite-journal deleted file mode 100644 index d975e7d..0000000 Binary files a/server/prisma/db.sqlite-journal and /dev/null differ diff --git a/server/src/axios/iot.types.ts b/server/src/axios/iot.types.ts index 0b38442..ade7983 100644 --- a/server/src/axios/iot.types.ts +++ b/server/src/axios/iot.types.ts @@ -1,10 +1,18 @@ -/** - * A number between 0 and 100 to represent precentages - */ -export type moisturePrecentage = number; - -export type moistureResponse = { - sensor_0: moisturePrecentage; - sensor_1: moisturePrecentage; - sensor_2: moisturePrecentage; +export type MoistureReading = { + /** + * A number between 0 and 100 to represent precentages + */ + precentage: number; + /** + * Raw read + */ + read: number; +}; + +export type MoistureResponse = { + data: { + sensor_0: MoistureReading; + sensor_1: MoistureReading; + sensor_2: MoistureReading; + }; }; diff --git a/server/src/cron/index.ts b/server/src/cron/index.ts index e791db2..339b527 100644 --- a/server/src/cron/index.ts +++ b/server/src/cron/index.ts @@ -1,30 +1,54 @@ import cron from "node-cron"; import { iotClient } from "../axios/iot.axios"; -import { moistureResponse } from "../axios/iot.types"; +import { MoistureResponse } from "../axios/iot.types"; import { prisma } from "../prisma"; import { emitter } from "../eventemitter"; +import { AxiosError } from "axios"; export function registerCronjobs() { cron.schedule("* * * * *", async () => { console.log("Checking moisture levels"); // Read moisture sensors - const { data } = await iotClient.post("moisture"); - const rows = []; - for (const [key, value] of Object.entries(data)) { - const row = await prisma.moistureValue.create({ + try { + const { data } = await readMoistureLevels(); + const rows = await insertRows(data); + + console.log("Successfully checked moisture levels"); + if (rows.length === 0) return; + // Emit event + emitter.emit("moisture.updated", ...rows); + } catch (e) { + console.log(e); + } + }); +} + +function readMoistureLevels() { + return iotClient + .get("moisture/read") + .catch((err: AxiosError) => { + return { + data: undefined, + }; + }); +} + +async function insertRows(data: MoistureResponse | undefined) { + if (!data) { + return []; + } + + return Promise.all( + Object.entries(data.data).map(([key, value]) => + prisma.moistureValue.create({ data: { name: key, - value, + value: value.precentage, createdAt: new Date(), }, select: { createdAt: true, id: true, name: true, value: true }, - }); - - rows.push(row); - } - - // Emit event - emitter.emit("moisture.updated", rows); - }); + }) + ) + ); } diff --git a/server/src/index.ts b/server/src/index.ts index 3daf1d5..cb8d769 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -3,7 +3,7 @@ import { prisma } from "./prisma"; startServer() .then(async () => { - await prisma.$disconnect(); + await prisma.$connect(); }) .catch(async (e) => { console.error(e); diff --git a/server/src/server.ts b/server/src/server.ts index 1b01438..13aaee0 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -4,7 +4,11 @@ import { registerCronjobs } from "./cron"; export async function startServer() { const port = 3000 || process.env.HTTP_PORT; - const io = new Server({}); + const io = new Server({ + cors: { + origin: "*", + }, + }); registerSockets(io); registerCronjobs(); diff --git a/server/src/sockets/moisture.socket.ts b/server/src/sockets/moisture.socket.ts index adf0e06..e4efcc5 100644 --- a/server/src/sockets/moisture.socket.ts +++ b/server/src/sockets/moisture.socket.ts @@ -7,7 +7,12 @@ import { prisma } from "../prisma"; export class MoistureSocket extends SocketHandler { constructor(server: Server) { super(server); + + this.server.on("getMoisture", this.getMoisture); + this.server.on("getAllMoistures", this.getAllMoistures); + emitter.on("moisture.updated", (...rows: any) => { + console.log("Moisture updated event listener called"); server.emit("moisture.updated", rows); }); } diff --git a/server/src/sockets/sockets.ts b/server/src/sockets/sockets.ts index 920f090..ee3a80b 100644 --- a/server/src/sockets/sockets.ts +++ b/server/src/sockets/sockets.ts @@ -1,15 +1,24 @@ -import io, { Server, Socket } from "socket.io"; +import { Server, Socket } from "socket.io"; +/** + * Registers methods to socket.io server passed in constructors. + * All methods will be registered unless it is prefixed with "_". + */ export abstract class SocketHandler { - constructor(private readonly server: Server) { - const ignoredMethods = ["connection"]; + constructor(protected readonly server: Server) { + const ignoredMethods: string[] = ["constructor"]; - for (const [key, value] of Object.entries(this)) { - if (typeof value === "function" && !ignoredMethods.includes(key)) { - this.server.on(key, value); - } - } + const prototype = Object.getPrototypeOf(this); + const methodNames = Object.getOwnPropertyNames(prototype).filter( + (name) => typeof prototype[name] === "function" + ); + + methodNames.forEach((methodName) => { + if (methodName.startsWith("_")) return; + if (ignoredMethods.includes(methodName)) return; + + this.server.on(methodName, prototype[methodName]); + }); } - abstract connection(socket: Socket): void; }