vigilar/vigilar/storage/schema.py

184 lines
5.9 KiB
Python

"""SQLAlchemy Core table definitions for Vigilar."""
from sqlalchemy import (
Column,
Float,
Index,
Integer,
MetaData,
String,
Table,
Text,
)
metadata = MetaData()
cameras = Table(
"cameras",
metadata,
Column("id", String, primary_key=True),
Column("display_name", String, nullable=False),
Column("rtsp_url", String, nullable=False),
Column("enabled", Integer, nullable=False, default=1),
Column("created_at", Integer, nullable=False),
)
sensors = Table(
"sensors",
metadata,
Column("id", String, primary_key=True),
Column("display_name", String, nullable=False),
Column("type", String, nullable=False),
Column("protocol", String, nullable=False),
Column("device_address", String),
Column("location", String),
Column("enabled", Integer, nullable=False, default=1),
)
sensor_states = Table(
"sensor_states",
metadata,
Column("sensor_id", String, nullable=False),
Column("state_key", String, nullable=False),
Column("value", Text, nullable=False),
Column("updated_at", Integer, nullable=False),
)
Index("pk_sensor_states", sensor_states.c.sensor_id, sensor_states.c.state_key, unique=True)
events = Table(
"events",
metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
Column("ts", Integer, nullable=False),
Column("type", String, nullable=False),
Column("source_id", String),
Column("severity", String, nullable=False),
Column("payload", Text),
Column("acknowledged", Integer, nullable=False, default=0),
Column("ack_ts", Integer),
)
Index("idx_events_ts", events.c.ts.desc())
Index("idx_events_type", events.c.type)
Index("idx_events_source", events.c.source_id)
recordings = Table(
"recordings",
metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
Column("camera_id", String, nullable=False),
Column("started_at", Integer, nullable=False),
Column("ended_at", Integer),
Column("duration_s", Float),
Column("file_path", String, nullable=False),
Column("file_size", Integer),
Column("trigger", String, nullable=False),
Column("event_id", Integer),
Column("encrypted", Integer, nullable=False, default=1),
Column("thumbnail_path", String),
Column("detection_type", String), # person, vehicle, motion, None
Column("starred", Integer, nullable=False, default=0),
)
Index("idx_recordings_camera_ts", recordings.c.camera_id, recordings.c.started_at.desc())
system_events = Table(
"system_events",
metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
Column("ts", Integer, nullable=False),
Column("component", String, nullable=False),
Column("level", String, nullable=False),
Column("message", Text, nullable=False),
)
Index("idx_sysevents_ts", system_events.c.ts.desc())
arm_state_log = Table(
"arm_state_log",
metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
Column("ts", Integer, nullable=False),
Column("state", String, nullable=False),
Column("triggered_by", String, nullable=False),
Column("pin_hash", String),
)
alert_log = Table(
"alert_log",
metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
Column("ts", Integer, nullable=False),
Column("event_id", Integer),
Column("channel", String, nullable=False),
Column("status", String, nullable=False),
Column("error", Text),
)
push_subscriptions = Table(
"push_subscriptions",
metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
Column("endpoint", String, nullable=False, unique=True),
Column("p256dh_key", String, nullable=False),
Column("auth_key", String, nullable=False),
Column("created_at", Integer, nullable=False),
Column("last_used_at", Integer),
Column("user_agent", String),
)
pets = Table(
"pets",
metadata,
Column("id", String, primary_key=True),
Column("name", String, nullable=False),
Column("species", String, nullable=False),
Column("breed", String),
Column("color_description", String),
Column("photo_path", String),
Column("training_count", Integer, nullable=False, default=0),
Column("created_at", Float, nullable=False),
)
pet_sightings = Table(
"pet_sightings",
metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
Column("ts", Float, nullable=False),
Column("pet_id", String),
Column("species", String, nullable=False),
Column("camera_id", String, nullable=False),
Column("confidence", Float),
Column("crop_path", String),
Column("labeled", Integer, nullable=False, default=0),
Column("event_id", Integer),
)
Index("idx_pet_sightings_ts", pet_sightings.c.ts.desc())
Index("idx_pet_sightings_pet", pet_sightings.c.pet_id, pet_sightings.c.ts.desc())
Index("idx_pet_sightings_camera", pet_sightings.c.camera_id, pet_sightings.c.ts.desc())
wildlife_sightings = Table(
"wildlife_sightings",
metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
Column("ts", Float, nullable=False),
Column("species", String, nullable=False),
Column("threat_level", String, nullable=False),
Column("camera_id", String, nullable=False),
Column("confidence", Float),
Column("crop_path", String),
Column("event_id", Integer),
Column("temperature_c", Float),
Column("conditions", String),
Column("bbox", String), # JSON [x, y, w, h] normalized
)
Index("idx_wildlife_ts", wildlife_sightings.c.ts.desc())
Index("idx_wildlife_threat", wildlife_sightings.c.threat_level, wildlife_sightings.c.ts.desc())
pet_training_images = Table(
"pet_training_images",
metadata,
Column("id", Integer, primary_key=True, autoincrement=True),
Column("pet_id", String, nullable=False),
Column("image_path", String, nullable=False),
Column("source", String, nullable=False),
Column("created_at", Float, nullable=False),
)