diff --git a/src/index.js b/src/index.js index ab8ec56..7853874 100644 --- a/src/index.js +++ b/src/index.js @@ -433,6 +433,90 @@ app.get('/api/v1/nodes/:nodeId/traceroutes', async (req, res) => { } }); +app.get('/api/v1/nodes/:nodeId/position-history', async (req, res) => { + try { + + // defaults + const nowInMilliseconds = new Date().getTime(); + const oneHourAgoInMilliseconds = new Date().getTime() - (3600 * 1000); + + // get request params + const nodeId = parseInt(req.params.nodeId); + const timeFrom = req.query.time_from ? parseInt(req.query.time_from) : oneHourAgoInMilliseconds; + const timeTo = req.query.time_to ? parseInt(req.query.time_to) : nowInMilliseconds; + + // find node + const node = await prisma.node.findFirst({ + where: { + node_id: nodeId, + }, + }); + + // make sure node exists + if(!node){ + res.status(404).json({ + message: "Not Found", + }); + return; + } + + const positions = await prisma.position.findMany({ + where: { + node_id: nodeId, + created_at: { + gte: new Date(timeFrom), + lte: new Date(timeTo), + }, + } + }); + + const mapReports = await prisma.mapReport.findMany({ + where: { + node_id: nodeId, + created_at: { + gte: new Date(timeFrom), + lte: new Date(timeTo), + }, + } + }); + + const positionHistory = [] + + positions.forEach((position) => { + positionHistory.push({ + node_id: position.node_id, + latitude: position.latitude, + longitude: position.longitude, + altitude: position.altitude, + created_at: position.created_at, + }); + }); + + mapReports.forEach((mapReport) => { + positionHistory.push({ + node_id: mapReport.node_id, + latitude: mapReport.latitude, + longitude: mapReport.longitude, + altitude: mapReport.altitude, + created_at: mapReport.created_at, + }); + }); + + // sort oldest to newest + positionHistory.sort((a, b) => a.created_at - b.created_at); + + res.json({ + position_history: positionHistory, + }); + + } catch(err) { + console.error(err); + res.status(500).json({ + message: "Something went wrong, try again later.", + }); + } +}); + app.get('/api/v1/stats/hardware-models', async (req, res) => { try { diff --git a/src/mqtt.js b/src/mqtt.js index e5808bc..137129e 100644 --- a/src/mqtt.js +++ b/src/mqtt.js @@ -135,11 +135,11 @@ const mqttUsername = options["mqtt-username"] ?? "meshdev"; const mqttPassword = options["mqtt-password"] ?? "large4cats"; const mqttTopic = options["mqtt-topic"] ?? "msh/#"; const collectServiceEnvelopes = options["collect-service-envelopes"] ?? false; -const collectPositions = options["collect-positions"] ?? false; +const collectPositions = options["collect-positions"] ?? true; const collectTextMessages = options["collect-text-messages"] ?? false; const collectWaypoints = options["collect-waypoints"] ?? true; const collectNeighbourInfo = options["collect-neighbour-info"] ?? false; -const collectMapReports = options["collect-map-reports"] ?? false; +const collectMapReports = options["collect-map-reports"] ?? true; const decryptionKeys = options["decryption-keys"] ?? [ "1PG7OiApB1nwvP+rz05pAQ==", // add default "AQ==" decryption key ]; diff --git a/src/public/index.html b/src/public/index.html index 10bf900..f27e51e 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -66,6 +66,12 @@ border: 1px solid white; } + .icon-position-history { + background-color: #a855f7; + border-radius: 25px; + border: 1px solid white; + } + .waypoint-label { font-size: 26px; background-color: transparent; @@ -748,7 +754,14 @@