Chapter 4: Phase 1 - Data Format Specification

弘益人間 (Hongik Ingan) · Benefit All Humanity

4.1 Purpose of Phase 1

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:

@typeContentSpec section
CleaningRobotRobot identity2.1
RobotStateBattery, pose, operating mode, sensor state2.2
OccupancyGridOccupancy grid map, rooms, no-go zones, dock location2.3
CleaningSessionCleaning session log and statistics2.4
LidarScan, CameraImageSensor data3.1, 3.2
RobotEventInfo, warning and error events4
RobotCommandCommands sent to the robot5

4.2 Robot Identity (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).

4.3 Robot State (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
  }
}

Operating Mode and Cleaning Mode

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.

FieldValueMeaning
modeidleIdle
cleaningCleaning
chargingCharging
returningReturning to the dock
errorError state
cleaningModeautoAutomatic cleaning
spotSpot cleaning
edgeEdge cleaning
zigzagZigzag path
spiralSpiral 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.

4.4 Maps (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.

4.5 Cleaning Session Log (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).

4.6 Sensor Data

LiDAR Scan (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)"]
}

Camera Image (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.

4.7 Events and Commands

Events (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.

Commands (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).

4.8 Validation Rules

Section 6 of the specification lays down six rules that all Phase 1 data must follow.

  1. All timestamps MUST use ISO 8601 format with a time zone (for example 2025-12-26T14:30:00Z).
  2. All measurements MUST use SI units (metres, seconds, radians and so on).
  3. All arrays MUST have elements of a consistent type.
  4. All UUIDs MUST be version 4.
  5. Required fields MUST NOT be null.
  6. Enum values MUST match the specification exactly.

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.

4.9 Extension Fields and Versioning

Extension Fields (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.

Data Versioning

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.

4.10 Complete Example

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.

Key Takeaways

Review Questions

  1. Why does WIA-ROB-011 require JSON-LD rather than plain JSON?
  2. What do mode and cleaningMode each represent?
  3. How large, in metres, is the space covered by an occupancy grid with resolution 0.05, width 300 cells and height 200 cells?
  4. List the four interruption reasons of a cleaning session.
  5. Explain the six validation rules of the specification.
  6. What problem do x_ extension fields solve?
  7. What is required when the minor version changes, and when the major version changes?

📐 Simulator Panel 3