mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-09-29 11:26:49 +03:00
backend
This commit is contained in:
+38
-8
@@ -88,7 +88,7 @@ class StorageMaintainer(threading.Thread):
|
|||||||
# type and sum the rates; mixing streams would average small
|
# type and sum the rates; mixing streams would average small
|
||||||
# sub segments against large main segments and underestimate
|
# sub segments against large main segments and underestimate
|
||||||
# the true write rate
|
# the true write rate
|
||||||
bandwidth = 0.0
|
bandwidth_by_stream: dict[str, float] = {}
|
||||||
for stream_type in (STREAM_TYPE_MAIN, STREAM_TYPE_SUB):
|
for stream_type in (STREAM_TYPE_MAIN, STREAM_TYPE_SUB):
|
||||||
avg_bw = self._recent_stream_bandwidth(camera, stream_type, 100)
|
avg_bw = self._recent_stream_bandwidth(camera, stream_type, 100)
|
||||||
if avg_bw is None:
|
if avg_bw is None:
|
||||||
@@ -99,17 +99,27 @@ class StorageMaintainer(threading.Thread):
|
|||||||
camera, stream_type, 1000
|
camera, stream_type, 1000
|
||||||
)
|
)
|
||||||
if avg_bw is not None:
|
if avg_bw is not None:
|
||||||
bandwidth += round(avg_bw * 3600, 2)
|
bandwidth_by_stream[stream_type] = round(avg_bw * 3600, 2)
|
||||||
|
|
||||||
bandwidth = round(bandwidth, 2)
|
bandwidth = round(sum(bandwidth_by_stream.values()), 2)
|
||||||
|
|
||||||
if bandwidth > MAX_CALCULATED_BANDWIDTH:
|
if bandwidth > MAX_CALCULATED_BANDWIDTH:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"{camera} has a bandwidth of {bandwidth} MB/hr which exceeds the expected maximum. This typically indicates an issue with the cameras recordings."
|
f"{camera} has a bandwidth of {bandwidth} MB/hr which exceeds the expected maximum. This typically indicates an issue with the cameras recordings."
|
||||||
)
|
)
|
||||||
|
# scale each stream so the per stream values still sum to
|
||||||
|
# the clamped total the UI displays alongside them
|
||||||
|
scale = MAX_CALCULATED_BANDWIDTH / bandwidth
|
||||||
|
bandwidth_by_stream = {
|
||||||
|
stream_type: round(value * scale, 2)
|
||||||
|
for stream_type, value in bandwidth_by_stream.items()
|
||||||
|
}
|
||||||
bandwidth = MAX_CALCULATED_BANDWIDTH
|
bandwidth = MAX_CALCULATED_BANDWIDTH
|
||||||
|
|
||||||
self.camera_storage_stats[camera]["bandwidth"] = bandwidth
|
self.camera_storage_stats[camera]["bandwidth"] = bandwidth
|
||||||
|
self.camera_storage_stats[camera]["bandwidth_by_stream"] = (
|
||||||
|
bandwidth_by_stream
|
||||||
|
)
|
||||||
logger.debug(f"{camera} has a bandwidth of {bandwidth} MiB/hr.")
|
logger.debug(f"{camera} has a bandwidth of {bandwidth} MiB/hr.")
|
||||||
|
|
||||||
def calculate_camera_usages(self) -> dict[str, dict]:
|
def calculate_camera_usages(self) -> dict[str, dict]:
|
||||||
@@ -121,20 +131,40 @@ class StorageMaintainer(threading.Thread):
|
|||||||
if camera.startswith(REPLAY_CAMERA_PREFIX):
|
if camera.startswith(REPLAY_CAMERA_PREFIX):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
camera_storage = (
|
stream_usages = {
|
||||||
Recordings.select(fn.SUM(Recordings.segment_size))
|
row["stream_type"]: row["usage"] or 0
|
||||||
.where(Recordings.camera == camera, Recordings.segment_size != 0)
|
for row in (
|
||||||
.scalar()
|
Recordings.select(
|
||||||
|
Recordings.stream_type,
|
||||||
|
fn.SUM(Recordings.segment_size).alias("usage"),
|
||||||
|
)
|
||||||
|
.where(Recordings.camera == camera, Recordings.segment_size != 0)
|
||||||
|
.group_by(Recordings.stream_type)
|
||||||
|
.dicts()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
stream_bandwidths = self.camera_storage_stats.get(camera, {}).get(
|
||||||
|
"bandwidth_by_stream", {}
|
||||||
)
|
)
|
||||||
|
|
||||||
camera_key = (
|
camera_key = (
|
||||||
getattr(self.config.cameras[camera], "friendly_name", None) or camera
|
getattr(self.config.cameras[camera], "friendly_name", None) or camera
|
||||||
)
|
)
|
||||||
usages[camera_key] = {
|
usages[camera_key] = {
|
||||||
"usage": camera_storage,
|
"usage": sum(stream_usages.values()),
|
||||||
"bandwidth": self.camera_storage_stats.get(camera, {}).get(
|
"bandwidth": self.camera_storage_stats.get(camera, {}).get(
|
||||||
"bandwidth", 0
|
"bandwidth", 0
|
||||||
),
|
),
|
||||||
|
# only streams with segments on disk are reported, so a camera
|
||||||
|
# keeps its sub entry until sub retention expires those segments
|
||||||
|
"streams": {
|
||||||
|
stream_type: {
|
||||||
|
"usage": stream_usages[stream_type],
|
||||||
|
"bandwidth": stream_bandwidths.get(stream_type, 0),
|
||||||
|
}
|
||||||
|
for stream_type in (STREAM_TYPE_MAIN, STREAM_TYPE_SUB)
|
||||||
|
if stream_usages.get(stream_type)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return usages
|
return usages
|
||||||
|
|||||||
Reference in New Issue
Block a user