diff --git a/app/package-lock.json b/app/package-lock.json index a2dbf79aeb9ac365c5290b409317a92e50d96943..55cad54168d808131aa8b1839a2656feb686cd60 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -13,7 +13,8 @@ "express": "^4.18.2", "mongoose": "^8.1.1", "pug": "^3.0.2", - "serialport": "^12.0.0" + "serialport": "^12.0.0", + "ws": "^8.16.0" }, "devDependencies": { "chai": "^4.3.10", @@ -2937,6 +2938,26 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/app/package.json b/app/package.json index af0db2e0e5f3fecfcf94f6259229f8e15c3b740a..348860e27e8aa1636356e10ffec75f962bc6bb4e 100644 --- a/app/package.json +++ b/app/package.json @@ -16,7 +16,8 @@ "express": "^4.18.2", "mongoose": "^8.1.1", "pug": "^3.0.2", - "serialport": "^12.0.0" + "serialport": "^12.0.0", + "ws": "^8.16.0" }, "devDependencies": { "chai": "^4.3.10", diff --git a/app/routes/index.js b/app/routes/index.js index e1ee3e97a22e31970f51b723e51f0a2f2e3c10aa..ddd3855446c272cf9ae19b51ad27a97093a45cbc 100644 --- a/app/routes/index.js +++ b/app/routes/index.js @@ -1,30 +1,55 @@ -const express = require('express'); - require('dotenv').config(); -const app = express(); -const mongoose = require('mongoose'); +const express = require('express'); +const http = require('http'); +const WebSocket = require('ws'); + const Consommation = require('../models/consommation'); -const mongoURI = process.env.MONGO_URI const MethodeNotification = require('../models/methodeNotification'); +const mongoURI = process.env.MONGO_URI + // Constantes 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 app = express(); const port = 3000; +// Créez un serveur HTTP en utilisant Express +const server = http.createServer(app); +// Créez un serveur WebSocket attaché à votre serveur HTTP +const wss = new WebSocket.Server({ server }); + +const mongoose = require('mongoose'); + +const path = require('path'); +const viewsPath = path.join(__dirname, '../views'); + module.exports = app; app.use(express.json()); + app.use(express.static('public')); -const path = require('path'); -const viewsPath = path.join(__dirname, '../views'); app.set('views', viewsPath); app.set('view engine', 'pug'); +// Gérez les connexions WebSocket +wss.on('connection', (ws) => { + console.log('Nouvelle connexion WebSocket établie.'); + + // Écoutez les messages du client WebSocket + ws.on('message', (message) => { + console.log(`Message reçu du client: ${message}`); + // Traitez le message selon vos besoins + }); + + // Envoyez un message au client WebSocket + ws.send('Bienvenue sur le serveur WebSocket!'); +}); + // Connexion à MongoDB mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('MongoDB Connected')) @@ -32,6 +57,7 @@ mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true }) console.error('MongoDB connection error:', err.message); }); + app.get('/', (req, res) => { res.render('index'); }); @@ -166,23 +192,6 @@ 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 @@ -267,12 +276,18 @@ app.put('/methode-notification', async (req, res) => { await methodeNotification.save(); + wss.clients.forEach(client => { + if (client.readyState === WebSocket.OPEN) { + client.send(notificationMessage); + } + }); + res.json({ message: 'Méthode de notification mise à jour avec succès.' }); } catch (error) { res.status(500).json({ message: error.message }); } }); -app.listen(port, () => { +server.listen(port, () => { console.log(`Server listening at http://localhost:${port}`); }); diff --git a/readPortSerie/Pipfile b/readPortSerie/Pipfile index 47579543731b01dcf41b2bd2a8c8f08cd6d1dfc2..ec55f1c4ab2e43eb280fbcfba4cfc9b7426aa681 100644 --- a/readPortSerie/Pipfile +++ b/readPortSerie/Pipfile @@ -9,6 +9,7 @@ gpiozero = "*" "rpi.gpio" = "*" requests = "*" python-dotenv = "*" +websockets = "*" [dev-packages] diff --git a/readPortSerie/Pipfile.lock b/readPortSerie/Pipfile.lock index 50853549928bfd165c050c34b207186c77634437..9f745f4a6dc755c38e42711088c8cee91a164ac7 100644 --- a/readPortSerie/Pipfile.lock +++ b/readPortSerie/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "634eecb4e53777dfe165c63790651a58f1ee0798d2ede37a60e8a6b3d8f10a24" + "sha256": "f5ce96e6dfef2958f45a479c38a0290e6fd3ef4a83cae9ab77780d0979d69743" }, "pipfile-spec": 6, "requires": { @@ -185,11 +185,11 @@ }, "setuptools": { "hashes": [ - "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05", - "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78" + "sha256:850894c4195f09c4ed30dba56213bf7c3f21d86ed6bdaafb5df5972593bfc401", + "sha256:c054629b81b946d63a9c6e732bc8b2513a7c3ea645f11d0139a2191d735c60c6" ], "markers": "python_version >= '3.8'", - "version": "==69.0.3" + "version": "==69.1.0" }, "urllib3": { "hashes": [ @@ -198,6 +198,85 @@ ], "markers": "python_version >= '3.8'", "version": "==2.2.0" + }, + "websockets": { + "hashes": [ + "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b", + "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6", + "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df", + "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b", + "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205", + "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892", + "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53", + "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2", + "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed", + "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c", + "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd", + "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b", + "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931", + "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30", + "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370", + "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be", + "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec", + "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf", + "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62", + "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b", + "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402", + "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f", + "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123", + "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9", + "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603", + "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45", + "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558", + "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4", + "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438", + "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137", + "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480", + "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447", + "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8", + "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04", + "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c", + "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb", + "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967", + "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b", + "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d", + "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def", + "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c", + "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92", + "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2", + "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113", + "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b", + "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28", + "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7", + "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d", + "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f", + "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468", + "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8", + "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae", + "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611", + "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d", + "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9", + "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca", + "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f", + "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2", + "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077", + "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2", + "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6", + "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374", + "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc", + "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e", + "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53", + "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399", + "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547", + "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3", + "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870", + "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5", + "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8", + "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==12.0" } }, "develop": {} diff --git a/readPortSerie/readPortSerieArduino.py b/readPortSerie/readPortSerieArduino.py index d1aef29954b10b62b1eb08fae1a25e4e7c7c7519..a589bf7297fe6e55c6c4bbbf27ee957ef695a4c9 100644 --- a/readPortSerie/readPortSerieArduino.py +++ b/readPortSerie/readPortSerieArduino.py @@ -2,6 +2,8 @@ import serial import requests import time import os +import asyncio +import websockets from dotenv import load_dotenv @@ -18,38 +20,71 @@ temps_recuperation_distance = os.getenv('TEMPS_RECUPERATION_DISTANCE') # en seco arduino_port = '/dev/ttyACM0' ser = serial.Serial(arduino_port, 9600, timeout=1) -try: - while True: - # Récupérer la méthode de notification actuelle toutes les 20 minutes - if time.time() % 1200 == 0: - try: - notification_response = requests.get(methode_notification_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 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(1) - -except KeyboardInterrupt: - ser.close() - print("Arrêt du programme.") +async def fetch_methode_notification(): + try: + notification_reponse = await requests.get(methode_notification_url) + notification_reponse.raise_for_status() + notification_methode = notification_reponse.json().get('methodeNotification', 'sound') + except requests.exceptions.RequestException as e: + print(f"Erreur lors de la récupération de la méthode de notification : {e}") + notification_methode = 'sound' + + return notification_methode + +async def process_distance(distance): + payload = {'distance': distance} + try: + reponse = await requests.post(calculer_consommation, json=payload) + reponse.raise_for_status() + data = reponse.json() + print(f"API Response: {data}") + except requests.exceptions.RequestException as e: + print(f"Erreur lors de l'appel API : {e}") + +async def process_notification(message): + print(f"Notification reçue : {message}") + + parts = message.split(':') + if len(parts) == 2 and parts[0] == 'MethodNotification': + notification_methode = parts[1] + print(f"Nouvelle méthode de notification reçue: {notification_methode}") + ser.write(notification_methode.encode()) + +async def main(): + async with websockets.connect('ws://localhost:3000') as websocket: + try: + while True: + # Attendre un message du serveur WebSocket + message = await websocket.recv() + + # Traitement du message reçu + await process_notification(message) + + # Récupérer la méthode de notification actuelle toutes les 20 minutes + """ + if time.time() % 1200 == 0: + notification_method = await fetch_methode_notification() + + # Envoyer la méthode de notification au serveur WebSocket + await websocket.send(f'MethodNotification:{notification_method}') + """ + + # Récupérer la distance toutes les 5 minutes + if time.time() % 300 == 0: + line = ser.readline().decode('utf-8').rstrip() + + if 'Distance' in line: + distance = float(line.split(':')[-1].strip().split(' ')[0]) + print(f"Distance : {distance} cm") + + # Traitement de la distance + await process_distance(distance) + + await time.sleep(1) + + except KeyboardInterrupt: + ser.close() + print("Arrêt du programme.") + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(main())