This commit is contained in:
jeanGaston 2024-04-30 13:50:33 +02:00
parent 8cc32d9279
commit eaee2e77c9
9 changed files with 337 additions and 17 deletions

11
.gitignore vendored
View File

@ -1,3 +1,14 @@
Program/__pycache__/env.cpython-311.pyc Program/__pycache__/env.cpython-311.pyc
Program/data.db Program/data.db
Program/env.py Program/env.py
Program/__pycache__/Webserver.cpython-311.pyc
Program/__pycache__/datascraper.cpython-311.pyc
Program/__pycache__/database.cpython-311.pyc
Program/__pycache__/database.cpython-311.pyc
Program/__pycache__/database.cpython-311.pyc
Program/__pycache__/database.cpython-311.pyc
Program/__pycache__/database.cpython-311.pyc
data.db
Program/__pycache__/database.cpython-311.pyc
Program/__pycache__/database.cpython-311.pyc
Program/__pycache__/database.cpython-311.pyc

View File

@ -0,0 +1,21 @@
#!/bin/bash
# Install Python3 and pip
sudo apt update
sudo apt install -y python3 python3-pip python3-flask python3-schedule
# Install required Python modules
pip3 install schedule
pip3 install bluepy
# Create env.py file
echo -n "Enter database file name (default: data.db): "
read db_file
db_file=${db_file:-data.db}
echo -e "DB_FILE = '$db_file'" > Program/env.py
# Execute main.py
cd Program
python3 main.py

49
Program/Webserver.py Normal file
View File

@ -0,0 +1,49 @@
import threading
from env import *
from flask import Flask, render_template
import sqlite3
app = Flask(__name__)
# Function to fetch data from the database
def fetch_all_data():
conn = sqlite3.connect(DBFILE)
c = conn.cursor()
c.execute("SELECT * FROM SensorData ")
data = c.fetchall()
conn.close()
data.reverse()
return data
# Function to fetch data from the database with the sensor name as a parameter
def fetch_data_by_sensor(sensor):
conn = sqlite3.connect(DBFILE)
c = conn.cursor()
c.execute("SELECT * FROM SensorData WHERE Sensor LIKE ? ", ('%' + sensor + '%',))
data = c.fetchall()
conn.close()
data.reverse()
return data
# Route to display the database contents
@app.route('/')
def dashboard():
data = fetch_all_data()[:5]
return render_template('index.html', data=data)
#Route to display the sensor history
@app.route('/history')
def history():
S1 = fetch_data_by_sensor("DEMO1")
S2 = fetch_data_by_sensor("DEMO2")
S3 = fetch_data_by_sensor("DEMO3")
return render_template('history.html', S1=S1, S2=S2, S3=S3)
def run_flask():
app.run()
def RunInThread_WebServer():
threading.Thread(target=run_flask, daemon=True).start()
if __name__ == '__main__':
app.run(debug=True)

View File

@ -9,7 +9,7 @@ def create_database(db_name):
# Create SensorData table # Create SensorData table
c.execute('''CREATE TABLE IF NOT EXISTS SensorData c.execute('''CREATE TABLE IF NOT EXISTS SensorData
(Id INTEGER PRIMARY KEY AUTOINCREMENT, (Id INTEGER PRIMARY KEY AUTOINCREMENT,
Sensor TEXT, FOREIGN KEY (Sensor) REFERENCES Sensors(Name),
Timestamp TEXT, Timestamp TEXT,
Temp INT, Temp INT,
HR INTEGER, HR INTEGER,
@ -17,8 +17,7 @@ def create_database(db_name):
# Create Sensors table # Create Sensors table
c.execute('''CREATE TABLE IF NOT EXISTS Sensors c.execute('''CREATE TABLE IF NOT EXISTS Sensors
(Id INTEGER PRIMARY KEY AUTOINCREMENT, (Mac TEXT RIMARY KEY,
Mac TEXT,
Name TEXT )''') Name TEXT )''')
conn.commit() conn.commit()

View File

@ -1,22 +1,34 @@
import schedule
import threading
import time
from env import * from env import *
from database import add_sensor_data from database import add_sensor_data
from bluepy.btle import Scanner from bluepy.btle import Scanner
def BltDataScrap(): def BltDataScrap():
scanner = Scanner() scanner = Scanner()
print("Begin device scan") #print("Begin device scan")
devices = scanner.scan(timeout=3.0) devices = scanner.scan(timeout=3.0)
for device in devices: for device in devices:
if device.addr in SENSORS : if device.addr in SENSORS :
print( #print(
f"Device found {device.addr} ({device.addrType}), " #f"Device found {device.addr} ({device.addrType}), "
f"RSSI={device.rssi} dB" #f"RSSI={device.rssi} dB"
) #)
for adtype, description, value in device.getScanData(): for adtype, description, value in device.getScanData():
if adtype == 22: if adtype == 22:
temp = int(value[24:28], 16) / 100 temp = int(value[24:28], 16) / 100
HR = int(value[28:32], 16) / 100 HR = int(value[28:32], 16) / 100
Bat = int(value[20:22], 16) Bat = int(value[20:22], 16)
print(f"Temp : {temp} °c \n HR : {HR} % , \n Batterie : {Bat} %") #print(f"Temp : {temp} °c \n HR : {HR} % , \n Batterie : {Bat} %")
add_sensor_data() add_sensor_data(DBFILE, SENSORS[device.addr], time.strftime("%Y-%m-%d %H:%M:%S"), temp, HR, Bat)
return 0
def RunInThread_DataScrap():
print("######################################################################\nOpen Thread datascrap")
threading.Thread(target=BltDataScrap, daemon=True).start()
def ScheduleDataScrap():
RunInThread_DataScrap()
schedule.every(10).seconds.do(RunInThread_DataScrap) #run every 10 seconds

View File

@ -1,4 +1,15 @@
from database import * from database import *
from datascraper import *
from Webserver import RunInThread_WebServer
from env import * from env import *
import schedule
check_database(DBFILE) check_database(DBFILE)
RunInThread_WebServer()
ScheduleDataScrap()
while True:
schedule.run_pending()
time.sleep(1)

View File

@ -0,0 +1,129 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Database Contents</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link rel="stylesheet" href="/css">
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.container {
max-width: 800px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
}
h1 {
text-align: center;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 8px;
text-align: left;
border-bottom: 1px solid #ddd;
}
tr:hover {
background-color: #f2f2f2;
}
.btn-container {
text-align: center;
margin-top: 20px;
}
.btn {
padding: 10px 20px;
font-size: 16px;
text-decoration: none;
color: #fff;
background-color: #007bff;
border: none;
border-radius: 5px;
cursor: pointer;
}
.btn:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<h1>Database Contents</h1>
<h2>Sensor 1</h2>
<table border="1">
<tr>
<th>Id</th>
<th>Sensor</th>
<th>Timestamp</th>
<th>Temp</th>
<th>HR</th>
<th>Bat</th>
</tr>
{% for row in S1 %}
<tr>
<td>{{ row[0] }}</td>
<td>{{ row[1] }}</td>
<td>{{ row[2] }}</td>
<td>{{ row[3] }}</td>
<td>{{ row[4] }}</td>
<td>{{ row[5] }}</td>
</tr>
{% endfor %}
</table>
<h2>Sensor 2</h2>
<table border="1">
<tr>
<th>Id</th>
<th>Sensor</th>
<th>Timestamp</th>
<th>Temp</th>
<th>HR</th>
<th>Bat</th>
</tr>
{% for row in S2 %}
<tr>
<td>{{ row[0] }}</td>
<td>{{ row[1] }}</td>
<td>{{ row[2] }}</td>
<td>{{ row[3] }}</td>
<td>{{ row[4] }}</td>
<td>{{ row[5] }}</td>
</tr>
{% endfor %}
</table>
<h2>Sensor 3</h2>
<table border="1">
<tr>
<th>Id</th>
<th>Sensor</th>
<th>Timestamp</th>
<th>Temp</th>
<th>HR</th>
<th>Bat</th>
</tr>
{% for row in S3 %}
<tr>
<td>{{ row[0] }}</td>
<td>{{ row[1] }}</td>
<td>{{ row[2] }}</td>
<td>{{ row[3] }}</td>
<td>{{ row[4] }}</td>
<td>{{ row[5] }}</td>
</tr>
{% endfor %}
</table>
<script>
// Refresh the page every 10 seconds
setTimeout(function(){
location.reload();
}, 20000);
</script>
</body>
</html>

View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sensor Data Dashboard</title>
<link rel="stylesheet" href="/css">
<style>body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.container {
max-width: 800px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
}
h1 {
text-align: center;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 8px;
text-align: left;
border-bottom: 1px solid #ddd;
}
tr:hover {
background-color: #f2f2f2;
}
.btn-container {
text-align: center;
margin-top: 20px;
}
.btn {
padding: 10px 20px;
font-size: 16px;
text-decoration: none;
color: #fff;
background-color: #007bff;
border: none;
border-radius: 5px;
cursor: pointer;
}
.btn:hover {
background-color: #0056b3;
}</style>
</head>
<body>
<div class="container">
<h1>Sensor Data Dashboard</h1>
<table>
<tr>
<th>Id</th>
<th>Sensor</th>
<th>Timestamp</th>
<th>Temp</th>
<th>HR</th>
<th>Bat</th>
</tr>
{% for row in data %}
<tr>
<td>{{ row[0] }}</td>
<td>{{ row[1] }}</td>
<td>{{ row[2] }}</td>
<td>{{ row[3] }}</td>
<td>{{ row[4] }}</td>
<td>{{ row[5] }}</td>
</tr>
{% endfor %}
</table>
<div class="btn-container">
<a href="/history" class="btn">View History</a>
<a href="/Admin" class="btn">Admin</a>
</div>
</div>
<script>
// Refresh the page every 10 seconds
setTimeout(function(){
location.reload();
}, 20000);
</script>
</body>
</html>