The Phase 1 specification (PHASE-1-DATA-FORMAT, v1.0.0) defines common formats for the data that cleaning robots exchange: robot identity, robot state, maps, cleaning session logs, sensor data, events and commands. The specification states that all data MUST use the JSON-LD format for semantic interoperability.
JSON-LD is a W3C standard that adds keywords such as @context and @type to ordinary JSON so that machines can interpret what each field means. The @context of WIA-ROB-011 documents is https://wiastandards.com/rob-011/v1, and @type identifies what kind of data a document holds. The main types covered in this chapter are:
@type | Content | Spec section |
|---|---|---|
CleaningRobot | Robot identity | 2.1 |
RobotState | Battery, pose, operating mode, sensor state | 2.2 |
OccupancyGrid | Occupancy grid map, rooms, no-go zones, dock location | 2.3 |
CleaningSession | Cleaning session log and statistics | 2.4 |
LidarScan, CameraImage | Sensor data | 3.1, 3.2 |
RobotEvent | Info, warning and error events | 4 |
RobotCommand | Commands sent to the robot | 5 |
CleaningRobot)The robot identity holds the manufacturer, model, serial number, firmware and hardware versions, manufacture date and a list of capabilities. The firmware version is written in semantic versioning (semver) form.
{
"@context": "https://wiastandards.com/rob-011/v1",
"@type": "CleaningRobot",
"robotId": "ROB-2025-XXXX-YYYY",
"manufacturer": "string",
"model": "string",
"serialNumber": "string",
"firmwareVersion": "semver",
"hardwareVersion": "string",
"manufactureDate": "ISO8601 date",
"capabilities": ["array", "of", "capability", "strings"]
}
capabilities is an array of strings. The specification does not fix a list of capability names, but the Phase 3 mDNS advertisement example uses values such as slam, camera and mopping (see Chapter 6).
RobotState)The robot state captures the battery, pose, operating mode, cleaning settings and sensor values at a given moment in a single document.
{
"@type": "RobotState",
"timestamp": "ISO8601 datetime",
"battery": {
"percentage": 0-100,
"voltage": "float (V)",
"current": "float (A)",
"temperature": "float (°C)",
"health": 0-100,
"cycleCount": "integer"
},
"pose": {
"x": "float (meters)",
"y": "float (meters)",
"theta": "float (radians)",
"floor": "integer",
"confidence": 0-1
},
"mode": "idle|cleaning|charging|returning|error",
"cleaningMode": "auto|spot|edge|zigzag|spiral",
"suctionPower": 0-100,
"brushSpeed": 0-100,
"waterFlow": 0-100,
"sensors": {
"lidar": "SensorReading",
"camera": "SensorReading",
"cliff": ["boolean", "array"],
"bumper": "boolean",
"dirtLevel": 0-100
}
}
mode says what the robot is doing now; cleaningMode says how it cleans while cleaning. Both are enumerations, and the specification requires enum values to match the specification exactly.
| Field | Value | Meaning |
|---|---|---|
mode | idle | Idle |
cleaning | Cleaning | |
charging | Charging | |
returning | Returning to the dock | |
error | Error state | |
cleaningMode | auto | Automatic cleaning |
spot | Spot cleaning | |
edge | Edge cleaning | |
zigzag | Zigzag path | |
spiral | Spiral path |
suctionPower, brushSpeed, waterFlow, battery.percentage, battery.health and sensors.dirtLevel range from 0 to 100, and pose.confidence is the localisation confidence from 0 to 1. Position coordinates are in metres and the heading theta in radians.
OccupancyGrid)Maps are represented as occupancy grids: the space is divided into equally sized cells, and each cell records whether it is free or blocked by an obstacle. The grid itself is a uint8 array encoded in base64 and stored in the data field.
{
"@type": "OccupancyGrid",
"resolution": 0.05,
"width": "integer (cells)",
"height": "integer (cells)",
"origin": {
"x": "float (meters)",
"y": "float (meters)",
"theta": "float (radians)"
},
"data": "base64 encoded uint8 array",
"rooms": [
{
"id": "UUID",
"name": "string",
"polygon": [[x, y], ...],
"surfaceType": "hardwood|tile|carpet|vinyl|marble",
"lastCleaned": "ISO8601 datetime",
"cleanCount": "integer"
}
],
"noGoZones": [
{
"id": "UUID",
"polygon": [[x, y], ...],
"type": "no_go|restricted"
}
],
"dockLocation": { "x": "float", "y": "float", "theta": "float" }
}
resolution is the size of one cell in metres; the specification's value of 0.05 means each cell is 5 cm. The physical size of the map is therefore width × resolution by height × resolution metres: a grid 200 cells wide and 160 cells high covers a 10 m × 8 m space. Rooms (rooms) and no-go zones (noGoZones) are polygons given as lists of vertices, and these coordinates must lie within the map. Each room records its floor surface (surfaceType) so the robot can adjust suction or water flow to suit it.
Authoring note: polygon vertices and the dock location are coordinates in metres, not cell indices. If cell indices are written instead, room boundaries will be badly misplaced when another system imports the map. Validation rule 2 of the specification (use SI units) requires this.
CleaningSession)A cleaning session log holds the start and end time, duration, area cleaned, distance travelled, energy consumed, rooms cleaned, interruptions and statistics for one cleaning run.
{
"@type": "CleaningSession",
"sessionId": "UUID",
"startTime": "ISO8601 datetime",
"endTime": "ISO8601 datetime",
"duration": "integer (seconds)",
"areaCleaned": "float (m²)",
"distanceTraveled": "float (m)",
"batteryConsumed": "float (Wh)",
"cleaningMode": "string",
"rooms": ["room_id", "array"],
"interruptions": [
{
"timestamp": "ISO8601 datetime",
"reason": "stuck|battery_low|manual_stop|error",
"duration": "integer (seconds)"
}
],
"statistics": {
"avgSpeed": "float (m/s)",
"avgSuction": "float (%)",
"dirtCollected": "float (g)",
"coverage": "float (%)"
}
}
There are four interruption reasons (reason): stuck (stuck), low battery (battery_low), stopped by the user (manual_stop) and error (error). The session log is also the basic unit returned by the Phase 2 cleaning history query (GET /robot/history).
LidarScan)A LiDAR scan consists of the angular range and increment, the measurable distance range and an array of range readings. Intensities (intensities) are optional.
{
"@type": "LidarScan",
"timestamp": "ISO8601 datetime",
"angleMin": "float (radians)",
"angleMax": "float (radians)",
"angleIncrement": "float (radians)",
"rangeMin": "float (meters)",
"rangeMax": "float (meters)",
"ranges": ["float", "array"],
"intensities": ["float", "array (optional)"]
}
CameraImage)A camera image carries its size, encoding (rgb8, bgr8, jpeg, png) and base64 image data, together with the objects the robot has recognised (detectedObjects), each with a class, confidence and bounding box. Camera images are privacy-sensitive, so the Phase 3 security requirements must be applied to their transmission and storage.
RobotEvent)
{
"@type": "RobotEvent",
"eventId": "UUID",
"timestamp": "ISO8601 datetime",
"type": "info|warning|error|critical",
"category": "navigation|cleaning|battery|sensor|communication",
"message": "string",
"details": { "arbitrary": "key-value pairs" }
}
Events are classified by four severities (type) and five categories (category). details holds any event-specific information as key-value pairs.
RobotCommand)
{
"@type": "RobotCommand",
"commandId": "UUID",
"timestamp": "ISO8601 datetime",
"action": "start|stop|pause|resume|dock|set_mode",
"parameters": {
"mode": "string (optional)",
"rooms": ["array (optional)"],
"powerLevel": "integer (optional)"
}
}
There are six command actions (action): start, stop, pause, resume, return to dock and set mode. The same commands are sent over the Phase 2 REST API through endpoints such as POST /robot/clean, POST /robot/stop and POST /robot/dock, and over MQTT on the wia/rob/{robot_id}/command topic (see Chapters 5 and 6).
Section 6 of the specification lays down six rules that all Phase 1 data must follow.
2025-12-26T14:30:00Z).Conformance Tier 1, described in Chapter 3, requires a JSON Schema validation report as a mandatory artefact. In practice, implementation teams therefore benefit from expressing these rules in JSON Schema and using it for automated validation.
x_)Implementations MAY add custom fields prefixed with x_. The prefix prevents vendor-specific fields from clashing with fields added to the standard in future. Robot types other than floor cleaners use the same mechanism to express their own information (see Chapter 3).
{
"@type": "RobotState",
"battery": 75,
"x_customField": "vendor-specific data"
}
This example is reproduced verbatim from section 7 of the specification and only shows the shape of an extension field. In a real document, battery must follow the object structure in section 4.3.
Every data format carries version information for backward compatibility.
{
"@context": "https://wiastandards.com/rob-011/v1",
"@version": "1.0.0",
"schemaVersion": "1.0.0"
}
The specification's migration guidelines are: maintain backward compatibility between minor versions, provide migration tools for major versions, document all breaking changes, and support multiple versions during transition periods.
The following is the robot state example from section 9 of the specification. A robot that is cleaning has 75% battery and is at position (2.5 m, 3.1 m) on floor 0, heading at about 90 degrees (1.57 rad).
{
"@context": "https://wiastandards.com/rob-011/v1",
"@type": "RobotState",
"timestamp": "2025-12-26T14:30:00Z",
"battery": {
"percentage": 75,
"voltage": 14.8,
"current": 2.5,
"temperature": 35.2,
"health": 95,
"cycleCount": 245,
"charging": false,
"timeToEmpty": 3600
},
"pose": { "x": 2.5, "y": 3.1, "theta": 1.57, "floor": 0, "confidence": 0.95 },
"mode": "cleaning",
"cleaningMode": "auto",
"suctionPower": 80,
"brushSpeed": 100,
"sensors": {
"lidar": { "timestamp": "2025-12-26T14:30:00Z", "ranges": [1.2, 1.5, 2.0] },
"cliff": [false, false, false, false],
"bumper": false,
"dirtLevel": 45
}
}
The example's charging and timeToEmpty (remaining run time in seconds) are not part of the basic structure in section 4.3; they show that the specification's example allows extra information in the battery object.
@context https://wiastandards.com/rob-011/v1CleaningRobot, RobotState, OccupancyGrid, CleaningSession, LidarScan, CameraImage, RobotEvent and RobotCommandidle, cleaning, charging, returning and errorx_ extension fields; compatibility is managed with @version and schemaVersionmode and cleaningMode each represent?x_ extension fields solve?