Skip to content

Commit 27e506a

Browse files
committed
Merge remote-tracking branch 'origin/v0.26' into v0.26
2 parents 0b3c618 + 820861b commit 27e506a

12 files changed

Lines changed: 459 additions & 465 deletions

brainframe/api/bf_codecs/alarm_codecs.py

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,47 @@
11
from typing import List, Optional
22

3+
from dataclasses import dataclass
4+
35
from .base_codecs import Codec
46
from .condition_codecs import ZoneAlarmCountCondition, ZoneAlarmRateCondition
57

68

9+
@dataclass
710
class ZoneAlarm(Codec):
811
"""This is the configuration for an alarm."""
912

10-
def __init__(self, *,
11-
name: str,
12-
count_conditions: List[ZoneAlarmCountCondition],
13-
rate_conditions: List[ZoneAlarmRateCondition],
14-
use_active_time: bool,
15-
active_start_time: str,
16-
active_end_time: str,
17-
id_: int = None,
18-
zone_id: int = None,
19-
stream_id: int = None):
20-
self.name: str = name
21-
"""A friendly name for the zone alarm"""
22-
self.id: int = id_
23-
"""A unique identifier"""
24-
self.zone_id: int = zone_id
25-
"""The ID of the zone this alarm is associated with"""
26-
self.stream_id: int = stream_id
27-
"""The ID of the stream the associated zone is in"""
28-
self.count_conditions: List[ZoneAlarmCountCondition] = count_conditions
29-
"""All count conditions for this alarm"""
30-
self.rate_conditions: List[ZoneAlarmRateCondition] = rate_conditions
31-
"""All rate conditions for this alarm"""
32-
self.use_active_time: bool = use_active_time
33-
"""If True, the alarm will only be triggered when the current time is
34-
between the active_start_time and active_end_time.
35-
"""
36-
self.active_start_time: str = active_start_time
37-
"""The time of day where this alarm starts being active, in the format
38-
"hh:mm:ss"
39-
"""
40-
self.active_end_time: str = active_end_time
41-
"""The time of day where this alarm starts being active, in the format
42-
"hh:mm:ss"
43-
"""
13+
name: str
14+
"""A friendly name for the zone alarm"""
15+
16+
zone_id: int
17+
"""The ID of the zone this alarm is associated with"""
18+
19+
stream_id: int
20+
"""The ID of the stream the associated zone is in"""
21+
22+
count_conditions: List[ZoneAlarmCountCondition]
23+
"""All count conditions for this alarm"""
24+
25+
rate_conditions: List[ZoneAlarmRateCondition]
26+
"""All rate conditions for this alarm"""
27+
28+
use_active_time: bool
29+
"""If True, the alarm will only be triggered when the current time is
30+
between the active_start_time and active_end_time.
31+
"""
32+
33+
active_start_time: str
34+
"""The time of day where this alarm starts being active, in the format
35+
"hh:mm:ss"
36+
"""
37+
38+
active_end_time: str
39+
"""The time of day where this alarm starts being active, in the format
40+
"hh:mm:ss"
41+
"""
42+
43+
id: Optional[int] = None
44+
"""A unique identifier"""
4445

4546
def to_dict(self):
4647
d = dict(self.__dict__)
@@ -59,7 +60,7 @@ def from_dict(d):
5960
for cond in d["rate_conditions"]]
6061

6162
return ZoneAlarm(name=d["name"],
62-
id_=d["id"],
63+
id=d["id"],
6364
count_conditions=count_conditions,
6465
rate_conditions=rate_conditions,
6566
use_active_time=d["use_active_time"],
@@ -69,45 +70,44 @@ def from_dict(d):
6970
stream_id=d["stream_id"])
7071

7172

73+
@dataclass
7274
class Alert(Codec):
7375
"""This is sent when an Alarm has been triggered."""
7476

75-
def __init__(self, *,
76-
alarm_id: int,
77-
zone_id: int,
78-
stream_id: int,
79-
start_time: float,
80-
end_time: float,
81-
verified_as: Optional[bool],
82-
id_: int = None):
83-
self.id: int = id_
84-
"""A unique identifier"""
85-
self.alarm_id: int = alarm_id
86-
"""The ID of the alarm that this alert came from"""
87-
self.zone_id: int = zone_id
88-
"""The ID of the zone this alert pertains to"""
89-
self.stream_id: int = stream_id
90-
"""The ID of the stream this alert pertains to"""
91-
self.start_time: float = start_time
92-
"""When the event started happening, in Unix Time (seconds)"""
93-
self.end_time: Optional[float] = end_time
94-
"""When the event stopped happening, in Unix Time (seconds), or None
95-
if the alert is ongoing.
96-
"""
97-
self.verified_as: Optional[bool] = verified_as
98-
"""
99-
- If True, then this alert was labeled by a person as legitimate
100-
- If False, then this alert was labeled by a person as a false alarm
101-
- If None, then this alert has not been reviewed by a person
102-
"""
77+
alarm_id: int
78+
"""The ID of the alarm that this alert came from"""
79+
80+
zone_id: int
81+
"""The ID of the zone this alert pertains to"""
82+
83+
stream_id: int
84+
"""The ID of the stream this alert pertains to"""
85+
86+
start_time: float
87+
"""When the event started happening, in Unix Time (seconds)"""
88+
89+
end_time: Optional[float]
90+
"""When the event stopped happening, in Unix Time (seconds), or None
91+
if the alert is ongoing.
92+
"""
93+
94+
verified_as: Optional[bool]
95+
"""
96+
- If True, then this alert was labeled by a person as legitimate
97+
- If False, then this alert was labeled by a person as a false alarm
98+
- If None, then this alert has not been reviewed by a person
99+
"""
100+
101+
id: Optional[int] = None
102+
"""A unique identifier"""
103103

104104
def to_dict(self):
105105
d = dict(self.__dict__)
106106
return d
107107

108108
@staticmethod
109109
def from_dict(d):
110-
return Alert(id_=d["id"],
110+
return Alert(id=d["id"],
111111
alarm_id=d["alarm_id"],
112112
zone_id=d["zone_id"],
113113
stream_id=d["stream_id"],

brainframe/api/bf_codecs/base_codecs.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,6 @@ def to_json(self) -> str:
2020
def from_json(cls, j: str):
2121
return cls.from_dict(json.loads(j))
2222

23-
def __repr__(self):
24-
"""Formats a string in the format of
25-
ClassName(arg1=val, arg2=val, arg3=val)"""
26-
argstring = ""
27-
for argname, argval in self.to_dict().items():
28-
if len(argstring):
29-
argstring += ", "
30-
argstring += f"{argname}={argval}"
31-
return f"{type(self).__name__}({argstring})"
32-
3323
def __eq__(self, other):
3424
if type(other) is dict:
3525
return self.to_dict() == other

brainframe/api/bf_codecs/condition_codecs.py

Lines changed: 68 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from enum import Enum
22
from typing import Optional
33

4+
from dataclasses import dataclass
5+
46
from .base_codecs import Codec
57
from .detection_codecs import Attribute
68

@@ -46,43 +48,42 @@ def values(cls):
4648
return [v.value for v in cls]
4749

4850

51+
@dataclass
4952
class ZoneAlarmCountCondition(Codec):
5053
"""A condition that must be met for an alarm to go off. Compares the number
5154
of objects in a zone to some number.
5255
"""
5356

54-
def __init__(self, *,
55-
test: CountConditionTestType,
56-
check_value: int,
57-
with_class_name: str,
58-
with_attribute: Optional[Attribute],
59-
window_duration: float,
60-
window_threshold: float,
61-
intersection_point: IntersectionPointType,
62-
id_: int = None):
63-
self.test: CountConditionTestType = test
64-
"""The way that the check value will be compared to the actual count
65-
"""
66-
self.check_value: int = check_value
67-
"""The value to test the actual count against"""
68-
self.with_class_name: str = with_class_name
69-
"""The class name of the objects to count"""
70-
self.with_attribute: Optional[Attribute] = with_attribute
71-
"""If provided, only objects that have this attribute value will be
72-
counted.
73-
"""
74-
self.window_duration: float = window_duration
75-
"""The sliding window duration for this condition"""
76-
self.window_threshold: float = window_threshold
77-
"""The portion of time during the sliding window duration that this
78-
condition must be true in order for the associated alarm to trigger
79-
"""
80-
self.intersection_point: IntersectionPointType = intersection_point
81-
"""The point in each detection that must be within the zone in order
82-
for that detection to be counted as in that zone
83-
"""
84-
self.id: int = id_
85-
"""A unique identifier"""
57+
test: CountConditionTestType
58+
"""The way that the check value will be compared to the actual count
59+
"""
60+
61+
check_value: int
62+
"""The value to test the actual count against"""
63+
64+
with_class_name: str
65+
"""The class name of the objects to count"""
66+
67+
with_attribute: Optional[Attribute]
68+
"""If provided, only objects that have this attribute value will be
69+
counted.
70+
"""
71+
72+
window_duration: float
73+
"""The sliding window duration for this condition"""
74+
75+
window_threshold: float
76+
"""The portion of time during the sliding window duration that this
77+
condition must be true in order for the associated alarm to trigger
78+
"""
79+
80+
intersection_point: IntersectionPointType
81+
"""The point in each detection that must be within the zone in order
82+
for that detection to be counted as in that zone
83+
"""
84+
85+
id: Optional[int] = None
86+
"""A unique identifier"""
8687

8788
def __repr__(self):
8889
condition_str = condition_test_map[self.test.value]
@@ -118,7 +119,7 @@ def from_dict(d: dict):
118119
window_duration=d["window_duration"],
119120
window_threshold=d["window_threshold"],
120121
intersection_point=intersection_point,
121-
id_=d["id"])
122+
id=d["id"])
122123

123124

124125
class RateConditionTestType(Enum):
@@ -146,48 +147,47 @@ def values(cls):
146147
return [v.value for v in cls]
147148

148149

150+
@dataclass
149151
class ZoneAlarmRateCondition(Codec):
150152
"""A condition that must be met for an alarm to go off. Compares the rate
151153
of change in the count of some object against a test value.
152154
"""
153155

154-
direction_map = {DirectionType.ENTERING: "entered",
155-
DirectionType.EXITING: "exited",
156-
DirectionType.ENTERING_OR_EXITING: "entered or exited"}
157-
158-
def __init__(self, *,
159-
test: RateConditionTestType,
160-
duration: float,
161-
change: float,
162-
direction: DirectionType,
163-
with_class_name: str,
164-
with_attribute: Optional[Attribute],
165-
intersection_point: IntersectionPointType,
166-
id_: int = None):
167-
self.test: RateConditionTestType = test
168-
"""The way that the change value will be compared to the actual rate"""
169-
self.duration: float = duration
170-
"""The time in seconds for this rate change to occur"""
171-
self.change: float = change
172-
"""The rate change value to compare the actual rate value against"""
173-
self.direction: DirectionType = direction
174-
"""The direction of flow this condition tests for"""
175-
self.with_class_name: str = with_class_name
176-
"""The class name of the objects to measure rate of change for"""
177-
self.with_attribute: Optional[Attribute] = with_attribute
178-
"""If provided, only objects that have this attribute will be counted
179-
in the rate calculation
180-
"""
181-
self.intersection_point: IntersectionPointType = intersection_point
182-
"""The point in each detection that must be within the zone in order
183-
for that detection to be counted as in that zone
184-
"""
185-
self.id: int = id_
186-
"""A unique identifier"""
156+
_direction_map = {DirectionType.ENTERING: "entered",
157+
DirectionType.EXITING: "exited",
158+
DirectionType.ENTERING_OR_EXITING: "entered or exited"}
159+
160+
test: RateConditionTestType
161+
"""The way that the change value will be compared to the actual rate"""
162+
163+
duration: float
164+
"""The time in seconds for this rate change to occur"""
165+
166+
change: float
167+
"""The rate change value to compare the actual rate value against"""
168+
169+
direction: DirectionType
170+
"""The direction of flow this condition tests for"""
171+
172+
with_class_name: str
173+
"""The class name of the objects to measure rate of change for"""
174+
175+
with_attribute: Optional[Attribute]
176+
"""If provided, only objects that have this attribute will be counted
177+
in the rate calculation
178+
"""
179+
180+
intersection_point: IntersectionPointType
181+
"""The point in each detection that must be within the zone in order
182+
for that detection to be counted as in that zone
183+
"""
184+
185+
id: int = None
186+
"""A unique identifier"""
187187

188188
def __repr__(self):
189189
condition_str = condition_test_map[self.test.value]
190-
direction_str = self.direction_map[self.direction]
190+
direction_str = self._direction_map[self.direction]
191191
return f"{condition_str} {self.change} {self.with_class_name}(s) " \
192192
f"{direction_str} within {self.duration} seconds"
193193

@@ -220,4 +220,4 @@ def from_dict(d: dict):
220220
with_class_name=d["with_class_name"],
221221
with_attribute=with_attribute,
222222
intersection_point=intersection_point,
223-
id_=d["id"])
223+
id=d["id"])

0 commit comments

Comments
 (0)