Files
ems/docs/02-architecture.md
Dusan Vojacek 4881966d00
All checks were successful
deploy / deploy (push) Successful in 15s
test / smoke-test (push) Successful in 3s
multisite update dokumentace
2026-04-05 22:11:50 +02:00

7.6 KiB
Raw Blame History

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_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

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