mirror of
https://github.com/eliasrenman/gardentron.git
synced 2026-03-16 20:46:07 +01:00
fix: sqlite and types
This commit is contained in:
@@ -1,2 +1 @@
|
|||||||
DATABASE_URL="file:./db.sqlite"
|
|
||||||
IOT_BASE_URL='192.168.1.203'
|
IOT_BASE_URL='192.168.1.203'
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
|
import { config } from "dotenv";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
config();
|
||||||
|
|
||||||
export const BASE_URL = process.env.IOT_BASE_URL;
|
export const BASE_URL = process.env.IOT_BASE_URL;
|
||||||
export const iotClient = axios.create({
|
export const iotClient = axios.create({
|
||||||
baseURL: BASE_URL,
|
baseURL: BASE_URL,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { MoistureResponse } from "../axios/iot.types";
|
|||||||
import { emitter } from "../eventemitter";
|
import { emitter } from "../eventemitter";
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
import { logger } from "../config";
|
import { logger } from "../config";
|
||||||
import { db } from "../db/Databasehandler";
|
import { MoistureValueRow, db } from "../db/Databasehandler";
|
||||||
|
|
||||||
export function registerCronjobs() {
|
export function registerCronjobs() {
|
||||||
cron.schedule(
|
cron.schedule(
|
||||||
@@ -33,27 +33,29 @@ export function readMoistureLevels() {
|
|||||||
return iotClient
|
return iotClient
|
||||||
.get<MoistureResponse | undefined>("moisture/read")
|
.get<MoistureResponse | undefined>("moisture/read")
|
||||||
.catch((err: AxiosError) => {
|
.catch((err: AxiosError) => {
|
||||||
|
console.log(err);
|
||||||
return {
|
return {
|
||||||
data: undefined,
|
data: undefined,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MositureRow = Awaited<ReturnType<typeof insertRows>>[number];
|
function insertRows(data: MoistureResponse | undefined): MoistureValueRow[] {
|
||||||
|
|
||||||
function insertRows(data: MoistureResponse | undefined) {
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
return Object.entries(data.data).map(([key, value]) => {
|
||||||
return Object.entries(data.data).map(([key, value]) =>
|
const result = db.moistureValue.create({
|
||||||
db.moistureValue.create({
|
|
||||||
data: {
|
data: {
|
||||||
name: key,
|
name: key,
|
||||||
value: value.precentage,
|
value: value.precentage,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
},
|
},
|
||||||
select: { createdAt: true, id: true, name: true, value: true },
|
select: { createdAt: true, id: true, name: true, value: true },
|
||||||
})
|
});
|
||||||
);
|
if ("changes" in result && "lastInsertRowid" in result) {
|
||||||
|
throw Error("Failed to insert row");
|
||||||
|
}
|
||||||
|
return result as MoistureValueRow;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import sqlite from "better-sqlite3";
|
import sqlite from "better-sqlite3";
|
||||||
import { validate } from "node-cron";
|
import { validate } from "node-cron";
|
||||||
import { join, resolve } from "path";
|
import { join, resolve } from "path";
|
||||||
|
import { logger } from "../config";
|
||||||
|
|
||||||
export class DatabaseHandler extends sqlite {
|
export class DatabaseHandler extends sqlite {
|
||||||
public moistureValue: MositureValue;
|
public moistureValue: MositureValue;
|
||||||
@@ -12,7 +13,7 @@ export class DatabaseHandler extends sqlite {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type MoistureValueRow = {
|
export type MoistureValueRow = {
|
||||||
name: string;
|
name: string;
|
||||||
value: number;
|
value: number;
|
||||||
createdAt: Date | string;
|
createdAt: Date | string;
|
||||||
@@ -57,7 +58,7 @@ class MositureValue {
|
|||||||
public select(query: string, value: Record<keyof MoistureValueRow, boolean>) {
|
public select(query: string, value: Record<keyof MoistureValueRow, boolean>) {
|
||||||
const select = this.getSelectStatement(value);
|
const select = this.getSelectStatement(value);
|
||||||
const sql = `SELECT ${select} FROM 'MoistureValue' ${query}`;
|
const sql = `SELECT ${select} FROM 'MoistureValue' ${query}`;
|
||||||
console.log("SQL SELECT STATEMENT:", sql);
|
logger.debug("SQL SELECT STATEMENT:", sql);
|
||||||
return this.db.prepare(sql);
|
return this.db.prepare(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import Queue from "queue";
|
import Queue from "queue";
|
||||||
import { iotClient } from "../axios/iot.axios";
|
import { iotClient } from "../axios/iot.axios";
|
||||||
import { config, logger } from "../config";
|
import { config, logger } from "../config";
|
||||||
import { MositureRow, readMoistureLevels } from "../cron";
|
import { readMoistureLevels } from "../cron";
|
||||||
import { emitter } from "../eventemitter";
|
import { emitter } from "../eventemitter";
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
|
import { MoistureValueRow } from "../db/Databasehandler";
|
||||||
|
|
||||||
const queue = new Queue({ results: [], concurrency: 1 });
|
const queue = new Queue({ results: [], concurrency: 1 });
|
||||||
|
|
||||||
queue.start((result) => logger.info("Successfully started queue"));
|
queue.start((result) => logger.info("Successfully started queue"));
|
||||||
|
|
||||||
export function checkReadingAndEnqueue(rows: MositureRow[]) {
|
export function checkReadingAndEnqueue(rows: MoistureValueRow[]) {
|
||||||
rows
|
rows
|
||||||
.sort((a, b) => +a.name)
|
.sort((a, b) => +a.name)
|
||||||
.forEach((row) => {
|
.forEach((row) => {
|
||||||
@@ -18,8 +19,8 @@ export function checkReadingAndEnqueue(rows: MositureRow[]) {
|
|||||||
config.config.moisture.thresholds.lower["sensor_" + row.name];
|
config.config.moisture.thresholds.lower["sensor_" + row.name];
|
||||||
|
|
||||||
// Conclude which sensors need watering.
|
// Conclude which sensors need watering.
|
||||||
if (row.value.toNumber() <= threshold) {
|
if (row.value <= threshold) {
|
||||||
logger.info(`Enqueing ${row.name} Value at ${row.value.toNumber()}%`);
|
logger.info(`Enqueing ${row.name} Value at ${row.value}%`);
|
||||||
// Enqueue relevant sensors
|
// Enqueue relevant sensors
|
||||||
queue.push((cb) =>
|
queue.push((cb) =>
|
||||||
process(row)
|
process(row)
|
||||||
@@ -27,15 +28,13 @@ export function checkReadingAndEnqueue(rows: MositureRow[]) {
|
|||||||
.catch((err) => cb && cb(err!))
|
.catch((err) => cb && cb(err!))
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
logger.info(
|
logger.info(`Will not enqueue ${row.name} Value at ${row.value}%`);
|
||||||
`Will not enqueue ${row.name} Value at ${row.value.toNumber()}%`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
queue.start();
|
queue.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function process(row: MositureRow) {
|
async function process(row: MoistureValueRow) {
|
||||||
logger.info("Started processing of", row.name);
|
logger.info("Started processing of", row.name);
|
||||||
const index = row.name;
|
const index = row.name;
|
||||||
try {
|
try {
|
||||||
@@ -46,7 +45,7 @@ async function process(row: MositureRow) {
|
|||||||
// Check moisture level once per second for configured time
|
// Check moisture level once per second for configured time
|
||||||
await Promise.race([
|
await Promise.race([
|
||||||
// sleep(config.config.timeout * 1000),
|
// sleep(config.config.timeout * 1000),
|
||||||
timeoutCb(row.name, row.value.toNumber()),
|
timeoutCb(row.name, row.value),
|
||||||
]);
|
]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.info(`Failed to processing of ${row.name}`);
|
logger.info(`Failed to processing of ${row.name}`);
|
||||||
@@ -117,7 +116,6 @@ function toggleWater(index: string, on: boolean) {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then(async (item) => {
|
.then(async (item) => {
|
||||||
console.log(item.status, item.data);
|
|
||||||
logger.info(`Successfully ${on ? "activate" : "deactivate"}d water gate`);
|
logger.info(`Successfully ${on ? "activate" : "deactivate"}d water gate`);
|
||||||
return { on };
|
return { on };
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { Server, Socket } from "socket.io";
|
|||||||
import { DefaultEventsMap } from "socket.io/dist/typed-events";
|
import { DefaultEventsMap } from "socket.io/dist/typed-events";
|
||||||
import { SocketHandler } from "./sockets";
|
import { SocketHandler } from "./sockets";
|
||||||
import { emitter } from "../eventemitter";
|
import { emitter } from "../eventemitter";
|
||||||
import { MositureRow } from "../cron";
|
|
||||||
import { checkReadingAndEnqueue } from "../processors/moisture.processor";
|
import { checkReadingAndEnqueue } from "../processors/moisture.processor";
|
||||||
import { logger } from "../config";
|
import { logger } from "../config";
|
||||||
import { db } from "../db/Databasehandler";
|
import { MoistureValueRow, db } from "../db/Databasehandler";
|
||||||
|
|
||||||
export class MoistureSocket extends SocketHandler {
|
export class MoistureSocket extends SocketHandler {
|
||||||
constructor(server: Server) {
|
constructor(server: Server) {
|
||||||
@@ -14,7 +14,7 @@ export class MoistureSocket extends SocketHandler {
|
|||||||
this.server.on("getMoisture", this.getMoisture);
|
this.server.on("getMoisture", this.getMoisture);
|
||||||
this.server.on("getAllMoistures", this.getAllMoistures);
|
this.server.on("getAllMoistures", this.getAllMoistures);
|
||||||
|
|
||||||
emitter.on("moisture.updated", (...rows: MositureRow[]) => {
|
emitter.on("moisture.updated", (...rows: MoistureValueRow[]) => {
|
||||||
logger.info("Moisture updated event listener called");
|
logger.info("Moisture updated event listener called");
|
||||||
server.emit("moisture.updated", rows);
|
server.emit("moisture.updated", rows);
|
||||||
checkReadingAndEnqueue(rows);
|
checkReadingAndEnqueue(rows);
|
||||||
|
|||||||
Reference in New Issue
Block a user