Files
ems/db/views/R__vw_site_effective_price_economics.sql
Dusan Vojacek 64221f701a
All checks were successful
deploy / deploy (push) Successful in 13s
test / smoke-test (push) Successful in 5s
fix view
2026-04-10 21:57:08 +02:00

108 lines
6.0 KiB
SQL
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.
-- =============================================================
-- R__vw_site_effective_price_economics.sql
-- EMS Platform ekonomické views (závisí na vw_site_effective_price)
-- Musí běžet až PO R__vw_site_effective_price.sql (abecední pořadí Flyway).
-- Repeatable migration
--
-- Pozn.: při změně pořadí / názvů výstupních sloupců nestačí CREATE OR REPLACE VIEW —
-- PostgreSQL hlásí 42P16 („cannot change name of view column …“). Nejdřív DROP.
-- =============================================================
DROP VIEW IF EXISTS ems.vw_economics_daily CASCADE;
DROP VIEW IF EXISTS ems.vw_economics_interval CASCADE;
CREATE VIEW ems.vw_economics_interval AS
SELECT
ai.site_id,
ai.interval_start,
-- Wh-based kWh (per-direction, zachytí bidirectional flow)
ROUND(COALESCE(ai.actual_grid_import_wh, GREATEST(ai.actual_grid_power_w, 0)::NUMERIC / 4) / 1000, 4)
AS import_kwh,
ROUND(COALESCE(ai.actual_grid_export_wh, ABS(LEAST(ai.actual_grid_power_w, 0))::NUMERIC / 4) / 1000, 4)
AS export_kwh,
-- Směrové cashflow: kolik Kč za import ze sítě / kolik Kč za export do sítě
ROUND(
COALESCE(ai.actual_grid_import_wh, GREATEST(ai.actual_grid_power_w, 0)::NUMERIC / 4)
/ 1000.0 * COALESCE(ep.effective_buy_price_czk_kwh, 0), 4
) AS grid_import_cashflow_czk,
ROUND(
COALESCE(ai.actual_grid_export_wh, ABS(LEAST(ai.actual_grid_power_w, 0))::NUMERIC / 4)
/ 1000.0 * COALESCE(ep.effective_sell_price_czk_kwh, 0), 4
) AS grid_export_revenue_czk,
-- Net cost (zpětná kompatibilita): import_cashflow - export_revenue
ROUND(
COALESCE(ai.actual_grid_import_wh, GREATEST(ai.actual_grid_power_w, 0)::NUMERIC / 4)
/ 1000.0 * COALESCE(ep.effective_buy_price_czk_kwh, 0)
- COALESCE(ai.actual_grid_export_wh, ABS(LEAST(ai.actual_grid_power_w, 0))::NUMERIC / 4)
/ 1000.0 * COALESCE(ep.effective_sell_price_czk_kwh, 0), 4
) AS dynamic_cost_czk,
ai.actual_cost_czk AS stored_cost_czk,
ai.green_bonus_czk,
pi.expected_cost_czk AS planned_cost_czk,
pi.grid_setpoint_w AS planned_grid_w,
ai.actual_grid_power_w,
ep.effective_buy_price_czk_kwh,
ep.effective_sell_price_czk_kwh,
pi.effective_buy_price AS planned_buy_price,
pi.effective_sell_price AS planned_sell_price,
ai.actual_pv_power_w,
ai.actual_load_power_w,
ai.actual_ev_power_w,
ai.actual_heat_pump_power_w,
ai.actual_battery_power_w,
ai.actual_battery_soc_pct,
ai.actual_grid_import_wh,
ai.actual_grid_export_wh,
ai.actual_batt_charge_wh,
ai.actual_batt_discharge_wh,
ai.actual_pv_production_wh,
ai.actual_load_consumption_wh
FROM ems.audit_interval ai
LEFT JOIN ems.vw_site_effective_price ep
ON ep.site_id = ai.site_id AND ep.interval_start = ai.interval_start
LEFT JOIN ems.planning_interval pi
ON pi.run_id = ai.planning_run_id AND pi.interval_start = ai.interval_start;
COMMENT ON VIEW ems.vw_economics_interval IS
'Dynamické ekonomické vyhodnocení per 15min slot.
import/export kWh primárně z per-direction Wh sloupců audit_interval (Deye counter / per-minute split),
fallback na průměrný výkon pro zpětnou kompatibilitu se starými daty.
grid_import_cashflow_czk / grid_export_revenue_czk = směrové cashflow podle skutečného toku energie.';
CREATE VIEW ems.vw_economics_daily AS
SELECT
site_id,
date_trunc('day', interval_start AT TIME ZONE 'Europe/Prague')::date AS day_local,
COUNT(*)::int AS interval_count,
ROUND(SUM(import_kwh), 3) AS import_kwh,
ROUND(SUM(export_kwh), 3) AS export_kwh,
ROUND(SUM(GREATEST(actual_pv_power_w, 0)::NUMERIC / 4000), 3) AS pv_kwh,
ROUND(SUM(GREATEST(actual_load_power_w, 0)::NUMERIC / 4000), 3) AS load_kwh,
ROUND(SUM(GREATEST(actual_ev_power_w, 0)::NUMERIC / 4000), 3) AS ev_kwh,
ROUND(SUM(GREATEST(actual_heat_pump_power_w, 0)::NUMERIC / 4000), 3) AS hp_kwh,
ROUND(SUM(GREATEST(actual_pv_power_w, 0)::NUMERIC / 4000)
- SUM(export_kwh), 3) AS pv_self_consumption_kwh,
-- Směrové cashflow (podle směru energie, ne znaménka peněz)
ROUND(SUM(grid_import_cashflow_czk), 2) AS grid_import_cashflow_czk,
ROUND(SUM(grid_export_revenue_czk), 2) AS grid_export_revenue_czk,
-- Staré sloupce (podle znaménka peněz zpětná kompatibilita)
ROUND(SUM(CASE WHEN dynamic_cost_czk > 0
THEN dynamic_cost_czk ELSE 0 END), 2) AS import_cost_czk,
ROUND(SUM(CASE WHEN dynamic_cost_czk < 0
THEN ABS(dynamic_cost_czk) ELSE 0 END), 2) AS export_revenue_czk,
ROUND(SUM(dynamic_cost_czk), 2) AS net_cost_czk,
ROUND(COALESCE(SUM(green_bonus_czk), 0), 2) AS green_bonus_czk,
ROUND(-SUM(dynamic_cost_czk)
+ COALESCE(SUM(green_bonus_czk), 0), 2) AS total_balance_czk,
ROUND(SUM(planned_cost_czk), 2) AS planned_net_cost_czk,
ROUND(-COALESCE(SUM(planned_cost_czk), 0), 2) AS planned_balance_czk,
ROUND(SUM(dynamic_cost_czk)
- COALESCE(SUM(planned_cost_czk), 0), 2) AS deviation_cost_czk
FROM ems.vw_economics_interval
GROUP BY site_id,
date_trunc('day', interval_start AT TIME ZONE 'Europe/Prague')::date;
COMMENT ON VIEW ems.vw_economics_daily IS
'Denní souhrn ekonomiky. planned_balance_czk = jen síťové náklady (bez zeleného bonusu).
grid_import_cashflow_czk / grid_export_revenue_czk = směrové cashflow podle skutečného toku energie.';