# 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`.