-- ============================================================= -- V043__site_25a_fixed_buy_seed.sql -- Sloupce pro fixní nákupní energii (NT + příplatek VT) a seed lokality site-25a. -- -- Jedna verzovaná migrace: čtyři FVE pole (různá orientace), žádný mezikrok pv-a/pv-b. -- -- Obnova / přepnutí checksum na DB, kde už běžela starší varianta V043 nebo V044: -- DELETE FROM flyway_schema_history WHERE version IN ('043', '044'); -- Potom: flyway migrate -- (Sloupce buy_fixed_* zůstanou díky ADD COLUMN IF NOT EXISTS; DO blok smaže legacy pv-a/pv-b -- a doplní pv-str-*/pv-mi-* pokud chybí.) -- ============================================================= -- Fixní složka nákupu bez DPH (k distribuci / poplatkům / marži / DPH dle fn_effective_buy_price) ALTER TABLE ems.site_market_config ADD COLUMN IF NOT EXISTS buy_fixed_energy_nt_czk_kwh NUMERIC(10,6), ADD COLUMN IF NOT EXISTS buy_fixed_vt_surcharge_czk_kwh NUMERIC(10,6) NOT NULL DEFAULT 0; COMMENT ON COLUMN ems.site_market_config.buy_fixed_energy_nt_czk_kwh IS 'Při purchase_pricing_mode = fixed: základní nákupní cena energie Kč/kWh bez DPH v NT hodinách. VT = tato hodnota + buy_fixed_vt_surcharge_czk_kwh podle HDO oken.'; COMMENT ON COLUMN ems.site_market_config.buy_fixed_vt_surcharge_czk_kwh IS 'Při purchase_pricing_mode = fixed: příplatek Kč/kWh bez DPH k NT ceně ve VT oknech dle hdo_code_id.'; -- ============================================================= -- Seed lokality (idempotentní DO blok) -- Viz docs/new-site-setup-template.md – ev-charger-1 pro planner/telemetrii. -- FVE: čtyři záznamy asset_pv_array (forecast service běží per pole; planner sčítá controllable / !controllable). -- ============================================================= DO $$ DECLARE v_site_code TEXT := 'BA81'; v_host_modbus TEXT := '109.164.83.155'; v_port_modbus INT := 502; v_host_loxone TEXT := '109.164.83.155'; v_port_loxone INT := 8080; v_site_id INT; v_ep_deye INT; v_ep_ev INT; v_ep_loxone INT; v_inv_main INT; v_inv_gen INT; v_hdo_id INT; v_ch_id INT; BEGIN SELECT hc.id INTO v_hdo_id FROM ems.hdo_code hc WHERE hc.distributor = 'EGD' AND hc.code = 'custom_fve_home01' ORDER BY hc.valid_from DESC NULLS LAST LIMIT 1; INSERT INTO ems.site (code, name, timezone, latitude, longitude, active, notes) VALUES ( v_site_code, 'Lokalita 25A / 17 kW příkon', 'Europe/Prague', 49.24368977130069, 17.425553019721196, true, 'Připojení 3×25 A → import max 17 kW, export max 16 kW. ' 'Při omezení exportu do DS nastavit v Deye SmartLoad: „MI export to Grid cutoff“ = enable; ' 'po uvolnění exportu znovu disable. Veřejná IP tunelovaná z EMS serveru.' ) ON CONFLICT (code) DO UPDATE SET name = EXCLUDED.name, timezone = EXCLUDED.timezone, latitude = EXCLUDED.latitude, longitude = EXCLUDED.longitude, active = EXCLUDED.active, notes = EXCLUDED.notes RETURNING id INTO v_site_id; SELECT se.id INTO v_ep_deye FROM ems.site_endpoint se WHERE se.site_id = v_site_id AND se.endpoint_type = 'modbus_tcp' AND se.notes ILIKE '%Deye%' ORDER BY se.id LIMIT 1; IF v_ep_deye IS NULL THEN INSERT INTO ems.site_endpoint ( site_id, endpoint_type, host, port, protocol, unit_id, enabled, notes ) VALUES ( v_site_id, 'modbus_tcp', v_host_modbus, v_port_modbus, 'modbus_tcp', 1, true, 'Deye 12kW LV – Modbus TCP (Waveshare).' ) RETURNING id INTO v_ep_deye; END IF; SELECT se.id INTO v_ep_ev FROM ems.site_endpoint se WHERE se.site_id = v_site_id AND se.endpoint_type = 'modbus_tcp' AND se.notes ILIKE '%Teltonika%' ORDER BY se.id LIMIT 1; IF v_ep_ev IS NULL THEN INSERT INTO ems.site_endpoint ( site_id, endpoint_type, host, port, protocol, unit_id, enabled, notes ) VALUES ( v_site_id, 'modbus_tcp', v_host_modbus, v_port_modbus, 'modbus_tcp', 2, true, 'Teltonika TeltoCharge 22kW – stejná IP jako Deye, unit_id 2 (upřesni dle zapojení).' ) RETURNING id INTO v_ep_ev; END IF; SELECT se.id INTO v_ep_loxone FROM ems.site_endpoint se WHERE se.site_id = v_site_id AND se.endpoint_type = 'loxone_http' ORDER BY se.id LIMIT 1; IF v_ep_loxone IS NULL THEN INSERT INTO ems.site_endpoint ( site_id, endpoint_type, host, port, protocol, unit_id, enabled, notes ) VALUES ( v_site_id, 'loxone_http', v_host_loxone, v_port_loxone, 'http', NULL, true, 'Loxone Miniserver (HTTP Virtual Inputs).' ) RETURNING id INTO v_ep_loxone; END IF; INSERT INTO ems.site_grid_connection ( site_id, max_import_power_w, max_export_power_w, no_export, reserved_capacity_w, notes ) VALUES ( v_site_id, 17000, 16000, false, 0, 'Max 25 A přívod → cca 17 kW import; přetok / export povolen 16 kW.' ) ON CONFLICT (site_id) DO UPDATE SET max_import_power_w = EXCLUDED.max_import_power_w, max_export_power_w = EXCLUDED.max_export_power_w, no_export = EXCLUDED.no_export, reserved_capacity_w = EXCLUDED.reserved_capacity_w, notes = EXCLUDED.notes; IF NOT EXISTS ( SELECT 1 FROM ems.site_market_config smc WHERE smc.site_id = v_site_id AND smc.valid_to IS NULL ) THEN INSERT INTO ems.site_market_config ( site_id, purchase_pricing_mode, sale_pricing_mode, buy_margin_fixed_czk, buy_margin_percent, sell_margin_fixed_czk, sell_margin_percent, currency, valid_from, valid_to, notes, tariff_id, hdo_code_id, system_services_czk_kwh, ote_fee_czk_kwh, buy_fixed_energy_nt_czk_kwh, buy_fixed_vt_surcharge_czk_kwh ) VALUES ( v_site_id, 'fixed', 'spot', 0, 0, -0.020, 0, 'CZK', now(), NULL, 'Nákup fixní 3,67 Kč/kWh bez DPH (NT) + 0,52 Kč/kWh bez DPH ve VT (okna dle HDO jako home-01). ' 'Prodej na spotu jako home-01. Distribuce v efektivní ceně 0 (tariff_id NULL) – energie jen fix + DPH dle vat_rate výchozí.', NULL, v_hdo_id, 0, 0, 3.67, 0.52 ); END IF; INSERT INTO ems.site_operating_mode (site_id, mode_code, activated_by, notes) VALUES ( v_site_id, 'MANUAL', 'migration:V043_site_25a', 'Start MANUAL; po ověření přepnout na AUTO.' ) ON CONFLICT (site_id) DO NOTHING; SELECT ai.id INTO v_inv_main FROM ems.asset_inverter ai WHERE ai.site_id = v_site_id AND ai.code = 'deye-main' LIMIT 1; IF v_inv_main IS NULL THEN INSERT INTO ems.asset_inverter ( site_id, code, manufacturer, model, endpoint_id, max_charge_power_w, max_discharge_power_w, max_export_power_w, max_ac_output_w, max_dc_input_w, max_battery_charge_w, max_battery_discharge_w, gen_port_max_power_w, controllable, active, notes ) VALUES ( v_site_id, 'deye-main', 'Deye', NULL, v_ep_deye, 6250, 6250, 12000, 12000, 24000, 6250, 6250, 5000, true, true, '12kW LV hybrid. Baterie limit 0,5C ≈ 6,25 kW (280 A teoreticky vyšší – plánování dle 6,25 kW). ' 'GEN port max ~5 kW součet MI.' ) RETURNING id INTO v_inv_main; END IF; SELECT ai.id INTO v_inv_gen FROM ems.asset_inverter ai WHERE ai.site_id = v_site_id AND ai.code = 'ongrid-gen' LIMIT 1; IF v_inv_gen IS NULL THEN INSERT INTO ems.asset_inverter ( site_id, code, manufacturer, model, endpoint_id, max_export_power_w, controllable, active, notes ) VALUES ( v_site_id, 'ongrid-gen', NULL, NULL, NULL, 5000, false, true, 'Mikroinvertory na GEN portu (2 skupiny panelů), EMS necurtailuje.' ) RETURNING id INTO v_inv_gen; END IF; IF NOT EXISTS ( SELECT 1 FROM ems.asset_battery ab WHERE ab.site_id = v_site_id AND ab.code = 'bat-main' ) THEN INSERT INTO ems.asset_battery ( site_id, inverter_id, code, usable_capacity_wh, min_soc_percent, reserve_soc_percent, max_soc_percent, charge_efficiency, discharge_efficiency, degradation_cost_czk_kwh, max_charge_c_rate, max_discharge_c_rate, bms_max_charge_w, bms_max_discharge_w ) VALUES ( v_site_id, v_inv_main, 'bat-main', 12500, 10, 15, 95, 0.95, 0.95, 0.50, 0.5, 0.5, 6250, 6250 ); END IF; -- Odstranění starého agregovaného seedu (pv-a / pv-b), pokud na DB zůstal z dřívější verze. DELETE FROM ems.forecast_accuracy fa WHERE fa.pv_array_id IN ( SELECT id FROM ems.asset_pv_array WHERE site_id = v_site_id AND code IN ('pv-a', 'pv-b') ); DELETE FROM ems.forecast_pv_interval fpi USING ems.asset_pv_array apa WHERE apa.site_id = v_site_id AND apa.code IN ('pv-a', 'pv-b') AND fpi.pv_array_id = apa.id; DELETE FROM ems.forecast_pv_run fpr WHERE fpr.site_id = v_site_id AND fpr.pv_array_id IN ( SELECT id FROM ems.asset_pv_array WHERE site_id = v_site_id AND code IN ('pv-a', 'pv-b') ); DELETE FROM ems.asset_pv_array WHERE site_id = v_site_id AND code IN ('pv-a', 'pv-b'); -- String 1: 12×620 Wp @110° / 45° (Deye, řiditelné) IF NOT EXISTS ( SELECT 1 FROM ems.asset_pv_array ap WHERE ap.site_id = v_site_id AND ap.code = 'pv-str-1' ) THEN INSERT INTO ems.asset_pv_array ( site_id, inverter_id, code, name, nominal_power_wp, azimuth_deg, tilt_deg, module_count, shading_factor, controllable, telemetry_source, notes ) VALUES ( v_site_id, v_inv_main, 'pv-str-1', 'String 1 – 12×620 Wp', 7440, 110, 45, 12, 1.0, true, 'pv_strings', 'Hlavní telemetrie stringů Deye (pv1+pv2); druhý string má telemetry_source NULL.' ); END IF; -- String 2: 8×620 Wp @200° / 10° (Deye, řiditelné) IF NOT EXISTS ( SELECT 1 FROM ems.asset_pv_array ap WHERE ap.site_id = v_site_id AND ap.code = 'pv-str-2' ) THEN INSERT INTO ems.asset_pv_array ( site_id, inverter_id, code, name, nominal_power_wp, azimuth_deg, tilt_deg, module_count, shading_factor, controllable, telemetry_source, notes ) VALUES ( v_site_id, v_inv_main, 'pv-str-2', 'String 2 – 8×620 Wp', 4960, 200, 10, 8, 1.0, true, NULL, 'Vlastní predikce orientace; telemetrie sdílená se stringem 1.' ); END IF; -- MI 5×620 Wp @200° / 45° (GEN, neriditelné) IF NOT EXISTS ( SELECT 1 FROM ems.asset_pv_array ap WHERE ap.site_id = v_site_id AND ap.code = 'pv-mi-1' ) THEN INSERT INTO ems.asset_pv_array ( site_id, inverter_id, code, name, nominal_power_wp, azimuth_deg, tilt_deg, module_count, shading_factor, controllable, telemetry_source, notes ) VALUES ( v_site_id, v_inv_gen, 'pv-mi-1', 'Mikroinvertory 5×620 Wp', 3100, 200, 45, 5, 1.0, false, 'gen_port', 'Souhrnná telemetrie GEN portu; druhá MI skupina má telemetry NULL.' ); END IF; -- MI 3×620 Wp @110° / 10° (GEN, neriditelné) IF NOT EXISTS ( SELECT 1 FROM ems.asset_pv_array ap WHERE ap.site_id = v_site_id AND ap.code = 'pv-mi-2' ) THEN INSERT INTO ems.asset_pv_array ( site_id, inverter_id, code, name, nominal_power_wp, azimuth_deg, tilt_deg, module_count, shading_factor, controllable, telemetry_source, notes ) VALUES ( v_site_id, v_inv_gen, 'pv-mi-2', 'Mikroinvertory 3×620 Wp', 1860, 110, 10, 3, 1.0, false, NULL, 'Predikce samostatně; gen_port u pv-mi-1.' ); END IF; IF NOT EXISTS ( SELECT 1 FROM ems.asset_ev_charger c WHERE c.site_id = v_site_id AND c.code = 'ev-charger-1' ) THEN INSERT INTO ems.asset_ev_charger ( site_id, code, manufacturer, model, endpoint_id, max_power_w, min_power_w, phases, connector_count, schedulable, notes ) VALUES ( v_site_id, 'ev-charger-1', 'Teltonika', 'TeltoCharge 22kW', v_ep_ev, 22000, 1380, 3, 1, true, 'Jedna nabíječka; kód ev-charger-1 kvůli planneru / telemetrii.' ) RETURNING id INTO v_ch_id; ELSE SELECT id INTO v_ch_id FROM ems.asset_ev_charger WHERE site_id = v_site_id AND code = 'ev-charger-1' LIMIT 1; END IF; INSERT INTO ems.asset_vehicle ( site_id, code, name, make, model, battery_capacity_kwh, max_charge_power_w, default_charger_id, api_type, default_target_soc_pct, default_deadline_hour, active ) VALUES ( v_site_id, 'ev-default', 'EV (výchozí)', NULL, NULL, 60.0, 11000, v_ch_id, 'none', 80, 7, true ) ON CONFLICT (site_id, code) DO NOTHING; END; $$;