fix repeatable migrations
This commit is contained in:
137
db/routines/R__005_fn_cop_estimate.sql
Normal file
137
db/routines/R__005_fn_cop_estimate.sql
Normal file
@@ -0,0 +1,137 @@
|
||||
-- =============================================================
|
||||
-- R__005_fn_cop_estimate.sql
|
||||
-- EMS Platform – odhad COP tepelného čerpadla dle venkovní teploty
|
||||
-- Repeatable migration
|
||||
-- =============================================================
|
||||
|
||||
CREATE OR REPLACE FUNCTION ems.fn_cop_estimate(
|
||||
p_heat_pump_id INT,
|
||||
p_outdoor_temp_c NUMERIC
|
||||
)
|
||||
RETURNS NUMERIC(4,2)
|
||||
LANGUAGE plpgsql
|
||||
STABLE
|
||||
AS $$
|
||||
DECLARE
|
||||
v_cop_rated NUMERIC;
|
||||
v_cop_ref_temp NUMERIC;
|
||||
v_cop_estimated NUMERIC;
|
||||
BEGIN
|
||||
-- Načíst referenční COP a teplotu z konfigurace čerpadla
|
||||
SELECT cop_rated, cop_temp_reference_c
|
||||
INTO v_cop_rated, v_cop_ref_temp
|
||||
FROM ems.asset_heat_pump
|
||||
WHERE id = p_heat_pump_id;
|
||||
|
||||
IF v_cop_rated IS NULL OR v_cop_ref_temp IS NULL THEN
|
||||
-- Fallback: obecný odhad pro vzduch-voda TČ bez konfigurace
|
||||
-- Zdroj: přibližná lineární závislost COP na venkovní teplotě
|
||||
-- COP ≈ 2.0 při -10°C, COP ≈ 4.5 při +15°C
|
||||
v_cop_estimated := 2.0 + (p_outdoor_temp_c + 10.0) * (4.5 - 2.0) / 25.0;
|
||||
ELSE
|
||||
-- Lineární interpolace od referenčního bodu
|
||||
-- COP klesá přibližně o 0.10 na každý stupeň poklesu venkovní teploty
|
||||
-- Toto je zjednodušený model – zpřesnit dle skutečných dat z tepelky
|
||||
v_cop_estimated := v_cop_rated + (p_outdoor_temp_c - v_cop_ref_temp) * 0.10;
|
||||
END IF;
|
||||
|
||||
-- Omezit na rozumné hodnoty (COP vzduch-voda reálně 1.5–6.0)
|
||||
v_cop_estimated := GREATEST(1.5, LEAST(6.0, v_cop_estimated));
|
||||
|
||||
RETURN ROUND(v_cop_estimated, 2);
|
||||
END;
|
||||
$$;
|
||||
|
||||
COMMENT ON FUNCTION ems.fn_cop_estimate(INT, NUMERIC) IS
|
||||
'Odhadne COP tepelného čerpadla pro danou venkovní teplotu.
|
||||
Používá lineární model od referenčního bodu (cop_rated při cop_temp_reference_c).
|
||||
Výstup slouží k rozhodnutí zda je výhodné spustit TČ v daném intervalu.
|
||||
Přesnost modelu zlepšit kalibrací na historická data (cop_actual z telemetrie).
|
||||
Výsledek omezen na rozsah 1.5–6.0.';
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
CREATE OR REPLACE FUNCTION ems.fn_heat_pump_cost_per_kwh_heat(
|
||||
p_heat_pump_id INT,
|
||||
p_outdoor_temp_c NUMERIC,
|
||||
p_buy_price_czk_kwh NUMERIC
|
||||
)
|
||||
RETURNS NUMERIC(8,4)
|
||||
LANGUAGE sql
|
||||
STABLE
|
||||
AS $$
|
||||
-- Cena za 1 kWh tepla = cena elektřiny / COP
|
||||
-- Čím vyšší COP, tím levnější teplo
|
||||
SELECT ROUND(
|
||||
p_buy_price_czk_kwh / NULLIF(ems.fn_cop_estimate(p_heat_pump_id, p_outdoor_temp_c), 0),
|
||||
4
|
||||
);
|
||||
$$;
|
||||
|
||||
COMMENT ON FUNCTION ems.fn_heat_pump_cost_per_kwh_heat(INT, NUMERIC, NUMERIC) IS
|
||||
'Vypočte efektivní cenu za 1 kWh dodaného tepla v Kč.
|
||||
Vstup: ID tepelného čerpadla, venkovní teplota, nákupní cena elektřiny.
|
||||
Výstup slouží k porovnání výhodnosti ohřevu v různých časových intervalech.
|
||||
Nižší hodnota = výhodnější čas pro provoz TČ.';
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
CREATE OR REPLACE FUNCTION ems.fn_heat_pump_should_run(
|
||||
p_heat_pump_id INT,
|
||||
p_interval_start TIMESTAMPTZ,
|
||||
p_outdoor_temp_c NUMERIC,
|
||||
p_tuv_tank_temp_c NUMERIC,
|
||||
p_buy_price_czk_kwh NUMERIC,
|
||||
p_max_cost_threshold NUMERIC DEFAULT 3.0 -- Kč/kWh tepla – maximální akceptovatelná cena
|
||||
)
|
||||
RETURNS BOOLEAN
|
||||
LANGUAGE plpgsql
|
||||
STABLE
|
||||
AS $$
|
||||
DECLARE
|
||||
v_hp ems.asset_heat_pump%ROWTYPE;
|
||||
v_cost_per_kwh NUMERIC;
|
||||
v_override BOOLEAN;
|
||||
BEGIN
|
||||
SELECT * INTO v_hp FROM ems.asset_heat_pump WHERE id = p_heat_pump_id;
|
||||
|
||||
-- Kontrola override (blokování TČ)
|
||||
SELECT EXISTS(
|
||||
SELECT 1 FROM ems.site_override
|
||||
WHERE site_id = v_hp.site_id
|
||||
AND override_type = 'block_heat_pump'
|
||||
AND valid_from <= p_interval_start
|
||||
AND (valid_to IS NULL OR valid_to > p_interval_start)
|
||||
) INTO v_override;
|
||||
|
||||
IF v_override THEN
|
||||
RETURN false;
|
||||
END IF;
|
||||
|
||||
-- Povinný ohřev: teplota pod minimem
|
||||
IF p_tuv_tank_temp_c IS NOT NULL AND p_tuv_tank_temp_c < v_hp.tuv_min_temp_c THEN
|
||||
RETURN true;
|
||||
END IF;
|
||||
|
||||
-- Zásobník je plný
|
||||
IF p_tuv_tank_temp_c IS NOT NULL AND p_tuv_tank_temp_c >= v_hp.tuv_max_temp_c THEN
|
||||
RETURN false;
|
||||
END IF;
|
||||
|
||||
-- Ekonomické rozhodnutí: spustit pokud cena tepla je pod prahem
|
||||
v_cost_per_kwh := ems.fn_heat_pump_cost_per_kwh_heat(
|
||||
p_heat_pump_id, p_outdoor_temp_c, p_buy_price_czk_kwh
|
||||
);
|
||||
|
||||
RETURN v_cost_per_kwh <= p_max_cost_threshold;
|
||||
END;
|
||||
$$;
|
||||
|
||||
COMMENT ON FUNCTION ems.fn_heat_pump_should_run(INT, TIMESTAMPTZ, NUMERIC, NUMERIC, NUMERIC, NUMERIC) IS
|
||||
'Rozhodne zda má tepelné čerpadlo v daném intervalu běžet.
|
||||
Logika priorit:
|
||||
1. Pokud existuje override block_heat_pump → false.
|
||||
2. Pokud teplota zásobníku pod tuv_min_temp_c → true (povinný ohřev).
|
||||
3. Pokud zásobník nad tuv_max_temp_c → false.
|
||||
4. Jinak ekonomické rozhodnutí: spustit pokud cena tepla ≤ p_max_cost_threshold Kč/kWh.
|
||||
Výhodné časy jsou přes poledne v chladných měsících (vyšší venkovní teplota = lepší COP).';
|
||||
Reference in New Issue
Block a user