Browse Source

fix(obico): Failure Detection status panel shows thresholds for the selected sensitivity (#1469)

  The Status panel's Low / High thresholds readout was stuck at 0.38 /
  0.78 regardless of the Sensitivity dropdown, so the setting looked
  dead. Detection itself was correct -- classify() always used the real
  sensitivity -- but get_status() computed the displayed thresholds with
  a hardcoded thresholds("medium").

  get_status() now takes an optional sensitivity argument and the
  /obico/status route passes settings["sensitivity"] (it already loads
  settings fresh). The readout updates as soon as the change is saved.
maziggy 6 days ago
parent
commit
5b3962e3e6

File diff suppressed because it is too large
+ 2 - 0
CHANGELOG.md


+ 1 - 1
backend/app/api/routes/obico.py

@@ -25,7 +25,7 @@ async def get_status(
 ):
 ):
     """Scheduler status, per-printer classification, and recent detection history."""
     """Scheduler status, per-printer classification, and recent detection history."""
     settings = await obico_detection_service._load_settings()
     settings = await obico_detection_service._load_settings()
-    status = obico_detection_service.get_status()
+    status = obico_detection_service.get_status(settings["sensitivity"])
     return {
     return {
         **status,
         **status,
         "enabled": settings["enabled"],
         "enabled": settings["enabled"],

+ 6 - 2
backend/app/services/obico_detection.py

@@ -320,8 +320,12 @@ class ObicoDetectionService:
 
 
     # ---- queries ----
     # ---- queries ----
 
 
-    def get_status(self) -> dict:
-        low, high = thresholds("medium")
+    def get_status(self, sensitivity: str = "medium") -> dict:
+        # Report the thresholds for the configured sensitivity, not a hardcoded
+        # "medium" — otherwise the Status panel always shows the medium row
+        # regardless of the user's selection (#1469). thresholds() falls back
+        # to the medium multiplier for any unrecognized value.
+        low, high = thresholds(sensitivity)
         return {
         return {
             "is_running": self._task is not None and not self._task.done(),
             "is_running": self._task is not None and not self._task.done(),
             "last_error": self._last_error,
             "last_error": self._last_error,

+ 16 - 0
backend/tests/unit/test_obico_detection.py

@@ -74,6 +74,22 @@ class TestGetStatus:
         assert s["history"] == []
         assert s["history"] == []
         assert "low" in s["thresholds"] and "high" in s["thresholds"]
         assert "low" in s["thresholds"] and "high" in s["thresholds"]
 
 
+    def test_thresholds_reflect_configured_sensitivity(self):
+        """#1469 — get_status() reports the thresholds for the passed
+        sensitivity, not a hardcoded 'medium'. Each level must be distinct so
+        the Status panel changes when the user changes the setting."""
+        svc = ObicoDetectionService()
+        low = svc.get_status("low")["thresholds"]
+        medium = svc.get_status("medium")["thresholds"]
+        high = svc.get_status("high")["thresholds"]
+
+        # Higher sensitivity → lower thresholds (easier to trigger).
+        assert low["low"] > medium["low"] > high["low"]
+        assert low["high"] > medium["high"] > high["high"]
+        # Default and unknown values fall back to medium.
+        assert svc.get_status()["thresholds"] == medium
+        assert svc.get_status("bogus")["thresholds"] == medium
+
 
 
 class TestTestConnection:
 class TestTestConnection:
     @pytest.mark.asyncio
     @pytest.mark.asyncio

Some files were not shown because too many files changed in this diff