fix repeatable migrations

This commit is contained in:
Dusan Vojacek
2026-04-19 20:15:46 +02:00
parent 0c93f493a4
commit 22bca9cd9e
73 changed files with 22 additions and 15 deletions

View File

@@ -0,0 +1,265 @@
create or replace function ems.fn_site_configuration(p_site_id int)
returns jsonb
language sql
stable
as $fn$
select
case
when not exists (select 1 from ems.site s0 where s0.id = p_site_id) then null::jsonb
else jsonb_build_object(
'site',
(
select to_jsonb(x)
from (
select
s.id,
s.code,
s.name,
s.timezone,
s.latitude::float8 as latitude,
s.longitude::float8 as longitude,
s.active,
s.notes,
s.created_at
from ems.site s
where s.id = p_site_id
) x
),
'grid_connection',
(
select to_jsonb(g.*)
from ems.site_grid_connection g
where g.site_id = p_site_id
limit 1
),
'market_config',
(
select to_jsonb(m.*)
from ems.site_market_config m
where m.site_id = p_site_id
and m.valid_from <= now()
and (m.valid_to is null or m.valid_to > now())
order by m.valid_from desc
limit 1
),
'market_config_note',
'Zelený bonus za výrobu je u FVE polí (asset_pv_array), ne v obchodní konfiguraci.',
'endpoints',
coalesce(
(
select jsonb_agg(
to_jsonb(e.*)
|| jsonb_build_object(
'auth_reference',
case
when e.auth_reference is null or btrim(e.auth_reference::text) = '' then null::text
when length(btrim(e.auth_reference::text)) <= 4 then 'nastaveno'::text
else concat('', right(btrim(e.auth_reference::text), 2))
end
)
order by e.id
)
from ems.site_endpoint e
where e.site_id = p_site_id
),
'[]'::jsonb
),
'inverters',
coalesce(
(
select jsonb_agg(
(
(
to_jsonb(ai.*)
- 'deye_last_system_time_sync_at'::text
- 'deye_last_system_time_sync_minute'::text
- 'deye_last_tou_inactive_write_prague_date'::text
- 'deye_tou_inactive_signature'::text
)
|| jsonb_build_object(
'endpoint_connection',
(
select ep.host || case
when ep.port is not null then ':' || ep.port::text
else ''
end
from ems.site_endpoint ep
where ep.id = ai.endpoint_id
),
'deye_meta',
case
when jsonb_strip_nulls(
jsonb_build_object(
'deye_last_system_time_sync_at', to_jsonb(ai.deye_last_system_time_sync_at),
'deye_last_system_time_sync_minute', to_jsonb(ai.deye_last_system_time_sync_minute),
'deye_last_tou_inactive_write_prague_date',
to_jsonb(ai.deye_last_tou_inactive_write_prague_date),
'deye_tou_inactive_signature', to_jsonb(ai.deye_tou_inactive_signature)
)
) = '{}'::jsonb then null::jsonb
else jsonb_strip_nulls(
jsonb_build_object(
'deye_last_system_time_sync_at', to_jsonb(ai.deye_last_system_time_sync_at),
'deye_last_system_time_sync_minute', to_jsonb(ai.deye_last_system_time_sync_minute),
'deye_last_tou_inactive_write_prague_date',
to_jsonb(ai.deye_last_tou_inactive_write_prague_date),
'deye_tou_inactive_signature', to_jsonb(ai.deye_tou_inactive_signature)
)
)
end
)
)
order by ai.id
)
from ems.asset_inverter ai
where ai.site_id = p_site_id
),
'[]'::jsonb
),
'batteries',
coalesce(
(
select jsonb_agg(to_jsonb(b.*) order by b.id)
from ems.asset_battery b
where b.site_id = p_site_id
),
'[]'::jsonb
),
'pv_arrays',
coalesce(
(
select jsonb_agg(to_jsonb(p.*) order by p.id)
from ems.asset_pv_array p
where p.site_id = p_site_id
),
'[]'::jsonb
),
'ev_chargers',
coalesce(
(
select jsonb_agg(
to_jsonb(ec.*)
|| jsonb_build_object(
'endpoint_connection',
se.host || case
when se.port is not null then ':' || se.port::text
else ''
end
)
order by ec.id
)
from ems.asset_ev_charger ec
left join ems.site_endpoint se on se.id = ec.endpoint_id
where ec.site_id = p_site_id
),
'[]'::jsonb
),
'vehicles',
coalesce(
(
select jsonb_agg(
to_jsonb(v.*)
|| jsonb_build_object(
'api_reference',
case
when v.api_reference is null or btrim(v.api_reference::text) = '' then null::text
when length(btrim(v.api_reference::text)) <= 4 then 'nastaveno'::text
else concat('', right(btrim(v.api_reference::text), 2))
end
)
order by v.code
)
from ems.asset_vehicle v
where v.site_id = p_site_id
),
'[]'::jsonb
),
'heat_pumps',
coalesce(
(
select jsonb_agg(
to_jsonb(hp.*)
|| jsonb_build_object(
'endpoint_connection',
se.host || case
when se.port is not null then ':' || se.port::text
else ''
end
)
order by hp.id
)
from ems.asset_heat_pump hp
left join ems.site_endpoint se on se.id = hp.endpoint_id
where hp.site_id = p_site_id
),
'[]'::jsonb
),
'operating_mode',
(
select to_jsonb(om)
from (
select
m.mode_code,
m.activated_at,
m.activated_by,
m.valid_until,
m.previous_mode,
m.notes,
d.name as mode_name,
d.description as mode_description,
d.loxone_mode_value,
d.ev_enabled,
d.heat_pump_enabled,
d.battery_mode,
d.grid_mode,
d.is_autonomous
from ems.site_operating_mode m
join ems.operating_mode_def d on d.code = m.mode_code
where m.site_id = p_site_id
) om
),
'active_overrides',
coalesce(
(
select jsonb_agg(to_jsonb(o.*) order by o.valid_from desc)
from (
select *
from ems.site_override so
where so.site_id = p_site_id
and so.valid_from <= now()
and (so.valid_to is null or so.valid_to > now())
order by so.valid_from desc
limit 50
) o
),
'[]'::jsonb
),
'operational',
jsonb_build_object(
'heartbeat_last_seen',
(select hb.last_seen from ems.site_heartbeat hb where hb.site_id = p_site_id limit 1),
'heartbeat_status',
(select hb.status from ems.site_heartbeat hb where hb.site_id = p_site_id limit 1),
'has_active_plan',
exists (
select 1
from ems.planning_run pr
where pr.site_id = p_site_id
and pr.status = 'active'
),
'active_plan_created_at',
(
select pr.created_at
from ems.planning_run pr
where pr.site_id = p_site_id
and pr.status = 'active'
order by pr.created_at desc
limit 1
)
)
)
end;
$fn$;
comment on function ems.fn_site_configuration(int) is
'GET /configuration jako jeden JSON bundle (maskované reference, deye_meta).';