next cahgnes
This commit is contained in:
@@ -13,13 +13,13 @@ Continuous aggregate vytvořený jako `CREATE MATERIALIZED VIEW … WITH (timesc
|
|||||||
- **Nepoužívat** `COMMENT ON MATERIALIZED VIEW ems.<název_ca> …` → chyba SQL state **42809** („is not a materialized view“).
|
- **Nepoužívat** `COMMENT ON MATERIALIZED VIEW ems.<název_ca> …` → chyba SQL state **42809** („is not a materialized view“).
|
||||||
- **Použít** `COMMENT ON VIEW ems.<název_ca> …` — stejný vzor jako u `telemetry_inverter_hourly` v migraci **V011**.
|
- **Použít** `COMMENT ON VIEW ems.<název_ca> …` — stejný vzor jako u `telemetry_inverter_hourly` v migraci **V011**.
|
||||||
|
|
||||||
Samotné **wrapper view** nad CA (např. `vw_telemetry_15m_7d` v repeatable `R__vw_telemetry_15m_7d.sql`) komentovat standardně `COMMENT ON VIEW`.
|
Samotné **wrapper view** nad CA (např. `vw_telemetry_15m_7d` v repeatable `R__071_vw_telemetry_15m_7d.sql`) komentovat standardně `COMMENT ON VIEW`.
|
||||||
|
|
||||||
## Struktura repa
|
## Struktura repa
|
||||||
|
|
||||||
- **Definice CA + `add_continuous_aggregate_policy`**: verzovaná migrace `db/migration/V0xx__*.sql` (po aplikaci na DB neměnit — nová V migrace).
|
- **Definice CA + `add_continuous_aggregate_policy`**: verzovaná migrace `db/migration/V0xx__*.sql` (po aplikaci na DB neměnit — nová V migrace).
|
||||||
- **Definice čtecího view nad CA**: raději **repeatable** `db/views/R__vw_*.sql`, aby šla měnit jedna aktuální verze bez nové V migrace.
|
- **Definice čtecího view nad CA**: raději **repeatable** `db/views/R__NNN_vw_*.sql` (číselný prefix kvůli pořadí Flyway), aby šla měnit jedna aktuální verze bez nové V migrace.
|
||||||
- **PostgREST**: `GRANT SELECT` na view v `db/views/R__z_postgrest_ems_anon_grants.sql`, ne na samotný CA.
|
- **PostgREST**: `GRANT SELECT` na view v `db/views/R__072_z_postgrest_ems_anon_grants.sql`, ne na samotný CA.
|
||||||
|
|
||||||
## Odkaz v dokumentaci
|
## Odkaz v dokumentaci
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ DB_PASSWORD=change_me_strong_password
|
|||||||
# POSTGRES_MAX_CONNECTIONS=300
|
# POSTGRES_MAX_CONNECTIONS=300
|
||||||
# ---- PostgREST ----
|
# ---- PostgREST ----
|
||||||
POSTGREST_JWT_SECRET=change_me_jwt_secret_min_32_chars
|
POSTGREST_JWT_SECRET=change_me_jwt_secret_min_32_chars
|
||||||
# PostgREST anonymní role (viz db/migration/V009__postgrest_roles.sql + R__z_postgrest_ems_anon_grants.sql).
|
# PostgREST anonymní role (viz db/migration/V009__postgrest_roles.sql + R__072_z_postgrest_ems_anon_grants.sql).
|
||||||
POSTGREST_ANON_ROLE=ems_anon
|
POSTGREST_ANON_ROLE=ems_anon
|
||||||
|
|
||||||
# ---- OTE CZ import ----
|
# ---- OTE CZ import ----
|
||||||
|
|||||||
2
.idea/data_source_mapping.xml
generated
2
.idea/data_source_mapping.xml
generated
@@ -4,7 +4,7 @@
|
|||||||
<file url="file://$PROJECT_DIR$/../ems-cursor-db-pracovni/debug-forecast.sql" value="26ebef46-ff23-475b-8adc-082723263a02" />
|
<file url="file://$PROJECT_DIR$/../ems-cursor-db-pracovni/debug-forecast.sql" value="26ebef46-ff23-475b-8adc-082723263a02" />
|
||||||
<file url="file://$PROJECT_DIR$/../ems-cursor-db-pracovni/porovnani-view-status.sql" value="26ebef46-ff23-475b-8adc-082723263a02" />
|
<file url="file://$PROJECT_DIR$/../ems-cursor-db-pracovni/porovnani-view-status.sql" value="26ebef46-ff23-475b-8adc-082723263a02" />
|
||||||
<file url="file://$PROJECT_DIR$/db/migration/V009__postgrest_roles.sql" value="26ebef46-ff23-475b-8adc-082723263a02" />
|
<file url="file://$PROJECT_DIR$/db/migration/V009__postgrest_roles.sql" value="26ebef46-ff23-475b-8adc-082723263a02" />
|
||||||
<file url="file://$PROJECT_DIR$/db/views/R__z_postgrest_ems_anon_grants.sql" value="26ebef46-ff23-475b-8adc-082723263a02" />
|
<file url="file://$PROJECT_DIR$/db/views/R__072_z_postgrest_ems_anon_grants.sql" value="26ebef46-ff23-475b-8adc-082723263a02" />
|
||||||
<file url="file://$PROJECT_DIR$/scripts/analysis/ote_arbitrage_proxy.sql" value="26ebef46-ff23-475b-8adc-082723263a02" />
|
<file url="file://$PROJECT_DIR$/scripts/analysis/ote_arbitrage_proxy.sql" value="26ebef46-ff23-475b-8adc-082723263a02" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
12
CLAUDE.md
12
CLAUDE.md
@@ -133,7 +133,7 @@ Multi-site Energy Management System: optimalizuje FVE, baterii a flexibilní zá
|
|||||||
| `modbus_command` | Journal Modbus zápisů (pending → written → verified / mismatch / failed); retry a vazba na `planning_run`; u Deye exportu `deye_physical_mode` (PASSIVE/SELL/CHARGE). |
|
| `modbus_command` | Journal Modbus zápisů (pending → written → verified / mismatch / failed); retry a vazba na `planning_run`; u Deye exportu `deye_physical_mode` (PASSIVE/SELL/CHARGE). |
|
||||||
| `cutoff_switch_log` | Log přepnutí cut-off přepínačů (mikroinvertory); edge trigger, důvod a cena. |
|
| `cutoff_switch_log` | Log přepnutí cut-off přepínačů (mikroinvertory); edge trigger, důvod a cena. |
|
||||||
|
|
||||||
**View / funkce (nejsou tabulky):** `vw_site_effective_price`, `vw_site_directory`, `vw_modbus_last_verified`, `vw_asset_inverter_modbus_poll`, `vw_asset_ev_charger_modbus_poll`, `vw_asset_heat_pump_modbus_poll`, `vw_latest_telemetry`, `vw_telemetry_hourly_7d`, `vw_telemetry_15m_7d` (15min agregát pro dashboard sloty; repeatable `R__vw_telemetry_15m_7d.sql`), `vw_audit_summary`, `vw_operating_mode`, `vw_forecast_accuracy_by_lead_time`, `vw_forecast_accuracy_daily`; `fn_effective_price`, `fn_green_bonus_revenue`, `fn_cop_estimate`, `fn_fill_audit_interval`, `fn_fill_forecast_accuracy`, `fn_set_mode`, `fn_expire_modes` (vrací řádky přepnutí pro Discord), `fn_restore_previous_mode`, `fn_update_ev_arrival_stats`, `fn_ev_expected_arrival`, `fn_update_baseline_stats`, `fn_get_baseline_forecast`, `fn_update_market_price_stats`, `fn_update_tuv_usage_stats`, `fn_get_predicted_price`, dále read-modely: `fn_site_configuration`, `fn_site_full_status`, `fn_site_notifications_context`, `fn_plan_current_bundle`, `fn_planning_run_horizon`, `fn_planning_future_price_days`, `fn_economics_daily_month`, `fn_economics_monthly_chart`, `fn_economics_lock_day`, `fn_economics_unlock_day`, `fn_energy_flows_daily_month`, `fn_energy_flows_intervals_day`, `fn_forecast_pv_split`, `fn_ev_sessions_active`, `fn_ev_session_apply_patch`, `fn_ev_arrival_prediction_bundle`, `fn_ev_session_transition`, `fn_negative_price_predictions`, `fn_latest_ote_day_stats`, `fn_ote_day_slot_stats_prague`, `fn_ote_list_missing_days`, `fn_site_effective_prices_day_prague`, `fn_modbus_journal_list`, `fn_modbus_written_command_ids`, `fn_modbus_commands_by_ids`, `fn_inverter_modbus_caps_patch`, `fn_set_mode_with_context`, `fn_fill_audit_for_site_window`, plánování: `fn_load_planning_slots_full`, `fn_planning_site_context`, `fn_pv_forecast_correction_factor`, `fn_planning_run_commit`, `fn_planning_slot_boundary_prague`, `fn_planning_interval_at_offset`, `fn_telemetry_inverter_sample`, `fn_telemetry_ev_charger_sample`, `fn_telemetry_heat_pump_sample`, `fn_battery_cycle_audit`, Deye helpery: `fn_deye_pack_system_time`, `fn_deye_clock_drift_sec`, `fn_deye_time_point_regs`, `fn_deye_tou_inactive_signature`, `fn_modbus_last_verified_map`.
|
**View / funkce (nejsou tabulky):** `vw_site_effective_price`, `vw_site_directory`, `vw_modbus_last_verified`, `vw_asset_inverter_modbus_poll`, `vw_asset_ev_charger_modbus_poll`, `vw_asset_heat_pump_modbus_poll`, `vw_latest_telemetry`, `vw_telemetry_hourly_7d`, `vw_telemetry_15m_7d` (15min agregát pro dashboard sloty; repeatable `R__071_vw_telemetry_15m_7d.sql`), `vw_audit_summary`, `vw_operating_mode`, `vw_forecast_accuracy_by_lead_time`, `vw_forecast_accuracy_daily`; `fn_effective_price`, `fn_green_bonus_revenue`, `fn_cop_estimate`, `fn_fill_audit_interval`, `fn_fill_forecast_accuracy`, `fn_set_mode`, `fn_expire_modes` (vrací řádky přepnutí pro Discord), `fn_restore_previous_mode`, `fn_update_ev_arrival_stats`, `fn_ev_expected_arrival`, `fn_update_baseline_stats`, `fn_get_baseline_forecast`, `fn_update_market_price_stats`, `fn_update_tuv_usage_stats`, `fn_get_predicted_price`, dále read-modely: `fn_site_configuration`, `fn_site_full_status`, `fn_site_notifications_context`, `fn_plan_current_bundle`, `fn_planning_run_horizon`, `fn_planning_future_price_days`, `fn_economics_daily_month`, `fn_economics_monthly_chart`, `fn_economics_lock_day`, `fn_economics_unlock_day`, `fn_energy_flows_daily_month`, `fn_energy_flows_intervals_day`, `fn_forecast_pv_split`, `fn_ev_sessions_active`, `fn_ev_session_apply_patch`, `fn_ev_arrival_prediction_bundle`, `fn_ev_session_transition`, `fn_negative_price_predictions`, `fn_latest_ote_day_stats`, `fn_ote_day_slot_stats_prague`, `fn_ote_list_missing_days`, `fn_site_effective_prices_day_prague`, `fn_modbus_journal_list`, `fn_modbus_written_command_ids`, `fn_modbus_commands_by_ids`, `fn_inverter_modbus_caps_patch`, `fn_set_mode_with_context`, `fn_fill_audit_for_site_window`, plánování: `fn_load_planning_slots_full`, `fn_planning_site_context`, `fn_pv_forecast_correction_factor`, `fn_planning_run_commit`, `fn_planning_slot_boundary_prague`, `fn_planning_interval_at_offset`, `fn_telemetry_inverter_sample`, `fn_telemetry_ev_charger_sample`, `fn_telemetry_heat_pump_sample`, `fn_battery_cycle_audit`, Deye helpery: `fn_deye_pack_system_time`, `fn_deye_clock_drift_sec`, `fn_deye_time_point_regs`, `fn_deye_tou_inactive_signature`, `fn_modbus_last_verified_map`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -164,22 +164,22 @@ Specifikace z `docs/02-architecture.md`, modulových docs a komentářů v `plan
|
|||||||
|-------|-----|
|
|-------|-----|
|
||||||
| Pochopit systém end-to-end | `docs/01-overview.md`, `docs/02-architecture.md` |
|
| Pochopit systém end-to-end | `docs/01-overview.md`, `docs/02-architecture.md` |
|
||||||
| Tabulky, vazby, jednotky | `docs/03-data-model.md` |
|
| Tabulky, vazby, jednotky | `docs/03-data-model.md` |
|
||||||
| OTE ceny, marže, efektivní cena | `docs/04-modules/market-prices.md`, `db/views/R__vw_site_effective_price.sql`, `backend/services/price_importer.py` |
|
| OTE ceny, marže, efektivní cena | `docs/04-modules/market-prices.md`, `db/views/R__061_vw_site_effective_price.sql`, `backend/services/price_importer.py` |
|
||||||
| Multi-site UI (combobox), seznam aktivních lokalit | `GET /api/v1/me/sites` v `backend/app/main.py`, `frontend/src/context/SiteSelectionContext.tsx`, `useSiteStatus` (filtr `vw_site_status`) |
|
| Multi-site UI (combobox), seznam aktivních lokalit | `GET /api/v1/me/sites` v `backend/app/main.py`, `frontend/src/context/SiteSelectionContext.tsx`, `useSiteStatus` (filtr `vw_site_status`) |
|
||||||
| FVE forecast, počasí | `docs/04-modules/forecast.md` |
|
| FVE forecast, počasí | `docs/04-modules/forecast.md` |
|
||||||
| Bazální spotřeba | `docs/04-modules/consumption.md` |
|
| Bazální spotřeba | `docs/04-modules/consumption.md` |
|
||||||
| TČ, COP, TUV | `docs/04-modules/heat-pump.md`, `db/routines/R__fn_cop_estimate.sql` |
|
| TČ, COP, TUV | `docs/04-modules/heat-pump.md`, `db/routines/R__005_fn_cop_estimate.sql` |
|
||||||
| Modbus, telemetrie, agregace | `docs/04-modules/telemetry.md` |
|
| Modbus, telemetrie, agregace | `docs/04-modules/telemetry.md` |
|
||||||
| Dashboard přehled – 15min grafy slotů, SoC vs. živá telemetrie | `docs/04-modules/telemetry.md` (CA `telemetry_inverter_15m`, view `vw_telemetry_15m_7d`), `frontend/src/hooks/useDashboardData.ts`, `frontend/src/components/charts/SocTuvChart.tsx` |
|
| Dashboard přehled – 15min grafy slotů, SoC vs. živá telemetrie | `docs/04-modules/telemetry.md` (CA `telemetry_inverter_15m`, view `vw_telemetry_15m_7d`), `frontend/src/hooks/useDashboardData.ts`, `frontend/src/components/charts/SocTuvChart.tsx` |
|
||||||
| Modbus journal, verifikace, Discord | `docs/04-modules/modbus-command-journal.md` |
|
| Modbus journal, verifikace, Discord | `docs/04-modules/modbus-command-journal.md` |
|
||||||
| Deye registry (FC 0x10, 108/109/141/142/178/143) | `docs/04-modules/modbus-registers.md` |
|
| Deye registry (FC 0x10, 108/109/141/142/178/143) | `docs/04-modules/modbus-registers.md` |
|
||||||
| Export setpointů, Loxone HTTP | `docs/04-modules/control.md`, `docs/loxone-integration.md` |
|
| Export setpointů, Loxone HTTP | `docs/04-modules/control.md`, `docs/loxone-integration.md` |
|
||||||
| LP solver, rolling replan, korekce FVE, horizont 96h | `docs/04-modules/planning.md`, `docs/04-modules/planning-extended-horizon.md`, `planning_engine.py` |
|
| LP solver, rolling replan, korekce FVE, horizont 96h | `docs/04-modules/planning.md`, `docs/04-modules/planning-extended-horizon.md`, `planning_engine.py` |
|
||||||
| Provozní režimy AUTO / SELF_SUSTAIN / … | `docs/04-modules/operating-modes.md`, `db/migration/V004__operating_modes.sql`, `R__fn_set_mode.sql` |
|
| Provozní režimy AUTO / SELF_SUSTAIN / … | `docs/04-modules/operating-modes.md`, `db/migration/V004__operating_modes.sql`, `db/routines/R__044_fn_set_mode.sql` |
|
||||||
| EV, session, deadline charging | `docs/04-modules/ev-charging.md`, `db/migration/V006__vehicles.sql` |
|
| EV, session, deadline charging | `docs/04-modules/ev-charging.md`, `db/migration/V006__vehicles.sql` |
|
||||||
| Curtailment A, zelený bonus B | `db/migration/V005__planning_curtailment.sql` |
|
| Curtailment A, zelený bonus B | `db/migration/V005__planning_curtailment.sql` |
|
||||||
| Rolling plán, forecast log | `db/migration/V007__rolling_replanning.sql` |
|
| Rolling plán, forecast log | `db/migration/V007__rolling_replanning.sql` |
|
||||||
| Audit 15min | `db/routines/R__fn_fill_audit_interval.sql`, `docs/04-modules/telemetry.md` |
|
| Audit 15min | `db/routines/R__019_fn_fill_audit_interval.sql`, `docs/04-modules/telemetry.md` |
|
||||||
| Nové sloupce / tabulky | nový `db/migration/V00x__*.sql` + případně `db/routines` / `db/views` |
|
| Nové sloupce / tabulky | nový `db/migration/V00x__*.sql` + případně `db/routines` / `db/views` |
|
||||||
| JSONB read-model (`fn_*`, `fetch_json`) | `docs/02-architecture.md` sekce Read-model JSONB, `app/db_json.py` |
|
| JSONB read-model (`fn_*`, `fetch_json`) | `docs/02-architecture.md` sekce Read-model JSONB, `app/db_json.py` |
|
||||||
| Self-hosted deploy (Gitea, Caddy, `/opt/ems-deploy`) | `docs/deployment-self-hosted.md`, `deploy/deploy.sh` |
|
| Self-hosted deploy (Gitea, Caddy, `/opt/ems-deploy`) | `docs/deployment-self-hosted.md`, `deploy/deploy.sh` |
|
||||||
@@ -192,7 +192,7 @@ Specifikace z `docs/02-architecture.md`, modulových docs a komentářů v `plan
|
|||||||
## Konvence (krátce)
|
## Konvence (krátce)
|
||||||
|
|
||||||
- Python: `snake_case`, type hints, Pydantic pro API modely.
|
- Python: `snake_case`, type hints, Pydantic pro API modely.
|
||||||
- SQL: `snake_case`, explicitní FK; Flyway pořadí `V###__` / repeatable `R__`.
|
- SQL: `snake_case`, explicitní FK; Flyway pořadí `V###__` / repeatable `R__NNN_*.sql` (třímístný prefix = pořadí závislostí mezi fn/vw).
|
||||||
- Timescale **continuous aggregate** (CA): komentář k objektu CA je **`COMMENT ON VIEW`**, ne `COMMENT ON MATERIALIZED VIEW` (PG hlásí 42809). Viz `.cursor/rules/timescale-continuous-aggregate.mdc`.
|
- Timescale **continuous aggregate** (CA): komentář k objektu CA je **`COMMENT ON VIEW`**, ne `COMMENT ON MATERIALIZED VIEW` (PG hlásí 42809). Viz `.cursor/rules/timescale-continuous-aggregate.mdc`.
|
||||||
- Výkon **W**, energie **Wh**, ceny **Kč/kWh**; čas v DB **`TIMESTAMPTZ` (UTC)**.
|
- Výkon **W**, energie **Wh**, ceny **Kč/kWh**; čas v DB **`TIMESTAMPTZ` (UTC)**.
|
||||||
- NIKDY neupravuj existující V__ migrační soubory po jejich aplikaci na DB.
|
- NIKDY neupravuj existující V__ migrační soubory po jejich aplikaci na DB.
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
## Read-model JSONB (`ems.fn_*`)
|
## Read-model JSONB (`ems.fn_*`)
|
||||||
|
|
||||||
FastAPI endpointy pro dashboard a konfiguraci preferují **jedno volání** `select ems.fn_*(…)` vracející **jsonb** (pole řádků, agregace, merge locků), aby v Pythonu nezůstávaly ad-hoc `SELECT`/`JOIN`/`WITH`. Pomocník `app.db_json.fetch_json` vrací `dict`/`list`. Telemetrie a IO zůstávají v Pythonu; čisté agregace a sjednocení TZ patří do SQL. Opakované migrace: `db/routines/R__fn_*.sql`, `db/views/R__vw_*.sql`.
|
FastAPI endpointy pro dashboard a konfiguraci preferují **jedno volání** `select ems.fn_*(…)` vracející **jsonb** (pole řádků, agregace, merge locků), aby v Pythonu nezůstávaly ad-hoc `SELECT`/`JOIN`/`WITH`. Pomocník `app.db_json.fetch_json` vrací `dict`/`list`. Telemetrie a IO zůstávají v Pythonu; čisté agregace a sjednocení TZ patří do SQL. Opakované migrace: `db/routines/R__NNN_fn_*.sql`, `db/views/R__NNN_vw_*.sql` (prefix `NNN` = pořadí závislostí pro Flyway).
|
||||||
|
|
||||||
## Komponenty
|
## Komponenty
|
||||||
|
|
||||||
@@ -77,18 +77,18 @@ ems-platform/
|
|||||||
V002__timescale_hypertables.sql
|
V002__timescale_hypertables.sql
|
||||||
V003__seed_site_home01.sql
|
V003__seed_site_home01.sql
|
||||||
routines/
|
routines/
|
||||||
R__fn_effective_price.sql
|
R__003_fn_baseline_consumption.sql
|
||||||
R__fn_cop_estimate.sql
|
R__005_fn_cop_estimate.sql
|
||||||
R__fn_baseline_consumption.sql
|
R__011_fn_effective_price.sql
|
||||||
R__fn_fill_audit_interval.sql
|
R__019_fn_fill_audit_interval.sql
|
||||||
(historicky) R__fn_plan_day.sql – primární plánování je PuLP v Pythonu
|
(historicky) R__fn_plan_day.sql – primární plánování je PuLP v Pythonu
|
||||||
R__fn_create_planning_run.sql
|
R__fn_create_planning_run.sql
|
||||||
views/
|
views/
|
||||||
R__vw_site_effective_price.sql
|
R__061_vw_site_effective_price.sql
|
||||||
R__vw_latest_telemetry.sql
|
R__058_vw_latest_telemetry.sql
|
||||||
R__vw_telemetry_15m_7d.sql
|
R__071_vw_telemetry_15m_7d.sql
|
||||||
R__vw_actual_baseline.sql
|
R__vw_actual_baseline.sql
|
||||||
R__vw_audit_summary.sql
|
R__053_vw_audit_summary.sql
|
||||||
R__vw_heat_pump_cop_history.sql
|
R__vw_heat_pump_cop_history.sql
|
||||||
flyway.conf
|
flyway.conf
|
||||||
|
|
||||||
|
|||||||
@@ -271,9 +271,9 @@ CREATE TABLE telemetry_inverter (
|
|||||||
Z `telemetry_inverter` počítá TimescaleDB materializované agregáty (viz `db/migration/V011__indexes_and_aggregates.sql`, `V039__telemetry_inverter_15m_aggregate.sql`):
|
Z `telemetry_inverter` počítá TimescaleDB materializované agregáty (viz `db/migration/V011__indexes_and_aggregates.sql`, `V039__telemetry_inverter_15m_aggregate.sql`):
|
||||||
|
|
||||||
- **`telemetry_inverter_hourly`** – hodinové průměry + `LAST(battery_soc_percent, measured_at)`; čtení přes view **`vw_telemetry_hourly_7d`**.
|
- **`telemetry_inverter_hourly`** – hodinové průměry + `LAST(battery_soc_percent, measured_at)`; čtení přes view **`vw_telemetry_hourly_7d`**.
|
||||||
- **`telemetry_inverter_15m`** – čtvrthodinové bucket odpovídající 15min slotům EMS; čtení přes **`vw_telemetry_15m_7d`** (definice v **`db/views/R__vw_telemetry_15m_7d.sql`**, repeatable).
|
- **`telemetry_inverter_15m`** – čtvrthodinové bucket odpovídající 15min slotům EMS; čtení přes **`vw_telemetry_15m_7d`** (definice v **`db/views/R__071_vw_telemetry_15m_7d.sql`**, repeatable).
|
||||||
|
|
||||||
PostgREST role `ems_anon` má `SELECT` na tyto views (ne na samotné CA); u view nad CA je `security_invoker = false`, stejně jako u `vw_telemetry_hourly_7d` (viz `db/views/R__z_postgrest_ems_anon_grants.sql`).
|
PostgREST role `ems_anon` má `SELECT` na tyto views (ne na samotné CA); u view nad CA je `security_invoker = false`, stejně jako u `vw_telemetry_hourly_7d` (viz `db/views/R__072_z_postgrest_ems_anon_grants.sql`).
|
||||||
|
|
||||||
### `telemetry_ev_charger`
|
### `telemetry_ev_charger`
|
||||||
Stav EV nabíječek.
|
Stav EV nabíječek.
|
||||||
|
|||||||
@@ -70,6 +70,6 @@ Tabulka pro budoucí logování **cut-off** přepínačů (mikroinvertory / GEN
|
|||||||
|
|
||||||
## Související soubory
|
## Související soubory
|
||||||
|
|
||||||
- Migrace: `db/migration/V023__modbus_command_journal.sql`, `V025__deye_physical_mode.sql`, `V030__deye_clock_sync_at.sql`, `V044__deye_register_max_current_a.sql`; repeatables `db/routines/R__fn_set_mode.sql` (`fn_expire_modes` vrací detail přepnutí pro notifikace)
|
- Migrace: `db/migration/V023__modbus_command_journal.sql`, `V025__deye_physical_mode.sql`, `V030__deye_clock_sync_at.sql`, `V044__deye_register_max_current_a.sql`; repeatables `db/routines/R__044_fn_set_mode.sql` (`fn_expire_modes` vrací detail přepnutí pro notifikace)
|
||||||
- Backend: `backend/services/control_exporter.py`, `backend/services/modbus_client.py`, `backend/services/notification_service.py`, `backend/app/main.py`
|
- Backend: `backend/services/control_exporter.py`, `backend/services/modbus_client.py`, `backend/services/notification_service.py`, `backend/app/main.py`
|
||||||
- Registry Deye: `docs/04-modules/modbus-registers.md`
|
- Registry Deye: `docs/04-modules/modbus-registers.md`
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ ev_expected_w[t] = arrival_prob * ev_charge_power_typical
|
|||||||
### Fáze 3a – Historické průměry cen (hotovo)
|
### Fáze 3a – Historické průměry cen (hotovo)
|
||||||
|
|
||||||
1. Tabulka `ems.market_price_stats` – migrace **V022__extended_planning.sql**
|
1. Tabulka `ems.market_price_stats` – migrace **V022__extended_planning.sql**
|
||||||
2. `fn_update_market_price_stats()` – `db/routines/R__fn_extended_planning.sql`, APScheduler **14:45** (`main.py`)
|
2. `fn_update_market_price_stats()` – `db/routines/R__018_fn_extended_planning.sql`, APScheduler **14:45** (`main.py`)
|
||||||
3. Solver: slotová páteř `generate_series` + `COALESCE(effective_*, fn_get_predicted_price(...))` v `_load_slots`
|
3. Solver: slotová páteř `generate_series` + `COALESCE(effective_*, fn_get_predicted_price(...))` v `_load_slots`
|
||||||
|
|
||||||
### Fáze 3b – TUV statistika potřeby (hotovo)
|
### Fáze 3b – TUV statistika potřeby (hotovo)
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ Nad `ems.telemetry_inverter` běží dva **continuous aggregate** (TimescaleDB);
|
|||||||
| Objekt | Bucket | View pro PostgREST / UI | Poznámka |
|
| Objekt | Bucket | View pro PostgREST / UI | Poznámka |
|
||||||
|--------|--------|-------------------------|----------|
|
|--------|--------|-------------------------|----------|
|
||||||
| `ems.telemetry_inverter_hourly` | 1 hodina | `ems.vw_telemetry_hourly_7d` | CA a view v **V011**; `security_invoker` v **V031**. Hodinové trendy. |
|
| `ems.telemetry_inverter_hourly` | 1 hodina | `ems.vw_telemetry_hourly_7d` | CA a view v **V011**; `security_invoker` v **V031**. Hodinové trendy. |
|
||||||
| `ems.telemetry_inverter_15m` | 15 minut | `ems.vw_telemetry_15m_7d` | **`db/views/R__vw_telemetry_15m_7d.sql`** – posledních 7 dní, zarovnání s 15min sloty přehledu. |
|
| `ems.telemetry_inverter_15m` | 15 minut | `ems.vw_telemetry_15m_7d` | **`db/views/R__071_vw_telemetry_15m_7d.sql`** – posledních 7 dní, zarovnání s 15min sloty přehledu. |
|
||||||
|
|
||||||
**Frontend přehled** (`frontend/src/hooks/useDashboardData.ts`): skutečné výkony a SoC po slotech bere z **`/vw_telemetry_15m_7d`** (klíč slotu = začátek 15min intervalu v UTC, stejně jako `floorSlotUtcMs` v grafu). Horní karty a **aktuální SoC** v grafu jsou dál z **`vw_site_status`** (poslední 1min vzorek) a z WebSocketu `/ws/telemetry`, aby „teď“ odpovídalo boxu i po refreshi agregátu.
|
**Frontend přehled** (`frontend/src/hooks/useDashboardData.ts`): skutečné výkony a SoC po slotech bere z **`/vw_telemetry_15m_7d`** (klíč slotu = začátek 15min intervalu v UTC, stejně jako `floorSlotUtcMs` v grafu). Horní karty a **aktuální SoC** v grafu jsou dál z **`vw_site_status`** (poslední 1min vzorek) a z WebSocketu `/ws/telemetry`, aby „teď“ odpovídalo boxu i po refreshi agregátu.
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Shrnutí otevřených bodů z `docs/06-open-questions.md`, checklistů v modulec
|
|||||||
| Popis |
|
| Popis |
|
||||||
|-------|
|
|-------|
|
||||||
| **Zelený bonus:** přesunuto na `asset_pv_array` (`green_bonus_*`), výpočet `fn_green_bonus_revenue()`, audit_filler (`fn_fill_audit_interval`) počítá bonus z výroby pole; legacy sloupce odstraněny ze `site_market_config` (V018). |
|
| **Zelený bonus:** přesunuto na `asset_pv_array` (`green_bonus_*`), výpočet `fn_green_bonus_revenue()`, audit_filler (`fn_fill_audit_interval`) počítá bonus z výroby pole; legacy sloupce odstraněny ze `site_market_config` (V018). |
|
||||||
| **Rozšířený horizont plánování 96h** (fáze 3a+3b+3c): tabulky `market_price_stats`, `tuv_usage_stats`, funkce `fn_update_market_price_stats`, `fn_update_tuv_usage_stats`, `fn_get_predicted_price` (V022 + `R__fn_extended_planning.sql`), solver váhy 1,0 / 0,7 / 0,4, joby 14:45 / 00:45 v `main.py`. |
|
| **Rozšířený horizont plánování 96h** (fáze 3a+3b+3c): tabulky `market_price_stats`, `tuv_usage_stats`, funkce `fn_update_market_price_stats`, `fn_update_tuv_usage_stats`, `fn_get_predicted_price` (V022 + `R__018_fn_extended_planning.sql`), solver váhy 1,0 / 0,7 / 0,4, joby 14:45 / 00:45 v `main.py`. |
|
||||||
| **Import OTE – robustní provoz:** timeouty + retry/backoff v `price_importer.py`, detailní error kódy v API, fallback D+1 → dnešek, scheduler importů 13:30 / 14:00 / 00:05. |
|
| **Import OTE – robustní provoz:** timeouty + retry/backoff v `price_importer.py`, detailní error kódy v API, fallback D+1 → dnešek, scheduler importů 13:30 / 14:00 / 00:05. |
|
||||||
| **Fail-safe bez OTE dat:** při predikovaných cenách v kritickém okně je zákaz exportu; vybíjení baterie omezeno jen v predikovaných slotech; runtime guard v `control_exporter.py` brání SELL v nejistém stavu. |
|
| **Fail-safe bez OTE dat:** při predikovaných cenách v kritickém okně je zákaz exportu; vybíjení baterie omezeno jen v predikovaných slotech; runtime guard v `control_exporter.py` brání SELL v nejistém stavu. |
|
||||||
| **Forecast provoz:** refresh každé 2 hodiny (`:05`), konfigurovatelný Open-Meteo horizont (`OPEN_METEO_FORECAST_DAYS`, default 7, clamp 2..16), endpoint pro UI vrací latest-run bez duplicit slotů. |
|
| **Forecast provoz:** refresh každé 2 hodiny (`:05`), konfigurovatelný Open-Meteo horizont (`OPEN_METEO_FORECAST_DAYS`, default 7, clamp 2..16), endpoint pro UI vrací latest-run bez duplicit slotů. |
|
||||||
|
|||||||
@@ -43,6 +43,6 @@ Tento soubor slouží jako živý seznam věcí které je potřeba rozhodnout p
|
|||||||
|
|
||||||
## Vyřešeno
|
## Vyřešeno
|
||||||
|
|
||||||
- **PostgREST anon role:** `ems_anon`, read-only na vybrané views a tabulky (migrace `V009__postgrest_roles.sql` + repeatable `R__z_postgrest_ems_anon_grants.sql` kvůli pořadí Flyway); zápisy přes FastAPI. Compose / `.env`: `POSTGREST_ANON_ROLE=ems_anon`, PostgREST `PGRST_DB_ANON_ROLE`.
|
- **PostgREST anon role:** `ems_anon`, read-only na vybrané views a tabulky (migrace `V009__postgrest_roles.sql` + repeatable `R__072_z_postgrest_ems_anon_grants.sql` kvůli pořadí Flyway); zápisy přes FastAPI. Compose / `.env`: `POSTGREST_ANON_ROLE=ems_anon`, PostgREST `PGRST_DB_ANON_ROLE`.
|
||||||
|
|
||||||
- **Multi-site (částečně):** OTE import jednou pro celý systém do `market_interval_price`; frontend výběr lokality (`SiteSelectionContext`, persist `ems.selected_site_id`), API `GET /api/v1/me/sites` (zatím všechny aktivní site). Chybí: mapování uživatel → site, JWT/RLS u PostgREST (viz otevřená otázka výše).
|
- **Multi-site (částečně):** OTE import jednou pro celý systém do `market_interval_price`; frontend výběr lokality (`SiteSelectionContext`, persist `ems.selected_site_id`), API `GET /api/v1/me/sites` (zatím všechny aktivní site). Chybí: mapování uživatel → site, JWT/RLS u PostgREST (viz otevřená otázka výše).
|
||||||
|
|||||||
Reference in New Issue
Block a user