diff --git a/ReadPortSerieArduino/.env b/ReadPortSerieArduino/.env new file mode 100644 index 0000000000000000000000000000000000000000..76afc0b1d396bb7efd4dbdab374d491ef49d954d --- /dev/null +++ b/ReadPortSerieArduino/.env @@ -0,0 +1 @@ + API_URL=localhost:3000 \ No newline at end of file diff --git a/ReadPortSerieArduino/ReadPortSerieArduino.py b/ReadPortSerieArduino/ReadPortSerieArduino.py index 3dbf8254a5c9bf27f365b28b8db1b1f9631e66eb..953f3c3163b8619792fad7867772788e271da695 100644 --- a/ReadPortSerieArduino/ReadPortSerieArduino.py +++ b/ReadPortSerieArduino/ReadPortSerieArduino.py @@ -1,31 +1,50 @@ import serial import requests import time +import os + +from dotenv import load_dotenv + +load_dotenv() arduino_port = '/dev/ttyACM0' ser = serial.Serial(arduino_port, 9600, timeout=1) -api_url = 'http://localhost:3000/calculer-volume' +api_url = os.getenv('API_URL') +calculer_consommation = api_url + '/calculer-volume-consumption' +notification_method_url = api_url + '/methode-notification' try: while True: - line = ser.readline().decode('utf-8').rstrip() - # print(f"Arduino dit : {line}") - - if 'Distance' in line: - distance = float(line.split(':')[-1].strip().split(' ')[0]) - print(f"Distance : {distance} cm") - - payload = {'distance': distance} + # Récupérer la méthode de notification actuelle toutes les 20 minutes + if time.time() % 1200 == 0: try: - response = requests.post(api_url, json=payload) - response.raise_for_status() - data = response.json() - print(f"API Response: {data}") + notification_response = requests.get(notification_method_url) + notification_response.raise_for_status() + notification_method = notification_response.json().get('methodeNotification', 'sound') except requests.exceptions.RequestException as e: - print(f"Erreur lors de l'appel API : {e}") + print(f"Erreur lors de la récupération de la méthode de notification : {e}") + notification_method = 'sound' + + # Récupérer la distance toutes les 5 minutes + if time.time() % 300 == 0: + line = ser.readline().decode('utf-8').rstrip() + # print(f"Arduino dit : {line}") + + if 'Distance' in line: + distance = float(line.split(':')[-1].strip().split(' ')[0]) + print(f"Distance : {distance} cm") + + payload = {'distance': distance} + try: + response = requests.post(calculer_consommation, json=payload) + response.raise_for_status() + data = response.json() + print(f"API Response: {data}") + except requests.exceptions.RequestException as e: + print(f"Erreur lors de l'appel API : {e}") - time.sleep(300) + time.sleep(1) except KeyboardInterrupt: ser.close() diff --git a/app/models/methodeNotification.js b/app/models/methodeNotification.js new file mode 100644 index 0000000000000000000000000000000000000000..4bcad7f2adf52598b868d39d8afe40f544c801bc --- /dev/null +++ b/app/models/methodeNotification.js @@ -0,0 +1,10 @@ +const mongoose = require('mongoose'); + +const methodeNotificationSchema = new mongoose.Schema({ + notificationMethod: { + type: String, + required: true + }, +}); + +module.exports = mongoose.model('MethodeNotification', methodeNotificationSchema); diff --git a/app/routes/index.js b/app/routes/index.js index 8b7e23e6536af522631c9089a98113d6789c0b33..5dcb6f6350f560e8e69b55283de88982bbb50831 100644 --- a/app/routes/index.js +++ b/app/routes/index.js @@ -1,14 +1,17 @@ const express = require('express'); + require('dotenv').config(); + const app = express(); const mongoose = require('mongoose'); const Consommation = require('../models/consommation'); const mongoURI = process.env.MONGO_URI || 'mongodb://localhost/abreuvoir'; +const MethodeNotification = require('../models/methodeNotification'); // Constantes -const rayonSeau = 15; // Le rayon du seau en cm -const hauteurInitialeEau = 50; // la hauteur initiale de l'eau en cm -const distanceSupplementaire = 5; // la distance supplémentaire en cm entre le capteur et le bord supérieur du seau +const rayonSeau = process.env.RAYON_SEAU; // Le rayon du seau en cm +const hauteurInitialeEau = process.env.HAUTEUR_INITIALE_EAU ; // la hauteur initiale de l'eau en cm +const distanceSupplementaire = process.env.DISTANCE_SUPPLEMENTAIRE; // la distance supplémentaire en cm entre le capteur et le bord supérieur du seau let volumeEauInitial = Math.PI * rayonSeau**2 * hauteurInitialeEau; // Calcul du volume d'eau initial en cm^3 (mL) const port = 3000; @@ -76,7 +79,7 @@ app.get('/consommations/:startDate/:endDate', async (req, res) => { }); // Route pour récupérer les dernières consommations -app.get('/last-consommations', async (req, res) => { +app.get('/dernieres-consommations', async (req, res) => { try { const latestConsommations = await Consommation.find().sort({ timestamp: -1 }).limit(10); res.json(latestConsommations); @@ -161,25 +164,47 @@ app.get('/consommations/par-annee', async (req, res) => { } }); +/* app.post('/distance', (req, res) => { const { distance } = req.body; console.log(`Distance reçue: ${distance} cm`); res.status(200).json({ message: 'Distance reçue avec succès' }); }); +*/ +/* // Route pour définir/mettre à jour le volume d'eau initial app.post('/definir-volume-initial', (req, res) => { const { hauteurEau } = req.body; // Hauteur d'eau fournie par l'utilisateur volumeEauInitial = Math.PI * rayonSeau**2 * hauteurEau; // Mise à jour du volume d'eau initial res.json({ message: 'Volume d\'eau initial mis à jour', volumeEauInitial }); }); +*/ + +app.get('/parametres-seau', (req, res) => { + try { + // Retourne les paramètres du seau + res.json({ + rayonSeau: rayonSeau, + hauteurInitialeEau: hauteurInitialeEau, + distanceSupplementaire: distanceSupplementaire, + volumeEauInitial: volumeEauInitial + }); + } catch (error) { + res.status(500).json({ message: error.message }); + } +}); // Route pour calculer le volume d'eau et la consommation -app.post('/calculer-volume', async (req, res) => { +app.post('/calculer-volume-consommation', async (req, res) => { let { distanceCapteur } = req.body; distanceCapteur = parseInt(distanceCapteur); + if(isNaN(distanceCapteur)) { + return res.status(400).json({ message: 'Distance invalide' }); + } + if (typeof distanceCapteur !== 'number' || distanceCapteur < 0) { return res.status(400).json({ message: 'Distance invalide' }); } @@ -215,6 +240,39 @@ app.post('/calculer-volume', async (req, res) => { } }); +// Route pour obtenir la méthode de notification actuelle +app.get('/methode-notification', async (req, res) => { + try { + const methodeNotification = await MethodeNotification.findOne(); + const options = ["sound", "leds"]; + + res.json({ methodeNotification: methodeNotification || 'sound', options }); + } catch (error) { + res.status(500).json({ message: error.message }); + } +}); + +// Route pour mettre à jour la méthode de notification +app.put('/methode-notification', async (req, res) => { + const { notificationMethod } = req.body; + + try { + let methodeNotification = await MethodeNotification.findOne(); + + if (!methodeNotification) { + methodeNotification = new MethodeNotification({ notificationMethod }); + } else { + methodeNotification.notificationMethod = notificationMethod; + } + + await methodeNotification.save(); + + res.json({ message: 'Méthode de notification mise à jour avec succès.' }); + } catch (error) { + res.status(500).json({ message: error.message }); + } +}); + app.listen(port, () => { console.log(`Server listening at http://localhost:${port}`); }); diff --git a/app/views/dashboard.pug b/app/views/dashboard.pug index ab123d7a75293c22b8483643b56246065c204ad0..de715b8ac5961cc853621db09bb23209fb39f20e 100644 --- a/app/views/dashboard.pug +++ b/app/views/dashboard.pug @@ -5,14 +5,16 @@ block content h1 Information Générale hr + // Ajouter une section pour afficher les paramètres du seau div.mb-3 - label(for='hauteurEau', class='form-label') Hauteur d'eau (cm): - input(type='number', class='form-control', id='hauteurEau', placeholder='Entrez la hauteur en cm') + h2 Paramètres du Seau + div#seau-parameters - button.btn.btn-primary.mb-3(onclick='updateInitialVolume()') Mettre à jour le volume initial + hr + // Ajouter le formulaire pour calculer le volume et la consommation div.mb-3 - label(for='distanceCapteur', class='form-label') Distance du capteur au niveau d'eau (cm): + label(for='distanceCapteur', class='form-label') Consommation d'eau: input(type='number', class='form-control', id='distanceCapteur', placeholder='Entrez la distance en cm') button.btn.btn-primary.mb-3(onclick='calculateVolume()') Calculer le volume et la consommation @@ -20,36 +22,79 @@ block content div#result hr + div.mb-3 + label(for='notificationMethod', class='form-label') Méthode de notification: + select(id='notificationMethod', class='form-select', onchange='updateNotificationMethod()') + option(value='sound') Son + option(value='leds') LEDs + script. - async function updateInitialVolume() { - const hauteurEau = document.getElementById('hauteurEau').value; - const response = await fetch('/definir-volume-initial', { + // Charger les paramètres du seau au chargement de la page + document.addEventListener('DOMContentLoaded', async function () { + const seauParametersDiv = document.getElementById('seau-parameters'); + const responseParameters = await fetch('/parametres-seau'); + const seauParameters = await responseParameters.json(); + + // Afficher les paramètres du seau dans la page + seauParametersDiv.innerHTML = ` +

Rayon du seau: ${seauParameters.rayonSeau} cm

+

Hauteur initiale de l'eau: ${seauParameters.hauteurInitialeEau} cm

+

Distance supplémentaire entre le capteur et le bord supérieur du seau: ${seauParameters.distanceSupplementaire} cm

+

Volume initial d'eau: ${seauParameters.volumeEauInitial.toFixed(2)} cm³

+ `; + + // Charger la méthode de notification actuelle et les options + const notificationMethodSelect = document.getElementById('notificationMethod'); + const responseNotification = await fetch('/methode-notification'); + const {methodeNotification, options} = await responseNotification.json(); + + // Mettre à jour le formulaire avec la méthode de notification actuelle et les options + notificationMethodSelect.innerHTML = options.map(option => + `` + ).join(''); + }); + + async function calculateVolume() { + const distanceCapteur = document.getElementById('distanceCapteur').value; + const response = await fetch('/calculer-volume-consommation', { method: 'POST', headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify({ hauteurEau }), + body: JSON.stringify({ distanceCapteur }), }); - const result = await response.json(); - alert(result.message); + + if (response.ok) { + const result = await response.json(); + + // Mettre à jour le contenu de la balise
+ const resultDiv = document.getElementById('result'); + resultDiv.innerHTML = ` +

Hauteur d'eau: ${result.calculs.hauteurEau} cm

+

Volume d'eau: ${result.calculs.volumeEau.toFixed(2)} cm³

+

Consommation d'eau: ${result.calculs.consommationEau.toFixed(2)} cm³

+ `; + } else { + const errorResponse = await response.json(); + alert(`Erreur: ${errorResponse.message}`); + } } - async function calculateVolume() { - const distanceCapteur = document.getElementById('distanceCapteur').value; - const response = await fetch('/calculer-volume', { - method: 'POST', + // Fonction pour mettre à jour la méthode de notification + async function updateNotificationMethod() { + const notificationMethod = document.getElementById('notificationMethod').value; + const response = await fetch('/methode-notification', { + method: 'PUT', headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify({ distanceCapteur }), + body: JSON.stringify({notificationMethod}), }); - const result = await response.json(); - - // Mettre à jour le contenu de la balise
- const resultDiv = document.getElementById('result'); - resultDiv.innerHTML = ` -

Hauteur d'eau: ${result.calculs.hauteurEau} cm

-

Volume d'eau: ${result.calculs.volumeEau.toFixed(2)} cm³

-

Consommation d'eau: ${result.calculs.consommationEau.toFixed(2)} cm³

- `; + + if (response.ok) { + alert('Méthode de notification mise à jour avec succès'); + } else { + const errorResponse = await response.json(); + alert(`Erreur: ${errorResponse.message}`); + } } diff --git a/app/views/lastConsumptions.pug b/app/views/lastConsumptions.pug index 758b58c95e643a91e660f74490d24dc287d19192..00c1957e8d49f3f0799f57a1fb940e7549b16f1e 100644 --- a/app/views/lastConsumptions.pug +++ b/app/views/lastConsumptions.pug @@ -9,7 +9,7 @@ block content script. async function updateList() { try { - const response = await fetch('/last-consommations'); + const response = await fetch('/dernieres-consommations'); const latestConsommations = await response.json(); // Mise à jour de la liste des dernières consommations