# Source audit: error manager and feedback transport This is a static review of the supplied `dobot_error.py` and `dobot_tcp.py`; it does not establish hardware behavior. ## DobotErrorManager - `DobotTcp` injects Dashboard access, feedback-state access, scalar conversion and logging. The error manager does not own TCP connections. - `_get_error_records()` returns an empty list if Dashboard is unavailable, the `GetErrorID()` return code is nonzero, or the payload is absent/malformed. **An empty list does not prove that no alarm exists.** - The first group in the response denotes controller alarms; subsequent groups denote servo alarms, with the group index recorded as `joint`. - Description language preference is `jp`, then `ja`, then `en`. An ID-only lookup prioritizes controller records; use `get_current_error_info()` when alarm origin matters. - `get_error_code()` returns 0 for an empty record list; `get_error_info(index)` returns `None` for an out-of-range index. This `index` is **zero-based**, unlike joint numbering. - `motion_error_active()` reads feedback `ErrorStatus` and optionally queries `GetErrorID()`. A `RuntimeError` while reading feedback is converted to `ErrorStatus=False`; **a communication failure can therefore be mistaken for a clear status**. `wait_motion_start_or_error()` observes only a short interval immediately after dispatch, not the entire motion. ## DobotTcp feedback - `connect()` creates Dashboard, Motion and Feedback connections and starts a receive thread. `True` does not mean a valid feedback frame has arrived. - The receive loop accumulates a full 1440-byte frame, validates `test_value`, and updates state under a lock. - Feedback EOF triggers a feedback-socket reconnect; the general exception path logs and retries after a short sleep, **without necessarily reconnecting**. - `_feedback_ready` is set on the first valid frame and is not cleared when subsequent feedback stalls. `_state()` returns the **last received** value, not a freshness-guaranteed current state. - `is_connected()` only checks that three connection objects are non-`None`, not TCP liveness or feedback freshness. - `disconnect()` sets the stop event, closes sockets and clears cached state, but does not `join()` the receiver thread. ## Operational limitation Do not treat these Booleans or cached feedback values as sufficient safety interlocks, guaranteed stop signals, or evidence that alarm recovery is safe. Communication loss, unavailable data and confirmed no-alarm states require explicit separation.