Merge remote-tracking branch 'origin/master'

# Conflicts:
#	flask_app/Dockerfile
#	flask_app/requirements.txt
This commit is contained in:
Kyle Gabriel 2021-04-23 15:03:57 -04:00
commit 1dc8b06537
4 changed files with 85 additions and 9 deletions

View file

@ -26,6 +26,8 @@ Successfully built this on the Raspberry Pi (Raspbian Buster) and a desktop PC (
- Measuring tool for measure distances between points
- Map stays focused on the same point across page refreshes
- Clicking gateway or data point markers pops up information about them
- Toggle visibility of markers of each device on map
- Select age of markers to show on map
### TODO
@ -40,19 +42,20 @@ Make sure you have your application set up on The Things Network with the integr
### Install dependencies
```
sudo apt-get install libffi-dev libssl-dev
sudo apt-get install -y libffi-dev libssl-dev
```
### Install docker and docker-compose
```
curl -sSL https://get.docker.com | sh
sudo pip install docker-compose
sudo apt-get install -y python3 python3-pip
sudo pip3 install docker-compose
```
### Add user to docker group
```sudo usermod -a -G docker YOUR_USER```
```sudo usermod -a -G docker $USER```
Then log out and back in again.

View file

@ -91,6 +91,7 @@ def main_page():
get_new_data()
return render_template('map.html',
bing_api_key=bing_api_key,
devices=devices,
gateway_locations=gateway_locations,
location_data=Location.query.all(),
refresh_period_seconds=refresh_period_seconds,
@ -122,8 +123,11 @@ def get_new_data():
endpoint = "https://{app}.data.thethingsnetwork.org/api/v2/query/{dev}?last={time}".format(
app=application, dev=each_device, time="{}s".format(past_seconds))
logger.info(endpoint)
headers = {"Authorization": app_key}
key = 'key {}'.format(app_key)
headers = {'Authorization': key, 'Content-Type': 'application/json'}
response = requests.get(endpoint, headers=headers)
if response.status_code != 200:
logger.info(response.reason)
try:
for each_resp in response.json():
if (not Location.query.filter(Location.datetime == each_resp['time']).first() and

View file

@ -11,7 +11,7 @@ start_lon = -77.855346
# TTN Application
application = "ttn_application"
app_key = "key ttn-account-TTN_APP_KEY"
app_key = "ttn-account-TTN_APP_KEY"
# Application devices
devices = [

View file

@ -58,8 +58,7 @@
var default_zoom = true;
b = JSON.parse(localStorage.getItem('bounds'));
if (b == null)
{
if (b == null) {
map = L.map('mapid', {layers: [esri_Map]}).setView([{{start_lat}}, {{start_lon}}], 15);
}
else {
@ -78,7 +77,6 @@
//disable inertia because it is irritating and slow
map.options.inertia=false;
var measureControl = L.control.measure({
activeColor: '#FF0000',
completedColor: '#FF8000',
@ -112,6 +110,54 @@
var gateway = L.marker([{{each_gateway[1]}}, {{each_gateway[2]}}]).bindPopup('Gateway: {{each_gateway[0]}}<br />Lat/Lon: {{each_gateway[1]}}, {{each_gateway[2]}}').addTo(map);
{% endfor %}
var markers = {};
{% for each_device in devices %}
markers['{{each_device}}'] = new L.FeatureGroup();
map.addLayer(markers['{{each_device}}']);
{% endfor %}
var legend_age = L.control({position: 'topright'});
legend_age.onAdd = function(map) {
var div = L.DomUtil.create('div', 'info legend_age');
div.innerHTML = '<select>' +
'<option value="all">All markers</option>' +
'<option value="7day">Past 7 Days</option>' +
'<option value="1day">Past 1 Day</option>' +
'<option value="6hour">Past 6 Hours</option>' +
'<option value="1hour">Past 1 Hour</option>' +
'<option value="30min">Past 30 Min</option>' +
'</select>';
div.firstChild.onmousedown = div.firstChild.ondblclick = L.DomEvent.stopPropagation;
return div;
};
legend_age.addTo(map);
function toggleFunction(element) {
if (element.checked) {
map.addLayer(markers[element.value]);
} else {
map.removeLayer(markers[element.value]);
}
}
var legend_devices = L.control({position: 'topright'});
legend_devices.onAdd = function(map) {
var div = L.DomUtil.create('div');
div.innerHTML = `
<div class="leaflet-control-layers leaflet-control-layers-expanded">
<form>
{% for each_device in devices -%}
<div>
<input class="leaflet-control-layers-overlays" id="command"
onclick=toggleFunction(this) type="checkbox" value="{{each_device}}" checked>{{each_device}}</input>
</div>
{%- endfor %}
</form>
</div>`;
return div;
};
legend_devices.addTo(map);
function add_new_markers(past_seconds) {
var url = '/dsf673bh_past/' + past_seconds;
$.getJSON(url,
@ -121,13 +167,36 @@
var node = L.circleMarker([parseFloat(data[i]["latitude"]), parseFloat(data[i]["longitude"])], {
color: 'red',
radius: 5
}).bindPopup('Node: ' + data[i]["device_id"] + '<br />' + data[i]["datetime"] + '<br />Lat/Lon: ' + data[i]["latitude"] + ', ' + data[i]["longitude"] + '<br />Altitude: ' + data[i]["altitude"] + ' m, hdop: ' + data[i]["hdop"]).addTo(map);
});
node.bindPopup('Node: ' + data[i]["device_id"] + '<br />' + data[i]["datetime"] + '<br />Lat/Lon: ' + data[i]["latitude"] + ', ' + data[i]["longitude"] + '<br />Altitude: ' + data[i]["altitude"] + ' m, hdop: ' + data[i]["hdop"]);
markers[data[i]["device_id"]].addLayer(node);
}
}
}
);
}
$('select').change(function(){
for (var key in markers) {
map.removeLayer(markers[key]);
markers[key] = new L.FeatureGroup();
map.addLayer(markers[key]);
}
if ($(this).val() === "all") {
add_new_markers(0);
} else if ($(this).val() === "7day") {
add_new_markers(604800);
} else if ($(this).val() === "1day") {
add_new_markers(86400);
} else if ($(this).val() === "6hour") {
add_new_markers(21600);
} else if ($(this).val() === "1hour") {
add_new_markers(3600);
} else if ($(this).val() === "30min") {
add_new_markers(1800);
}
});
// Repeat function for getLastData()
function repeat_add_new_markers(past_seconds) {
setInterval(function () {