diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..0d34a70 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +COUCHDB_USER=TO_BE_CHANGED +COUCHDB_PASSWORD=TO_BE_CHANGED \ No newline at end of file diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d8d5028..300f122 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -27,6 +27,8 @@ jobs: npm run build - name: Start frontend run: | + export COUCHDB_USER="TO_BE_CHANGED" + export COUCHDB_PASSWORD="TO_BE_CHANGED" docker compose up --detach - name: Wait for frontend uses: docker://benel/wait-for-response:1 diff --git a/.gitignore b/.gitignore index 8daaedd..d762d6f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -GreenIT-Analysis-cli/ \ No newline at end of file +GreenIT-Analysis-cli/ +.env \ No newline at end of file diff --git a/.greenframe.yml b/.greenframe.yml index c2df476..aae0c8f 100644 --- a/.greenframe.yml +++ b/.greenframe.yml @@ -4,4 +4,5 @@ scenarios: - path: ./benchmark/consulterMeteo/scenario1.js name: Consulter la meteo containers: - - helios-static_hosting-1 \ No newline at end of file + - helios-static_hosting-1 + - helios-backend-1 \ No newline at end of file diff --git a/README.md b/README.md index 990744c..580f7d7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# HELIOS : Réduction de l'impact écologique du service numérique d'un établissement de météorologie et de climatologie + # HELIOS : Réduction de l'impact écologique du service numérique d'un établissement de météorologie et de climatologie ## Choix du sujet Nous revenons tous deux d'un semestre à l'étranger dans deux pays avec une météo très distincte. En Norvège la météo était particulièrement changeante et extrême par moments. Consulter la météo chaque jour est devenu une habitude, de même que la programmation journalière d'une notification récapitulative. @@ -180,3 +180,22 @@ Par ailleurs, nous remarquons que cette consommation ne compte que pour 3% de la ![Impact du prototype](./benchmark/helios_homepage.png) __Fig.6__ : Consommation de ressources par le navigateur lors de la consultation de la météo dans notre prototype. + +## Prototype n°3 : Fonctionnalités pour le scénario prioritaire avec données stockées dans une base de données + +Pour la troisième version du prototype, les données sont désormais stockées dans un système de base de données interrogeable à travers une API Web (*CouchDB*). +L'intérêt d'une source de données dynamique est d'une part, à terme, de pouvoir ajouter ou modifier la météo plus facilement, et d'autre part de déporter sur le serveur le filtrage des données pertinentes. + +Sur ce deuxième enjeu, on observe dans les mesures (cf. Fig.7) que la charge du réseau entre les deux prototypes concernant la consultation de la météo est sensiblement la même. Ceci est dû à la simplicité de notre application qui ne contient qu'une page à charger. Néanmoins, en supposant que notre application contiendra à terme plusieurs pages et d'autres lots de données, on peut s'attendre à une baisse de la charge du réseau pour l'aff + +![](./benchmark/helios_v2.png) +![](./benchmark/helios_v3.png) +__Fig.7__ : Comparaison de l'impact de la consultation de la page de la météo entre les prototypes 2 (en haut) et (3 en bas). + +De plus, on peut constater une utilisation du CPU par la base de données, utilisation qui semble par ailleurs continue et plus important qu'auparavant. (cf. Fig.8). + +![](./benchmark/helios_backend_v3.png) +__Fig.8__ : Profil dans le temps de l'impact de la base de données lors de la consultation de la météo. + +De ces différentes mesures, nous pouvons retenir que l'effet de l'introduction d'une base de données, quoique négligeable, est, pour l'instant, plutôt défavorable d'un point de vue écologique. +Le bilan de ce changement devrait cependant rapidement s'inverser avec l'augmentation de la quantité de données gérées. \ No newline at end of file diff --git a/benchmark/helios_backend_v3.png b/benchmark/helios_backend_v3.png new file mode 100644 index 0000000..c774894 Binary files /dev/null and b/benchmark/helios_backend_v3.png differ diff --git a/benchmark/helios_v2.png b/benchmark/helios_v2.png new file mode 100644 index 0000000..649bbc4 Binary files /dev/null and b/benchmark/helios_v2.png differ diff --git a/benchmark/helios_v3.png b/benchmark/helios_v3.png new file mode 100644 index 0000000..308ab95 Binary files /dev/null and b/benchmark/helios_v3.png differ diff --git a/docker-compose.yml b/docker-compose.yml index 8524f80..ec9446b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,4 +6,42 @@ services: - ./frontend/dist:/usr/share/nginx/html:ro - ./settings/nginx.conf:/etc/nginx/conf.d/default.conf:ro ports: - - 80:80 \ No newline at end of file + - 80:80 + + backend: + image: couchdb:3 + ports: + - 5984:5984 + environment: + - COUCHDB_USER + - COUCHDB_PASSWORD + healthcheck: + test: curl -f http://localhost:5984/_up || exit 1 + interval: 2s + timeout: 3s + + accessible_backend: + image: curlimages/curl + entrypoint: ["/bin/sh","-c"] + command: + - | + alias put="curl -X PUT -u '${COUCHDB_USER}:${COUCHDB_PASSWORD}'" + put backend:5984/_node/nonode@nohost/_config/chttpd/enable_cors --data '"true"' + put backend:5984/_node/nonode@nohost/_config/cors/origins --data '"*"' + put backend:5984/helios + put backend:5984/helios/_security --data '{"members":{"roles":[]},"admins":{"roles":["_admin"]}}' + depends_on: + backend: + condition: service_healthy + + updated_samples: + image: curlimages/curl + entrypoint: ["/bin/sh","-c"] + volumes: + - ./frontend/public/sample_data.json:/sample_data.json + command: + - | + curl -X POST http://backend:5984/helios/_bulk_docs -H "Content-Type: application/json" -d @/sample_data.json + depends_on: + accessible_backend: + condition: service_completed_successfully \ No newline at end of file diff --git a/frontend/public/sample_data.json b/frontend/public/sample_data.json index 8a9d7b4..9dfad3f 100644 --- a/frontend/public/sample_data.json +++ b/frontend/public/sample_data.json @@ -1,214 +1,256 @@ { - "forecasts": [ + "docs": [ { "city": "Paris", + "date": "2024-10-15", "sunrise": "07:32", "sunset": "18:45", - "dailyForecasts": [ - { - "date": "2024-10-15", - "morningTemperature": "10", - "afternoonTemperature": "11", - "eveningTemperature": "10", - "condition": "Rainy", - "windSpeed": "5", - "humidity": "99%" - }, - { - "date": "2024-10-16", - "morningTemperature": "20", - "afternoonTemperature": "29", - "eveningTemperature": "24", - "condition": "Snowy", - "windSpeed": "42", - "humidity": "44%" - }, - { - "date": "2024-10-17", - "morningTemperature": "15", - "afternoonTemperature": "23", - "eveningTemperature": "18", - "condition": "Sunny", - "windSpeed": "39", - "humidity": "61%" - }, - { - "date": "2024-10-18", - "morningTemperature": "14", - "afternoonTemperature": "22", - "eveningTemperature": "19", - "condition": "Cloudy", - "windSpeed": "20", - "humidity": "70%" - }, - { - "date": "2024-10-19", - "morningTemperature": "16", - "afternoonTemperature": "25", - "eveningTemperature": "21", - "condition": "Sunny", - "windSpeed": "15", - "humidity": "55%" - }, - { - "date": "2024-10-20", - "morningTemperature": "14", - "afternoonTemperature": "21", - "eveningTemperature": "19", - "condition": "Cloudy", - "windSpeed": "9", - "humidity": "70%" - }, - { - "date": "2024-10-21", - "morningTemperature": "12", - "afternoonTemperature": "20", - "eveningTemperature": "16", - "condition": "Rainy", - "windSpeed": "12", - "humidity": "80%" - } - ] + "morningTemperature": "10", + "afternoonTemperature": "11", + "eveningTemperature": "10", + "condition": "Rainy", + "windSpeed": "5", + "humidity": "99%" + }, + { + "city": "Paris", + "date": "2024-10-16", + "sunrise": "07:32", + "sunset": "18:45", + "morningTemperature": "20", + "afternoonTemperature": "29", + "eveningTemperature": "24", + "condition": "Snowy", + "windSpeed": "42", + "humidity": "44%" + }, + { + "city": "Paris", + "date": "2024-10-17", + "sunrise": "07:32", + "sunset": "18:45", + "morningTemperature": "15", + "afternoonTemperature": "23", + "eveningTemperature": "18", + "condition": "Sunny", + "windSpeed": "39", + "humidity": "61%" + }, + { + "city": "Paris", + "date": "2024-10-18", + "sunrise": "07:32", + "sunset": "18:45", + "morningTemperature": "14", + "afternoonTemperature": "22", + "eveningTemperature": "19", + "condition": "Cloudy", + "windSpeed": "20", + "humidity": "70%" + }, + { + "city": "Paris", + "date": "2024-10-19", + "sunrise": "07:32", + "sunset": "18:45", + "morningTemperature": "16", + "afternoonTemperature": "25", + "eveningTemperature": "21", + "condition": "Sunny", + "windSpeed": "15", + "humidity": "55%" + }, + { + "city": "Paris", + "date": "2024-10-20", + "sunrise": "07:32", + "sunset": "18:45", + "morningTemperature": "14", + "afternoonTemperature": "21", + "eveningTemperature": "19", + "condition": "Cloudy", + "windSpeed": "9", + "humidity": "70%" + }, + { + "city": "Paris", + "date": "2024-10-21", + "sunrise": "07:32", + "sunset": "18:45", + "morningTemperature": "12", + "afternoonTemperature": "20", + "eveningTemperature": "16", + "condition": "Rainy", + "windSpeed": "12", + "humidity": "80%" + }, + { + "city": "Troyes", + "date": "2024-10-15", + "sunrise": "07:36", + "sunset": "18:39", + "morningTemperature": "9", + "afternoonTemperature": "11", + "eveningTemperature": "10", + "condition": "Sunny", + "windSpeed": "11", + "humidity": "39%" + }, + { + "city": "Troyes", + "date": "2024-10-16", + "sunrise": "07:36", + "sunset": "18:39", + "morningTemperature": "4", + "afternoonTemperature": "6", + "eveningTemperature": "5", + "condition": "Snowy", + "windSpeed": "7", + "humidity": "58%" + }, + { + "city": "Troyes", + "date": "2024-10-17", + "sunrise": "07:36", + "sunset": "18:39", + "morningTemperature": "12", + "afternoonTemperature": "19", + "eveningTemperature": "15", + "condition": "Cloudy", + "windSpeed": "26", + "humidity": "60%" }, { "city": "Troyes", + "date": "2024-10-18", "sunrise": "07:36", "sunset": "18:39", - "dailyForecasts": [ - { - "date": "2024-10-15", - "morningTemperature": "9", - "afternoonTemperature": "11", - "eveningTemperature": "10", - "condition": "Sunny", - "windSpeed": "11", - "humidity": "39%" - }, - { - "date": "2024-10-16", - "morningTemperature": "4", - "afternoonTemperature": "6", - "eveningTemperature": "5", - "condition": "Snowy", - "windSpeed": "7", - "humidity": "58%" - }, - { - "date": "2024-10-17", - "morningTemperature": "12", - "afternoonTemperature": "19", - "eveningTemperature": "15", - "condition": "Cloudy", - "windSpeed": "26", - "humidity": "60%" - }, - { - "date": "2024-10-18", - "morningTemperature": "14", - "afternoonTemperature": "21", - "eveningTemperature": "17", - "condition": "Rainy", - "windSpeed": "20", - "humidity": "75%" - }, - { - "date": "2024-10-19", - "morningTemperature": "18", - "afternoonTemperature": "23", - "eveningTemperature": "20", - "condition": "Sunny", - "windSpeed": "10", - "humidity": "52%" - }, - { - "date": "2024-10-20", - "morningTemperature": "20", - "afternoonTemperature": "25", - "eveningTemperature": "22", - "condition": "Cloudy", - "windSpeed": "33", - "humidity": "50%" - }, - { - "date": "2024-10-21", - "morningTemperature": "15", - "afternoonTemperature": "20", - "eveningTemperature": "16", - "condition": "Stormy", - "windSpeed": "28", - "humidity": "88%" - } - ] + "morningTemperature": "14", + "afternoonTemperature": "21", + "eveningTemperature": "17", + "condition": "Rainy", + "windSpeed": "20", + "humidity": "75%" + }, + { + "city": "Troyes", + "date": "2024-10-19", + "sunrise": "07:36", + "sunset": "18:39", + "morningTemperature": "18", + "afternoonTemperature": "23", + "eveningTemperature": "20", + "condition": "Sunny", + "windSpeed": "10", + "humidity": "52%" + }, + { + "city": "Troyes", + "date": "2024-10-20", + "sunrise": "07:36", + "sunset": "18:39", + "morningTemperature": "20", + "afternoonTemperature": "25", + "eveningTemperature": "22", + "condition": "Cloudy", + "windSpeed": "33", + "humidity": "50%" + }, + { + "city": "Troyes", + "date": "2024-10-21", + "sunrise": "07:36", + "sunset": "18:39", + "morningTemperature": "15", + "afternoonTemperature": "20", + "eveningTemperature": "16", + "condition": "Stormy", + "windSpeed": "28", + "humidity": "88%" + }, + { + "city": "Strasbourg", + "date": "2024-10-15", + "sunrise": "07:34", + "sunset": "18:38", + "morningTemperature": "13", + "afternoonTemperature": "16", + "eveningTemperature": "14", + "condition": "Cloudy", + "windSpeed": "22", + "humidity": "55%" + }, + { + "city": "Strasbourg", + "date": "2024-10-16", + "sunrise": "07:34", + "sunset": "18:38", + "morningTemperature": "15", + "afternoonTemperature": "17", + "eveningTemperature": "16", + "condition": "Snowy", + "windSpeed": "33", + "humidity": "46%" + }, + { + "city": "Strasbourg", + "date": "2024-10-17", + "sunrise": "07:34", + "sunset": "18:38", + "morningTemperature": "8", + "afternoonTemperature": "13", + "eveningTemperature": "10", + "condition": "Sunny", + "windSpeed": "10", + "humidity": "49%" + }, + { + "city": "Strasbourg", + "date": "2024-10-18", + "sunrise": "07:34", + "sunset": "18:38", + "morningTemperature": "9", + "afternoonTemperature": "10", + "eveningTemperature": "10", + "condition": "Rainy", + "windSpeed": "31", + "humidity": "59%" + }, + { + "city": "Strasbourg", + "date": "2024-10-19", + "sunrise": "07:34", + "sunset": "18:38", + "morningTemperature": "16", + "afternoonTemperature": "21", + "eveningTemperature": "18", + "condition": "Cloudy", + "windSpeed": "12", + "humidity": "67%" + }, + { + "city": "Strasbourg", + "date": "2024-10-20", + "sunrise": "07:34", + "sunset": "18:38", + "morningTemperature": "12", + "afternoonTemperature": "15", + "eveningTemperature": "13", + "condition": "Cloudy", + "windSpeed": "14", + "humidity": "72%" }, { "city": "Strasbourg", + "date": "2024-10-21", "sunrise": "07:34", "sunset": "18:38", - "dailyForecasts": [ - { - "date": "2024-10-15", - "morningTemperature": "13", - "afternoonTemperature": "16", - "eveningTemperature": "14", - "condition": "Cloudy", - "windSpeed": "22", - "humidity": "55%" - }, - { - "date": "2024-10-16", - "morningTemperature": "15", - "afternoonTemperature": "17", - "eveningTemperature": "16", - "condition": "Snowy", - "windSpeed": "33", - "humidity": "46%" - }, - { - "date": "2024-10-17", - "morningTemperature": "8", - "afternoonTemperature": "13", - "eveningTemperature": "10", - "condition": "Sunny", - "windSpeed": "10", - "humidity": "49%" - }, - { - "date": "2024-10-18", - "morningTemperature": "9", - "afternoonTemperature": "10", - "eveningTemperature": "10", - "condition": "Rainy", - "windSpeed": "31", - "humidity": "59%" - }, - { - "date": "2024-10-19", - "morningTemperature": "16", - "afternoonTemperature": "21", - "eveningTemperature": "18", - "condition": "Cloudy", - "windSpeed": "12", - "humidity": "67%" - }, - { - "date": "2024-10-20", - "morningTemperature": "12", - "afternoonTemperature": "15", - "eveningTemperature": "13", - "condition": "Cloudy", - "windSpeed": "14", - "humidity": "72%" - }, - { - "date": "2024-10-21", - "morningTemperature": "10", - "afternoonTemperature": "12", - "eveningTemperature": "11", - "condition": "Rainy", - "windSpeed": "20", - "humidity": "82%" - } - ] + "morningTemperature": "10", + "afternoonTemperature": "12", + "eveningTemperature": "11", + "condition": "Rainy", + "windSpeed": "20", + "humidity": "82%" } ] } diff --git a/frontend/src/Homepage.jsx b/frontend/src/Homepage.jsx index 160d49e..082dee2 100644 --- a/frontend/src/Homepage.jsx +++ b/frontend/src/Homepage.jsx @@ -1,62 +1,67 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect } from 'react'; import './App.css'; import Icon from '@mdi/react'; -import { mdiMenu, mdiWeatherSunny, mdiWeatherCloudy, mdiWeatherSnowyHeavy, mdiWeatherRainy } from '@mdi/js'; +import { mdiMenu, mdiWeatherSunny, mdiWeatherCloudy, mdiWeatherSnowyHeavy, mdiWeatherRainy, mdiWeatherLightningRainy } from '@mdi/js'; import dayjs from 'dayjs'; - function Homepage() { const [searchQuery, setSearchQuery] = useState(''); const [filteredData, setFilteredData] = useState([]); - const [data, setData] = useState( [] ); - -useEffect(() => { - fetch('./sample_data.json') - .then((response) => response.json()) - .then((data) =>{ - setData(data); - setFilteredData(data.forecasts);}); + const [data, setData] = useState([]); + const [error, setError] = useState(null); + useEffect(() => { + fetch('http://localhost:5984/helios/_all_docs?include_docs=true') + .then((response) => response.json()) + .then((data) => { + setData(data.rows.map((row) => row.doc)); + setFilteredData(data.rows.map((row) => row.doc)); + }) + .catch((error) => { + setError(error); + console.error('Error fetching data:', error); + }); }, []); - const handleSearch = (event) => { - + if (event.key === 'Enter') { const query = searchQuery.trim().toLowerCase(); - const result = data.forecasts.filter(forecast => + const result = data.filter((forecast) => forecast.city.toLowerCase().includes(query) ); setFilteredData(result); - + } }; return ( - <> -
Error fetching data: {error.message}
+ ) : ({forecast.city} | -{dayjs(dailyForecast.date).format('DD/MM/YYYY')} | -{dailyForecast.morningTemperature} | -{dailyForecast.afternoonTemperature} | -{dailyForecast.eveningTemperature} | -
- {dailyForecast.condition.toLowerCase() === 'sunny' && |
- {dailyForecast.humidity} | -
{forecast.city} | +{dayjs(forecast.date).format('DD/MM/YYYY')} | +{forecast.morningTemperature} | +{forecast.afternoonTemperature} | +{forecast.eveningTemperature} | +{forecast.humidity} | +
+ {forecast.condition.toLowerCase() === 'sunny' && (
+ |
+