Files
egorin/lora/schema.sql
T

78 lines
3.3 KiB
SQL

-- ================================================================
-- Схема БД: учёт устройств энергомониторинга (Егорин / 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';