# Nutikodu veebiliides Interaktiivne ajatelg `uus67` skeemi zigbee andurite andmetele (ClickHouse). FastAPI backend + üks staatiline leht (ECharts). Eestikeelne, mobiilisõbralik, tume/hele teema. ## Ligipääs | Keskkond | URL | |----------|-----| | Avalik | https://nutikodu.odamus.com | | Tailscale | http://100.87.1.24:8095 · http://ohmu.tail20e23.ts.net:8095 | ## Funktsioonid (v1) - Temperatuuri ja niiskuse ajatelg (kahe teljega), interaktiivne zoom (pinch/pan). - Perioodivalik: 24 h / 7 p / 30 p / 90 p / 1 a / Kõik + kohandatud vahemik. - Agregeerimine: tund / päev. - **Täidetud tunnid** (kui andur ei olnud kättesaadav) on koguja poolt eelmise väärtusega asendatud (`taidetud = true`) ja kuvatakse graafikul **tühjade ringidena** — aegreas ei teki auke. - **Välistemperatuur** (eraldi koguja, Open-Meteo) kuvatakse samal graafikul rohelise joonena; niiskus/tuul/sademed salvestatakse andmebaasi. - Viimaste väärtuste kaardid + lahtiste häirete ülevaade (60 s värskendus). - PWA-manifest (installitav telefonis), `noindex`. ## API | Otspunkt | Kirjeldus | |----------|-----------| | `GET /api/meta` | seadmed, tz, andmete ulatus | | `GET /api/temperatuur?from=&to=&device=&agg=hour\|day` | aegrida | | `GET /api/valisilm?from=&to=&agg=hour\|day` | välistemperatuuri aegrida (temp, niiskus, tuul, sademed) | | `GET /api/ukseandur?from=&to=&device=` | 🔒 ukseolekute sündmused | | `GET /api/vead?from=&to=&device=` | 🔒 häirete sündmused | | `GET /api/liikumine?from=&to=&device=` | 🔒 liikumise/kohalolu sündmused | | `GET /api/energia?from=&to=&device=&agg=hour\|day` | 🔒 pistikute energiatarve | | `GET /api/uus67_latest` | 🔒 viimane energia + liikumine | | `GET /api/latest` | viimased väärtused (lahtised häired ainult sisselogitult) | | `GET /api/me` | kas päring on autenditud (`{"authed":bool}`) | | `GET /health` | tervis | Ajavahemikud kujul `YYYY-MM-DD[ HH:MM[:SS]]` või ISO (T-eraldaja). Vaikimisi viimased 7 päeva. **🔒 = nõuab autentimist** (Bearer-token automaatikale või sessiooniküpsis brauserile). Ülejäänud on avalikud. ## Autentimine - **Brauser:** ava `/login`, sisesta parool → allkirjastatud sessiooniküpsis (`HttpOnly`, `SameSite=Lax`). Välja: `/logout`. - **API / automaatika:** saada päis `Authorization: Bearer `. - **Kaitstud:** kõik `ukseandur` / `vead` / `liikumine` / `energia` / `uus67_latest` päringud. Avalikud on ainult temp/niiskus/väli/meta. - **Login-rate-limit:** 5 ebaõnnestunud katset / 300 s / IP (libisev aken). ### Näide (API-integratsioon, nt Uptime Kuma, curl, skript) ```bash # Kaitstud lõpp-punkt Bearer-tokeniga: curl -H "Authorization: Bearer $WEB_ACCESS_TOKEN" \ "http://100.87.1.24:8095/api/uus67_latest" # Tervisekontroll (avalik, Uptime Kuma monitor): curl "http://100.87.1.24:8095/health" ``` `WEB_ACCESS_TOKEN` väärtus on `nutikodu-web` `.env`-is (ohmu: `/opt/docker-compose/dev/.env`). Ära pane tokenit URL-i ega jaga avalikult. ## Keskkonnamuutujad | Muutuja | Vaikimisi | Kirjeldus | |---------|-----------|-----------| | `CH_URL` | `http://clickhouse:8123` | ClickHouse HTTP | | `CH_DB` | `uus67` | andmebaas | | `CH_USER` / `CH_PASS` | `zigbee` / – | ainult SELECT `uus67.*` | | `WEB_PASSWORD` | tühi | brauseri sisselogimise parool (`/login`) | | `WEB_ACCESS_TOKEN` | tühi | API Bearer-token (automaatikaks) | | `WEB_SECRET_KEY` | juhuslik | sessiooniküpsise allkirjastamise võti (**sea püsivaks!**) | | `SESSION_MAX_AGE` | `604800` | sessiooni kehtivus sekundites (7 p) | | `LOGIN_MAX_ATTEMPTS` | `5` | ebaõnnestunud logimiskatsed enne blokeeringut | | `LOGIN_WINDOW_SECONDS` | `300` | logimise blokeerimise aken (sek) | ## Struktuur ``` nutikodu/web/ ├── app.py # FastAPI backend (ClickHouse HTTP, JSONEachRow) ├── requirements.txt ├── Dockerfile # python:3.12-slim, port 8095 └── static/ ├── index.html # üks leht, eestikeelne ├── style.css # light/dark, mobiil-first ├── app.js # ECharts ajatelg, perioodivalik, teema ├── manifest.webmanifest ├── icon.svg └── vendor/echarts.min.js ``` ## Arendus / juurutus Kood elab workspace'is (`nutikodu/web/`) ja on juurutatud ohmu'le `/opt/docker-compose/dev/nutikodu-web/` (teenus `dev/docker-compose.yml`-is, võrkudes `main_ai_network` + `prod_net`). ```bash # Muudatuse järel (ohmu): scp app.py static/* ohmu:/opt/docker-compose/dev/nutikodu-web/... docker compose -f /opt/docker-compose/dev/docker-compose.yml up -d --build nutikodu-web docker logs -f nutikodu-web ``` ### Avalik ligipääs (2026-09-17) - **DNS:** DigitalOcean A-kirje `nutikodu.odamus.com` → `188.166.84.16`. - **Edge Caddy** (`kanad`, `/opt/edge/Caddyfile`): `nutikodu.odamus.com { reverse_proxy http://100.91.118.16:80 }`. - **Sisemine Caddy** (ohmu `prod_caddy`, `/opt/prod/Caddyfile`): `nutikodu.odamus.com:80 { reverse_proxy nutikodu-web:8095 }`. - TLS väljastab edge automaatselt. ## Edasi (järgmised iteratsioonid) - Ukseanduri olekuribad ajateljel (`/api/ukseandur` on valmis). - Häirete markerid/annotatsioonid (`/api/vead` on valmis). - Autentimine: **tehtud 2026-10-07** (sessioon + Bearer-token; vt "Autentimine").