Files
ems/db/views/R__058_vw_latest_telemetry.sql
Dusan Vojacek 1d5b97c65f Výkon: vw_latest_inverter / vw_latest_ev_charger přepis na LATERAL
DISTINCT ON třídilo ~195k/277k řádků hypertable při každém čtení
(fn_site_full_status 1.7 s). LATERAL limit 1 per zařízení jde po PK indexu.
Ověřeno na živé DB: identické výsledky, inverter 508→56 ms, EV 460→75 ms.
EV konektory: discovery za 30 dní (tabulka konektorů neexistuje; mrtvý
konektor po 30 dnech z latest pohledu zmizí — vědomá změna sémantiky).
Sloupce i pořadí beze změny (create or replace view kompatibilní).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 14:30:44 +02:00

157 lines
4.4 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__058_vw_latest_telemetry.sql
-- EMS Platform aktuální stav všech zařízení per lokalita
-- Repeatable migration
--
-- Výkon (audit 2026-06-11): původní DISTINCT ON přes celé hypertable
-- třídilo ~195k (inverter) / ~277k (EV) řádků při každém čtení
-- (fn_site_full_status ~1.7 s). LATERAL limit 1 per zařízení čte jen
-- špičku PK indexu ((inverter_id|charger_id, …, measured_at)).
-- =============================================================
-- security_invoker = false: oprávnění na podkladové hypertably nemusí mít ems_anon (PostgREST).
create or replace view ems.vw_latest_inverter
with (security_invoker = false)
as
select
inv.site_id,
inv.id as inverter_id,
inv.code as inverter_code,
t.measured_at,
t.pv_power_w,
t.battery_soc_percent,
t.battery_power_w,
t.grid_power_w,
t.load_power_w,
t.inverter_temp_c,
t.operating_mode,
t.fault_code,
now() - t.measured_at as data_age,
t.pv1_power_w,
t.pv2_power_w,
t.gen_port_power_w,
t.batt_charge_today_wh,
t.batt_discharge_today_wh,
t.run_state,
t.is_export_limited,
t.pv_derating_flags
from ems.asset_inverter inv
left join lateral (
select
ti.measured_at,
ti.pv_power_w,
ti.battery_soc_percent,
ti.battery_power_w,
ti.grid_power_w,
ti.load_power_w,
ti.inverter_temp_c,
ti.operating_mode,
ti.fault_code,
ti.pv1_power_w,
ti.pv2_power_w,
ti.gen_port_power_w,
ti.batt_charge_today_wh,
ti.batt_discharge_today_wh,
ti.run_state,
ti.is_export_limited,
ti.pv_derating_flags
from ems.telemetry_inverter ti
where ti.inverter_id = inv.id
order by ti.measured_at desc
limit 1
) t on true
where t.measured_at is not null;
comment on view ems.vw_latest_inverter is
'Nejnovější telemetrická data pro každý střídač (LATERAL per-inverter, PK index). Slouží pro real-time dashboard a health check.';
-- ------------------------------------------------------------
create or replace view ems.vw_latest_ev_charger
with (security_invoker = false)
as
select
ch.site_id,
ch.id as charger_id,
ch.code as charger_code,
conn.connector_id,
t.measured_at,
t.status,
t.power_w,
t.energy_kwh,
t.current_a,
t.session_id,
t.error_code,
now() - t.measured_at as data_age
from ems.asset_ev_charger ch
-- konektory za posledních 30 dní (tabulka konektorů neexistuje; konektor bez
-- telemetrie 30 dní je pro „latest“ dashboard mrtvý)
left join lateral (
select distinct tc.connector_id
from ems.telemetry_ev_charger tc
where tc.charger_id = ch.id
and tc.measured_at >= now() - interval '30 days'
) conn on true
left join lateral (
select
te.measured_at,
te.status,
te.power_w,
te.energy_kwh,
te.current_a,
te.session_id,
te.error_code
from ems.telemetry_ev_charger te
where te.charger_id = ch.id
and te.connector_id = conn.connector_id
order by te.measured_at desc
limit 1
) t on true
where t.measured_at is not null;
comment on view ems.vw_latest_ev_charger is
'Nejnovější telemetrická data pro každý konektor EV nabíječky (LATERAL per-konektor, PK index). Slouží pro dashboard a řízení nabíjení.';
-- ------------------------------------------------------------
create or replace view ems.vw_latest_heat_pump
with (security_invoker = false)
as
select
hp.site_id,
hp.id as heat_pump_id,
hp.code as heat_pump_code,
t.measured_at,
t.outdoor_temp_c,
t.tuv_tank_temp_c,
t.water_outlet_temp_c,
t.power_w,
t.operating_mode,
t.cop_actual,
t.defrost_active,
t.alarm_code,
-- Odhadovaný COP pro aktuální venkovní teplotu
ems.fn_cop_estimate(hp.id, t.outdoor_temp_c) as cop_estimated,
now() - t.measured_at as data_age
from ems.asset_heat_pump hp
left join lateral (
select
thp.measured_at,
thp.outdoor_temp_c,
thp.tuv_tank_temp_c,
thp.water_outlet_temp_c,
thp.power_w,
thp.operating_mode,
thp.cop_actual,
thp.defrost_active,
thp.alarm_code
from ems.telemetry_heat_pump thp
where thp.heat_pump_id = hp.id
order by thp.measured_at desc
limit 1
) t on true;
comment on view ems.vw_latest_heat_pump is
'Nejnovější telemetrická data pro každé tepelné čerpadlo včetně odhadovaného COP.
Slouží pro real-time dashboard a rozhodovací logiku plánování.';