From f2bfcebbc4289eb3892cc36afd11b17b45acb706 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Mon, 28 Sep 2026 09:04:04 -0500 Subject: [PATCH] share a unit's temperature across repeated detector devices Detector temperatures were matched to units by counting detectors of each type, so a device listed twice to run a second inference process (`hailo:PCIe` and `hailo:PCIe#2`) showed the next unit's temperature, or none at all. Distinct devices are numbered now and repeats share their unit's reading. --- frigate/stats/util.py | 11 +++++--- frigate/test/test_detector_stats.py | 39 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 frigate/test/test_detector_stats.py diff --git a/frigate/stats/util.py b/frigate/stats/util.py index ef220e0125..620f8d691d 100644 --- a/frigate/stats/util.py +++ b/frigate/stats/util.py @@ -111,15 +111,18 @@ def get_detector_stats( ) -> dict[str, dict[str, Any]]: """Get stats for all detectors, including temperatures based on detector type.""" detector_stats: dict[str, dict[str, Any]] = {} - detector_type_indices: dict[str, int] = {} + # detector type -> device -> index into that type's temperatures + device_indices: dict[str, dict[str, int]] = {} for name, detector in stats_tracking["detectors"].items(): pid = detector.detect_process.pid if detector.detect_process else None detector_type = detector.detector_config.type - # Keep track of the index for each detector type to match temperatures correctly - current_index = detector_type_indices.get(detector_type, 0) - detector_type_indices[detector_type] = current_index + 1 + # temperatures are per physical unit, so a repeated device + # ("hailo:PCIe#2", see runner_names) shares its unit's reading + device = name.partition("#")[0] + type_devices = device_indices.setdefault(detector_type, {}) + current_index = type_devices.setdefault(device, len(type_devices)) detector_stat = { "inference_speed": round(detector.avg_inference_speed.value * 1000, 2), # type: ignore[attr-defined] diff --git a/frigate/test/test_detector_stats.py b/frigate/test/test_detector_stats.py new file mode 100644 index 0000000000..db7f265e0d --- /dev/null +++ b/frigate/test/test_detector_stats.py @@ -0,0 +1,39 @@ +"""Tests for per-detector stats.""" + +import unittest +from unittest.mock import MagicMock, patch + +from frigate.stats.util import get_detector_stats + + +def _detector(detector_type: str) -> MagicMock: + detector = MagicMock() + detector.detector_config.type = detector_type + detector.avg_inference_speed.value = 0.01 + detector.detection_start.value = 0.0 + detector.detect_process.pid = 1 + return detector + + +class TestDetectorTemperatures(unittest.TestCase): + def test_repeated_device_shares_its_unit_temperature(self): + stats_tracking = { + "detectors": { + "hailo:PCIe": _detector("hailo8l"), + "hailo:PCIe#2": _detector("hailo8l"), + "hailo:PCIe:1": _detector("hailo8l"), + } + } + + with patch( + "frigate.stats.util.get_hardware_temperatures", return_value=[50.0, 60.0] + ): + stats = get_detector_stats(stats_tracking) + + self.assertEqual(stats["hailo:PCIe"]["temperature"], 50.0) + self.assertEqual(stats["hailo:PCIe#2"]["temperature"], 50.0) + self.assertEqual(stats["hailo:PCIe:1"]["temperature"], 60.0) + + +if __name__ == "__main__": + unittest.main()