-
Notifications
You must be signed in to change notification settings - Fork 16
Description
Summary
Modes represent entity states - things like "diagnostic session level" or "security access level" - that may be prerequisites for accessing certain resources or executing certain operations. For example, a component might require diagnostic_session=EXTENDED before allowing certain calibration operations.
Clients can list available modes, read their current values, and change them.
Proposed solution
1. GET /api/v1/{entity-path}/modes
List all modes defined for an entity.
Applies to entity types: Components, Apps
Path parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
{entity-path} |
URL segment | Yes | e.g., components/engine_ecu |
Response 200 OK:
{
"items": [
{
"id": "diagnostic_session",
"name": "Diagnostic Session",
"href": "/api/v1/components/engine_ecu/modes/diagnostic_session"
},
{
"id": "access_level",
"name": "Security Access Level",
"href": "/api/v1/components/engine_ecu/modes/access_level"
}
]
}Each item is a ModeReference:
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
Yes | Mode identifier |
name |
string |
Yes | Human-readable mode name |
translation_id |
string |
No | Translation key for localization |
href |
string |
Yes | URI to read/set this mode |
2. GET /api/v1/{entity-path}/modes/{mode-id}
Read the current value of a mode, including its JSON Schema (enum of allowed values).
Path parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
{entity-path} |
URL segment | Yes | e.g., components/engine_ecu |
{mode-id} |
string |
Yes | Mode identifier |
Response 200 OK:
{
"name": "Diagnostic Session",
"value": "DEFAULT",
"schema": {
"type": "string",
"enum": ["DEFAULT", "EXTENDED", "PROGRAMMING"]
}
}| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Mode name |
value |
string |
Yes | Current mode value |
schema |
object |
Yes | JSON Schema describing allowed values. Usually { "type": "string", "enum": [...] } |
Error responses:
| Status | Error Code | When |
|---|---|---|
404 |
resource-not-found |
Mode doesn't exist on this entity |
3. PUT /api/v1/{entity-path}/modes/{mode-id}
Change the current mode value. Optionally set an expiration timer after which the mode reverts to its default value.
Path parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
{entity-path} |
URL segment | Yes | e.g., components/engine_ecu |
{mode-id} |
string |
Yes | Mode identifier |
Request body:
{
"value": "EXTENDED",
"mode_expiration": 1200
}| Field | Type | Required | Description |
|---|---|---|---|
value |
string |
Yes | Target mode value (must be one of the values in the mode's schema enum) |
mode_expiration |
integer |
No | Seconds until auto-revert to default. If omitted, mode stays until explicitly changed or server restarts. |
Response 200 OK: Returns the updated mode (same format as GET).
Error responses:
| Status | Error Code | When |
|---|---|---|
400 |
invalid-parameter |
Value not in allowed enum, invalid expiration |
404 |
resource-not-found |
Mode doesn't exist |
500 |
internal-error |
Entity returned an error when changing mode |
Hint-based Mode Control (request header)
Instead of making separate SET mode calls, any API request can include modes via the x-sovd-mode header:
POST /api/v1/apps/temp_sensor/operations/calibrate/executions HTTP/1.1
x-sovd-mode: diagnostic_session;EXTENDED,access_level;UNLOCKEDHeader format: x-sovd-mode: {mode-id};{value}[,{mode-id};{value}]*
The server sets the requested modes before executing the main request. This avoids separate mode-setting round-trips.
Behavior:
- If mode setting fails, the main request is not executed and a
400error is returned - Modes set via hint header follow the same validation as
PUT /modes/{id} - If
mode_expirationis needed, use the explicitPUTendpoint instead
Additional context
ROS 2 mapping
Modes can be implemented via:
- ROS 2 node parameters - mode values stored as parameters on the entity's node (e.g.,
diagnostic_sessionparameter with string enum) - Gateway-managed state - the gateway tracks mode values internally, applying them as prerequisites before forwarding requests
For initial implementation, gateway-managed state is simpler:
- Store mode definitions per entity (from manifest)
- Track current values in memory
- Reset to defaults on server restart
Mode definitions
Modes should be declarable in the manifest YAML:
components:
engine_ecu:
modes:
- id: diagnostic_session
name: "Diagnostic Session"
default: "DEFAULT"
values: ["DEFAULT", "EXTENDED", "PROGRAMMING"]
- id: access_level
name: "Security Access Level"
default: "LOCKED"
values: ["LOCKED", "UNLOCKED"]Mode expiration
- Use a ROS 2 timer per active expiration
- On expiry: revert mode to its default value
- Cancel timer if mode is changed again before expiry
Mode prerequisites
The capability description (OpenAPI extensions) defines which modes must be set before an operation can execute:
x-sovd-required-modes: { "diagnostic_session": "EXTENDED" }on an operation means thediagnostic_sessionmode must beEXTENDEDbefore that operation can run- The operation handler should check mode prerequisites and return
400if not met
Route registration
srv->Get((api_path("/components") + R"(/([^/]+)/modes$)"), handler);
srv->Get((api_path("/components") + R"(/([^/]+)/modes/([^/]+)$)"), handler);
srv->Put((api_path("/components") + R"(/([^/]+)/modes/([^/]+)$)"), handler);
// Same for /apps/Tests
- Unit test: list modes returns manifest-defined modes
- Unit test: get mode returns current value and schema
- Unit test: set mode → value changes → 200
- Unit test: set invalid enum value → 400
- Unit test: mode expiration auto-reverts
- Unit test: nonexistent mode → 404
- Unit test: x-sovd-mode header parsed and applied