implementace Ekonomiky
All checks were successful
test / smoke-test (push) Successful in 5s
deploy / deploy (push) Successful in 11s

This commit is contained in:
Dusan Vojacek
2026-04-05 20:10:43 +02:00
parent caf3f522e2
commit 5fcc47bce2
13 changed files with 1310 additions and 31 deletions

View File

@@ -92,24 +92,49 @@ BEGIN
ELSE COALESCE(v_sell_price, 0) END;
END IF;
-- Zelený bonus: výroba bonusových polí z poslední ok predikce pro slot (Wh = W × 0,25 h)
-- Zelený bonus: výroba bonusových polí z reálné telemetrie (Wh = průměr W × 0,25 h)
v_pv_b_production_wh := NULL;
FOR r_bonus IN
SELECT id
FROM ems.asset_pv_array
WHERE site_id = p_site_id
AND green_bonus_czk_kwh IS NOT NULL
SELECT pa.id, pa.inverter_id, pa.telemetry_source
FROM ems.asset_pv_array pa
WHERE pa.site_id = p_site_id
AND pa.green_bonus_czk_kwh IS NOT NULL
AND pa.green_bonus_valid_from <= p_interval_start::DATE
AND (pa.green_bonus_valid_to IS NULL
OR pa.green_bonus_valid_to > p_interval_start::DATE)
LOOP
SELECT fpi.power_w * 0.25
INTO v_array_prod_wh
FROM ems.forecast_pv_interval fpi
JOIN ems.forecast_pv_run fpr ON fpr.id = fpi.run_id
WHERE fpr.site_id = p_site_id
AND fpr.pv_array_id = r_bonus.id
AND fpi.interval_start = p_interval_start
AND fpr.status = 'ok'
ORDER BY fpr.created_at DESC
LIMIT 1;
v_array_prod_wh := NULL;
IF r_bonus.telemetry_source IS NOT NULL AND r_bonus.inverter_id IS NOT NULL THEN
SELECT AVG(
CASE r_bonus.telemetry_source
WHEN 'gen_port' THEN ti.gen_port_power_w
WHEN 'pv_strings' THEN COALESCE(ti.pv1_power_w, 0)
+ COALESCE(ti.pv2_power_w, 0)
WHEN 'pv_total' THEN ti.pv_power_w
ELSE NULL
END
)::NUMERIC * 0.25
INTO v_array_prod_wh
FROM ems.telemetry_inverter ti
WHERE ti.inverter_id = r_bonus.inverter_id
AND ti.measured_at >= p_interval_start
AND ti.measured_at < v_interval_end;
END IF;
-- Fallback na forecast pokud telemetrie není k dispozici
IF v_array_prod_wh IS NULL THEN
SELECT fpi.power_w * 0.25
INTO v_array_prod_wh
FROM ems.forecast_pv_interval fpi
JOIN ems.forecast_pv_run fpr ON fpr.id = fpi.run_id
WHERE fpr.site_id = p_site_id
AND fpr.pv_array_id = r_bonus.id
AND fpi.interval_start = p_interval_start
AND fpr.status = 'ok'
ORDER BY fpr.created_at DESC
LIMIT 1;
END IF;
v_array_prod_wh := COALESCE(v_array_prod_wh, 0);
IF v_pv_b_production_wh IS NULL THEN
@@ -175,7 +200,8 @@ $$;
COMMENT ON FUNCTION ems.fn_fill_audit_interval(INT, TIMESTAMPTZ) IS
'Naplní nebo aktualizuje jeden řádek v audit_interval pro danou lokalitu a 15min interval.
Agreguje průměry z telemetrie (střídač, EV, TČ), porovná se skutečným plánem a spočítá odchylky.
Zelený bonus: součet přes všechna pole s nastaveným bonusem, výroba z poslední ok forecast_pv_interval.
Zelený bonus: součet přes pole s green_bonus_czk_kwh; výroba primárně z reálné telemetrie
(dle asset_pv_array.telemetry_source), fallback na forecast_pv_interval pokud telemetrie chybí.
Volat každých 15 minut pro interval který právě skončil.';
-- ============================================================