create or replace function ems.fn_forecast_pv_split(p_site_id int, p_day date) returns jsonb language sql stable as $fn$ with latest as ( select distinct on (fpi.interval_start, fpr.pv_array_id) fpi.run_id, fpi.pv_array_id, fpi.interval_start, fpi.power_w, fpi.irradiance_wm2, fpi.temp_c, apa.code as pv_array_code, apa.controllable from ems.forecast_pv_interval fpi join ems.forecast_pv_run fpr on fpr.id = fpi.run_id join ems.asset_pv_array apa on apa.id = fpr.pv_array_id and apa.site_id = fpr.site_id where fpr.site_id = p_site_id and ( fpi.interval_start at time zone coalesce( nullif(trim((select timezone from ems.site s where s.id = p_site_id)), ''), 'Europe/Prague' ) )::date = p_day and fpr.status = 'ok' order by fpi.interval_start, fpr.pv_array_id, fpr.created_at desc ), rows as ( select case when controllable then 'a' else 'b' end as pole, jsonb_build_object( 'run_id', run_id, 'pv_array_id', pv_array_id, 'interval_start', interval_start, 'power_w', power_w, 'irradiance_wm2', irradiance_wm2, 'temp_c', temp_c, 'pv_array_code', pv_array_code ) as j, controllable, pv_array_code, interval_start from latest ) select jsonb_build_object( 'pv_a', coalesce( ( select jsonb_agg(j order by pv_array_code, interval_start) from rows where controllable ), '[]'::jsonb ), 'pv_b', coalesce( ( select jsonb_agg(j order by pv_array_code, interval_start) from rows where not controllable ), '[]'::jsonb ) ); $fn$; comment on function ems.fn_forecast_pv_split(int, date) is 'Predikce FVE rozsplitěná na pole A (controllable) a B pro UI.';