diff --git a/Program/Webserver.py b/Program/Webserver.py index ee3e4bb..3a54eec 100644 --- a/Program/Webserver.py +++ b/Program/Webserver.py @@ -1,44 +1,90 @@ +import csv +from datetime import datetime, timedelta import threading -from env import * -from flask import Flask, render_template -import sqlite3 +import requests +from env import * +from flask import Flask, render_template, request +import sqlite3 +from database import * 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 + +# Function to fetch outdoor temperature from Météo-France +def fetch_outdoor_temperature(): + # Format the date in the required format (YYYYMMDD) + formatted_csv_date = datetime.now().strftime("%Y%m%d%H") + print(formatted_csv_date) + # Construct the URL + url = f"https://donneespubliques.meteofrance.fr/donnees_libres/Txt/Synop/synop.{formatted_csv_date}.csv" + + # Make the HTTP GET request + response = requests.get(url) + print(response) + # Check if request was successful + try: + # Decode the content as UTF-8 and split into lines + lines = response.content.decode('utf-8').splitlines() + # Read the CSV data using csv.DictReader + reader = csv.DictReader(lines, delimiter=";") + + # Extract outdoor temperature from the CSV data + for row in reader: + if row['numer_sta'] == '07149': # + outdoor_temp = float(row['t']) + return round(outdoor_temp - 273.15, 1) #convert °K to °c + except: + print("Failed to fetch data from Météo-France.") + + + +# Appel de la fonction pour obtenir la température +temperature = fetch_outdoor_temperature() +print(temperature) + # Route to display the database contents @app.route('/') def dashboard(): data = fetch_all_data()[:5] - return render_template('index.html', data=data) + return render_template('index.html', data=data, temperature=temperature) #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) + data = fetch_all_sensor() + disp_data = [] + + for mac, name in data: + disp_data += [fetch_data_by_sensor(name)] + """ S1 = fetch_data_by_sensor("DEMO1") + S2 = fetch_data_by_sensor("DEMO2") + S3 = fetch_data_by_sensor("DEMO3") """ + + return render_template('history.html', S1=disp_data[0], S2=disp_data[1], S3=disp_data[2]) + +@app.route('/adm', methods=['GET', 'POST']) +def admin(): + if request.method == 'POST': + # Get form data + old_name = request.form['old_name'] + new_name = request.form['new_name'] + + # Update sensor name in the database + conn = sqlite3.connect(DBFILE) + c = conn.cursor() + print(old_name, new_name) + c.execute("UPDATE Sensors SET Name = ? WHERE mac = ?", (new_name, old_name)) + print() + conn.commit() + conn.close() + + + data = fetch_all_sensor() + print(data) + return render_template('admin.html', data=data, sensors=data) + def run_flask(): app.run() diff --git a/Program/__pycache__/database.cpython-311.pyc b/Program/__pycache__/database.cpython-311.pyc index 1f07046..58aa4c6 100644 Binary files a/Program/__pycache__/database.cpython-311.pyc and b/Program/__pycache__/database.cpython-311.pyc differ diff --git a/Program/database.py b/Program/database.py index ba36946..6950b1f 100644 --- a/Program/database.py +++ b/Program/database.py @@ -1,24 +1,32 @@ import sqlite3 from os import path +from env import SENSORS, DBFILE + # Function to create the database and tables if they don't exist def create_database(db_name): conn = sqlite3.connect(db_name) c = conn.cursor() # Create SensorData table - c.execute('''CREATE TABLE IF NOT EXISTS SensorData - (Id INTEGER PRIMARY KEY AUTOINCREMENT, - FOREIGN KEY (Sensor) REFERENCES Sensors(Name), - Timestamp TEXT, - Temp INT, - HR INTEGER, - Bat INT)''') - - # Create Sensors table c.execute('''CREATE TABLE IF NOT EXISTS Sensors - (Mac TEXT RIMARY KEY, - Name TEXT )''') + (Mac TEXT PRIMARY KEY, + Name TEXT)''') + + # Create SensorData table + c.execute('''CREATE TABLE IF NOT EXISTS SensorData + (Id INTEGER PRIMARY KEY AUTOINCREMENT, + Sensor TEXT, + Timestamp TEXT, + Temp INT, + HR INTEGER, + Bat INT, + FOREIGN KEY (Sensor) REFERENCES Sensors(Name))''') + + for mac, name in SENSORS.items(): + # Use INSERT OR IGNORE to prevent duplicates based on primary key + c.execute("INSERT OR IGNORE INTO Sensors (Mac, Name) VALUES (?, ?)", (mac, name)) + conn.commit() conn.close() @@ -42,4 +50,32 @@ def add_sensor_data(db_name, sensor, timestamp, temp, hr, bat): VALUES (?, ?, ?, ?, ?)''', (sensor, timestamp, temp, hr, bat)) conn.commit() - conn.close() \ No newline at end of file + conn.close() + +# 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 +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 +# Function to fetch data from the database +def fetch_all_sensor(): + conn = sqlite3.connect(DBFILE) + c = conn.cursor() + c.execute("SELECT * FROM Sensors ") + data = c.fetchall() + conn.close() + data.reverse() + return data \ No newline at end of file diff --git a/Program/datascraper.py b/Program/datascraper.py index d31c95a..6bfe513 100644 --- a/Program/datascraper.py +++ b/Program/datascraper.py @@ -2,10 +2,11 @@ import schedule import threading import time from env import * -from database import add_sensor_data +from database import add_sensor_data, fetch_all_sensor from bluepy.btle import Scanner def BltDataScrap(): + sensor_dict = {mac: name for mac, name in fetch_all_sensor()} scanner = Scanner() #print("Begin device scan") devices = scanner.scan(timeout=3.0) @@ -21,7 +22,16 @@ def BltDataScrap(): HR = int(value[28:32], 16) / 100 Bat = int(value[20:22], 16) #print(f"Temp : {temp} °c \n HR : {HR} % , \n Batterie : {Bat} %") - add_sensor_data(DBFILE, SENSORS[device.addr], time.strftime("%Y-%m-%d %H:%M:%S"), temp, HR, Bat) + add_sensor_data(DBFILE, sensor_dict[device.addr], time.strftime("%Y-%m-%d %H:%M:%S"), temp, HR, Bat) + if temp > MAX_TEMP : + + email(RECIPIENT, MESSAGE_Temp, temp, sensor_dict[device.addr], time.strftime("%Y-%m-%d %H:%M:%S") ) + print("mail sent for temp max") + elif temp > MAX_HR : + email(RECIPIENT, MESSAGE_HR, HR, sensor_dict[device.addr], time.strftime("%Y-%m-%d %H:%M:%S") ) + print("mail sent for HR max") + + return 0 def RunInThread_DataScrap(): print("######################################################################\nOpen Thread datascrap") diff --git a/Program/main.py b/Program/main.py index f467779..b2dc1a0 100644 --- a/Program/main.py +++ b/Program/main.py @@ -1,3 +1,5 @@ +import smtplib +import ssl from database import * from datascraper import * from Webserver import RunInThread_WebServer diff --git a/Program/templates/admin.html b/Program/templates/admin.html new file mode 100644 index 0000000..d41d527 --- /dev/null +++ b/Program/templates/admin.html @@ -0,0 +1,121 @@ + + +
+ + +| mac | +Name | +||||
|---|---|---|---|---|---|
| {{ row[0] }} | +{{ row[1] }} | +{{ row[2] }} | +{{ row[3] }} | +{{ row[4] }} | +{{ row[5] }} | +
The current temperature is {{ temperature }}°C
+ {% else %} +Unable to fetch weather data.
+ {% endif %}