feat: testowanie nastrojów za pomocą rest api
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# ESP32-C6 Desk Buddy
|
||||
|
||||
Animowany "biurkowy przyjaciel" na Seeed XIAO ESP32-C6 z czujnikiem gestów PAJ7620 i wyświetlaczem OLED 128×64. Reaguje na gesty emocjami, wykonuje webhooki HTTP, wyświetla informacje na żądanie i symuluje potrzeby w stylu Tamagotchi. Konfigurowany przez przeglądarkę.
|
||||
Animowany "biurkowy przyjaciel" na Seeed XIAO ESP32-C6 z czujnikiem gestów PAJ7620 i wyświetlaczem OLED 128×64. Reaguje na gesty emocjami, wykonuje webhooki HTTP, wyświetla informacje na żądanie, symuluje potrzeby w stylu Tamagotchi i pokazuje pogodę z Open-Meteo. Konfigurowany przez przeglądarkę.
|
||||
|
||||
---
|
||||
|
||||
@@ -73,6 +73,21 @@ Buddy ma trzy potrzeby narastające z czasem:
|
||||
|
||||
Gdy potrzeba przekroczy próg, Buddy automatycznie zmienia nastrój. W lewym dolnym rogu ekranu pojawiają się litery: **G** (głód), **Z** (zabawa), **M** (mycie).
|
||||
|
||||
### Pogoda (Open-Meteo)
|
||||
|
||||
Co jakiś czas (konfigurowalny interwał) wyświetlany jest ekran pogodowy — zamiast oczu pojawia się ikona pogodowa, a zamiast ust — temperatura i ciśnienie:
|
||||
|
||||
| Ikona | Warunki |
|
||||
|-------|---------|
|
||||
| Słońce | Bezchmurnie (WMO 0) |
|
||||
| Chmura + słońce | Częściowe zachmurzenie (WMO 1–2) |
|
||||
| Chmura | Zachmurzenie, mgła (WMO 3–48) |
|
||||
| Deszcz | Mżawka, deszcz, przelotny deszcz (WMO 51–82) |
|
||||
| Śnieg | Śnieg i opady śnieżne (WMO 71–86) |
|
||||
| Burza | Burza z piorunami (WMO 95–99) |
|
||||
|
||||
Dane z [Open-Meteo](https://open-meteo.com/) — **darmowe, bez klucza API**. Dwuetapowe pobieranie: geocoding (nazwa miasta → współrzędne) + aktualna prognoza.
|
||||
|
||||
### Gesty (PAJ7620)
|
||||
|
||||
Czujnik rozpoznaje 9 gestów ręką:
|
||||
@@ -132,27 +147,56 @@ Po uruchomieniu wejdź przeglądarką na adres IP wypisany w Serial (lub na OLED
|
||||
http://<IP>/
|
||||
```
|
||||
|
||||
Dla każdego gestu można ustawić:
|
||||
- **URL webhoka** — endpoint HTTP POST (pusty = wyłączony)
|
||||
- **Nastrój** — jaki nastrój ustawić po geście (0 = bez zmiany)
|
||||
- **Akcja** — co zrobić/wyświetlić na OLED
|
||||
- **ON** — czy gest jest aktywny
|
||||
Panel zawiera cztery sekcje:
|
||||
|
||||
#### Gesty
|
||||
Dla każdego gestu można ustawić URL webhoka, nastrój, akcję i czy gest jest aktywny.
|
||||
|
||||
#### Tamagotchi
|
||||
Podgląd aktualnych potrzeb (głód, szczęście, higiena) z paskami postępu oraz przyciski: **Nakarm**, **Pobaw się**, **Umyj**.
|
||||
|
||||
#### Pogoda
|
||||
Aktualny stan pogody (ikona, temperatura, ciśnienie) oraz ustawienia:
|
||||
- **Miasto** — nazwa w języku polskim lub angielskim (np. `Warszawa`, `Kraków`)
|
||||
- **Co ile sekund** — interwał wyświetlania ekranu pogodowego (0 = wyłączony)
|
||||
- **Pokazuj przez (s)** — czas trwania ekranu pogodowego
|
||||
|
||||
#### Test nastroju
|
||||
12 przycisków do ręcznego ustawienia dowolnego nastroju na **10 sekund** — do testowania wyglądu oczu bez czujnika gestów.
|
||||
|
||||
### JSON API
|
||||
|
||||
```bash
|
||||
# Odczyt konfiguracji gestów
|
||||
GET http://<IP>/api/config
|
||||
# Odczyt / zapis konfiguracji gestów
|
||||
GET http://<IP>/api/config
|
||||
POST http://<IP>/api/config (Content-Type: application/json)
|
||||
|
||||
# Zapis konfiguracji gestów
|
||||
POST http://<IP>/api/config
|
||||
Content-Type: application/json
|
||||
# Stan Tamagotchi
|
||||
GET http://<IP>/api/tama
|
||||
|
||||
# Akcje Tamagotchi
|
||||
POST http://<IP>/api/tama/feed
|
||||
POST http://<IP>/api/tama/play
|
||||
POST http://<IP>/api/tama/clean
|
||||
|
||||
# Aktualna pogoda + konfiguracja
|
||||
GET http://<IP>/api/weather
|
||||
|
||||
# Zapis konfiguracji pogody (form POST)
|
||||
POST http://<IP>/weather/save
|
||||
|
||||
# Test nastroju (0–11) na 10 sekund
|
||||
POST http://<IP>/api/mood/test?m=1
|
||||
```
|
||||
|
||||
Przykład zapisu gestów:
|
||||
|
||||
```json
|
||||
{
|
||||
"wave": {
|
||||
"url": "http://homeassistant.local:8123/api/webhook/my_hook",
|
||||
"mood": 6,
|
||||
"action": 4,
|
||||
"action": 0,
|
||||
"enabled": true
|
||||
},
|
||||
"up": {
|
||||
@@ -215,6 +259,10 @@ Plik `data/config.json` zawiera wyłącznie konfigurację gestów (bez danych Wi
|
||||
}
|
||||
```
|
||||
|
||||
### Konfiguracja pogody
|
||||
|
||||
Konfiguracja przechowywana w `/weather.json` na LittleFS — zapisywana przez panel webowy, persystuje przez restarty. Nie wymaga reflashowania.
|
||||
|
||||
---
|
||||
|
||||
## Instalacja i build
|
||||
@@ -243,7 +291,7 @@ task flash-monitor # uploadfs + upload + monitor
|
||||
|---------|------|
|
||||
| `task build` | Tylko kompilacja |
|
||||
| `task flash` | Wgraj filesystem + firmware |
|
||||
| `task upload` | Wgraj tylko firmware |
|
||||
| `task upload` | Wgraj tylko firmware (zachowuje LittleFS) |
|
||||
| `task uploadfs` | Wgraj `data/wifi.json` + `data/config.json` |
|
||||
| `task monitor` | Monitor portu szeregowego |
|
||||
| `task flash-monitor` | Pełne wgranie + monitor |
|
||||
@@ -251,8 +299,11 @@ task flash-monitor # uploadfs + upload + monitor
|
||||
| `task gestures` | Edytuj gesty (`data/config.json`) + wgraj FS |
|
||||
| `task config-download` | Pobierz konfigurację gestów z urządzenia |
|
||||
| `task erase-flash` | Skasuj flash i wgraj od nowa |
|
||||
| `task test` | Uruchom testy jednostkowe (native, na Mac) |
|
||||
| `task` | Lista wszystkich zadań |
|
||||
|
||||
> **Uwaga:** `task uploadfs` nadpisuje LittleFS — konfiguracja pogody zapisana przez panel webowy zostanie utracona. Użyj `task upload` do aktualizacji samego firmware'u.
|
||||
|
||||
### Zmiana WiFi bez rekompilacji
|
||||
|
||||
```bash
|
||||
@@ -272,13 +323,31 @@ mathieucarbou/ESPAsyncWebServer@^3.3.12
|
||||
|
||||
## Architektura kodu
|
||||
|
||||
Cały projekt mieści się w jednym pliku `src/main.cpp`.
|
||||
Logika domenowa wydzielona do bibliotek w `lib/` — zero zależności od Arduino, kompilowalne natywnie.
|
||||
|
||||
```
|
||||
src/main.cpp — hardware + HTTP server + WiFi + FreeRTOS (~1100 linii)
|
||||
lib/
|
||||
BuddyDomain/ — BuddyTypes.h, BuddyLogic.h/.cpp (nastroje, mruganie, źrenice)
|
||||
TamaLogic/ — TamaLogic.h/.cpp (potrzeby, ticki, override nastroju)
|
||||
GestureConfig/ — GestureConfig.h/.cpp (struct, enums, tablice stringów)
|
||||
test/native/
|
||||
test_buddy/ — ~21 testów Unity (initBuddy, mruganie, saccady)
|
||||
test_tama/ — ~19 testów Unity (ticki, progi, tamaFeed/Play/Clean)
|
||||
data/
|
||||
wifi.json — dane WiFi (nie commitowane)
|
||||
config.json — konfiguracja gestów
|
||||
partitions.csv — własna tablica partycji (app 1.75 MB, LittleFS 2.19 MB)
|
||||
```
|
||||
|
||||
### Przepływ inicjalizacji
|
||||
|
||||
```
|
||||
setup()
|
||||
loadAllConfig()
|
||||
/wifi.json → WIFI_SSID/PASS (nigdy nie serwowane)
|
||||
/config.json → gConfig[] (gesty)
|
||||
/weather.json → weatherCfg (miasto, interwał)
|
||||
initBuddy() + initTama()
|
||||
Wire.begin(22, 23) ← I2C0 HP dla obu urządzeń
|
||||
u8g2.begin() ← SSD1306 HW I2C
|
||||
@@ -286,15 +355,16 @@ setup()
|
||||
connectWiFi() → NTP sync
|
||||
setupHttpServer() ← AsyncWebServer port 80
|
||||
|
||||
loop() ← polling
|
||||
loop()
|
||||
sensor.readGesture() ← co 500 ms
|
||||
handleGesture()
|
||||
executeAction() ← tama efekt + overlay OLED
|
||||
executeAction() ← efekt tama + overlay OLED
|
||||
setBuddyMood() ← skonfigurowany lub domyślny
|
||||
fireWebhook() ← FreeRTOS task (async)
|
||||
updateTama() ← co 10 s (potrzeby + mood override)
|
||||
updateBuddyAnim() ← co 50 ms (mruganie, saccady, ZZZ)
|
||||
showBuddyScreen() ← co 50 ms (~20 fps)
|
||||
drawWeatherFace() ← priorytet gdy weatherShowUntil aktywny
|
||||
```
|
||||
|
||||
### Kluczowe decyzje techniczne
|
||||
@@ -306,13 +376,23 @@ loop() ← polling
|
||||
| `Wire1` (LP I2C) zablokowany na GPIO6/7 (niedostępne na XIAO) | Jeden `Wire` (HP I2C) dla SSD1306 + PAJ7620 |
|
||||
| `setContrast()` ma zbyt wąski zakres wizualny na SSD1306 | `setPowerSave(1/0)` — komenda 0xAE/0xAF wyłącza panel |
|
||||
| Hasło WiFi dostępne przez HTTP | Oddzielny `/wifi.json` — nigdy nie serwowany; `/config.json` zawiera tylko gesty |
|
||||
| Firmware nie mieścił się w partycji OTA (1.28 MB) | Własna `partitions.csv`: app0 1.75 MB, LittleFS 2.19 MB |
|
||||
| Domena logiki — testy natywne bez sprzętu | Biblioteki w `lib/` bez zależności Arduino; `pio test -e native` |
|
||||
|
||||
### Testy
|
||||
|
||||
```bash
|
||||
task test # pio test -e native — 40 testów na Mac, bez urządzenia
|
||||
```
|
||||
|
||||
Testy pokrywają: inicjalizację stanu, cykl mrugania (OPEN→CLOSING→CLOSED→OPENING), saccady źrenic, ticki tamagotchi, progi nastrojów, tamaFeed/Play/Clean z wartościami brzegowymi.
|
||||
|
||||
---
|
||||
|
||||
## Dodawanie nowych akcji
|
||||
|
||||
1. Dodaj wartość do `enum Action` w `main.cpp`
|
||||
2. Zaktualizuj `NUM_ACTIONS` i `ACTION_LABELS[]`
|
||||
1. Dodaj wartość do `enum Action` w `GestureConfig.h`
|
||||
2. Zaktualizuj `NUM_ACTIONS` i `ACTION_LABELS[]` w `GestureConfig.cpp`
|
||||
3. Napisz funkcję `showXxxScreen()`
|
||||
4. Dodaj `case ACTION_XXX:` w `showBuddyScreen()` (sekcja overlay)
|
||||
5. Opcjonalnie: dodaj efekt tama w `executeAction()` (np. zmiana potrzeby)
|
||||
|
||||
Reference in New Issue
Block a user