Files
bellsystems-cp/backend/alembic/versions/d4e5f6a7b8c9_device_alert_events.py
bonaminandClaude Sonnet 5 7c533b9245 feat(mqtt): add device health telemetry and migrate to v2 topic spec
Two efforts that landed together because the v2 topic work extends
tables the health-telemetry effort added days earlier in the same
files/functions, making them impractical to separate cleanly:

Health/diagnostics telemetry (schema, Jul 13-17):
- New Postgres tables: device_alert_events, device_boot_events,
  device_ping_samples, device_diagnostics_reports, plus a `source`
  column on device_logs to distinguish log origins
- Query/service layer in pg_mqtt.py and database/__init__.py for
  inserting and listing this history, plus a "latest metrics" endpoint
  combining most-recent diagnostics + ping RTT per device
- mqtt/router.py gains list endpoints for alert/boot/ping/diagnostics
  history, consumed by the upcoming Health tab

MQTT v2 topic migration (Sep 21):
- Heartbeat payload flattened per vesper_mqtt_topic_spec_v2.md, adding
  rssi/free_heap/state/ok fields
- Command replies move to control/ack, device-initiated events to
  control/reports; mqtt/client.py subscribes to the new topic set and
  runs a ping_loop (wired up in main.py) for RTT sampling
- mqtt/logger.py and pg_mqtt.py updated to parse and persist the new
  payload shape alongside the legacy fields for backwards compatibility

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 18:24:36 +03:00

49 lines
1.8 KiB
Python

"""device_alert_events
Adds an insert-only history log of device alert transitions (WARNING/CRITICAL/
FAILED only — CLEARED is not logged here). device_alerts remains the current-
state table and is untouched; this is purely additive, used to answer "when
was the most recent issue on this device" even after it has been resolved.
Also adds an optional rssi column to heartbeats, for a signal-strength
indicator once firmware starts reporting it on the heartbeat payload.
Revision ID: d4e5f6a7b8c9
Revises: c3d4e5f6a7b8
Create Date: 2026-07-13 00:00:00.000000
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
revision: str = "d4e5f6a7b8c9"
down_revision: Union[str, None] = "c3d4e5f6a7b8"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.create_table(
"device_alert_events",
sa.Column("id", sa.BigInteger(), primary_key=True, autoincrement=True),
sa.Column("device_serial", sa.String(128), nullable=False),
sa.Column("subsystem", sa.String(128), nullable=False),
sa.Column("state", sa.String(64), nullable=False),
sa.Column("message", sa.Text(), nullable=True),
sa.Column("occurred_at", sa.DateTime(timezone=True), nullable=False,
server_default=sa.func.now()),
)
op.create_index(
"idx_device_alert_events_serial_occurred",
"device_alert_events",
["device_serial", sa.text("occurred_at DESC")],
)
op.add_column("heartbeats", sa.Column("rssi", sa.Integer(), nullable=True))
def downgrade() -> None:
op.drop_column("heartbeats", "rssi")
op.drop_index("idx_device_alert_events_serial_occurred", table_name="device_alert_events")
op.drop_table("device_alert_events")