Skip to content

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:

Python
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: DURATION holds the robot at the stop for dwellTimeSecs seconds; NONE moves on as soon as it arrives. A stop that sets neither dwellStrategy nor dwellTimeSecs dwells for 15 seconds. Use these two strategies; the others behave like NONE.
  • 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 deployConditions or deviceUuid is 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:

Python
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 withRuns for
On the route's stoprules on each stop in createRobotRoute or updateRobotRouteEvery robot that runs the route
On a patrolwaypointActions in createPatrol or updatePatrol, one entry per stop IDOnly 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:

Python
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:

RunsdeployConditionsscheduleUuid
Once a day at a set time[{"type": "SCHEDULED_EVENT", "minOfDay": 1320}] (22:00)Optional: runs it only within the schedule, for example on weekdays
Every N minutes or hours during set times[{"type": "RECURRING_EVENT", "repeatInterval": 30, "timeUnit": "MINUTES"}]Required: the hours it repeats in. Without one the patrol never runs
  • minOfDay is minutes after midnight in the time zone of the robot's location.
  • scheduleUuid is 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:

FieldEffect
nameRenames the patrol
enabledfalse 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 oneA non-empty list replaces the schedule; an empty list removes it
waypointActionsReplaces all of the patrol's arrival actions
Python
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.