Files
frigate/frigate/models.py
T

208 lines
6.9 KiB
Python
Raw Normal View History

2022-04-16 17:40:04 +02:00
from peewee import (
2025-07-07 09:03:57 -05:00
BlobField,
2023-05-29 12:31:17 +02:00
BooleanField,
2022-04-16 17:40:04 +02:00
CharField,
2025-07-07 09:03:57 -05:00
CompositeKey,
2022-04-16 17:40:04 +02:00
DateTimeField,
FloatField,
2025-03-13 15:20:09 -05:00
ForeignKeyField,
2022-04-16 17:40:04 +02:00
IntegerField,
2023-05-29 12:31:17 +02:00
Model,
TextField,
2022-04-16 17:40:04 +02:00
)
2022-04-18 06:52:13 -05:00
from playhouse.sqlite_ext import JSONField
2020-11-01 08:06:15 -06:00
2020-11-04 06:31:25 -06:00
2025-08-08 11:25:39 -06:00
class Event(Model):
2020-11-01 08:06:15 -06:00
id = CharField(null=False, primary_key=True, max_length=30)
label = CharField(index=True, max_length=20)
sub_label = CharField(max_length=100, null=True)
2020-11-01 08:06:15 -06:00
camera = CharField(index=True, max_length=20)
start_time = DateTimeField()
end_time = DateTimeField()
2023-04-30 11:07:14 -06:00
top_score = (
FloatField()
) # TODO remove when columns can be dropped without rebuilding table
score = (
FloatField()
) # TODO remove when columns can be dropped without rebuilding table
2020-11-01 08:06:15 -06:00
false_positive = BooleanField()
2020-11-04 06:31:25 -06:00
zones = JSONField()
2020-11-15 08:50:49 -06:00
thumbnail = TextField()
2020-12-24 07:47:27 -06:00
has_clip = BooleanField(default=True)
has_snapshot = BooleanField(default=True)
2023-04-30 11:07:14 -06:00
region = (
JSONField()
) # TODO remove when columns can be dropped without rebuilding table
box = (
JSONField()
) # TODO remove when columns can be dropped without rebuilding table
area = (
IntegerField()
) # TODO remove when columns can be dropped without rebuilding table
retain_indefinitely = BooleanField(default=False)
2023-07-09 11:40:39 -05:00
ratio = FloatField(
default=1.0
) # TODO remove when columns can be dropped without rebuilding table
2022-04-03 15:00:11 -05:00
plus_id = CharField(max_length=30)
2023-04-24 07:24:28 -05:00
model_hash = CharField(max_length=32)
detector_type = CharField(max_length=32)
model_type = CharField(max_length=32)
2023-04-30 11:07:14 -06:00
data = JSONField() # ex: tracked object box, region, etc.
2021-06-06 21:24:36 -04:00
2025-08-08 11:25:39 -06:00
class Timeline(Model):
2023-04-23 09:45:19 -06:00
timestamp = DateTimeField()
camera = CharField(index=True, max_length=20)
source = CharField(index=True, max_length=20) # ex: tracked object, audio, external
source_id = CharField(index=True, max_length=30)
class_type = CharField(max_length=50) # ex: entered_zone, audio_heard
data = JSONField() # ex: tracked object id, region, box, etc.
2025-08-08 11:25:39 -06:00
class Regions(Model):
2023-10-18 17:21:52 -06:00
camera = CharField(null=False, primary_key=True, max_length=20)
grid = JSONField() # json blob of grid
last_update = DateTimeField()
2025-08-08 11:25:39 -06:00
class Recordings(Model):
2021-06-06 21:24:36 -04:00
id = CharField(null=False, primary_key=True, max_length=30)
camera = CharField(index=True, max_length=20)
path = CharField(unique=True)
start_time = DateTimeField()
end_time = DateTimeField()
duration = FloatField()
2021-12-11 13:47:59 -06:00
motion = IntegerField(null=True)
objects = IntegerField(null=True)
dBFS = IntegerField(null=True)
segment_size = FloatField(default=0) # this should be stored as MB
regions = IntegerField(null=True)
motion_heatmap = JSONField(null=True) # 16x16 grid, 256 values (0-255)
keyframes = JSONField(null=True) # ms offsets; NULL = unprobed (legacy rows)
stream_type = CharField(default="main", max_length=8)
has_audio = BooleanField(null=True) # NULL = unknown (legacy rows)
audio_rate = IntegerField(null=True) # Hz; NULL = unknown (legacy rows)
audio_codec = CharField(null=True, max_length=20) # NULL = unknown (legacy rows)
video_codec = CharField(null=True, max_length=20) # NULL = unknown (legacy rows)
class ExportCase(Model):
id = CharField(null=False, primary_key=True, max_length=30)
name = CharField(index=True, max_length=100)
description = TextField(null=True)
created_at = DateTimeField()
updated_at = DateTimeField()
2025-08-08 11:25:39 -06:00
class Export(Model):
2024-04-19 16:11:41 -06:00
id = CharField(null=False, primary_key=True, max_length=30)
camera = CharField(index=True, max_length=20)
name = CharField(index=True, max_length=100)
date = DateTimeField()
video_path = CharField(unique=True)
thumb_path = CharField(unique=True)
in_progress = BooleanField()
export_case = ForeignKeyField(
ExportCase,
null=True,
backref="exports",
column_name="export_case_id",
)
2024-04-19 16:11:41 -06:00
2025-08-08 11:25:39 -06:00
class ReviewSegment(Model):
id = CharField(null=False, primary_key=True, max_length=30)
camera = CharField(index=True, max_length=20)
start_time = DateTimeField()
end_time = DateTimeField()
severity = CharField(max_length=30) # alert, detection
thumb_path = CharField(unique=True)
data = JSONField() # additional data about detection like list of labels, zone, areas of significant motion
2025-08-08 11:25:39 -06:00
class UserReviewStatus(Model):
2025-03-13 15:20:09 -05:00
user_id = CharField(max_length=30)
review_segment = ForeignKeyField(ReviewSegment, backref="user_reviews")
has_been_reviewed = BooleanField(default=False)
class Meta:
indexes = ((("user_id", "review_segment"), True),)
2025-08-08 11:25:39 -06:00
class Previews(Model):
id = CharField(null=False, primary_key=True, max_length=30)
camera = CharField(index=True, max_length=20)
path = CharField(unique=True)
start_time = DateTimeField()
end_time = DateTimeField()
duration = FloatField()
# Used for temporary table in record/cleanup.py
2025-08-08 11:25:39 -06:00
class RecordingsToDelete(Model):
id = CharField(null=False, primary_key=False, max_length=30)
class Meta:
temporary = True
2024-05-18 11:36:13 -05:00
2025-08-08 11:25:39 -06:00
class User(Model):
2024-05-18 11:36:13 -05:00
username = CharField(null=False, primary_key=True, max_length=30)
2025-03-08 10:01:08 -06:00
role = CharField(
max_length=20,
2025-03-09 22:59:07 -05:00
default="admin",
2025-03-08 10:01:08 -06:00
)
2024-05-18 11:36:13 -05:00
password_hash = CharField(null=False, max_length=120)
2025-12-08 10:02:28 -06:00
password_changed_at = DateTimeField(null=True)
notification_tokens = JSONField()
2025-07-07 09:03:57 -05:00
@classmethod
def get_allowed_cameras(
cls, role: str, roles_dict: dict[str, list[str]], all_camera_names: set[str]
) -> list[str]:
if role not in roles_dict:
return [] # Invalid role grants no access
allowed = roles_dict[role]
if not allowed: # Empty list means all cameras
return list(all_camera_names)
return [cam for cam in allowed if cam in all_camera_names]
2025-07-07 09:03:57 -05:00
2025-08-08 11:25:39 -06:00
class Trigger(Model):
2025-07-07 09:03:57 -05:00
camera = CharField(max_length=20)
name = CharField()
type = CharField(max_length=10)
data = TextField()
threshold = FloatField()
model = CharField(max_length=30)
embedding = BlobField()
triggering_event_id = CharField(max_length=30)
last_triggered = DateTimeField()
class Meta:
primary_key = CompositeKey("camera", "name")
class Notice(Model):
id = CharField(null=False, primary_key=True, max_length=150)
kind = CharField(index=True, max_length=50)
scope = CharField(max_length=100, null=True)
params = JSONField()
first_seen = DateTimeField()
last_seen = DateTimeField()
count = IntegerField(default=1)
dismissed_at = DateTimeField(null=True)
class NoticeStats(Model):
kind = CharField(null=False, primary_key=True, max_length=50)
occurrences = IntegerField(default=0)
dismissals = IntegerField(default=0)
first_seen = DateTimeField()
last_seen = DateTimeField()
# watermarks for a future analytics reporter; unused until then
reported_occurrences = IntegerField(default=0)
reported_dismissals = IntegerField(default=0)