From ead358ab1c536e84c4625251b487f79a1ff76e38 Mon Sep 17 00:00:00 2001 From: jeanGaston Date: Wed, 1 May 2024 22:29:23 +0200 Subject: [PATCH] updates --- Program/Webserver.py | 100 ++++++++++----- Program/__pycache__/database.cpython-311.pyc | Bin 2273 -> 4239 bytes Program/database.py | 60 +++++++-- Program/datascraper.py | 14 ++- Program/main.py | 2 + Program/templates/admin.html | 121 +++++++++++++++++++ Program/templates/history.html | 4 + Program/templates/index.html | 14 ++- 8 files changed, 270 insertions(+), 45 deletions(-) create mode 100644 Program/templates/admin.html 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 1f0704624d9ef0f38d55db2bff23e3f0469ff6fb..58aa4c605b0a4420a753d48ccd3264be9caf560e 100644 GIT binary patch literal 4239 zcmeHJO>7fK6rTOF*KvMmptPt0Mj%KwbrK|`LMb#2VFM=42H8#_DJa_PZb-mCVRl2o za-@Ke_)#QUsS=S|Bu-R_OHV!YL~k5z$%klFB&4>7-h!YPPJJ_LZ~Q}w>AB1 z@6FEp=9~9pTU!f)vhv5inN$d&-)W~(_;TZ=290~jL?)L)lk}fYacO>%=V)6<32AXs zOiPmz^u-%!GGIy|gJuAvYz9GwOc`X083GwLxdc*L{-VY;g>%Ju-I-N*H<(bh#8^Dx z296yaj>c4jE4!zE0eA#>UY>=w_mERHcENAw(L-oI_WO%mo_kRF2x`SI525wg?=A9q z{sFb#P)x4YB8N8AmneJ9>kW?x=~QT2ei( z#;d*I!SUo+R0Er%s+Mf@?Jb>oZyZd{r7hdh)AJjRTQCGp8)u$~R~FMac2sxXJZX3= zu11e*bdzwmw=f0A)nPTRYD22O&E0gr6eV{cswLET5|4qe;~LDRR>vyAz;yE?nCap# z2V>)4pnD*K2NXqigZ8D=oMY{GgGM%!u?)uz7z+eq=mxDTma*ViLA zbB-$+sjO`&k{dLqr!ue#SETb@&TxgaZnz?SXH!@+AiVDFpUtMN{sr42{iiKB(H2QK zx-*x}^q(Tx^F&Ygn-I%s-M0GXueu!u0VQjy@{Vi)OBAH`&mfl2vvB9~z{-JQcy}qh zd+FG!+P*)&ABSpeG|Z(Zy+*_HA~t$qoFHkr7J3qC^l(@1!!Df3I(R0#kTLu45RK$q z=6qjYUrzD0^o)sNLdvqS7itsR3x;9Y_RK;mb+s=ica;q&BB6Wa2COS{wqv`}JekWl z3=j%O+F{71jE>1>s?~1HTE@k7+-!rFyQ$745EM5Z%b$JobuqlN6b3*@Qr|PVtYG#m28Kt9maMHS2kH@c|uT%M;FMP8bb>aPm0PS1ElslNa~uL^qW z>h*dI6ug$x%d}KQMic-QMvGvdRiOz48o?*x5e%fLG;n$iZvl0ARZ#+j!ko};CG8HC35$%P*NvD8&s9f{pTNuQH6S(vX zg%X1k6_u%39*l76#_n>GdWJYaOe;6Zrob0EsVxc^BpysH%6Rd-FTdcY{OD@C!VB=!`>{>Tm#YY%@D|<&~)Z1G>HuXupwx<-VL#F`UIp_Ww78_bVS7i_%*kO z?1Jxr8|WkWTSo%f3tgM;0p$q~30piQP>4)TUoEo*=>eTVs(cYdlXy7tM0hguYwJ_H z_(i-hkSvPhC2_nUj=wuPz^7kmWEndCXNn3_Y<&|NY|LU#_P~DCp7l-ZXWhFCNCb3F zQoVOL?R$%2S4r$Dh+Xd-Po4mD64DeHD;ZHq~^%tnz? z5k&APGKA6w@F>k)}W`zHN+f?r`dk`FLz+la(nrJ-zqCNtqp7hQjJHFo({tnK z_4;!LPYTV0pRbL5`pJN=bPn#68kbO$paSm()3DF(!54NHUh-Q;v*bANmo2~?uR)8~ zVS^XBx3>jvm~5QJwNr7%@~e%DBzek=2H>I!{N?2 zHN!!iL>^BIa?>9L!zeYvcr;3BnCS7KZ7i22F)(o@ufQ$3OPL_1c;9*3$%wG)Cq$UD zry7_drY<&_?Vb>3UO&~ya#*litRFozyR@lAJ*ps)j8$pjJ$l zs~CAg33Mro6Q!T3^hEi6dE+5bx+|ADvzCUjd@+dbt68k+ag#OpZ8xf!xJ;`Vxj+*Z NC$CkArHhDM;vY&khC~1W 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 @@ + + + + + + Sensor Data Dashboard + + + + + +
+

Sensors

+ + + + + + {% for row in data %} + + + + + + + + + {% endfor %} +
macName
{{ row[0] }}{{ row[1] }}{{ row[2] }}{{ row[3] }}{{ row[4] }}{{ row[5] }}
+
+

Rename Sensor

+
+ + +

+ + +

+ +
+ + + diff --git a/Program/templates/history.html b/Program/templates/history.html index 3356952..285cbdd 100644 --- a/Program/templates/history.html +++ b/Program/templates/history.html @@ -54,6 +54,10 @@ tr:hover { +

Database Contents

Sensor 1

diff --git a/Program/templates/index.html b/Program/templates/index.html index 2690e90..054b2e5 100644 --- a/Program/templates/index.html +++ b/Program/templates/index.html @@ -51,6 +51,10 @@ } +

Sensor Data Dashboard

@@ -73,10 +77,12 @@ {% endfor %}
- +

Current Weather

+ {% if temperature %} +

The current temperature is {{ temperature }}°C

+ {% else %} +

Unable to fetch weather data.

+ {% endif %}