implement database and mqtt client to cache node info

This commit is contained in:
liamcottle
2024-03-13 03:46:50 +13:00
parent 2970e34a48
commit cef784f7da
46 changed files with 6733 additions and 131 deletions

View File

@ -1,36 +1,28 @@
const path = require('path');
const axios = require('axios');
const express = require('express');
const NodeCache = require("node-cache");
const cache = new NodeCache();
const protobufjs = require("protobufjs");
// create prisma db client
const { PrismaClient } = require("@prisma/client");
const prisma = new PrismaClient();
// return big ints as string when using JSON.stringify
BigInt.prototype.toJSON = function() {
return this.toString();
}
// load protobufs
const root = new protobufjs.Root();
root.resolvePath = (origin, target) => path.join(__dirname, "protos", target);
root.loadSync('meshtastic/mqtt.proto');
const HardwareModel = root.lookupEnum("HardwareModel");
const Role = root.lookupEnum("Config.DeviceConfig.Role");
const app = express();
// serve files inside the public folder from /
app.use('/', express.static(path.join(__dirname, 'public')));
async function getCached(key, ttl, callback) {
// find data from cache
let data = cache.get(key);
// update cache
if(!data){
data = await callback();
cache.set(key, data, ttl);
}
// get expiration time in seconds
const cacheTtl = cache.getTtl(key);
const expiresIn = cacheTtl != null
? Math.ceil((cacheTtl - Date.now()) / 1000)
: 0;
// return data
return [ data, expiresIn ];
}
app.get('/', async (req, res) => {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
@ -59,15 +51,18 @@ app.get('/api', async (req, res) => {
app.get('/api/v1/nodes', async (req, res) => {
try {
// get nodes from cache, or retrieve from api
const [ nodes, expiresIn ] = await getCached('nodes', 10, async () => {
const response = await axios.get("https://meshmap.net/nodes2.json");
return response.data;
});
// get nodes from db
const nodes = await prisma.node.findMany();
res.json({
expires_in: expiresIn,
nodes: nodes,
nodes: nodes.map((node) => {
return {
...node,
node_id_hex: "!" + node.node_id.toString(16),
hardware_model_name: HardwareModel.valuesById[node.hardware_model] ?? "UNKNOWN",
role_name: Role.valuesById[node.role] ?? "UNKNOWN",
}
}),
});
} catch(err) {