second version

This commit is contained in:
Dusan Vojacek
2026-04-03 14:23:16 +02:00
parent 897b95f728
commit 9f4126946d
105 changed files with 9738 additions and 1470 deletions

View File

@@ -12,19 +12,23 @@ RETURNS VOID
LANGUAGE plpgsql
AS $$
DECLARE
v_interval_end TIMESTAMPTZ := p_interval_start + INTERVAL '15 minutes';
v_run_id INT;
v_avg_pv_power_w INT;
v_avg_battery_power_w INT;
v_avg_grid_power_w INT;
v_avg_load_power_w INT;
v_last_soc NUMERIC(5,2);
v_sum_ev_power_w INT;
v_avg_hp_power_w INT;
v_plan ems.planning_interval%ROWTYPE;
v_buy_price NUMERIC;
v_sell_price NUMERIC;
v_actual_cost NUMERIC := NULL;
v_interval_end TIMESTAMPTZ := p_interval_start + INTERVAL '15 minutes';
v_run_id INT;
v_avg_pv_power_w INT;
v_avg_battery_power_w INT;
v_avg_grid_power_w INT;
v_avg_load_power_w INT;
v_last_soc NUMERIC(5,2);
v_sum_ev_power_w INT;
v_avg_hp_power_w INT;
v_plan ems.planning_interval%ROWTYPE;
v_buy_price NUMERIC;
v_sell_price NUMERIC;
v_actual_cost NUMERIC := NULL;
v_green_bonus_czk NUMERIC := 0;
v_pv_b_production_wh NUMERIC;
v_array_prod_wh NUMERIC;
r_bonus RECORD;
BEGIN
-- Najít aktivní plán pro tento interval
SELECT pi.* INTO v_plan
@@ -88,6 +92,37 @@ 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)
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
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 := COALESCE(v_array_prod_wh, 0);
IF v_pv_b_production_wh IS NULL THEN
v_pv_b_production_wh := 0;
END IF;
v_pv_b_production_wh := v_pv_b_production_wh + v_array_prod_wh;
v_green_bonus_czk := v_green_bonus_czk + ems.fn_green_bonus_revenue(
r_bonus.id,
p_interval_start,
v_array_prod_wh
);
END LOOP;
-- Upsert do audit_interval
INSERT INTO ems.audit_interval (
site_id, interval_start, planning_run_id,
@@ -97,6 +132,8 @@ BEGIN
actual_ev_power_w,
actual_heat_pump_power_w,
actual_cost_czk,
pv_b_production_wh,
green_bonus_czk,
deviation_grid_w,
deviation_cost_czk
) VALUES (
@@ -109,6 +146,8 @@ BEGIN
v_sum_ev_power_w,
v_avg_hp_power_w,
ROUND(v_actual_cost, 4),
v_pv_b_production_wh,
ROUND(v_green_bonus_czk, 4),
CASE WHEN v_plan.run_id IS NOT NULL
THEN v_avg_grid_power_w - v_plan.grid_setpoint_w
ELSE NULL END,
@@ -126,6 +165,8 @@ BEGIN
actual_ev_power_w = EXCLUDED.actual_ev_power_w,
actual_heat_pump_power_w = EXCLUDED.actual_heat_pump_power_w,
actual_cost_czk = EXCLUDED.actual_cost_czk,
pv_b_production_wh = EXCLUDED.pv_b_production_wh,
green_bonus_czk = EXCLUDED.green_bonus_czk,
deviation_grid_w = EXCLUDED.deviation_grid_w,
deviation_cost_czk = EXCLUDED.deviation_cost_czk;
END;
@@ -134,6 +175,7 @@ $$;
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.
Volat každých 15 minut pro interval který právě skončil.';
-- ============================================================