Files
ems/docs/02-architecture.md
Dusan Vojacek eb8dd0368f
Some checks failed
deploy / deploy (push) Failing after 1m42s
test / smoke-test (push) Successful in 2s
fix telemtrie na dahsbaordu (15min misto 1h)
2026-04-10 20:48:41 +02:00

232 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# EMS Platform Architektura
## Vrstvy systému
```
┌─────────────────────────────────────────────┐
│ React Frontend (Vite + TypeScript) │
│ Dashboard, plány, telemetrie; výběr site │
│ (combobox → /api/v1/me/sites + PostgREST) │
└─────────────┬───────────────────────────────┘
│ HTTP/REST
┌─────────────▼───────────────────────────────┐
│ PostgREST │
│ Auto-REST API z PostgreSQL schématu ems │
│ Read: views, tabulky │
│ Write: insert/update přes API │
└─────────────┬───────────────────────────────┘
│ SQL
┌─────────────▼───────────────────────────────┐
│ PostgreSQL 16 + TimescaleDB │
│ Schéma: ems │
│ Funkce, views, hypertables │
└─────────────┬───────────────────────────────┘
┌─────────────▼───────────────────────────────┐
│ FastAPI (Python) │
Scheduled tasks (APScheduler) │
telemetry_collector (každých 60s) │
price_importer (13:30, 14:00, 00:05) │
forecast_service (každé 2h, minute 05)│
planning_engine (denně 15:00) │
control_exporter (každých 15min) │
audit_filler (každých 15min) │
verify_modbus (každé 2 min) │
└──────┬──────────────────────────┬────────────┘
│ Modbus TCP │ HTTP
┌──────▼──────┐ ┌───────▼────────────┐
│ Waveshare │ │ Loxone Miniserver │
│ WS-ETH │ │ (setpoint přijímač)│
└──────┬──────┘ └────────────────────┘
│ RS485
┌──────┼──────────────────────────────┐
│ Deye SUN-20K │ Teltonika 2× │ Samsung TČ │
└────────────────┴────────────────────┴──────────────┘
```
---
## Komponenty
| Komponenta | Technologie | Port | Popis |
|---|---|---|---|
| `db` | PostgreSQL 16 + TimescaleDB | 5432 | Datová vrstva |
| `postgrest` | PostgREST 12 | 3000 | Auto-REST API |
| `backend` | Python 3.12 / FastAPI | 8000 | Logika, scheduled tasks |
| `frontend` | React + Vite + TypeScript | 5173 (dev) / 80 (prod) | UI |
---
## Adresář projektu
```
ems-platform/
CLAUDE.md
docker-compose.yml
docker-compose.dev.yml
.env.example
.env ← gitignore!
db/
migration/
V001__init_schema.sql
V002__timescale_hypertables.sql
V003__seed_site_home01.sql
routines/
R__fn_effective_price.sql
R__fn_cop_estimate.sql
R__fn_baseline_consumption.sql
R__fn_fill_audit_interval.sql
R__fn_plan_day.sql
R__fn_create_planning_run.sql
views/
R__vw_site_effective_price.sql
R__vw_latest_telemetry.sql
R__vw_telemetry_15m_7d.sql
R__vw_actual_baseline.sql
R__vw_audit_summary.sql
R__vw_heat_pump_cop_history.sql
flyway.conf
backend/
Dockerfile
requirements.txt
app/
main.py ← FastAPI app + scheduler setup
config.py ← settings z env
database.py ← asyncpg connection pool
services/
telemetry_collector.py
price_importer.py
forecast_service.py
planning_engine.py ← volá ems.fn_create_planning_run()
control_exporter.py
audit_filler.py
modbus/
deye_client.py
ev_charger_client.py
heat_pump_client.py
models/
site.py
assets.py
setpoints.py
frontend/
Dockerfile
package.json
vite.config.ts
src/
main.tsx
App.tsx
api/
postgrest.ts ← PostgREST client
backend.ts ← FastAPI client (/me/sites, …)
context/
SiteSelectionContext.tsx ← výběr lokality, localStorage
pages/
Dashboard.tsx
Planning.tsx
Telemetry.tsx
Settings.tsx
components/
PowerFlowChart.tsx
PriceChart.tsx
SocGauge.tsx
OverridePanel.tsx
docs/
01-overview.md
02-architecture.md ← tento soubor
03-data-model.md
04-modules/
market-prices.md
forecast.md
consumption.md
heat-pump.md
telemetry.md
control.md
planning.md
06-open-questions.md
```
---
## Komunikační toky
### Sběr dat (každých 60s)
```
Zařízení → Waveshare → Modbus TCP → telemetry_collector → PostgreSQL
```
### Denní plánování (15:00)
```
PostgreSQL (ceny + forecast) → fn_create_planning_run() → planning_interval
```
### Operátorské manuální akce (UI)
```
Browser → FastAPI:
GET /api/v1/me/sites ← seznam aktivních lokalit (UI combobox; bez auth zatím = všechny aktivní)
POST /api/v1/sites/{site_id}/prices/import?date=YYYY-MM-DD ← zapisuje globální market_interval_price; site_id jen validace URL
POST /api/v1/sites/{site_id}/forecast/run
POST /api/v1/sites/{site_id}/plan/run?type=daily|rolling
```
### Export setpointů (každých 15min)
```
PostgreSQL (planning_interval + overrides) → control_exporter
→ Modbus TCP → Waveshare → Deye / Teltonika / Samsung
→ HTTP → Loxone
```
### Frontend
```
Browser → PostgREST (čtení views/tabulek, filtr site_id dle výběru v UI)
Browser → FastAPI (seznam lokalit /me/sites, triggery: replanning, import cen, …)
```
---
## Deployment: single-site (výchozí)
Vše na jednom stroji (x86 mini PC nebo silnější RPi 5):
```
Docker Compose:
db (PostgreSQL + TimescaleDB)
postgrest (PostgREST)
backend (FastAPI + všechny services)
frontend (Nginx + React build)
flyway (migrace při startu)
```
### Minimální HW požadavky
| Parametr | Minimum | Doporučeno |
|---|---|---|
| CPU | 2 jádra | 4 jádra (x86) |
| RAM | 4 GB | 8 GB |
| Storage | SSD 64 GB | NVMe 256 GB |
| OS | Debian 12 / Ubuntu 22.04 | Ubuntu 22.04 LTS |
| Síť | 100 Mbps | Gigabit Ethernet |
> **Raspberry Pi 5 (8GB):** Použitelné pro single-site s SSD přes USB 3 nebo NVMe HAT.
> **Nedoporučovat microSD** TimescaleDB zápisy microSD rychle opotřebují.
---
## Flyway konfigurace
```properties
# db/flyway.conf
flyway.url=jdbc:postgresql://db:5432/ems
flyway.user=${DB_USER}
flyway.password=${DB_PASSWORD}
flyway.schemas=ems
flyway.locations=filesystem:/flyway/migration,filesystem:/flyway/routines,filesystem:/flyway/views
flyway.validateOnMigrate=true
flyway.outOfOrder=false
```
Flyway se spouští jako jednorázový kontejner při `docker-compose up`.