feat: added moisture checker

This commit is contained in:
Elias Renman
2023-05-21 16:33:44 +02:00
parent bb9407c2fa
commit 028e825541
20 changed files with 454 additions and 756 deletions

View File

@@ -0,0 +1,5 @@
import axios from "axios";
export const iotClient = axios.create({
baseURL: process.env.IOT_BASE_URL,
});

View File

@@ -0,0 +1,10 @@
/**
* 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;
};

30
server/src/cron/index.ts Normal file
View File

@@ -0,0 +1,30 @@
import cron from "node-cron";
import { iotClient } from "../axios/iot.axios";
import { moistureResponse } from "../axios/iot.types";
import { prisma } from "../prisma";
import { emitter } from "../eventemitter";
export function registerCronjobs() {
cron.schedule("* * * * *", async () => {
console.log("Checking moisture levels");
// Read moisture sensors
const { data } = await iotClient.post<moistureResponse>("moisture");
const rows = [];
for (const [key, value] of Object.entries(data)) {
const row = await prisma.moistureValue.create({
data: {
name: key,
value,
createdAt: new Date(),
},
select: { createdAt: true, id: true, name: true, value: true },
});
rows.push(row);
}
// Emit event
emitter.emit("moisture.updated", rows);
});
}

View File

@@ -0,0 +1,3 @@
import EventEmitter2 from "eventemitter2";
export const emitter = new EventEmitter2();

View File

@@ -0,0 +1,12 @@
import { startServer } from "./server";
import { prisma } from "./prisma";
startServer()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});

3
server/src/prisma.ts Normal file
View File

@@ -0,0 +1,3 @@
import { PrismaClient } from "@prisma/client";
export const prisma = new PrismaClient();

View File

@@ -0,0 +1,13 @@
import { Server } from "socket.io";
import { registerSockets } from "./sockets";
import { registerCronjobs } from "./cron";
export async function startServer() {
const port = 3000 || process.env.HTTP_PORT;
const io = new Server({});
registerSockets(io);
registerCronjobs();
io.listen(port);
}

View File

View File

@@ -0,0 +1,6 @@
import { Server } from "socket.io";
import { MoistureSocket } from "./moisture.socket";
export function registerSockets(server: Server) {
new MoistureSocket(server);
}

View File

@@ -0,0 +1,19 @@
import { Server, Socket } from "socket.io";
import { DefaultEventsMap } from "socket.io/dist/typed-events";
import { SocketHandler } from "./sockets";
import { emitter } from "../eventemitter";
export class MoistureSocket extends SocketHandler {
constructor(server: Server) {
super(server);
emitter.on("moisture.updated", (...rows: any) => {
server.emit("moisture.updated", rows);
});
}
connection(
socket: Socket<DefaultEventsMap, DefaultEventsMap, DefaultEventsMap, any>
): void {
console.log("Connection established with moisture handler.");
}
}

View File

@@ -0,0 +1,15 @@
import io, { Server, Socket } from "socket.io";
export abstract class SocketHandler {
constructor(private readonly server: Server) {
const ignoredMethods = ["connection"];
for (const [key, value] of Object.entries(this)) {
if (typeof value === "function" && !ignoredMethods.includes(key)) {
this.server.on(key, value);
}
}
}
abstract connection(socket: Socket): void;
}