Repository navigation
fix(vitals): fall back to the body component list for telemetry state - #14
Conversation
Components without scalar telemetry (lidar, IMU, camera, audio) stayed "unknown" forever in the dashboard. Read the enabled flag of the body component entries instead and map it to ok/error, with an explicit detail when the robot reports a component offline. Assisted-by: Claude-Code:deepseek-flash Signed-off-by: lwxcd <l1393452711@gmail.com>
enkerewpo
left a comment
There was a problem hiding this comment.
Tested end to end: real Vitals conversion (snapshot_to_vitals in robonix system/vitals) → vitals_snapshot_to_dict on main (d368173) vs this branch (e1e3d92).
| Soma reports | main | this PR |
|---|---|---|
| sensor OK, online | unknown | ok |
| sensor ERROR, online, no fault entry | unknown | ok |
| sensor offline | unknown | error |
| joint torque off | warn | warn |
Existing 16 tests pass; none covers the new path.
Fix:
- Address the inline comments and add tests for the fallback.
- Follow-up in robonix: Vitals should forward
ComponentStatus.healthas a signal. The faulted-but-online case is then covered.
Logs
Vitals output:
PROBE_SIGNAL body/arm/joint_2/torque_enabled health=1 detail="body/arm/joint_2 torque is disabled"
PROBE_BODYCOMP body=computer_jetson id=body/computer_jetson/lidar_ok kind=sensor enabled=true error_code=0
PROBE_BODYCOMP body=computer_jetson id=body/computer_jetson/lidar_err kind=sensor enabled=true error_code=0
PROBE_BODYCOMP body=computer_jetson id=body/computer_jetson/lidar_off kind=sensor enabled=false error_code=0
PROBE_BODYCOMP body=computer_jetson id=body/computer_jetson/lidar_nohealth kind=sensor enabled=true error_code=0
PROBE_BODYCOMP body=arm id=body/arm/joint_2 kind=joint enabled=false error_code=0
Client output:
== main d368173
body/computer_jetson/cpu health=ok detail=''
body/computer_jetson/lidar_ok health=unknown detail=''
body/computer_jetson/lidar_err health=unknown detail=''
body/computer_jetson/lidar_off health=unknown detail=''
body/computer_jetson/lidar_nohealth health=unknown detail=''
body/arm/joint_2 health=warn detail='body/arm/joint_2 torque is disabled'
== pr e1e3d92
body/computer_jetson/cpu health=ok detail=''
body/computer_jetson/lidar_ok health=ok detail=''
body/computer_jetson/lidar_err health=ok detail=''
body/computer_jetson/lidar_off health=error detail='component reported offline by the robot health source'
body/computer_jetson/lidar_nohealth health=ok detail=''
body/arm/joint_2 health=warn detail='body/arm/joint_2 torque is disabled'
| # Components with no scalar telemetry (this deployment's lidar, imu, | ||
| # camera and audio) would otherwise read "unknown" forever; fall back | ||
| # to the online/present flag the robot's health source reports for | ||
| # them in the body component list. |
There was a problem hiding this comment.
This comment describes one specific robot. Please describe the rule instead, e.g. "Components without telemetry fall back to their online flag; ok only means the component is online."
| if body_enabled[component_id]: | ||
| direct_health = "ok" | ||
| direct_visual_state = "ok" |
There was a problem hiding this comment.
Being online does not mean healthy. If Soma reports a sensor as ERROR while it is still online, this shows it as ok. Please add a detail so users can tell the difference:
detail = "online, no health data"|
Upstream follow-up for the faulted-but-online case: syswonder/robonix#278 |
The body-component-list fallback maps an online component to "ok", but online does not mean healthy: a sensor that Soma reports as ERROR while still online is indistinguishable from a healthy one. Set an explicit "online, no health data" detail in this path so the two cases can be told apart, and describe the fallback rule in the comment rather than one deployment's component list. Add tests covering the online, offline and direct-telemetry-precedence cases. Assisted-by: Claude-Code:deepseek-flash Signed-off-by: lwxcd <l1393452711@gmail.com>
|
Thanks for the update; the inline points are addressed. One rule is still off: the fallback treats
Change: only a non-actuator that is explicitly The patch below applies on d251786 ( Patchdiff --git a/src/robonix_client/vitals_transport.py b/src/robonix_client/vitals_transport.py
index f13c835..197c4c3 100644
--- a/src/robonix_client/vitals_transport.py
+++ b/src/robonix_client/vitals_transport.py
@@ -29,6 +29,9 @@ VITALS_MODULES_GET_PATH = (
"/robonix.contracts.RobonixSystemVitalsModulesGet/GetModuleHealthSnapshot"
)
+# Body component kinds whose `enabled` is torque, not presence.
+ACTUATOR_KINDS = frozenset({"arm", "leg", "joint", "wheel", "gripper", "end_effector"})
+
HEALTH_SEVERITY = {
"unknown": 0,
"ok": 1,
@@ -347,11 +350,21 @@ def aggregate_component_health(
if match:
body_health[match] = str(body.get("health") or "unknown")
- body_enabled: dict[str, bool] = {}
+ # Vitals' `enabled` is torque for an actuator and present-and-online for
+ # anything else, and Soma reports a component nothing has observed as
+ # offline. So only a non-actuator that is explicitly enabled says
+ # anything: it is online. False means "offline" or "never observed"
+ # alike, and stays unknown.
+ online: set[str] = set()
for body in bodies:
for component in body.get("components") or []:
- if isinstance(component, dict) and component.get("id"):
- body_enabled[str(component["id"])] = bool(component.get("enabled"))
+ if (
+ isinstance(component, dict)
+ and component.get("id")
+ and component.get("enabled") is True
+ and str(component.get("kind") or "") not in ACTUATOR_KINDS
+ ):
+ online.add(str(component["id"]))
rows: dict[str, dict[str, Any]] = {}
for component in components:
@@ -373,17 +386,11 @@ def aggregate_component_health(
)
detail = str(worst_signal.get("detail") or "")
source_component_id = component_id if direct_values else ""
- # Components without telemetry fall back to their online flag;
- # `ok` only means the component is online.
- if direct_health == "unknown" and component_id in body_enabled:
- if body_enabled[component_id]:
- direct_health = "ok"
- direct_visual_state = "ok"
- detail = "online, no health data"
- else:
- direct_health = "error"
- direct_visual_state = "error"
- detail = "component reported offline by the robot health source"
+ # Without telemetry, `ok` only means the component is online.
+ if direct_health == "unknown" and component_id in online:
+ direct_health = "ok"
+ direct_visual_state = "ok"
+ detail = "online, no health data"
source_component_id = component_id
rows[component_id] = {
"componentId": component_id,
diff --git a/tests/test_vitals_transport.py b/tests/test_vitals_transport.py
index f257bb6..2442785 100644
--- a/tests/test_vitals_transport.py
+++ b/tests/test_vitals_transport.py
@@ -392,7 +392,9 @@ class ComponentHealthTest(unittest.TestCase):
self.assertEqual(camera["detail"], "online, no health data")
self.assertEqual(camera["sourceComponentId"], "body/head_camera")
- def test_treats_component_disabled_by_health_source_as_offline(self):
+ def test_keeps_unobserved_component_unknown(self):
+ """Soma reports a component nothing observed as offline, so a false
+ `enabled` cannot tell offline from never seen."""
rows = aggregate_component_health(
self.description,
[],
@@ -405,15 +407,25 @@ class ComponentHealthTest(unittest.TestCase):
],
)
health = {row["componentId"]: row for row in rows}
+ self.assertEqual(health["body/head_camera"]["health"], "unknown")
- camera = health["body/head_camera"]
- self.assertEqual(camera["health"], "error")
- self.assertEqual(camera["directHealth"], "error")
- self.assertEqual(
- camera["detail"],
- "component reported offline by the robot health source",
+ def test_ignores_actuator_torque_flag(self):
+ """An actuator's `enabled` is torque; torque on says nothing about health."""
+ rows = aggregate_component_health(
+ self.description,
+ [],
+ [
+ {
+ "key": "body",
+ "health": "ok",
+ "components": [
+ {"id": "body/head_camera", "enabled": True, "kind": "gripper"}
+ ],
+ }
+ ],
)
- self.assertEqual(camera["sourceComponentId"], "body/head_camera")
+ health = {row["componentId"]: row for row in rows}
+ self.assertEqual(health["body/head_camera"]["health"], "unknown")
def test_direct_telemetry_takes_precedence_over_online_flag(self):
signals = [ |
Soma reports a component that nothing has observed as offline, so a false `enabled` cannot distinguish offline from never seen, and marking it as error turns every unobserved sensor red after boot. Treat only an explicitly enabled non-actuator as online when it has no telemetry; actuator `enabled` is torque, so ignore it and stay unknown. Update the tests for the unobserved and actuator-torque cases. Assisted-by: Claude-Code:deepseek-flash Signed-off-by: lwxcd <l1393452711@gmail.com>
|
Thanks — applied. Only non-actuators with |
|
Thanks |
Problem
Components without scalar telemetry (lidar, IMU, camera, audio) read "unknown" forever in the client: they emit no Vitals signals, and the robot health source does not populate a per-component
healthfield either.Changes
enabledfrom the Soma body component list (body.components[].enabled).detail: "component reported offline by the robot health source"when absent.sourceComponentIdpoints at the component; all other paths unchanged.Validation
.venv/bin/python -m unittest tests.test_vitals_transport -v— 16 passed.python3 scripts/check_commit_authorship.py --base origin/main --head HEAD— passed.Compatibility
Additive; wire schema and frontend bundle unchanged; no config/migration.