Recon
Monitorear robots Recon
Vigila una flota de Recon desde tus propias herramientas: conexión y batería, qué hace cada robot y cuánto ha avanzado, y el historial de cada actividad que ejecutó, con las operaciones de estado y de eventos del robot.
Esta página se tradujo automáticamente. Si encuentras errores o tienes sugerencias, escríbenos.
Dos tipos de lecturas cubren una flota de robots: las operaciones de estado dicen qué hace cada robot ahora, y la operación de eventos dice qué hizo. Los ejemplos usan la función auxiliar robot_api de la descripción general.
Necesitas una clave de API con acceso de solo lectura a las ubicaciones de los robots.
Estado de la flota
getMinimalStateList devuelve una entrada por robot:
for robot in robot_api("getMinimalStateList", {})["minimalStates"]:
progress = ""
if robot.get("activity") == "ROUTE_RUN" and robot.get("waypointTotal"):
progress = f"stop {robot['waypointIndex'] + 1} of {robot['waypointTotal']}"
print(f"{robot['name']}: {robot['connectionStatus']}, {robot.get('batteryPercent')}%, {robot.get('activity')} {progress}")| Campo | Significado |
|---|---|
uuid, name, locationUuid | El robot, tal como lo identifican las demás operaciones de robots y la consola |
connectionStatus, healthStatus | GREEN, YELLOW, ORANGE o RED, de mejor a peor, como en todos los dispositivos |
batteryPercent | Nivel de batería, de 0 a 100 |
activity, activityUuid | Lo que hace el robot (abajo) y el ID de esa actividad. En un envío, activityUuid es el routeRunUuid que devolvió deploy |
event, phase, phaseEvent | El último paso de la actividad: event es su ciclo de vida (abajo) y phase, la parte en curso, como NAVIGATING, DWELLING, UNDOCKING o CHARGING |
routeUuid, waypointUuid, waypointIndex, waypointTotal | Durante una patrulla: la ruta, la parada actual (un ID de parada de la ruta), su posición contada desde 0 y el número de paradas |
goalPose, pose, mapId | Hacia dónde va el robot, dónde está y el mapa en el que están esas poses |
estimatedTimeRemainingSec, distanceRemaining | Tiempo (segundos) y distancia (metros) que faltan hasta el objetivo actual |
failureReason | Por qué falló la última actividad, cuando falló |
firmwareVersion, hwVariation | Firmware y modelo de hardware |
Para un solo robot, getFullState devuelve los mismos campos más las capacidades del robot. Incluye force (false sirve); sin él, la llamada se rechaza:
state = robot_api("getFullState", {"deviceUuid": ROBOT_UUID, "force": False})["fullState"]
capability = state.get("robotPlatformCapability") or {}
print(state["activity"], state.get("phase"), capability.get("supportedActions"))Usa activity y phase para saber si un robot está en su base, cargando o trabajando; los campos mode y charging no se informan.
Actividades
activity | El robot está |
|---|---|
IDLE | Esperando un comando |
ROUTE_RUN | Ejecutando una patrulla o una ruta. phase es DWELLING mientras espera en una parada |
NAVIGATE_TO_POSE | Yendo a un punto al que se le envió |
NAVIGATE_TO_HOME | Volviendo a su base de carga porque se le envió a la base |
IDLE_DOCKING | Volviendo a su base de carga por su cuenta, después de terminar su trabajo o de quedarse inactivo |
LOW_BATTERY_DOCKING | Volviendo a su base de carga para recargarse. Rechaza trabajo nuevo hasta que la batería se recupere |
MANUAL_CMD_VEL, MANUAL_ACTION, MANUAL_POSTURE | Conducido en vivo por un operador |
EMERGENCY | Detenido por una parada de emergencia, hasta que alguien lo libere |
EXPLORE_AND_MAP, EXPLORE_AREA, MAINTENANCE_HOLD | Mapeando su espacio, o retenido por mantenimiento del mapa |
Se pueden agregar valores nuevos. Trata como ocupado cualquier valor que no reconozcas.
Historial de eventos
findRobotEvents devuelve lo que hizo un robot entre startMs (incluido) y endMs (excluido). La respuesta es JSON delimitado por saltos de línea (application/x-ndjson), con un evento por línea, del más reciente al más antiguo:
import json
import time
def robot_events(robot_uuid, start_ms, end_ms):
response = requests.post(
f"{API}/findRobotEvents",
headers=HEADERS,
json={"deviceUuid": robot_uuid, "startMs": start_ms, "endMs": end_ms},
timeout=60,
)
response.raise_for_status()
events = []
for line in response.text.splitlines():
if not line.strip():
continue
event = json.loads(line)
if "_error" in event:
raise RuntimeError(f"findRobotEvents stopped early: {event.get('_message')}")
events.append(event)
return events
now = int(time.time() * 1000)
for event in robot_events(ROBOT_UUID, now - 24 * 3600 * 1000, now):
print(event["timestampMs"], event.get("activity"), event.get("event"), event.get("phase"), event.get("failureReason"))- No hay paginación. Pide una ventana que puedas manejar, por ejemplo un día, y retrocede ventana por ventana para periodos más largos.
- Una última línea con
_errorsignifica que el flujo se detuvo antes del final, aunque el estado sea200. Vuelve a pedir esa ventana. - Los eventos pueden llegar tarde. Un robot que estuvo desconectado sube lo que registró cuando se reconecta, con el
timestampMsoriginal. Si recopilas eventos de forma periódica, superpón las ventanas y omite los eventos cuyouuidya guardaste.
| Campo | Significado |
|---|---|
uuid | El ID del evento; úsalo para omitir duplicados |
timestampMs | Cuándo ocurrió, según el reloj del robot |
activity, activityUuid | La actividad a la que pertenece el evento |
event | STARTED, PROGRESS, SUSPENDED, RESUMED, COMPLETED, FAILED, CANCELED o REJECTED |
phase, phaseEvent | En PROGRESS, la fase y si empezó (STARTED) o terminó (COMPLETED) |
routeUuid, waypointUuid, waypointIndex, waypointTotal | La ruta y la parada, durante una patrulla |
preemptedBy | En SUSPENDED o REJECTED, la actividad que tuvo prioridad |
failureReason | En FAILED, el motivo |
originator | Quién o qué inició la actividad: type es USER, API_TOKEN o RULE, por ejemplo |
Todas las actividades siguen el mismo ciclo de vida: STARTED, luego eventos PROGRESS a medida que avanza por sus fases (llegar a una parada es un evento PROGRESS cuyo phaseEvent es COMPLETED), posiblemente SUSPENDED y RESUMED cuando algo de mayor prioridad la interrumpe, y exactamente uno de COMPLETED, FAILED o CANCELED al final. Una actividad que el robot rechazó es un único evento REJECTED, con preemptedBy indicando lo que la bloqueó.
Genera alertas sobre lo que importa
| Condición | Qué revisar |
|---|---|
| Desconectado | connectionStatus no es GREEN en dos consultas seguidas |
| Batería baja lejos de la base | batteryPercent por debajo de tu umbral mientras activity no es una de las actividades de regreso a la base |
| Patrulla fallida | Un evento FAILED de un ROUTE_RUN, con su failureReason |
| Envío rechazado | Un evento REJECTED, con preemptedBy |
| Atascado | Los mismos activity, phase y waypointIndex durante mucho más tiempo del que suele tomar la ruta |
Consultar la lista de estado cada uno o dos minutos queda muy por debajo de tu límite de tasa. Los eventos de robots no llegan por el WebSocket de eventos ni por los webhooks de organización; para recibir actualizaciones en tiempo real, conéctate al socket en vivo del robot.