|
1 | 1 | from enum import Enum |
2 | 2 | from typing import Optional |
3 | 3 |
|
| 4 | +from dataclasses import dataclass |
| 5 | + |
4 | 6 | from .base_codecs import Codec |
5 | 7 | from .detection_codecs import Attribute |
6 | 8 |
|
@@ -46,43 +48,42 @@ def values(cls): |
46 | 48 | return [v.value for v in cls] |
47 | 49 |
|
48 | 50 |
|
| 51 | +@dataclass |
49 | 52 | class ZoneAlarmCountCondition(Codec): |
50 | 53 | """A condition that must be met for an alarm to go off. Compares the number |
51 | 54 | of objects in a zone to some number. |
52 | 55 | """ |
53 | 56 |
|
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""" |
86 | 87 |
|
87 | 88 | def __repr__(self): |
88 | 89 | condition_str = condition_test_map[self.test.value] |
@@ -118,7 +119,7 @@ def from_dict(d: dict): |
118 | 119 | window_duration=d["window_duration"], |
119 | 120 | window_threshold=d["window_threshold"], |
120 | 121 | intersection_point=intersection_point, |
121 | | - id_=d["id"]) |
| 122 | + id=d["id"]) |
122 | 123 |
|
123 | 124 |
|
124 | 125 | class RateConditionTestType(Enum): |
@@ -146,48 +147,47 @@ def values(cls): |
146 | 147 | return [v.value for v in cls] |
147 | 148 |
|
148 | 149 |
|
| 150 | +@dataclass |
149 | 151 | class ZoneAlarmRateCondition(Codec): |
150 | 152 | """A condition that must be met for an alarm to go off. Compares the rate |
151 | 153 | of change in the count of some object against a test value. |
152 | 154 | """ |
153 | 155 |
|
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""" |
187 | 187 |
|
188 | 188 | def __repr__(self): |
189 | 189 | condition_str = condition_test_map[self.test.value] |
190 | | - direction_str = self.direction_map[self.direction] |
| 190 | + direction_str = self._direction_map[self.direction] |
191 | 191 | return f"{condition_str} {self.change} {self.with_class_name}(s) " \ |
192 | 192 | f"{direction_str} within {self.duration} seconds" |
193 | 193 |
|
@@ -220,4 +220,4 @@ def from_dict(d: dict): |
220 | 220 | with_class_name=d["with_class_name"], |
221 | 221 | with_attribute=with_attribute, |
222 | 222 | intersection_point=intersection_point, |
223 | | - id_=d["id"]) |
| 223 | + id=d["id"]) |
0 commit comments