Move reranker to Serenity, add monitoring and mesh-mqtt-observer stacks

- ai: remove reranker service (moved to Serenity at 10.5.1.5:9787)
- ai: add LiteLLM reranker proxy entry for Serenity
- ai: configure OpenWebUI to use LiteLLM for reranking
- monitoring: add Grafana + Prometheus stack
- mesh-mqtt-observer: add new service
- automation, documents, meshtastic: misc updates
This commit is contained in:
root
2026-05-09 10:42:54 -05:00
parent b2cbe4444c
commit 6c19f82a0a
17 changed files with 1115 additions and 23 deletions

View File

@@ -0,0 +1,146 @@
CREATE TABLE IF NOT EXISTS raw_mqtt_events (
id BIGSERIAL PRIMARY KEY,
received_at TIMESTAMPTZ NOT NULL DEFAULT now(),
source_system TEXT NOT NULL,
network_name TEXT,
modem_preset TEXT,
broker_host TEXT,
broker_port INTEGER,
topic TEXT NOT NULL,
qos INTEGER,
retain BOOLEAN,
payload_raw BYTEA,
payload_text TEXT,
payload_json JSONB,
parse_status TEXT NOT NULL DEFAULT 'raw',
parser_error TEXT
);
CREATE INDEX IF NOT EXISTS idx_raw_mqtt_events_received_at
ON raw_mqtt_events(received_at DESC);
CREATE INDEX IF NOT EXISTS idx_raw_mqtt_events_source_received
ON raw_mqtt_events(source_system, received_at DESC);
CREATE INDEX IF NOT EXISTS idx_raw_mqtt_events_topic
ON raw_mqtt_events(topic);
CREATE TABLE IF NOT EXISTS normalized_events (
id BIGSERIAL PRIMARY KEY,
raw_event_id BIGINT REFERENCES raw_mqtt_events(id) ON DELETE CASCADE,
event_time TIMESTAMPTZ NOT NULL DEFAULT now(),
source_system TEXT NOT NULL,
network_name TEXT,
modem_preset TEXT,
topic TEXT NOT NULL,
from_node_id TEXT,
to_node_id TEXT,
message_type TEXT,
text_body TEXT,
rssi NUMERIC,
snr NUMERIC,
payload JSONB
);
CREATE INDEX IF NOT EXISTS idx_normalized_events_event_time
ON normalized_events(event_time DESC);
CREATE INDEX IF NOT EXISTS idx_normalized_events_source_time
ON normalized_events(source_system, event_time DESC);
CREATE INDEX IF NOT EXISTS idx_normalized_events_from_node
ON normalized_events(source_system, from_node_id);
CREATE INDEX IF NOT EXISTS idx_normalized_events_message_type
ON normalized_events(message_type);
CREATE TABLE IF NOT EXISTS nodes_seen (
id BIGSERIAL PRIMARY KEY,
source_system TEXT NOT NULL,
node_id TEXT NOT NULL,
first_seen TIMESTAMPTZ NOT NULL DEFAULT now(),
last_seen TIMESTAMPTZ NOT NULL DEFAULT now(),
metadata JSONB,
UNIQUE(source_system, node_id)
);
CREATE INDEX IF NOT EXISTS idx_nodes_seen_last_seen
ON nodes_seen(last_seen DESC);
CREATE OR REPLACE VIEW v_packets_per_hour AS
SELECT
date_trunc('hour', event_time) AS hour,
source_system,
network_name,
modem_preset,
COUNT(*) AS packets
FROM normalized_events
GROUP BY 1, 2, 3, 4
ORDER BY 1 DESC;
CREATE OR REPLACE VIEW v_text_messages_per_day AS
SELECT
date_trunc('day', event_time) AS day,
source_system,
network_name,
modem_preset,
COUNT(*) AS text_messages
FROM normalized_events
WHERE message_type = 'text'
GROUP BY 1, 2, 3, 4
ORDER BY 1 DESC;
CREATE OR REPLACE VIEW v_unique_nodes_per_day AS
SELECT
date_trunc('day', event_time) AS day,
source_system,
network_name,
modem_preset,
COUNT(DISTINCT from_node_id) AS unique_nodes
FROM normalized_events
WHERE from_node_id IS NOT NULL
GROUP BY 1, 2, 3, 4
ORDER BY 1 DESC;
CREATE OR REPLACE VIEW v_utilization_hourly AS
SELECT
date_trunc('hour', event_time) AS hour,
CASE
WHEN source_system = 'meshtastic' AND modem_preset IS NOT NULL AND modem_preset <> ''
THEN 'Meshtastic ' || modem_preset
WHEN source_system = 'meshtastic'
THEN 'Meshtastic'
WHEN source_system = 'meshcore'
THEN 'MeshCore'
ELSE source_system
END AS network,
COUNT(*) AS packets,
COUNT(*) FILTER (WHERE message_type = 'text') AS text_messages,
COUNT(DISTINCT from_node_id) AS unique_nodes
FROM normalized_events
GROUP BY 1, 2
ORDER BY 1 DESC;
CREATE OR REPLACE VIEW v_top_talkers_24h AS
SELECT
source_system,
network_name,
modem_preset,
from_node_id,
COUNT(*) AS packets,
COUNT(*) FILTER (WHERE message_type = 'text') AS text_messages,
MAX(event_time) AS last_seen
FROM normalized_events
WHERE event_time >= now() - interval '24 hours'
AND from_node_id IS NOT NULL
GROUP BY 1, 2, 3, 4
ORDER BY packets DESC;