The four phases of WIA-ROB-011 build on each other, so it is natural to implement them in the same order. Linked to the compliance levels from Chapter 3, the sequence is:
| Step | What is implemented | Compliance level reached | Chapter |
|---|---|---|---|
| 0 | Gap analysis: differences between existing data/APIs and the specification | - | Chapter 3 |
| 1 | Phase 1 JSON-LD data formats and validation | Basic | Chapter 4 |
| 2 | Phase 2 REST and WebSocket API, authentication, rate limiting | Standard | Chapter 5 |
| 3 | Phase 3 MQTT, TLS 1.3, mDNS, OTA | Advanced (partial) | Chapter 6 |
| 4 | Phase 4 smart home, fleet and cloud integration | Advanced | Chapter 7 |
| 5 | Conformance testing and certification application | - | This chapter |
How long each step takes depends heavily on the structure of the existing product and the size of the team, so this book does not give durations.
The starting point provided by WIA is the cleaning-robot directory of the public repository (wia-standards-public) in the WIA-Official GitHub organization.
| Path | Contents |
|---|---|
spec/ | PHASE-1 to PHASE-4 specification documents |
api/typescript/ | TypeScript SDK skeleton (WiaCleaningRobot class, Phase 1 type definitions) |
cli/ | POSIX shell client demonstrating the request/response contract |
simulator/ | Browser-based simulator |
git clone https://github.com/WIA-Official/wia-standards-public.git cd wia-standards-public/cleaning-robot/api/typescript
You will also need common development tools such as a JSON Schema validator, an MQTT broker and an HTTP server that supports TLS 1.3. The specification does not require any particular library.
When translating the Phase 1 formats into code, it helps to enforce the specification's enum values and units at the type level. The following TypeScript example expresses part of RobotState.
type RobotMode = 'idle' | 'cleaning' | 'charging' | 'returning' | 'error';
type CleaningMode = 'auto' | 'spot' | 'edge' | 'zigzag' | 'spiral';
interface RobotState {
'@context': 'https://wiastandards.com/rob-011/v1';
'@type': 'RobotState';
timestamp: string; // ISO 8601 with time zone
battery: { percentage: number; voltage: number; current: number;
temperature: number; health: number; cycleCount: number };
pose: { x: number; y: number; theta: number; floor: number; confidence: number };
mode: RobotMode;
cleaningMode: CleaningMode;
suctionPower: number; // 0-100
[extension: `x_${string}`]: unknown; // vendor extension fields
}
function toWiaState(internal: InternalState): RobotState {
return {
'@context': 'https://wiastandards.com/rob-011/v1',
'@type': 'RobotState',
timestamp: new Date().toISOString(),
battery: { ...internal.battery },
pose: { x: internal.xMm / 1000, y: internal.yMm / 1000, // mm → m (SI units)
theta: internal.headingDeg * Math.PI / 180, // degrees → radians
floor: internal.floor, confidence: internal.locConfidence },
mode: internal.mode,
cleaningMode: internal.cleaningMode,
suctionPower: internal.suction
};
}
A translation layer like toWiaState, which converts an existing internal format into the standard format, lets a product comply with Phase 1 without major changes to its firmware internals. This is exactly the role of the "robot abstraction layer" in section 3.4 of Chapter 3.
The following example implements the Phase 2 start-cleaning endpoint with the Express framework for Node.js. The path, error format and rate limit all follow the specification in Chapter 5.
import express from 'express';
import rateLimit from 'express-rate-limit';
const app = express();
const api = express.Router();
api.use(rateLimit({ windowMs: 60_000, limit: 100 })); // 100 per minute per IP, 429 when exceeded
api.use(requireBearerJwt); // Authorization: Bearer {token}
function wiaError(res: express.Response, status: number, code: string, message: string) {
return res.status(status).json({
error: { code, message, details: {}, timestamp: new Date().toISOString() }
});
}
api.post('/robot/clean', express.json(), async (req, res) => {
if (robot.mode === 'cleaning') return wiaError(res, 409, 'ROBOT_BUSY', 'Robot is currently cleaning');
if (robot.battery.percentage < 15) return wiaError(res, 409, 'LOW_BATTERY', 'Battery too low for operation');
const { mode = 'auto', rooms, powerLevel } = req.body;
const session = await robot.startCleaning({ mode, rooms, powerLevel });
res.json({ sessionId: session.id, status: 'started', estimatedDuration: session.estimate });
});
app.use('/api/v1', api);
The HTTP status code (409) and battery threshold (15%) in this example are implementer choices, not values set by the specification. What the specification does define is the error code names, the error response format and HTTP 429 when the rate limit is exceeded.
import { WebSocketServer, WebSocket } from 'ws';
const wss = new WebSocketServer({ server: httpsServer, path: '/ws' });
const subscriptions = new Map<WebSocket, Set<string>>();
wss.on('connection', (ws) => {
subscriptions.set(ws, new Set());
ws.on('message', (raw) => {
const msg = JSON.parse(raw.toString());
if (msg.type === 'subscribe') subscriptions.get(ws)!.add(msg.channel);
if (msg.type === 'unsubscribe') subscriptions.get(ws)!.delete(msg.channel);
});
ws.on('close', () => subscriptions.delete(ws));
});
function publish(channel: 'status' | 'sensors' | 'map' | 'logs', data: object): void {
const frame = JSON.stringify({ type: 'event', channel, timestamp: new Date().toISOString(), data });
for (const [ws, channels] of subscriptions) {
if (channels.has(channel)) ws.send(frame);
}
}
The specification's WebSocket rate limit (10 messages per second) must be applied to messages sent by clients, and the robot should also respect the interval of each subscription so that it does not send events excessively.
wia/rob/{robot_id}/... topics and publishes/subscribes with QoS 0 for status, QoS 1 for commands and QoS 2 for critical alerts._wia-rob._tcp service over mDNS, and OTA updates implement SHA-256 verification and A/B rollback.Check that the translation layer obeys the specification's validation rules (ISO 8601 timestamps, SI units, UUID v4, exact enum values, non-null required fields).
test('pose is converted to metres and radians', () => {
const s = toWiaState(sampleInternal({ xMm: 2500, headingDeg: 90 }));
expect(s.pose.x).toBe(2.5);
expect(s.pose.theta).toBeCloseTo(1.5708, 4);
expect(s.timestamp).toMatch(/Z$|[+-]\d\d:\d\d$/); // includes a time zone
});
The test vectors published alongside the specification are a normative set of request/response pairs. To claim Tier 2 or higher, an implementation must pass every test vector in both the serialisation (request) and deserialisation (response) directions, and publish a signed report identifying which vectors were exercised. Test vectors are versioned independently of the specification documents.
Against a real robot or the simulator, test the full flow of authentication → start cleaning → receiving status over WebSocket → stop → history query, and also check that HTTP 429 is returned when the rate limit is exceeded and that TLS 1.2 connections are refused.
The certification process defined by the Phase 4 specification has five steps (section 3.8 of Chapter 3):
After certification, an annual security audit is required (Phase 3 specification, section 10.2). In addition, audit cadences are set by conformance tier: Tier 1 requires an annual self-review, Tier 2 an assessment every 24 months, and Tier 3 every 12 months. The tier must be disclosed in the OpenAPI info.x-wia-tier extension and on any public certification page, and a tier downgrade must be reported to the WIA registry within 30 days.
Fees and validity: at the time of writing, WIA has not published certification fees, numbers of test cases, certificate validity periods or renewal costs in the specification. These terms must be confirmed directly with WIA when applying for certification.
@context and @type?x_?@version and schemaVersion included?/robot/status, /robot/clean, /robot/stop, /robot/dock, /robot/map, /robot/history and /robot/schedule provided under /api/v1?POST /auth/token and Bearer token authentication implemented?error.code / message / details / timestamp format and the standard error codes?limit (maximum 100), offset, sort and order?wia/rob/{robot_id}/... structure and the QoS rules (0/1/2)?_wia-rob._tcp advertisement with TXT records provided?/fleet/...) and the zone assignment format supported?GET /health, GET /robot/metrics and GET /diagnostics/logs. The specification's annexes recommend (SHOULD) publishing a monthly error-budget summary with p95 latency, error rate and violation hours.Annex D of the specification lists future work items: a schema versioning policy, privacy-preserving aggregation, multilingual error catalogues, long-term retention and sustainability disclosure. These items have no fixed schedule and may be promoted to normative status after open discussion.
WIA-ROB-011 is a common language that lets cleaning robots work together across manufacturer and platform boundaries. By moving step by step from data formats to the API, communication protocols and system integration, even existing products can adopt the standard without disruption. This is the path of 弘益人間 (Hongik Ingan): extending the benefits of cleaning automation to more people.
/api/v1/robot/..., error.code, 100 requests per minute)