Sanitize floats for estimated speed and angle

Users can configure speed zones in such a way that velocity estimates from Norfair cause a value of inf to be stored as an estimated speed. FastAPI doesn't serialize inf as a float, so trying to return this value would result in an API error. Sanitizing the value before storing should correct this.
This commit is contained in:
Josh Hawkins 2025-05-22 10:15:26 -05:00
parent 0a6f13bcb2
commit 2e763a62f0
2 changed files with 14 additions and 0 deletions

View File

@ -18,6 +18,7 @@ from frigate.config import (
) )
from frigate.const import CLIPS_DIR, THUMB_DIR from frigate.const import CLIPS_DIR, THUMB_DIR
from frigate.review.types import SeverityEnum from frigate.review.types import SeverityEnum
from frigate.util.builtin import sanitize_float
from frigate.util.image import ( from frigate.util.image import (
area, area,
calculate_region, calculate_region,
@ -202,6 +203,11 @@ class TrackedObject:
) )
) )
# users can configure speed zones incorrectly, so sanitize speed_magnitude
# and velocity_angle in case the values come back as inf or NaN
speed_magnitude = sanitize_float(speed_magnitude)
self.velocity_angle = sanitize_float(self.velocity_angle)
if self.ui_config.unit_system == "metric": if self.ui_config.unit_system == "metric":
self.current_estimated_speed = ( self.current_estimated_speed = (
speed_magnitude * 3.6 speed_magnitude * 3.6

View File

@ -4,6 +4,7 @@ import ast
import copy import copy
import datetime import datetime
import logging import logging
import math
import multiprocessing as mp import multiprocessing as mp
import queue import queue
import re import re
@ -399,3 +400,10 @@ def serialize(
def deserialize(bytes_data: bytes) -> list[float]: def deserialize(bytes_data: bytes) -> list[float]:
"""Deserializes a compact "raw bytes" format into a list of floats""" """Deserializes a compact "raw bytes" format into a list of floats"""
return list(struct.unpack("%sf" % (len(bytes_data) // 4), bytes_data)) return list(struct.unpack("%sf" % (len(bytes_data) // 4), bytes_data))
def sanitize_float(value):
"""Replace NaN or inf with 0.0."""
if isinstance(value, (int, float)) and not math.isfinite(value):
return 0.0
return value