Update to push to firestore

This commit is contained in:
William Moore 2023-10-26 00:58:33 -05:00
parent c217a807a7
commit a865e2a89a
5 changed files with 3722 additions and 3349 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@ yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
google-services.json
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

6963
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@
"main": "index.js",
"type": "module",
"scripts": {
"start": "npx tsc && node --experimental-specifier-resolution=node build/index.js",
"start:dev": "export PORT=4500 npx tsc && node --experimental-specifier-resolution=node --trace-warnings build/index.js",
"start": "npx tsc && node build/index.js",
"start:dev": "export PORT=4500 npx tsc && node build/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
@ -16,21 +16,11 @@
"author": "",
"license": "ISC",
"dependencies": {
"async-lock": "^1.4.0",
"blinkdb": "^0.9.0",
"body-parser": "^1.20.1",
"cors": "^2.8.5",
"date-fns": "^2.29.3",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"mongoose": "^6.8.4",
"firebase-admin": "^11.11.0",
"node-fetch": "^3.3.0"
},
"devDependencies": {
"@types/body-parser": "^1.19.2",
"@types/cors": "^2.8.13",
"@types/date-fns": "^2.6.0",
"@types/express": "^4.17.15",
"@types/node": "^18.11.18",
"typescript": "^4.9.4"
}

View File

@ -1,71 +1,50 @@
import bodyParser from 'body-parser';
import express from 'express';
import 'dotenv/config';
import fetch from 'node-fetch';
import { subHours, subSeconds } from 'date-fns'
import {
createDB,
createTable,
insert,
many,
removeWhere,
uuid,
} from 'blinkdb';
const { json } = bodyParser;
import admin, { ServiceAccount } from 'firebase-admin';
import { FieldValue } from 'firebase-admin/firestore';
import serviceAccount from './google-services.json' assert { type: "json" };
const RAIN_GAUGE_ENDPOINT = process.env.RAIN_GAUGE_ENDPOINT;
const SOIL_SENSOR_ENDPOINT = process.env.SOIL_SENSOR_ENDPOINT;
const TEASENSE_ENDPOINT = process.env.TEASENSE_ENDPOINT;
const PORT = process.env.PORT || 3000;
const DATA_COLLECT_SLEEP = 2000;
const PURGE_SLEEP = 60000;
const PURGE_TEASENSE_SLEEP = 1000;
interface DataPoint {
id: string;
type DataPoint = {
name: string;
value: number;
timestamp: Date;
timestamp: Date | null;
};
const db = createDB();
const dataPointsTable = createTable<DataPoint>(db, 'dataPoints')();
(async () => {
const app = express();
app.use(
'/',
json(),
);
app.get('/:name', async (req: any, res: any) => {
const startTime = subHours(new Date(), 24);
const result = await many(dataPointsTable, {
where: {
name: req.params.name,
}
const app = admin.initializeApp({
credential: admin.credential.cert(serviceAccount as ServiceAccount),
databaseURL: process.env.DATABASE_URL ?? '',
});
res.json(result);
});
const db = app.firestore();
app.listen(PORT);
console.log(`Listening to port ${PORT}`);
})();
const saveDataPoint = async (name: string, value: number, noTimestamp?: boolean) => {
const docRef = db.collection('colligit').doc(name);
let rainfallTimestamp = '';
const saveDataPoint = async (name: string, value: number) => {
await insert(dataPointsTable, {
id: uuid(),
const values: DataPoint[] = [
{
name,
timestamp: (noTimestamp) ? null : new Date(),
value,
timestamp: new Date(),
}
];
if (!noTimestamp) {
await docRef.set({
data: FieldValue.arrayUnion(...values),
}, { merge: true });
} else {
await docRef.set({
data: FieldValue.arrayUnion(...values),
});
}
}
const collectData = async () => {
if (RAIN_GAUGE_ENDPOINT && RAIN_GAUGE_ENDPOINT.trim() !== '') {
@ -100,43 +79,13 @@ const collectData = async () => {
signal: AbortSignal.timeout(10000),
});
const data: any = await response.json();
await saveDataPoint('teasense', data.temperature);
await saveDataPoint('teasense', data.temperature, true);
} catch (e) {
console.error(e);
}
}
purger5Sec();
setTimeout(() => collectData(), DATA_COLLECT_SLEEP);
};
const purger = async () => {
const startTime = subHours(new Date(), 24);
await removeWhere(dataPointsTable, {
where: {
timestamp: {
lt: startTime,
},
},
});
};
const purger5Sec = async () => {
const startTime = subSeconds(new Date(), 5);
await removeWhere(dataPointsTable, {
where: {
name: {
in: ['teasense', 'soil_voltage'],
},
timestamp: {
lt: startTime,
},
},
});
};
setTimeout(() => collectData(), DATA_COLLECT_SLEEP);
setInterval(() => purger(), PURGE_SLEEP);
// setInterval(() => purger5Sec(), PURGE_TEASENSE_SLEEP);

View File

@ -25,7 +25,7 @@
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "ES2022", /* Specify what module code is generated. */
"module": "ESNext", /* Specify what module code is generated. */
"rootDir": "./src", /* Specify the root folder within your source files. */
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
@ -35,7 +35,7 @@
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "resolveJsonModule": true, /* Enable importing .json files. */
"resolveJsonModule": true, /* Enable importing .json files. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */