-- ================================================================ -- Схема БД: учёт устройств энергомониторинга (Егорин / ORBIT) -- PostgreSQL 14+ (LXC на Proxmox, та же база что у Лилии — ок) -- ================================================================ CREATE TABLE IF NOT EXISTS devices ( node_id TEXT PRIMARY KEY, -- eg01, eg-lan1, orb1... name TEXT, -- «Щит насосной», задаёт админ project TEXT, -- 'egorin' | 'orbit' object TEXT, -- площадка/объект transport TEXT NOT NULL DEFAULT 'lora', -- 'lora' | 'lan' status TEXT NOT NULL DEFAULT 'pending', -- pending|active|disabled caps JSONB DEFAULT '{}', -- {"pzem":true,"relays":4,"ctl":true} relay_names JSONB DEFAULT '[]', -- ["Насос","Свет",...] fw TEXT, ip INET, mac MACADDR, gw TEXT, -- через какой шлюз (lora) last_seen TIMESTAMPTZ, last_rssi INT, last_snr NUMERIC(4,1), online BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), approved_at TIMESTAMPTZ, approved_by TEXT ); CREATE TABLE IF NOT EXISTS telemetry ( id BIGSERIAL PRIMARY KEY, node_id TEXT NOT NULL REFERENCES devices(node_id) ON DELETE CASCADE, ts TIMESTAMPTZ NOT NULL DEFAULT now(), v NUMERIC(6,1), a NUMERIC(8,3), w NUMERIC(9,1), kwh NUMERIC(12,3), pf NUMERIC(4,2), hz NUMERIC(4,1), relays JSONB, -- [1,0,1,0] rssi INT, snr NUMERIC(4,1) ); CREATE INDEX IF NOT EXISTS telemetry_node_ts ON telemetry (node_id, ts DESC); -- журнал команд (кто/что/когда переключил) CREATE TABLE IF NOT EXISTS commands ( id BIGSERIAL PRIMARY KEY, node_id TEXT NOT NULL REFERENCES devices(node_id) ON DELETE CASCADE, ts TIMESTAMPTZ NOT NULL DEFAULT now(), payload JSONB NOT NULL, -- {"cmd":"relay","n":0,"s":1} source TEXT, -- 'ui' | 'n8n' | 'ha' | 'api' confirmed BOOLEAN DEFAULT FALSE -- узел подтвердил телеметрией ); -- события смены состояния реле (для журнала в UI) CREATE TABLE IF NOT EXISTS relay_events ( id BIGSERIAL PRIMARY KEY, node_id TEXT NOT NULL REFERENCES devices(node_id) ON DELETE CASCADE, ts TIMESTAMPTZ NOT NULL DEFAULT now(), relay_n INT NOT NULL, state BOOLEAN NOT NULL ); CREATE INDEX IF NOT EXISTS relay_events_node_ts ON relay_events (node_id, ts DESC); -- удобное представление для экрана «Устройства» CREATE OR REPLACE VIEW v_devices_board AS SELECT d.*, t.v, t.a, t.w, t.kwh, t.relays, t.ts AS telemetry_ts FROM devices d LEFT JOIN LATERAL ( SELECT * FROM telemetry WHERE node_id = d.node_id ORDER BY ts DESC LIMIT 1 ) t ON TRUE; -- ретенция сырой телеметрии: 90 дней (крон раз в сутки) -- DELETE FROM telemetry WHERE ts < now() - INTERVAL '90 days';