98 lines
3.8 KiB
SQL
98 lines
3.8 KiB
SQL
-- =============================================================
|
||
-- R__059_vw_operating_mode.sql
|
||
-- EMS Platform – views pro provozní režimy a heartbeat
|
||
-- Repeatable migration
|
||
-- =============================================================
|
||
|
||
-- Aktuální EMS provozní režim per lokalita (PostgREST / UI)
|
||
CREATE OR REPLACE VIEW ems.vw_operating_mode AS
|
||
SELECT
|
||
s.id AS site_id,
|
||
s.code AS site_code,
|
||
m.mode_code AS active_mode,
|
||
d.name AS mode_name,
|
||
d.description AS mode_description,
|
||
d.is_autonomous,
|
||
m.activated_at,
|
||
m.activated_by,
|
||
m.valid_until,
|
||
m.previous_mode,
|
||
m.notes AS mode_notes
|
||
FROM ems.site s
|
||
LEFT JOIN ems.site_operating_mode m ON m.site_id = s.id
|
||
LEFT JOIN ems.operating_mode_def d ON d.code = m.mode_code
|
||
WHERE s.active = true;
|
||
|
||
COMMENT ON VIEW ems.vw_operating_mode IS
|
||
'Aktuální provozní režim EMS per aktivní lokalita (bez telemetrie/heartbeat).';
|
||
|
||
-- Aktuální stav všech lokalit (pro dashboard a PostgREST)
|
||
CREATE OR REPLACE VIEW ems.vw_site_status AS
|
||
SELECT
|
||
s.id AS site_id,
|
||
s.code AS site_code,
|
||
s.name AS site_name,
|
||
m.mode_code AS active_mode,
|
||
d.name AS mode_name,
|
||
d.description AS mode_description,
|
||
d.is_autonomous,
|
||
m.activated_at,
|
||
m.activated_by,
|
||
m.valid_until,
|
||
m.previous_mode,
|
||
m.notes AS mode_notes,
|
||
-- Heartbeat
|
||
hb.last_seen AS ems_last_seen,
|
||
hb.status AS ems_status,
|
||
EXTRACT(EPOCH FROM (now() - hb.last_seen))::INT AS ems_age_seconds,
|
||
-- Varování pokud EMS dlouho nepingoval
|
||
CASE
|
||
WHEN hb.last_seen IS NULL THEN 'never_seen'
|
||
WHEN now() - hb.last_seen > INTERVAL '5 minutes' THEN 'stale'
|
||
WHEN now() - hb.last_seen > INTERVAL '2 minutes' THEN 'delayed'
|
||
ELSE 'ok'
|
||
END AS ems_heartbeat_status,
|
||
-- Aktuální telemetrie (snapshot)
|
||
li.pv_power_w,
|
||
li.battery_soc_percent,
|
||
li.battery_power_w,
|
||
li.grid_power_w,
|
||
li.load_power_w,
|
||
li.measured_at AS telemetry_at
|
||
FROM ems.site s
|
||
LEFT JOIN ems.site_operating_mode m ON m.site_id = s.id
|
||
LEFT JOIN ems.operating_mode_def d ON d.code = m.mode_code
|
||
LEFT JOIN ems.site_heartbeat hb ON hb.site_id = s.id
|
||
LEFT JOIN ems.vw_latest_inverter li ON li.site_id = s.id
|
||
WHERE s.active = true;
|
||
|
||
COMMENT ON VIEW ems.vw_site_status IS
|
||
'Kompletní stavový přehled lokality: aktivní režim, heartbeat EMS, aktuální telemetrie.
|
||
Primární view pro dashboard a health check endpoint. Jeden řádek na aktivní lokalitu.
|
||
ems_heartbeat_status slouží pro EMS vlastní alerting – Loxone watchdog tuto tabulku nečte,
|
||
sleduje HTTP pulzy přímo (viz docs/loxone-integration.md).';
|
||
|
||
-- ============================================================
|
||
|
||
-- Log přepnutí režimů (pro UI historii)
|
||
CREATE OR REPLACE VIEW ems.vw_mode_log_recent AS
|
||
SELECT
|
||
l.id,
|
||
l.site_id,
|
||
s.code AS site_code,
|
||
l.mode_code,
|
||
d.name AS mode_name,
|
||
l.activated_at,
|
||
l.deactivated_at,
|
||
EXTRACT(EPOCH FROM COALESCE(l.deactivated_at, now()) - l.activated_at)::INT AS duration_sec,
|
||
l.activated_by,
|
||
l.notes
|
||
FROM ems.site_operating_mode_log l
|
||
JOIN ems.site s ON s.id = l.site_id
|
||
JOIN ems.operating_mode_def d ON d.code = l.mode_code
|
||
WHERE l.activated_at >= now() - INTERVAL '7 days'
|
||
ORDER BY l.activated_at DESC;
|
||
|
||
COMMENT ON VIEW ems.vw_mode_log_recent IS
|
||
'Posledních 7 dní přepnutí provozních režimů. Slouží pro audit log v UI.';
|