Recon
Recon Routes and Patrols
Author the rounds a Recon robot makes: routes as ordered stops with dwell times and arrival actions, and patrols that put a route on a robot and run it on a schedule. Covers creating, changing and deleting both.
On this page
A route is the path: an ordered list of stops on one map. A patrol is a route given to one robot, with an optional schedule. You can run one route on several robots, each with its own patrol. The examples use the robot_api helper from the overview.
You need an API key with admin access to the map's location for routes, and admin access to the robot for patrols.
Create a route
createRobotRoute takes a name, the map, and the stops in the order the robot visits them. Each stop either references a waypoint or carries a pose of its own:
route = robot_api("createRobotRoute", {
"name": "Night perimeter",
"mapUuid": MAP_UUID,
"waypoints": [
{"name": "Dock door", "waypointRefUuid": DOCK_DOOR_WAYPOINT_UUID, "dwellStrategy": "DURATION", "dwellTimeSecs": 30},
{"name": "North fence", "pose": {"position": [40.0, 8.5, 0.0], "orientation": [0.0, 0.0, 0.0, 1.0]}, "dwellStrategy": "NONE"},
{"name": "Server room", "waypointRefUuid": SERVER_ROOM_WAYPOINT_UUID, "dwellStrategy": "DURATION", "dwellTimeSecs": 60},
],
})["routeView"]["route"]- Order is the order of the list.
- Dwell:
DURATIONholds the robot at the stop fordwellTimeSecsseconds;NONEmoves on as soon as it arrives. A stop that sets neitherdwellStrategynordwellTimeSecsdwells for 15 seconds. Use these two strategies; the others behave likeNONE. - One run per dispatch. The robot visits each stop once and the run ends. If it can't reach a stop, the whole run ends as
FAILED. Repeat a route with a patrol schedule. - Schedules belong to patrols: a route request with
deployConditionsordeviceUuidis refused.
The response's route.waypointMap holds the stops, keyed by stop ID, each with its ordinal (0 for the first stop), its pose or waypointRefUuid, and dwellTimeMs. Stop IDs are what arrival actions and the robot's progress (waypointUuid in its state and events) refer to; they aren't the IDs of the waypoints a stop references.
Read routes back with getRobotRoute (uuid) or every route on a map with findRobotRoutesByMap (mapUuid).
Change a route
updateRobotRoute changes one route, addressed by its uuid. A list of waypoints replaces all of the route's stops, so send every stop you want to keep, each with:
- its
uuid, to keep that stop's ID. A stop without one is created as a new stop with a new ID, and a patrol's arrival actions for the old ID stop applying; - its
ordinal, because on update the order comes from the ordinals, not from the list; - its
rules, because a stop sent without them loses its arrival actions.
The safe way to edit is to read the route, change it, and send all of it back:
route = robot_api("getRobotRoute", {"uuid": ROUTE_UUID})["routeView"]
stops = sorted(route["route"]["waypointMap"].values(), key=lambda s: s["ordinal"])
rules = route.get("waypointRules") or {}
def as_request(stop, ordinal):
request = {
"uuid": stop["uuid"],
"name": stop["name"],
"ordinal": ordinal,
"dwellStrategy": stop.get("dwellStrategy", "DURATION"),
"dwellTimeSecs": stop.get("dwellTimeMs", 15000) // 1000,
"rules": [{"ruleName": r["name"], "action": r["action"], "ruleFilters": r.get("ruleFilters")} for r in rules.get(stop["uuid"], [])],
}
if stop.get("waypointRefUuid"):
request["waypointRefUuid"] = stop["waypointRefUuid"]
else:
request["pose"] = stop["pose"]
return request
stops[0]["dwellTimeMs"] = 45000 # dwell 45 seconds at the first stop
robot_api("updateRobotRoute", {
"uuid": ROUTE_UUID,
"waypoints": [as_request(stop, i) for i, stop in enumerate(stops)],
})To rename a route, send only uuid and name; leaving waypoints out keeps the stops as they are. A route can't move to another map.
deleteRobotRoute (uuid) is refused while patrols use the route: delete those patrols first (findPatrolsByRoute lists them).
Arrival actions
A stop can run actions when the robot gets there. They're rules, in the same form as the actions of other Rhombus rules: each has a ruleName and an action, and optionally ruleFilters with scheduleUuids to run only during a schedule. For example, "action": {"alertAction": true} raises an alert in Rhombus at that stop.
They can live in two places:
| Set with | Runs for | |
|---|---|---|
| On the route's stop | rules on each stop in createRobotRoute or updateRobotRoute | Every robot that runs the route |
| On a patrol | waypointActions in createPatrol or updatePatrol, one entry per stop ID | Only that patrol's robot |
Prefer patrol arrival actions when robots share a route.
- The route's and the patrol's actions come back in
waypointRules, keyed by stop ID. - Arrival actions also run when the robot gives up on a stop (that leg failed or was canceled). When it matters whether the robot really got there, check its events.
- Change these actions only through the robot operations, not with the rules operations under
/api/rules/.
Create a patrol
createPatrol gives a route to a robot. The route must be on the robot's assigned map:
patrol = robot_api("createPatrol", {
"deviceUuid": ROBOT_UUID,
"routeUuid": ROUTE_UUID,
"name": "Night perimeter (east robot)",
"deployConditions": [{"type": "SCHEDULED_EVENT", "minOfDay": 1320}],
"waypointActions": [
{"routeWaypointUuid": SERVER_ROOM_STOP_ID, "rules": [{"ruleName": "Server room check", "action": {"alertAction": True}}]},
],
})["patrolView"]["patrol"]
print(patrol["uuid"], patrol["enabled"])Leave out deployConditions for a patrol that runs only when you dispatch it. A new patrol is enabled.
Schedules
A patrol's schedule is its first deploy condition. Send one:
| Runs | deployConditions | scheduleUuid |
|---|---|---|
| Once a day at a set time | [{"type": (22:00) | Optional: runs it only within the schedule, for example on weekdays |
| Every N minutes or hours during set times | [{"type": | Required: the hours it repeats in. Without one the patrol never runs |
minOfDayis minutes after midnight in the time zone of the robot's location.scheduleUuidis one of your organization's schedules (getSchedules).- The robot keeps the schedule itself. When a run is due while the robot is busy (already patrolling, recharging, or being driven), that run is skipped, not queued.
Change, pause or delete a patrol
updatePatrol addresses the patrol by patrolUuid and changes only the fields you send:
| Field | Effect |
|---|---|
name | Renames the patrol |
enabled | false pauses the schedule and refuses dispatches of this patrol; true resumes it. Always send a boolean: null counts as false |
deployConditions, with scheduleUuid when the schedule uses one | A non-empty list replaces the schedule; an empty list removes it |
waypointActions | Replaces all of the patrol's arrival actions |
robot_api("updatePatrol", {"patrolUuid": PATROL_UUID, "enabled": False})findPatrolsByRobot (deviceUuid) lists a robot's patrols on its assigned map, getPatrol (patrolUuid) returns one, and deletePatrol (patrolUuid) deletes it with its schedule and arrival actions. A patrol's robot and route can't change: create a new patrol instead.