commit 12aefa88e3f55ed1ed97601dbad6d8cef53a40ec
parent 523faaf082f6f804d77678746952315e8882ea9d
Author: Friedel Schön <[email protected]>
Date: Fri, 1 Jul 2022 01:12:25 +0200
last demo round-up
Diffstat:
33 files changed, 270 insertions(+), 532 deletions(-)
diff --git a/.vscode/arduino.json b/.vscode/arduino.json
@@ -1,6 +1,6 @@
{
"sketch": "client/client.ino",
"board": "SODAQ:samd:sodaq_sara",
- "port": "/dev/tty.usbmodem14201",
+ "port": "/dev/tty.usbmodem14101",
"output": "build"
}
\ No newline at end of file
diff --git a/client/client.ino b/client/client.ino
@@ -28,9 +28,12 @@ void setup() {
if (!config.valid)
config = config_default;
+ writeLED(COLOR_RED);
+ while (!usbSerial)
+ ;
+
do {
- writeLED(COLOR_RED);
- delay(2500);
+ delay(1000);
client.request["token"] = config.token;
client.request["domain"] = config.domain;
} while (!client.send(interface::METHOD_POST, "/api/hello"));
diff --git a/client/include/config.h b/client/include/config.h
@@ -31,9 +31,9 @@
#define commandTimeout 10 // seconds to cancel a command
#define commandDelay 0.1 // delay after every command
#define ignoreDelay 2 // seconds to wait if command is run with COMMAND_IGNORE
-#define gpsTimeout 30 // seconds to gps-timeout
-#define statusInterval 60 // send status every n seconds
-#define loopDelay 10 // seconds to wait each loop()
+#define gpsTimeout 20 // seconds to gps-timeout
+#define statusInterval 10 // send status every n seconds
+#define loopDelay 5 // seconds to wait each loop()
// -*- battery stuff -*-
#define adcAREF 3.3
diff --git a/client/interface.ino b/client/interface.ino
@@ -52,8 +52,7 @@ void interface::beginRemote() {
if (remoteReady) // already initalizised
return;
- if (!usbSerial)
- return;
+ delay(2500);
sendToken();
diff --git a/create-db.py b/create-db.py
@@ -5,8 +5,8 @@ from server.models import User
TOKEN_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'
users = [
- (1, False, 'Boer Herman', '[email protected]', 2),
- (2, True, 'Administrator Ralf', '[email protected]', None),
+ # (1, False, 'Boer Herman', '[email protected]', 2),
+ # (2, True, 'Administrator Ralf', '[email protected]', None),
]
address = 'Kerklaan 69\n9876XY Groningen'
diff --git a/directories.txt b/directories.txt
@@ -1,5 +0,0 @@
-/build - temporary build directory for Arduino IDE
-/client - arduino code for sara
-/dump - thing I don't want to delete but are unneeded
-/server - the main Flask server
-/ssl - https certificates
-\ No newline at end of file
diff --git a/server/templates/backup.html b/dump/backup.html
diff --git a/logo.png b/dump/logo.png
Binary files differ.
diff --git a/led-codes.txt b/led-codes.txt
@@ -1,7 +0,0 @@
-NONE = off
-CYAN = starting up
-
-BLUE = idle modem
-MAGENTA = idle remote
-YELLOW = idle modem with warnings
-RED = no interface
-\ No newline at end of file
diff --git a/make-admin.py b/make-admin.py
@@ -0,0 +1,12 @@
+from server.app import db
+from server.models import User
+import sys
+
+user = User.query.filter_by(email=sys.argv[1]).first()
+if not user:
+ print('not found')
+ exit(1)
+
+user.admin = True
+
+db.session.commit()
diff --git a/offline-trap.py b/offline-trap.py
@@ -0,0 +1,8 @@
+from datetime import timedelta
+from server.app import db
+from server.models import Trap
+
+for trap in Trap.query:
+ trap.last_status -= timedelta(hours=1)
+
+db.session.commit()
diff --git a/remote.py b/remote.py
@@ -14,7 +14,7 @@ import websockets
WEBSOCKET_PORT = 1612
-host, port = 'muizenval.tk', 80
+host, port = 'localhost', 5000
remote = Remote(115200)
token: Optional[str] = None
diff --git a/remote.txt b/remote.txt
@@ -1,7 +0,0 @@
-request: <command:string> <parameters:json>
-response: <status:string> [parameters:json]
-
-status:
-- ok
-- not-ready
-- not-connected
diff --git a/server/models.py b/server/models.py
@@ -78,6 +78,7 @@ class Trap(db.Model):
class Statistic(db.Model):
id: int = db.Column(db.Integer, primary_key=True)
user: int = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
+ trap: int = db.Column(db.Integer, db.ForeignKey('trap.id'), nullable=False)
date: datetime = db.Column(db.DateTime, nullable=False)
diff --git a/server/routes.py b/server/routes.py
@@ -12,23 +12,19 @@ import os
current_user: User
-""" index.html (home-page) route """
-
-
+# index.html (home-page) route
@app.route("/")
def index():
return render_template('index.html')
-
-""" home.html route """
+# about.html route
[email protected]("/home")
-def home():
- return render_template('home.html', title='Home')
[email protected]("/about")
+def about():
+ return render_template('about.html')
-
-""" register.html route """
+# register.html route
@app.route("/register", methods=['GET', 'POST'])
@@ -56,14 +52,7 @@ def register():
return render_template('register.html', title='Registeren', form=form)
[email protected]("/producten")
-def producten():
- return render_template('producten.html')
-
-
-""" login.html route """
-
-
+# login.html route
@app.route("/login", methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
@@ -84,18 +73,14 @@ def login():
return render_template('login.html', title='Inloggen', form=form)
-""" logout route """
-
-
+# logout route
@app.route("/logout")
def logout():
logout_user()
return redirect('/')
-""" save-picture function for account.html """
-
-
+# save-picture function for account.html
def save_picture(form_picture):
random_hex = secrets.token_hex(8)
_, f_ext = os.path.splitext(form_picture.filename)
diff --git a/server/site.db b/server/site.db
Binary files differ.
diff --git a/server/socket.py b/server/socket.py
@@ -1,6 +1,7 @@
from datetime import datetime
import os
import random
+import sys
from typing import Dict
from flask import request, jsonify
from flask_login import current_user
@@ -60,10 +61,11 @@ def update_status():
if not trap.caught and req['trap']:
if trap.owner:
- stc = Statistic(user=trap.owner, date=datetime.now())
+ stc = Statistic(user=trap.owner, trap=trap.id, date=datetime.now())
db.session.add(stc)
- os.system(
- f"echo \"<p>Uw muizenval '{trap.name}' heeft iets gevangen!<br>Ga naar <a href='http://muizenval.tk/traps'>uw dashboard</a>.</p><p>Groetjes Team Benni!</p>\" | mailx -a 'Content-Type: text/html' -s 'Muizenval is geactiveerd' {trap.owner_class().email}") # type: ignore
+ if os.environ.get('SEND_MAIL', '0') != '0':
+ os.system(
+ f"echo \"<p>Uw muizenval '{trap.name}' heeft iets gevangen!<br>Ga naar <a href='http://muizenval.tk/traps'>uw dashboard</a>.</p><p>Groetjes Team Benni!</p>\" | mailx -a 'Content-Type: text/html' -s 'Muizenval is geactiveerd' {trap.owner_class().email}") # type: ignore
print('Email sent!')
trap.last_status = datetime.now()
@@ -92,12 +94,15 @@ def update_status():
def make_statistics(user: int):
year = datetime.now().year
months = [0] * 12
+ table = []
stc: Statistic
for stc in Statistic.query.filter_by(user=user):
+ table.append([stc.id, Trap.query.get(stc.trap).name,
+ stc.date.strftime('%d-%m-%y %H:%M')])
if stc.date.year == year:
months[stc.date.month-1] += 1
- return months
+ return dict(months=months, table=table)
@socket.on('connect')
@@ -128,14 +133,13 @@ def socket_token(token):
return
trap: Trap = Trap.query.filter_by(token=token).first()
- if not trap or trap.owner == current_user.id:
- return
- trap.owner = current_user.id
- trap.owned_date = datetime.now()
- db.session.commit()
+ if trap.owner != current_user.id:
+ trap.owner = current_user.id
+ trap.owned_date = datetime.now()
+ db.session.commit()
- emit('trap-change', trap.to_json())
+ emit('trap-change', trap.to_json())
@socket.on('location-search')
@@ -164,7 +168,11 @@ def socket_delete(data):
if not trap or trap.owner != current_user.id:
return
+ Statistic.query.filter_by(trap=trap.id).delete()
+
trap.owner = False
+ trap.name = "n/a"
+
db.session.commit()
@@ -173,7 +181,6 @@ def socket_name(data):
if not data or not current_user.is_authenticated:
return
- print(data['id'])
trap: Trap = Trap.query.get(data['id'])
if not trap or trap.owner != current_user.id:
return
@@ -182,3 +189,15 @@ def socket_name(data):
db.session.commit()
emit('trap-change', trap.to_json())
+
+
[email protected]('delete-statistic')
+def socket_delete_statistic(id: int):
+ if not id or not current_user.is_authenticated:
+ return
+
+ Statistic.query.filter_by(id=id).delete()
+
+ db.session.commit()
+
+ emit('statistics', make_statistics(current_user.id))
diff --git a/logo.png b/server/static/logo.png
Binary files differ.
diff --git a/server/static/main.css b/server/static/main.css
@@ -1,6 +1,6 @@
body {
background-color: #efefef;
- font-size:25px;
+ font-size:20px;
}
#side_nav{
@@ -18,10 +18,6 @@ body {
width:80%;
}
-.carousel .carousel-item {
-
-}
-
.carousel-item img {
max-width: 100%;
height: auto;
@@ -39,10 +35,11 @@ body {
margin-bottom: 20px;
}
-#kutcss{
+.picture-css{
width: 50%;
padding: 10px;
}
+
.account-img {
height: 125px;
width: 125px;
diff --git a/server/static/trap.js b/server/static/trap.js
@@ -19,9 +19,20 @@ trap {
}
*/
-const errorDelay = 2500;
+var map = L.map('trap-map'),
+ socket = io();
+
+let token = null,
+ remote = false,
+ traps = {},
+ markers = [];
+
+map.setView([52.283333, 5.666667], 7);
+L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+ attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
+}).addTo(map);
-function addTrap(trap) {
+socket.on('trap-change', function (trap) {
var clone,
append = false;
@@ -50,11 +61,12 @@ function addTrap(trap) {
else if (trap.activated) (statusIcon = 'circle-exclamation'), (statusString += 'geactiveerd');
else (statusIcon = 'clock'), (statusString += 'wachtend');
statusIcons += `<i class='fas fa-${statusIcon}'></i>`;
+ // clone.style.background = '#bdecb6';
clone.style.background = '#ffffff';
if (!trap.offline) {
if (trap.activated) {
- clone.style.background = '#e8dcca';
+ clone.style.background = '#aec6cf';
}
if (trap.charging) (batteryIcon = 'plug-circle-bolt'), (statusString += ', aan het opladen');
else if (trap.battery == 0) batteryIcon = 'battery-empty';
@@ -136,52 +148,19 @@ function addTrap(trap) {
traps[trap.id].marker.remove();
traps[trap.id].marker = undefined;
}
-}
+});
-function removeTrap(trap) {
+socket.on('trap-remove', function (trap) {
if (traps[trap.id].marker) traps[trap.id].marker.remove();
traps[trap.id].element.remove();
delete traps[trap.id];
-}
-
-function openWebSocket() {
- let ws = new WebSocket('ws://localhost:1612/');
- ws.addEventListener('open', () => ws.send('token'));
- ws.addEventListener('message', (evt) => (token = evt.data));
- ws.addEventListener('close', () => {
- if (token) {
- socket.emit('token', token);
- remote = true;
- }
- });
- ws.addEventListener('error', () => {
- token = null;
- remote = false;
- setTimeout(openWebSocket, errorDelay);
- });
-}
-
-var map = L.map('trap-map'),
- socket = io();
-
-let token = null,
- remote = false,
- traps = {},
- markers = [];
-
-map.setView([52.283333, 5.666667], 7);
-L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
- attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
-}).addTo(map);
+});
-socket.on('trap-change', addTrap);
-socket.on('trap-remove', removeTrap);
-socket.on('statistics', function (months) {
+socket.on('statistics', function ({ table, months }) {
var chart = new CanvasJS.Chart('trap-chart', {
data: [
{
- // Change type to "doughnut", "line", "splineArea", etc.
type: 'column',
dataPoints: [
{ label: 'Januari', y: months[0] },
@@ -201,6 +180,34 @@ socket.on('statistics', function (months) {
],
});
chart.render();
+ var tbl = document.getElementById('trap-table');
+ tbl.innerHTML =
+ '<tr><th>Muizenval</th><th>Datum</th><th></th></tr>' +
+ table.map(([id, name, date]) => `<tr><td>${name}</td><td>${date}</td><td><a href="javascript:deleteStc(${id})">verwijderen</a></td></tr>`).join('\n');
});
-openWebSocket();
+function deleteStc(id) {
+ socket.emit('delete-statistic', id);
+}
+
+function websocket() {
+ let ws = new WebSocket('ws://localhost:1612/');
+ ws.addEventListener('open', () => ws.send('token'));
+ ws.addEventListener('message', (evt) => (token = evt.data));
+ ws.addEventListener('close', () => {
+ if (token) {
+ socket.emit('token', token);
+ remote = true;
+ } else {
+ remote = false;
+ }
+ });
+ ws.addEventListener('error', () => {
+ token = null;
+ remote = false;
+ });
+}
+
+setInterval(websocket, 10000);
+
+websocket();
diff --git a/server/templates/about.html b/server/templates/about.html
@@ -2,29 +2,34 @@
{% block content %}
<article class="media content-section">
<div class="media-body">
- <h2>Over ons</h2>
- <p>
- <h6>Wie zijn wij?</h6>
- Wij zijn een groep ICT studenten aan de Hanze Hogeschool die in samenwerking met 5Groningen een Slimme muizenval hebben ontwikkelt. 5Groningen is een programma waarin experts samen werken met ondernemers en non-profitorganisaties om toepassingen van 5G te testen.
-
- </p>
- <p>
- <h6>Reden voor dit project?</h6>
- Op de boerderij wordt er steeds diervriendelijker gewerkt en wordt er steeds bewuster omgegaan met bestrijdingsmiddelen.
- Daarnaast wordt de wetgeving ook steeds aangescherpt m.b.t. welke bestrijdingsmiddelen gebruikt mogen worden en in welke hoeveelheden (vanaf 2023 mag alleen bestreden worden als er aantoonbaar knaagdieren zijn).
- Het bestrijden van ongedierte met gif wordt dus steeds lastiger qua wetgeving en diervriendelijkheid.
- Toch moet de dieren (ratten en muizen) gevangen worden.
-
- </p>
- <p>
- <h6>Benni</h6>
- Het idee was om een muizenval te creëren die zodra er iets gevangen wordt een bericht stuurt naar de eigenaar van een val.
- In het bericht wordt de locatie van de val, en een foto meegestuurd van de inhoud.
- Ook kunnen de muizenvallen gemonitord worden via een dashboard op onze site.
- </p>
- <p>
- Voor meer informatie neem contact met ons op.
- </p>
+ <h1>Over ons</h2>
+ <p>
+ <h3>Wie zijn wij?</h3>
+ Wij zijn een groep ICT studenten aan de Hanze Hogeschool die in samenwerking met 5Groningen een Slimme
+ muizenval hebben ontwikkelt. 5Groningen is een programma waarin experts samen werken met ondernemers en
+ non-profitorganisaties om toepassingen van 5G te testen.
+
+ </p>
+ <h3>Reden voor dit project?</h3>
+ <p>
+ Op de boerderij wordt er steeds diervriendelijker gewerkt en wordt er steeds bewuster omgegaan met
+ bestrijdingsmiddelen.
+ Daarnaast wordt de wetgeving ook steeds aangescherpt m.b.t. welke bestrijdingsmiddelen gebruikt mogen
+ worden en in welke hoeveelheden (vanaf 2023 mag alleen bestreden worden als er aantoonbaar knaagdieren
+ zijn).
+ Het bestrijden van ongedierte met gif wordt dus steeds lastiger qua wetgeving en diervriendelijkheid.
+ Toch moet de dieren (ratten en muizen) gevangen worden.
+ </p>
+ <h3>Benni</h3>
+ <p>
+ Het idee was om een muizenval te creëren die zodra er iets gevangen wordt een bericht stuurt naar de
+ eigenaar van een val.
+ In het bericht wordt de locatie van de val, en een foto meegestuurd van de inhoud.
+ Ook kunnen de muizenvallen gemonitord worden via een dashboard op onze site.
+ </p>
+ <p>
+ Voor meer informatie neem contact met ons op.
+ </p>
</div>
</article>
{% endblock content %}
\ No newline at end of file
diff --git a/server/templates/admin.html b/server/templates/admin.html
@@ -1,27 +1,29 @@
{% extends "layout.html" %}
{% block content %}
-<h1>Rechten bewerken!</h1>
-<div class="content-section">
- <form method="POST" action="">
- {{ form.hidden_tag() }}
- <fieldset class="form-group">
- <legend class="border-bottom mb-4">Zoeken</legend>
- <div class="form-group">
- {{ form.username.label(class="form-control-label") }}
- {% if form.username.errors %}
- {{ form.username(class="form-control form-control-lg is-invalid") }}
- <div class="invalid-feedback">
- {% for error in form.username.errors %}
- <span>{{ error }}</span>
- {% endfor %}
+<article class="media content-section">
+ <div class="media-body">
+ <h1>Rechten bewerken!</h1>
+ <form method="POST" action="">
+ {{ form.hidden_tag() }}
+ <fieldset class="form-group">
+ <legend class="border-bottom mb-4">Zoeken</legend>
+ <div class="form-group">
+ {{ form.username.label(class="form-control-label") }}
+ {% if form.username.errors %}
+ {{ form.username(class="form-control form-control-lg is-invalid") }}
+ <div class="invalid-feedback">
+ {% for error in form.username.errors %}
+ <span>{{ error }}</span>
+ {% endfor %}
+ </div>
+ {% else %}
+ {{ form.username(class="form-control form-control-lg") }}
+ {% endif %}
</div>
- {% else %}
- {{ form.username(class="form-control form-control-lg") }}
- {% endif %}
+ </fieldset>
+ <div class="form-group">
+ {{ form.submit(class="btn btn-outline-info") }}
</div>
- </fieldset>
- <div class="form-group">
- {{ form.submit(class="btn btn-outline-info") }}
- </div>
-</div>
+ </div>
+</article>
{% endblock content %}
\ No newline at end of file
diff --git a/server/templates/connect.html b/server/templates/connect.html
@@ -1,33 +0,0 @@
-{% extends "layout.html" %}
-{% block content %}
-<article class="media content-section">
-<div class="media-body">
- <h1>Verbind een muizenval</h1>
- <p>Press the connect-button and enter the MAC-address of your trap:</p>
- <form method="POST" action="">
- {{ form.hidden_tag() }}
- <fieldset class="form-group">
- <legend class="border-bottom mb-4">
- <h1>{{ legend }}</h1>
- </legend>
- <div class="form-group">
- {{ form.mac.label(class="form-control-label") }}
- {% if form.mac.errors %}
- {{ form.mac(class="form-control form-control-lg is-invalid") }}
- <div class="invalid-feedback">
- {% for error in form.mac.errors %}
- <span>{{ error }}</span>
- {% endfor %}
- </div>
- {% else %}
- {{ form.mac(class="form-control form-control-lg form-code") }}
- {% endif %}
- </div>
- </fieldset>
- <div class="form-group">
- {{ form.submit(class="btn btn-outline-info") }}
- </div>
- </form>
-</div>
-</article>
-{% endblock content %}
-\ No newline at end of file
diff --git a/server/templates/home.html b/server/templates/home.html
diff --git a/server/templates/index.html b/server/templates/index.html
@@ -1,7 +1,7 @@
{% extends "layout.html" %}
{% block content %}
-<div id="carouseldiv">
- <div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
+<div style="padding:50px; background: #fff;">
+ <div id="product-slide" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="{{url_for('static', filename='product_pics/3.jpeg')}}" alt="First slide">
@@ -16,80 +16,89 @@
<img class="d-block w-100" src="{{url_for('static', filename='product_pics/4.jpeg')}}" alt="Second slide">
</div>
</div>
- <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
+ <a class="carousel-control-prev" href="#product-slide" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
- <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
+ <a class="carousel-control-next" href="#product-slide" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
-</div>
-<div class="d-flex flex-column">
- <div class="p-2">
- <article>
- Benni is dé grote hulp voor Groninger boeren om inzicht te krijgen in het ongedierte op hun erf. Alle door een netwerk van slimme vallen verzamelde data worden weergegeven op het persoonlijke dashboard. Benni verstuurt via 5G een mail als er iets gevangen is.
- </article>
- </div>
- <div class="p-2">
- <div class="d-flex flex-row">
- <div class="p-2" id="kutcss">
- <img class="flex-img" src="{{url_for('static', filename='product_pics/dash1.jpg')}}" alt="somethign">
- </div>
- <div class="p-2" id="kutcss">
- <h6>Functionaliteiten</h6></br>
- </br>
- GPS</br>
- 5G</br>
- Werkt op batterij</br>
- Dashboard met actuele informatie</br>
- Statistieken</br>
- Logboek</br>
- Melding als er een val is afgegaan</br>
- Goedkoop</br>
- Energiezuinig</br>
- </div>
+ <div class="d-flex flex-column">
+ <div class="p-2">
+ <article>
+ Benni is dé grote hulp voor Groninger boeren om inzicht te krijgen in het ongedierte op hun erf. Alle door een
+ netwerk van slimme vallen verzamelde data worden weergegeven op het persoonlijke dashboard. Benni verstuurt via
+ 5G een mail als er iets gevangen is.
+ </article>
</div>
- </div>
- <div class="p-2">
- <div class="d-flex flex-row">
- <div class="p-2" id="kutcss">
- <h6>Kopen of huren?</h6></br>
- </br>
- - Huren: hiervoor betaalt u maandelijks een vast bedrag van €20,- plus €1,- per val. U heeft de vallen in bruikleen en ontvangt extra service, zoals technische ondersteuning. </br>
- </br>
- - Kopen: een val kost €17,50 per stuk.
+ <div class="p-2">
+ <div class="d-flex flex-row">
+ <div class="p-2 picture-text">
+ <img class="flex-img" src="{{url_for('static', filename='product_pics/dash1.jpg')}}" alt="somethign">
+ </div>
+ <div class="p-2 picture-text">
+ <h2>Functionaliteiten</h2>
+ <ul>
+ <li>GPS</li>
+ <li>5G</li>
+ <li>Werkt op batterij</li>
+ <li>Dashboard met actuele informatie</li>
+ <li>Statistieken</li>
+ <li>Logboek</li>
+ <li>Melding als er een val is afgegaan</li>
+ <li>Goedkoop</li>
+ <li>Energiezuinig</li>
+ </ul>
+ </div>
</div>
- <div class="p-2" id="kutcss">
- <img class="flex-img" src="{{url_for('static', filename='product_pics/dash2.jpg')}}" alt="somethign">
+ </div>
+ <div class="p-2">
+ <div class="d-flex flex-row">
+ <div class="p-2 picture-text">
+ <h2>Kopen of huren?</h2>
+
+ <ul>
+ <li>Huren: hiervoor betaalt u maandelijks een vast bedrag van €20,- plus €1,- per val.<br> U heeft de vallen
+ in
+ bruikleen en ontvangt extra service, zoals technische ondersteuning.</li>
+ <li>Kopen: een val kost €17,50 per stuk.</li>
+ </ul>
+ </div>
+ <div class="p-2 picture-text">
+ <img class="flex-img" src="{{url_for('static', filename='product_pics/dash2.jpg')}}" alt="somethign">
+ </div>
</div>
</div>
- </div>
- <div class="p-2">
- <div class="d-flex flex-row">
- <div class="p-2" id="kutcss">
- <h6>Beveiliging</h6></br>
- </br>
- - Hashing</br>
- - communicatie vanuit server</br>
- - verschillende lagen (rechten)</br>
+ <div class="p-2">
+ <div class="d-flex flex-row">
+ <div class="p-2 picture-text">
+ <h2>Beveiliging</h2>
+
+ <ul>
+ <li>Hashing</li>
+ <li>communicatie vanuit server</li>
+ <li>verschillende lagen (rechten)</li>
+ </ul>
+ </div>
</div>
</div>
- </div>
- <div class="p-2">
- <div class="d-flex flex-row">
- <div class="p-2" id="kutcss">
- <h6>Foutpreventie</h6></br>
- </br>
- - Melding als de gemeten temperatuur hoger dan 50 graden is of onder de -10 graden</br>
- - Dashboard geeft aan of er problemen zijn met de batterij</br>
- - Val is te koppelen via USB</br>
- - Boardje en batterij waterdicht en stofvrij opgeborgen</br>
- - Sensor bestand tegen stof en water</br>
+ <div class="p-2">
+ <div class="d-flex flex-row">
+ <div class="p-2 picture-text">
+ <h2>Foutpreventie</h2>
+ <ul>
+ <li>Melding als de gemeten temperatuur hoger dan 50 graden is of onder de -10 graden</li>
+ <li>Dashboard geeft aan of er problemen zijn met de batterij</li>
+ <li>Val is te koppelen via USB</li>
+ <li>Boardje en batterij waterdicht en stofvrij opgeborgen</li>
+ <li>Sensor bestand tegen stof en water</li>
+ </ul>
+ </div>
+ </div>
</div>
</div>
-</div>
-
+</div>
{% endblock content %}
\ No newline at end of file
diff --git a/server/templates/layout.html b/server/templates/layout.html
@@ -20,9 +20,7 @@
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}">
- <!-- Bootstrap CSS
- <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css" rel="stylesheet">
- <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" />-->
+ <!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"
integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
@@ -47,12 +45,6 @@
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript" charset="utf-8">
- {% if user_token %}
- var userToken = {{ user_token | tojson }};
- {% else %}
- var userToken = null;
- {% endif %}
-
$('.dropdown-toggle').dropdown()
$(document).ready(function () {
@@ -81,11 +73,17 @@
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('traps') }}" class="text-decoration-none px-3 py-2 d-block text-white"><i
class="fas fa-chart-line"></i> Dashboard</a></li>
+ {% if current_user.admin %}
+ <li><a href="{{ url_for('admin') }}" class="text-decoration-none px-3 py-2 d-block text-white"><i
+ class="fas fa-users"></i> Gebruikers</a></li>
+ {% else %}
<li><a href="{{ url_for('contact') }}" class="text-decoration-none px-3 py-2 d-block text-white"><i
- class="far fa-address-book"></i> Contact opnemen</a></li>
+ class="fas fa-address-book"></i> Contact</a></li>
+
+ {% endif %}
{% endif %}
- <li><a href="#" class="text-decoration-none px-3 py-2 d-block text-white"><i
+ <li><a href="{{ url_for('about') }}" class="text-decoration-none px-3 py-2 d-block text-white"><i
class="far fa-clipboard"></i> Over ons</a></li>
</ul>
@@ -93,7 +91,9 @@
<ul class="list-unstyled px-2">
{% if current_user.is_authenticated %}
-
+ <li class=""><a href="{{ url_for('account') }}"
+ class="text-decoration-none px-3 py-2 d-block text-white"><i class="fas fa-wrench"></i>
+ Instellingen</a></li>
<li class=""><a href="{{ url_for('logout') }}"
class="text-decoration-none px-3 py-2 d-block text-white"><i
class="fas fa-arrow-right-from-bracket"></i>
diff --git a/server/templates/producten.html b/server/templates/producten.html
@@ -1,71 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-<article class="media content-section">
-
- <div class="media-body">
- <h2> Muizenvallen</h2>
-
- <p>Kies hier uit de meerdere artikelen die we ter beschikking hebben.</p>
-
- </div>
-
-</article>
-
-<!DOCTYPE html>
-<html>
-
-<head>
- <style>
- div.gallery {
- margin: 5px;
- border: 1px solid #ccc;
- float: left;
- width: 220px;
- }
-
- div.gallery:hover {
- border: 1.5px solid #777;
- }
-
- div.gallery img {
- width: 100%;
- height: auto;
- }
-
- div.title {
- padding: 5px;
- text-align: center;
- font-size: 20px;
-
- font-weight: bold;
- }
-
- div.desc {
- padding: 7px;
- text-align: center;
- font-size: 12px;
-
- }
- </style>
-
-
-</head>
-
-<body>
- <div class="gallery">
- <!---- <a target="_blank" href=""> -->
- <img src="../static/product_pics/muizenval1.jpg" alt="Cinque Terre" width="800" height="600">
- </a>
- <div class="title">slimme muizenval 3000</div>
- <div class="desc">De gekste muizenval ter wereld!! (source: trust me bro)</div>
-
- </div>
-
-
-
-</body>
-
-</html>
-
-{% endblock content %}
-\ No newline at end of file
diff --git a/server/templates/trap.html b/server/templates/trap.html
@@ -13,6 +13,17 @@
<div id="trap-chart"></div>
</div>
</article>
+ <article class="media content-section">
+ <div class="media-body">
+ <h2 style="text-align: center;">activiteiten logboek</h2>
+ <div class="collapse" id="trap-collapse">
+ <table id="trap-table" class="table"></table>
+ </div>
+ <hr>
+ <div style="text-align: center;"><a data-toggle="collapse" href="#trap-collapse" role="button"
+ aria-expanded="false" aria-controls="trap-collapse">logboek openen/sluiten</a></div>
+ </div>
+ </article>
</div>
<template id="trap-template">
<article class="media content-section">
diff --git a/server/templates/updatetrap.html b/server/templates/updatetrap.html
@@ -1,30 +0,0 @@
-{% extends "layout.html" %}
-{% block content %}
-<div class="content-section">
- <form method="POST" action="">
- {{ form.hidden_tag() }}
- <fieldset class="form-group">
- <legend class="border-bottom mb-4">
- <h1>{{ legend }}</h1>
- </legend>
- <div class="form-group">
- {{ form.name.label(class="form-control-label") }}
- {% if form.name.errors %}
- {{ form.name(class="form-control form-control-lg is-invalid") }}
- <div class="invalid-feedback">
- {% for error in form.name.errors %}
- <span>{{ error }}</span>
- {% endfor %}
- </div>
- {% else %}
- {{ form.name(class="form-control form-control-lg") }}
- {% endif %}
- </div>
- </fieldset>
- <div class="form-group">
- {{ form.submit(class="btn btn-outline-info") }}
- <a class="btn btn btn-danger" href="{{ url_for('trap_delete', trap_id=trap.id) }}">Verwijderen</a>
- </div>
- </form>
-</div>
-{% endblock content %}
-\ No newline at end of file
diff --git a/ssl/muizenval.tk.issuer.crt b/ssl/muizenval.tk.issuer.crt
@@ -1,63 +0,0 @@
-
------BEGIN CERTIFICATE-----
-MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
-TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
-WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
-RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
-R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
-sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
-NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
-Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
-/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
-AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
-Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
-FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
-AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
-Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
-gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
-PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
-ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
-CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
-lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
-avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
-yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
-yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
-hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
-HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
-MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
-nLRbwHOoq7hHwg==
------END CERTIFICATE-----
-
------BEGIN CERTIFICATE-----
-MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
-MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
-DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
-TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
-AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
-ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
-wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
-LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
-4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
-bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
-sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
-Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
-FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
-SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
-PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
-TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
-SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
-c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
-+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
-ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
-b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
-U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
-MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
-5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
-9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
-WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
-he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
-Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
------END CERTIFICATE-----
diff --git a/ssl/private.key b/ssl/private.key
@@ -1,6 +0,0 @@
------BEGIN EC PRIVATE KEY-----
-MIGkAgEBBDBIlNtB1IyZMxaGnYWuJP9mQ2ftm0evXty/jUnitnr8Zpe3neyFF+c4
-Jy7ayOycnTegBwYFK4EEACKhZANiAAQ6MBrVC6MjKRf2dEZp3VQ/qHxwzwU98wtZ
-arOaRBHCVbyqX2ZVWbvmcc7JoyIYGcxfB33cdPP0W7RQGyx6Z6PHnnvQlVjlB5TE
-39eKCvQox8RcojrfqfcPjyGju8fIoPg=
------END EC PRIVATE KEY-----
diff --git a/ssl/public.crt b/ssl/public.crt
@@ -1,89 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEcDCCA1igAwIBAgISA7joNosNzihXp9wQ3+fOqebqMA0GCSqGSIb3DQEBCwUA
-MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
-EwJSMzAeFw0yMjA2MjcxMjE2NDNaFw0yMjA5MjUxMjE2NDJaMBcxFTATBgNVBAMT
-DG11aXplbnZhbC50azB2MBAGByqGSM49AgEGBSuBBAAiA2IABDowGtULoyMpF/Z0
-RmndVD+ofHDPBT3zC1lqs5pEEcJVvKpfZlVZu+ZxzsmjIhgZzF8Hfdx08/RbtFAb
-LHpno8eee9CVWOUHlMTf14oK9CjHxFyiOt+p9w+PIaO7x8ig+KOCAkcwggJDMA4G
-A1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYD
-VR0TAQH/BAIwADAdBgNVHQ4EFgQUvFk8cm2DlCWQ9zFJH0QyHEp5C8YwHwYDVR0j
-BBgwFoAUFC6zF7dYVsuuUAlA5h+vnYsUwsYwVQYIKwYBBQUHAQEESTBHMCEGCCsG
-AQUFBzABhhVodHRwOi8vcjMuby5sZW5jci5vcmcwIgYIKwYBBQUHMAKGFmh0dHA6
-Ly9yMy5pLmxlbmNyLm9yZy8wFwYDVR0RBBAwDoIMbXVpemVudmFsLnRrMEwGA1Ud
-IARFMEMwCAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0
-dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDw
-AHYAQcjKsd8iRkoQxqE6CUKHXk4xixsD6+tLx2jwkGKWBvYAAAGBpU6lMgAABAMA
-RzBFAiBMQzJycnsDwp9Vn8kpFdwjrKR13B6Qkj8fwu6ZgQvVJwIhAL3l6NXN275b
-maqxb7J2mPMEzJQbYSbgj6XoiWI8kVvjAHYAKXm+8J45OSHwVnOfY6V35b5XfZxg
-Cvj5TV0mXCVdx4QAAAGBpU6nHAAABAMARzBFAiAubKyl9xQtz784YfNyfU/0uJXS
-Bg79MLRAXFhP0DPQFAIhAOr9lT8MZBHiJ423KNmUhZe7z8YsJVBwjCeM7rusRbp7
-MA0GCSqGSIb3DQEBCwUAA4IBAQBMZB2GMQ20cbjCEjPt8BGi6JD52riue8vH9uQk
-17UrlwGH4tJbdL02XtDyYsTePG7XxPVpJiewYkI9qJQh1IuTV22f+C1Jd0V2YupF
-2AYt17C+CD27e8ptS9JD7lZhFFXnQRvIO+nTBaN+QzyUkfFR5+MjjYV0jLvLvTsn
-dguTkE+4uZ8HFGn0uhTmPL4Qw/Dm8O3oIXLPgmcWSYXiSbSfvqlMGyOgL1eZlvMA
-gkpMdgYDYVbecEs9QnHkkH7aHzbK/D7IqVnQW2NZnb4hMHeassT9ex9O1wXG0Ydz
-wRqzA47R8txfIVDutn0o24yowSo39WySQgxriuL5YnDeZY6G
------END CERTIFICATE-----
-
------BEGIN CERTIFICATE-----
-MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
-TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
-WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
-RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
-R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
-sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
-NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
-Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
-/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
-AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
-Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
-FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
-AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
-Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
-gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
-PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
-ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
-CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
-lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
-avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
-yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
-yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
-hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
-HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
-MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
-nLRbwHOoq7hHwg==
------END CERTIFICATE-----
-
------BEGIN CERTIFICATE-----
-MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
-MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
-DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
-TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
-AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
-ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
-wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
-LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
-4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
-bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
-sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
-Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
-FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
-SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
-PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
-TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
-SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
-c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
-+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
-ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
-b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
-U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
-MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
-5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
-9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
-WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
-he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
-Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
------END CERTIFICATE-----
diff --git a/test.py b/test.py
@@ -1,4 +0,0 @@
-from remote import Remote
-
-for port in Remote.list_ports():
- print(f'{port.name} at {port.device} ({port.description})')