fix(db): čtecí cesty telemetrie robustní vůči řídkým řádkům (idle-skip)

- fn_fill_audit_interval: EV a TČ agregace sum(power_w)/15 místo avg přes
  přítomné řádky — avg by při řídké telemetrii nadhodnotil aktivitu části
  slotu; chybějící minuta = 0 W (idle). TČ drží NULL bez power_w (MIM-B19N).
- fn_update_tuv_usage_stats: delta TUV normalizovaná na °C/min délkou mezery
  mezi řádky (gap_min), mezery > 30 min vyloučeny; pro hustá 1min data
  numericky identické s původním LAG.
- vw_pool_pump_day_energy: komentář — on_minutes drží invariant „zapnuté
  čerpadlo se ukládá každou minutu".

Pro hustá 1min data beze změny výsledků; připravuje idle-skip zápisů
v telemetry_collector (navazující commit).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dusan Vojacek
2026-06-12 19:06:23 +02:00
parent e41840cb7d
commit f71bc944b4
3 changed files with 56 additions and 42 deletions

View File

@@ -150,25 +150,28 @@ BEGIN
v_grid_export_wh := ems.fn_audit_grid_export_wh_for_economics(
v_imp_before, v_exp_before, v_avg_grid_power_w);
-- Agregovat EV nabíječky (součet průměrů po charger_id)
SELECT COALESCE(SUM(avg_power), 0)::INT
INTO v_sum_ev_power_w
FROM (
SELECT AVG(power_w) AS avg_power
FROM ems.telemetry_ev_charger
WHERE site_id = p_site_id
AND measured_at >= p_interval_start
AND measured_at < v_interval_end
GROUP BY charger_id
) sub;
-- Agregovat EV nabíječky: sum(W·min) / 15 = průměrný výkon slotu.
-- Telemetrie je idle-skip (telemetry_collector): vypnutá nabíječka má jen
-- heartbeat řádky — avg přes přítomné řádky by nabíjení části slotu
-- NADHODNOTILO; chybějící minuta = 0 W (zařízení idle).
select round(coalesce(sum(power_w), 0) / 15.0)::int
into v_sum_ev_power_w
from ems.telemetry_ev_charger
where site_id = p_site_id
and measured_at >= p_interval_start
and measured_at < v_interval_end;
-- Agregovat tepelné čerpadlo
SELECT AVG(power_w)::INT
INTO v_avg_hp_power_w
FROM ems.telemetry_heat_pump
WHERE site_id = p_site_id
AND measured_at >= p_interval_start
AND measured_at < v_interval_end;
-- Agregovat tepelné čerpadlo: stejný sumový přístup (idle-skip řádky);
-- NULL pokud žádný řádek nenese power_w (MIM-B19N příkon neměří).
select case
when count(power_w) = 0 then null
else round(sum(power_w) / 15.0)::int
end
into v_avg_hp_power_w
from ems.telemetry_heat_pump
where site_id = p_site_id
and measured_at >= p_interval_start
and measured_at < v_interval_end;
-- Efektivní cena pro výpočet skutečných nákladů
v_buy_price := ems.fn_effective_buy_price(p_site_id, p_interval_start);
@@ -377,9 +380,10 @@ BEGIN
END;
$$;
COMMENT ON FUNCTION ems.fn_fill_audit_interval(INT, TIMESTAMPTZ) IS
COMMENT ON FUNCTION ems.fn_fill_audit_interval IS
'Naplní nebo aktualizuje jeden řádek v audit_interval pro danou lokalitu a 15min interval.
Agreguje průměry z telemetrie (střídač, EV,), porovná se skutečným plánem a spočítá odchylky.
Agreguje telemetrii (střídač průměry; EV a sum/15 — idle-skip zápisy, chybějící minuta = 0 W),
porovná se skutečným plánem a spočítá odchylky.
Per-minutový split pro 6 energetických veličin (import/export/batt/PV/load Wh);
grid import/export nejprve z delta Deye total counterů (reg 522-525), fallback per-minute; poté sjednocení
fn_audit_grid_*_wh_for_economics (u jednosměrného toku max s odhadem z průměrného grid_power_w).