first commit
All checks were successful
Meshtastic Map - See local Meshtastic Nodes / deploy (push) Successful in 1s
All checks were successful
Meshtastic Map - See local Meshtastic Nodes / deploy (push) Successful in 1s
This commit is contained in:
commit
92b5a0894d
30
.gitea/workflows/deploy.yml
Normal file
30
.gitea/workflows/deploy.yml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
name: Meshtastic Map - See local Meshtastic Nodes
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: pirf
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
run: |
|
||||||
|
cd ~/apps/mesh-map
|
||||||
|
git fetch
|
||||||
|
git checkout main
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
- name: Stop existing screen session, if running
|
||||||
|
run: |
|
||||||
|
if screen -list | grep -q "mesh_map_server"; then
|
||||||
|
echo "Stopping existing screen session..."
|
||||||
|
screen -S mesh_map_server -X quit
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Start server in screen session
|
||||||
|
run: |
|
||||||
|
cd ~/apps/mesh-map
|
||||||
|
setsid screen -dmS mesh_map_server bash -c 'python3 -m http.server 8083 > server.log 2>&1'
|
||||||
|
echo "Server started in detached screen session"
|
36
app.py
Normal file
36
app.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
from flask import Flask, render_template, jsonify
|
||||||
|
import meshtastic.serial_interface
|
||||||
|
import meshtastic
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
node_locations = {}
|
||||||
|
MY_NODE_ID = "!934f4430"
|
||||||
|
# MY_NODE_NUM = 2471445552
|
||||||
|
iface = meshtastic.serial_interface.SerialInterface()
|
||||||
|
# iface.nodes.clear()
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
def index():
|
||||||
|
return render_template("map.html")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/nodes")
|
||||||
|
def nodes():
|
||||||
|
data = {}
|
||||||
|
nodes = iface.nodes.items()
|
||||||
|
for node_id, node in nodes:
|
||||||
|
num = node.get('num')
|
||||||
|
user = node.get('user')
|
||||||
|
position = node.get('position')
|
||||||
|
deviceMetrics = node.get('deviceMetrics')
|
||||||
|
return jsonify({
|
||||||
|
# "myNodeNum": MY_NODE_NUM,
|
||||||
|
"myNodeId": MY_NODE_ID,
|
||||||
|
"nodes": dict(nodes)
|
||||||
|
})
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(host='0.0.0.0', port=5000)
|
83
templates/map.html
Normal file
83
templates/map.html
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Meshtastic Map</title>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="map" style="height: 100vh;"></div>
|
||||||
|
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||||
|
<script>
|
||||||
|
var map = L.map('map').setView([0, 0], 2);
|
||||||
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
||||||
|
let myCoords = null;
|
||||||
|
|
||||||
|
const getNodeDesc = (node) =>{
|
||||||
|
const deviceMetrics = node?.deviceMetrics
|
||||||
|
const hopsAway = node?.hopsAway ?? 'N/A';
|
||||||
|
const lastHeard = node?.lastHeard;
|
||||||
|
const num = node?.num;
|
||||||
|
const position = node?.position;
|
||||||
|
const snr = node?.snr ?? 'N/A';
|
||||||
|
const user = node?.user;
|
||||||
|
const lat = position?.latitude
|
||||||
|
const lon = position?.longitude
|
||||||
|
return `
|
||||||
|
Id: ${user.id}<br/>
|
||||||
|
Hops Away: ${hopsAway}<br/>
|
||||||
|
S/N: ${snr} dbM<br/>
|
||||||
|
Loc: ${lat}, ${lon}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const updateNodes= async() => {
|
||||||
|
const res = await fetch('/nodes');
|
||||||
|
const json = await res.json();
|
||||||
|
const myNodeId = json['myNodeId']
|
||||||
|
// const myNodeNum = json['myNodeNum']
|
||||||
|
const nodes = json['nodes']
|
||||||
|
|
||||||
|
let myNode = null;
|
||||||
|
// const my
|
||||||
|
// Object.entries(nodes).forEach()
|
||||||
|
|
||||||
|
Object.entries(nodes).forEach(([id, node]) => {
|
||||||
|
|
||||||
|
if (id == myNodeId) {
|
||||||
|
console.log("found")
|
||||||
|
myNode = node;
|
||||||
|
}
|
||||||
|
const deviceMetrics = node?.deviceMetrics
|
||||||
|
const hopsAway = node?.hopsAway;
|
||||||
|
const lastHeard = node?.lastHeard;
|
||||||
|
const num = node?.num;
|
||||||
|
const position = node?.position;
|
||||||
|
const snr = node?.snr;
|
||||||
|
const user = node?.user;
|
||||||
|
const lat = position?.latitude
|
||||||
|
const lon = position?.longitude
|
||||||
|
if (lat && lon) {
|
||||||
|
L.marker([lat, lon]).addTo(map)
|
||||||
|
.bindPopup(getNodeDesc(node));
|
||||||
|
if (id == myNodeId && myCoords != [lat, lon]) {
|
||||||
|
myCoords = [lat, lon];
|
||||||
|
map.setView([lat, lon], 15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
updateNodes();
|
||||||
|
center();
|
||||||
|
setInterval(updateNodes, 10000);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user