Search
Cílem miniprojektů je vytvořit komplexní IoT aplikaci, na které bude možné experimentálně ověřit probírané technologie a postupy.
Student bude své miniprojekty odevzdávat prostřednictvím fakultní GitLabu. Miniprojekty jsou koncipovány tak, že se postupně rozšiřuje funkcionalita jedné webové aplikace - každý student bude mít tedy jeden GitLab projekt, který bude průběžně hodnocen. Je nutné, aby byl repozitář dostupný, tj. viditelnost internal nebo public.
internal
public
Po dokončení miniprojektu student nahraje změny na GitLab a do BRUTE odevzdá do příslušného miniprojektu (MP01, MP02, …) textový soubor s url adresou projektu (preferujeme rozdělení miniprojektů do jednotlivých větví, např. miniprojekt-1, miniprojekt-2, …).
miniprojekt-1
miniprojekt-2
Pokud je pro vývoj aplikace využito virtuální prostředí (například venv), je nutné odpovídající adresáře a soubory vyloučit z repozitáře pomocí .gitignore. Pro správnou funkčnost je vyžadována správa balíčků pomocí requirements.txt (viz první cvičení).
venv
.gitignore
requirements.txt
Vytvořte webovou aplikaci ve frameworku Flask s pomocí knihovny Bootstrap. Součástí aplikace budou alespoň 3 endpointy - Dashboard, Přihlášení, Registrace.
Na stránce Dashboard budou alespoň tyto elementy: Poslední naměřená hodnota s časem zápisu, Tabulka zobrazující posledních 15 naměřených hodnot (sloupce = ID, Teplota, Čas zápisu), Tlačítko pro smazání nejstarší hodnoty. Naměřená data simulujte následujícím slovníkovým seznamem, který definujte v main.py:
DATA=[ {"id": 0,"temperature": 21,"timestamp": "2025-01-01 01:00:00"}, {"id": 1,"temperature": 33,"timestamp": "2025-01-01 01:05:52"}, {"id": 2,"temperature": 38,"timestamp": "2025-01-01 01:10:23"}, {"id": 3,"temperature": 21,"timestamp": "2025-01-01 01:15:17"}, {"id": 4,"temperature": 24,"timestamp": "2025-01-01 01:20:08"}, {"id": 5,"temperature": 35,"timestamp": "2025-01-01 01:25:42"}, {"id": 6,"temperature": 40,"timestamp": "2025-01-01 01:30:00"}, {"id": 7,"temperature": 37,"timestamp": "2025-01-01 01:35:19"}, {"id": 8,"temperature": 37,"timestamp": "2025-01-01 01:40:25"}, {"id": 9,"temperature": 20,"timestamp": "2025-01-01 01:45:53"}, {"id": 10,"temperature": 35,"timestamp": "2025-01-01 01:50:15"}, {"id": 11,"temperature": 34,"timestamp": "2025-01-01 01:55:19"}, {"id": 12,"temperature": 28,"timestamp": "2025-01-01 02:00:46"}, {"id": 13,"temperature": 23,"timestamp": "2025-01-01 02:05:55"}, {"id": 14,"temperature": 25,"timestamp": "2025-01-01 02:10:20"}, {"id": 15,"temperature": 23,"timestamp": "2025-01-01 02:15:43"}, {"id": 16,"temperature": 23,"timestamp": "2025-01-01 02:20:52"}, {"id": 17,"temperature": 31,"timestamp": "2025-01-01 02:25:47"}, {"id": 18,"temperature": 29,"timestamp": "2025-01-01 02:30:35"}, {"id": 19,"temperature": 31,"timestamp": "2025-01-01 02:35:52"}, {"id": 20,"temperature": 35,"timestamp": "2025-01-01 02:40:28"}, {"id": 21,"temperature": 26,"timestamp": "2025-01-01 02:45:53"}, {"id": 22,"temperature": 35,"timestamp": "2025-01-01 02:50:50"}, {"id": 23,"temperature": 28,"timestamp": "2025-01-01 02:55:56"}, {"id": 24,"temperature": 39,"timestamp": "2025-01-01 03:00:31"}, {"id": 25,"temperature": 36,"timestamp": "2025-01-01 03:05:56"}, {"id": 26,"temperature": 39,"timestamp": "2025-01-01 03:10:40"}, {"id": 27,"temperature": 23,"timestamp": "2025-01-01 03:15:47"}, {"id": 28,"temperature": 31,"timestamp": "2025-01-01 03:20:11"}, {"id": 29,"temperature": 21,"timestamp": "2025-01-01 03:25:43"}, {"id": 30,"temperature": 23,"timestamp": "2025-01-01 03:30:58"}, {"id": 32,"temperature": 28,"timestamp": "2025-01-01 03:35:51"}, {"id": 31,"temperature": 29,"timestamp": "2025-01-01 03:40:46"}, {"id": 33,"temperature": 31,"timestamp": "2025-01-01 03:45:38"}, {"id": 34,"temperature": 40,"timestamp": "2025-01-01 03:50:09"}, {"id": 35,"temperature": 37,"timestamp": "2025-01-01 03:55:26"}, {"id": 36,"temperature": 32,"timestamp": "2025-01-01 04:00:25"}, {"id": 37,"temperature": 39,"timestamp": "2025-01-01 04:05:03"}, {"id": 38,"temperature": 31,"timestamp": "2025-01-01 04:10:39"}, {"id": 39,"temperature": 31,"timestamp": "2025-01-01 04:15:16"}, {"id": 40,"temperature": 32,"timestamp": "2025-01-01 04:20:14"}, {"id": 41,"temperature": 33,"timestamp": "2025-01-01 04:25:03"}, {"id": 42,"temperature": 21,"timestamp": "2025-01-01 04:30:01"}, {"id": 43,"temperature": 34,"timestamp": "2025-01-01 04:35:24"}, {"id": 44,"temperature": 39,"timestamp": "2025-01-01 04:40:10"}, {"id": 45,"temperature": 36,"timestamp": "2025-01-01 04:45:47"}, {"id": 46,"temperature": 40,"timestamp": "2025-01-01 04:50:18"}, {"id": 47,"temperature": 27,"timestamp": "2025-01-01 04:55:35"}, {"id": 48,"temperature": 37,"timestamp": "2025-01-01 05:00:11"}, {"id": 49,"temperature": 38,"timestamp": "2025-01-01 05:05:45"} ]
navbar
Speciální případy, které student musí ošetřit:
BONUS (2b): Na dashboard přidejte graf naměřených hodnot v čase.
Místo slovníkového seznamu implementujte SQLite databázi. Databáze bude mít dvě tabulky - Data, Users. Zprovozněte registraci a přihlašování uživatelů.
Data
Users
Dále definujte REST API s následujícími endpointy:
{“temperature“: <value>}
URI endpointy pro API oddělte od ostatních endpointů do vlastního api_routes.py souboru. Endopointy budou mít prefix /api/<api endpoint>.
api_routes.py
/api/<api endpoint>
BONUS (2b): Definujte endpoint pro získání všech naměřených hodnot. Součástí endpointu bude nepovinný argument sort, který bude rozhodovat o tom, zda budou data v odpovědi řazena od nejnovější, nebo od nejstarší hodnoty. Argument může nabývat hodnot [asc, desc].
sort
[asc, desc]
Naprogramujte Raspberry Pi Pico W tak, aby periodicky odesílalo data o aktuální teplotě do SQLite databáze. Ke komunikaci použijte MQTT protokol.
BONUS (2 b): Zajistěte MQTT QoS třídy 1.
Rozšiřte funkcionalitu webové aplikace a programu pro Raspberry Pi Pico W o obousměrnou MQTT komunikaci. Pico W bude kromě odesílání naměřených dat také přijímat příkazy z webového serveru pro ovládání LED diody a řízení měření.
BONUS (2b): Implementujte možnost nastavení periody měření přes webové rozhraní. Uživatel může zadat požadovanou periodu v sekundách, webserver odešle hodnotu přes MQTT a Pico W podle ní upraví interval měření.
Nasaďte svou Flask aplikaci do produkčního prostředí pomocí WSGI serveru.
/health
BONUS (2b): Omezte počet požadavků na jednotlivých API endpointech pomocí rate-limitingu. O stavu limitů informujte v odpovídajících hodnotách HTTP hlavičky (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset). Při překročení server odpovídá správným HTTP kódem.
Virtualizujte svou Flask aplikaci pomocí Docker technologií.
BONUS (2b): Konfigurace Docker volumes pro persistenci dat (alespoň pro InfluxDB). Po zastavení, odstranění, znovuvytvoření a spuštění kontejneru jsou dostupná data z doby před zastavením kontejneru.