Update to push to firestore
This commit is contained in:
parent
c217a807a7
commit
a865e2a89a
1
.gitignore
vendored
1
.gitignore
vendored
@ -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
6963
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@ -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"
|
||||
}
|
||||
|
105
src/index.ts
105
src/index.ts
@ -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);
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user