Copyright © 2023 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
The Vehicle Information Service Specification (VISS) is a service for accessing vehicle information, signals from sensors on control units within a vehicle's network. It exposes this information using a hierarchical tree like taxonomy defined in COVESA Vehicle Signal Specification (VSS). The service provides this information in JSON format. The service may reside in the vehicle, or on servers in the internet with information already brought off the vehicle.
This specification describes a second version of VISS which has been implemented and deployed on production vehicles. It adds major new capabilities and improvements to the earlier version. The first version of VISS only supported WebSocket as a transport protocol, the second version is generalized to work across different protocols as some are better suited for different use cases. HTTP and MQTT are now supported with additional protocols used within the automotive industry being evaluated for inclusion. Subscription capabilities have been improved and access control has been added.
There are two parts to this specification, [viss2-core] and TRANSPORT. This document, the VISS version 2 TRANSPORT specification, describes the VISSv2 transport protocols, and the mapping of the message layer on these transports. The companion specification [viss2-core] describes the messaging layer.
This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.
This document was published by the Automotive Working Group as a Working Draft using the Recommendation track.
Publication as a Working Draft does not imply endorsement by W3C and its Members.
This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 2 November 2021 W3C Process Document.
This document describes the transport bindings of the Vehicle Information Service Specification, version 2. The split between transport bindings and messaging layer specifications improves readability and simplifies extending the specification to further transports in the future. This specification supports multiple transport bindings, the secure versions of HTTP, WebSocket, and MQTT.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, SHALL, and SHOULD in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
The acronym 'VISSv2' is used to refer to this document, the VISS version 2 specification. The acronym 'VSS' is used to refer to the 'Vehicle Signal Specification' which is defined by the COVESA Alliance. The term 'WebSocket' when used in this document, is as defined in the W3C WebSocket API and the WebSocket Protocol.
This chapter defines features that SHALL be common for all transport protocols.
The server implementation SHALL support the error numbers listed in the table below, with the associated reason and message fields, for all supported transport protocols.
The client SHOULD support any status code defined in [RFC2616].
Error Number (Code) | Error Reason | Error Message |
---|---|---|
304 (Not Modified) | not_modified | No changes have been made by the server. |
400 (Bad Request) | bad_request | The server is unable to fulfil the client request because the request is malformed. |
400 (Bad Request) | filter_invalid | Filter requested on non-primitive type. |
400 (Bad Request) | invalid_duration | Time duration is invalid. |
400 (Bad Request) | invalid_value | The requested set value is invalid. |
401 (Unauthorized) | token_expired | Access token has expired. |
401 (Unauthorized) | token_invalid | Access token is invalid. |
401 (Unauthorized) | token_missing | Access token is missing. |
401 (Unauthorized) | too_many_attempts | The client has failed to authenticate too many times. |
401 (Unauthorized) | read_only | The desired signal cannot be set since it is a read only signal. |
403 (Forbidden) | user_forbidden | The user is not permitted to access the requested resource. Retrying does not help. |
403 (Forbidden) | user_unknown | The user is unknown. Retrying does not help. |
403 (Forbidden) | device_forbidden | The device is not permitted to access the requested resource. Retrying does not help. |
403 (Forbidden) | device_unknown | The device is unknown. Retrying does not help. |
404 (Not Found) | invalid_path | The specified data path does not exist. |
404 (Not Found) | private_path | The specified data path is private and the request is not authorized to access signals on this path. |
404 (Not Found) | unavailable_data | The requested data was not found. |
404 (Not Found) | invalid_subscriptionId | The specified subscription was not found. |
406 (Not Acceptable) | insufficient_priviledges | The priviledges represented by the access token are not sufficient. |
406 (Not Acceptable) | not_acceptable | The server is unable to generate content that is acceptable to the client |
429 (Too Many Requests) | too_many_requests | The client has sent the server too many requests in a given amount of time. |
502 (Bad Gateway) | bad_gateway | The server was acting as a gateway or proxy and received an invalid response from an upstream server. |
503 (Service Unavailable) | service_unavailable | The server is currently unable to handle the request due to a temporary overload or scheduled maintenance (which may be alleviated after some delay). |
504 (Gateway Timeout) | gateway_timeout | The server did not receive a timely response from an upstream server it needed to access in order to complete the request. |
The payload SHALL have JSON format. See 6.2 JSON Schema Definitions for the payload format of the messages for the different transport protocols.
The transport protocols supported are the secure versions of HTTP, WebSocket, and MQTT,
the latter on which a thin application layer protocol is applied.
The server MUST support the HTTP and WebSocket protocols, other protocols are optional.
Further transport protocols may be supported in future versions of this specification.
The message data components described in the [viss2-core] document are in the first hand mapped to required HTTP parameters, and only when there is no appropriate mapping it is mapped to the payload. The subscribe/unsubscribe messages are not supported by this transport protocol.
HTTP long polling?
HTTP long polling?
The client MAY send a HTTPS GET request message to the server to get one or more value(s) of one or more vehicle signal(s). If the server is able to satisfy the request it SHALL return a response containing the requested value(s). If the server is unable to fulfil the request, e.g. because the client is not authorized to retrieve one or more of the signals, then the server response SHALL have the status code set to indicate error.
Example: Request:
GET /Vehicle/Cabin/SeatPosCount HTTP/1.1
Host: 127.0.0.1:1337
Accept: application/json
...
Successful response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
{
“data”:{“path”:”Vehicle.Cabin.SeatPosCount”,
“dp”:{“value”:[”2”, "3", "2"], “ts”:”2020-04-15T13:37:00Z”}
}
}
Error response:
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
...
{
"error": {"number": 404, "reason": "invalid_path", "message": "The specified data path does not exist."},
"ts": "2020-04-15T13:37:00Z"
}
The search read request uses the paths filter operation described in the [viss2-core] document to provide one or more path expressions,
relative to the path in the GET URL.
Example:
Request:
GET /Vehicle/Cabin/Door?filter={"type":"paths", "parameter":"*/*/IsOpen"} HTTP/1.1
Host: 127.0.0.1:1337
Accept: application/json
...
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
{
“data”:[{“path”:”Vehicle.Cabin.Door.Row1.Left.IsOpen”, “dp”:{“value”:”false”, “ts”:”2020-04-15T13:37:00Z”}},
{...},…
{“path”:”Vehicle.Cabin.Door.Row4.Right.IsOpen”, “dp”:{“value”:”true”, “ts”:”2020-04-15T13:37:00Z”}}
]
}
Error response:
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
...
{
"error": {"number": 404, "reason": "invalid_path", "message": "The specified data path does not exist."},
"ts": "2020-04-15T13:37:00Z"
}
The history read request uses the history filter operation described in the [viss2-core] document to read recorded values
for a given period backwards in time.
Example:
Request:
GET /Vehicle.Acceleration.Longitudinal?filter={"type":"history", "parameter":"P2DT12H"} HTTP/1.1
Host: 127.0.0.1:1337
Accept: application/json
...
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
{
“data”:{“path”:”Vehicle.Acceleration.Longitudinal”, “dp”:[{“value”:”0.123”, “ts”:”2020-04-15T13:00:00Z”}, ..., {“value”:”0.125”, “ts”:”2020-04-15T13:37:00Z”}]}
}
The signal discovery request uses the static metadata filtering type as described in the [viss2-core] document to retrieve metadata in the VSS tree.
If the parameter object is set to an empty string, then all metadata in the addressed VSS nodes is returned.
If only specific metadata is desired, the value can be set to this, e. g. "parameter":["type", "datatype"].
The values must be the names as defined in the VSS specification.
Example:
Request:
GET /Vehicle/Drivetrain/FuelSystem?filter={"type":"static-metadata", "parameter":""} HTTP/1.1
Host: 127.0.0.1:1337
Accept: application/json
...
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
{
"metadata": {"FuelSystem":{"type":"branch","description":"Fuel system data.","children":{"HybridType, ... }}},
"ts": "2020-04-15T13:37:00Z"
}
The dynamic metadata, i. e. any other metadata kept by the vehicle system,
is retrieved by the setting the "type" to "dynamic-metadata".
The value MUST be set to one of the domain names as specified in the [viss2-core], Dynamic Metadata Filter Operation chapter.
Example:
Request:
GET /Vehicle?filter={"type":"dynamic-metadata", "parameter":"server_capabilities"} HTTP/1.1
Host: 127.0.0.1:1337
Accept: application/json
...
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
{
"metadata": {"filter":["timebased", "change", "paths", "curvelog", "dynamic-metadata"], "access_ctrl": ["short_term", "signalset_claim"], "transport_protocol": "https", "wss"},
"ts": "2020-04-15T13:37:00Z"
}
The client may request that the server sets the value of one or more signals e.g. to lock one or more doors or open a window by sending an HTTPS POST request to the server. In the case of several signals being set, they MUST all be of the same data type, and be set to the same value. If the server is able to satisfy the request its response SHALL have a 200 OK status code set. If an error occurs e.g. because the client is not authorized to set the requested value, or the value is read-only, the server response SHALL have the status code set to indicate error.
Example:
POST /Vehicle/Drivetrain/Transmission/PerformanceMode HTTP/1.1
Host: 127.0.0.1:1337
Accept: application/json
...
{
"value": "sport"
}
Successful response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
{
"ts": "2020-04-15T13:37:00Z"
}
Error response:
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
...
{
"error": {"number": 404, "reason": "invalid_path", "message": "The specified data path does not exist."},
"ts": "2020-04-15T13:37:00Z"
}
As the WebSocket protocol does not implicitly provide a logical association between the request and response messages
described here a key-value pair with the keyname "requestId" is added to the data components described in the [viss2-core] document.
As the WebSocket protocol neither specifies a set of explicit methods,
another key-value pair with the keyname "action" is also added. See 6.3 Action Definitions for the declaration of these new key-value pairs.
All data components are mapped to the payload.
If the client application is an HTML Application running in a web runtime or is a web page running in a browser, the WebSocket instance may either be instantiated natively or be created using a 'standards compliant' WebSocket JavaScript library.
A WebSocket can also be initiated from a native (e.g. C++) Application or from an Application written using a 'Managed Runtime' language like Java or C#. It is assumed that native and managed clients use a suitable standards compliant WebSocket library to request that a WebSocket connection is opened on the server.
Implementations that support additional devices or multiple VISSv2 services should provide discovery. Alternatively, the location of a particular VISSv2 Server instance on the local vehicle network may be handled by configuration, either as part of a package manifest or by consulting a registry on application install. The 'wwwVISSv2' hostname in this specification is used an example.
A client running on the vehicle is able to connect to the VISSv2 Server instance using the hostname e.g. 'wwwVISSv2' and uses the default port 443. The hostname 'wwwVISSv2' may locally be mapped to the localhost IP address 127.0.0.1 e.g. by adding an entry to the /etc/hosts file.
The sub-protocol name SHALL be 'VISSv2' with the digit 2 being the version number. The sub-protocol version will be associated with exactly one VISS Server Specification version so that the client and server can correctly validate and parse request and response message packets.
var vehicle = new WebSocket("wss://wwwVISSv2:443", "VISSv2");
The client SHALL connect to the server over HTTPS and request that the server opens a WebSocket. All WebSocket communications between the client and server MUST be over ‘wss’. Non encrypted communication is not supported, hence the server MUST refuse ‘ws’ connection requests.
This specification assumes that a single WebSocket is used to enable communication between a client application and the server. The client MAY open more than one websocket. However, the server MAY refuse to open a subsequent WebSocket connection and the client is responsible for handling this gracefully.
If more than one WebSocket connection is established between a client application and the server then each connection MUST be managed independently. For example, subscriptions created using a particular WebSocket connection shall only trigger event messages via that connection and the client MUST use that WebSocket connection to unsubscribe.
If more than one WebSocket connection has been established between one or more clients and a particular server instance, there is a risk that race conditions and concurrency issues could occur. An example of this would be where two or more WebSocket connections are used to update a particular setting at the same time.
Unless explicitly stated otherwise, the client MAY only assume that the server implements a simple concurrency model where lost updates and dirty reads could potentially occur if the server has more than one WebSocket connection open.
The WebSocket may be closed by either the client or the server by invoking the ‘close()’ method on the WebSocket instance.
The following example shows the lifetime of a WebSocket on the client:
// Open the WebSocket
var vehicle = new WebSocket("wss://wwwVISSv2:443", "VISSv2");
…
// Close the WebSocket
vehicle.close();
The VISSv2 Server may terminate the WebSocket connection if it has not received a request for a period determined by the server. It is the client’s responsibility to handle this gracefully and to recover and request new subscriptions, where required.
The client MAY send a getRequest message to the server to get the value of one or more vehicle signals. If the server is able to satisfy the request it SHALL return a getSuccessResponse message. If the server is unable to fulfil the request, e.g. because the client is not authorized to retrieve one or more of the signals, then the server SHALL return a getErrorResponse message. The structure of these message objects is defined below.
Object Name | Attribute | Type | Required |
---|---|---|---|
getRequest | action | Action | Yes |
path | string | Yes | |
filter | string | Optional | |
authorization | string | Optional | |
requestId | string | Yes |
Object Name | Attribute | Type | Required |
---|---|---|---|
getSuccessResponse | action | Action | Yes |
requestId | string | Yes | |
data | object/array | Yes |
In the table above the "data" attribute is either an object containing "value" and "ts" name/value pairs, or an array of such objects.
Object Name | Attribute | Type | Required |
---|---|---|---|
getErrorResponse | action | Action | Yes |
requestId | string | Yes | |
error | Error | Yes | |
ts | string | Yes |
Example:
Request:
{
"action": "get",
"path": "Vehicle.Drivetrain.InternalCombustionEngine.RPM",
"requestId": "8756"
}
Successful response:
{
"action": "get",
"requestId": "8756",
“data”:{“path”:”Vehicle.Drivetrain.InternalCombustionEngine/RPM”,
“dp”:{“value”:”2372”, “ts”:”2020-04-15T13:37:00Z”}
}
}
Error response:
{
"action": "get",
"requestId": "8756",
"error": {"number": 404, "reason": "invalid_path", "message": "The specified data path does not exist."},
"ts": "2020-04-15T13:37:00Z"
}
A client may issue a search read request to access multiple values in one request message. This is realized by adding a "filter" object following the paths filter operation described in the [viss2-core].
Example:
Request:
{
"action": "get",
"path": "Vehicle.Cabin",
"filter": {"type":"paths", "parameter":["Door.*.*.IsOpen", "DriverPosition"]}value
"requestId": "5688"
}
Response:
{
"action": "get",
“data”:[{“path”:”Vehicle.Cabin.Door.Row1.Left.IsOpen”, “dp”:{“value”:”false”, “ts”:”2020-04-15T13:37:00Z”}},
{...},…
{“path”:”Vehicle.Cabin.Door.Row4.Right.IsOpen”, “dp”:{“value”:”true”, “ts”:”2020-04-15T13:37:00Z”}},
{“path”:”Vehicle.Cabin.DriverPosition”, “dp”:{“value”:”1”, “ts”:”2020-04-15T07:00:00Z”}}
]
"requestId": "5688",
}
A client may issue a history read request to access recorded data points. This is realized by adding a "filter" object following the history filter operation described in the [viss2-core].
Example:
Request:
{
"action": "get",
"path": "Vehicle.Acceleration.Longitudinal",
"filter": {"type":"history", "parameter":"P2DT12H"},
"requestId": "5688"
}
Response:
{
"action": "get",
“data”: {“path”: ”Vehicle.Acceleration.Longitudinal”, “dp”: [{“value”: ”0.123”, “ts”: ”2020-04-15T13:00:00Z”}, {“value”: ”0.125”, “ts”: ”2020-04-15T13:37:00Z”}]},
"requestId": "5688"
}
A client may issue a signal discovery read request to access dynamic metadata.
A successful response will contain the requested metadata from all nodes of the subtree defined by
the subtree root node that is addressed by the path.
The static metadata, i. e. the metadata in the VSS tree, is retrieved by the setting the "type" to "static-metadata",
and the parameter object to relevant static metadata.
Example:
Request:
{
"action": "get",
"path": "Vehicle.Drivetrain.FuelSystem",
"filter":{"type":"dynamic-metadata", "parameter":["availability", "validate"]}
"requestId": "5687"
}
Response:
{
"action": "get",
"requestId": "5687",
"metadata": {"FuelSystem":{"availability":"available","validate":"read-write","children":{"HybridType", ... }}}
"ts": "2020-04-15T13:37:00Z"
}
The client may request that the server sets the value of one or more signals e.g. to lock one or more doors or open a window by sending a setRequest message to the server. In the case of several signals being set, they MUST all be of the same data type, and be set to the same value. If the server is able to satisfy the request it SHALL return a setSuccessResponse message. If an error occurs e.g. because the client is not authorized to set the requested value, or the value is read-only, the server SHALL return a setErrorResponse message.
Object Name | Attribute | Type | Required |
---|---|---|---|
setRequest | action | Action | Yes |
path | string | Yes | |
value | string | Yes | |
authorization | string | Optional | |
requestId | string | Yes |
Object Name | Attribute | Type | Required |
---|---|---|---|
setSuccessResponse | action | Action | Yes |
requestId | string | Yes | |
ts | string | Yes |
Object Name | Attribute | Type | Required |
---|---|---|---|
setErrorResponse | action | Action | Yes |
requestId | string | Yes | |
error | Error | Yes | |
ts | string | Yes |
Example:
Request:
{
"action": "set",
"path": "Vehicle.Drivetrain.Transmission.PerformanceMode",
"value": "sport",
"requestId": "5687"
}
Successful response:
{
"action": "set",
"requestId": "5687",
"ts": "2020-04-15T13:37:00Z"
}
Error response:
{
"action": "set",
"requestId": "5687",
"error": {"number": 404, "reason": "invalid_path", "message": "The specified data path does not exist."},
"ts": "2020-04-15T13:37:00Z"
}
The client may send a subscribeRequest message
to request a subscription to one or more signals,
thereby requesting the server to repeatedly return subscription event messages, as specified by
the filter request described in the [viss2-core].
The server MAY reduce the number of
subcriptionEvent
messages sent to the client in order to reduce processing demands.
If the server is able to satisfy the request it SHALL return a
subscribeSuccessResponse message.
If an error occurs e.g. because the client is not authorized to read the requested value, the server SHALL return a
subscribeErrorResponse message.
If an error occurs during the subscription session, the server shall return an
subscriptionErrorEvent message.
The subscription variants are, as described in the [viss2-core] document:
Object Name | Attribute | Type | Required |
---|---|---|---|
subscribeRequest | action | Action | Yes |
path | string | Yes | |
filter | string | Optional | |
authorization | string | Optional | |
requestId | string | Yes |
Object Name | Attribute | Type | Required |
---|---|---|---|
subscribeSuccessResponse | action | Action | Yes |
requestId | string | Yes | |
subscriptionId | string | Yes | |
ts | string | Yes |
Object Name | Attribute | Type | Required |
---|---|---|---|
subscribeErrorResponse | action | Action | Yes |
requestId | string | Yes | |
error | Error | Yes | |
ts | string | Yes |
Object Name | Attribute | Type | Required |
---|---|---|---|
subscriptionEvent | action | Action | Yes |
subscriptionId | string | Yes | |
data | object/array | Yes | |
ts | string | Yes |
Object Name | Attribute | Type | Required |
---|---|---|---|
subscriptionErrorEvent | action | Action | Yes |
subscriptionId | string | Yes | |
error | Error | Yes | |
ts | string | Yes |
Example:
Request:
{
"action": "subscribe",
"path": "Vehicle.Drivetrain.FuelSystem.Level",
"filter": {"type":"timebased", "parameter":{"period":"500"}}
"requestId": "6578"
}
Successful response:
{
"action": "subscribe",
"subscriptionId": "12345",
"requestId": "6578",
"ts": "2020-04-15T13:37:00Z"
}
Error response:
{
"action": "subscribe",
"requestId": "6578",
"error": {"number": 404, "reason": "invalid_path", "message": "The specified data path does not exist."},
"ts": "2020-04-15T13:37:00Z"
}
Event:
{
"action": "subscription",
"subscriptionId": "12345",
“data”: {“path”: ”Vehicle.Drivetrain.FuelSystem.Level”,
“dp”: {“value”: ”50”, “ts”: ”2020-04-15T13:37:00Z”}
},
"ts": "2020-04-15T13:37:00Z"
}
Error event:
{
"action": "subscription",
"subscriptionId": "12345",
"error": {"number": 401, "reason": "token_expired", "message": "Access token has expired."},
"ts": "2020-04-15T13:37:00Z"
}
Curve logging data compression by eliminating data points that are within a set error margin is activated via a subscription request. Event messages will be issued when the buffer becomes full, after insignificant data points have been eliminated, refer the Curve logging Filter Operation chapter in the [viss2-core] documentation.
Example:
Request:
{
"action": "subscribe",
"path": "Vehicle.Drivetrain.FuelSystem.Level",
"filter": {"type":"curvelog", "parameter":{"maxerr":"0.5", "bufsize":"100"}},
"requestId": "6578"
}
Successful response:
{
"action": "subscribe",
"subscriptionId": "12345",
"requestId": "6578",
"ts": "2020-04-15T13:37:00Z"
}
Event:
{
"action": "subscription",
"subscriptionId": "12345",
“data”:{“path”: ”Vehicle.Drivetrain.FuelSystem.Level”,
“dp”:[{“value”: ”50”, “ts”: ”2020-04-15T13:38:00Z”}, ..., {“value”: ”25”, “ts”: ”2020-04-15T13:39:30Z”}]
},
"ts": "2020-04-15T13:37:00Z"
}
Subscription to a range of values, that can have either a single boundary, or multipe boundaries as in the example below. For a more information how to use range of values, refer the Range Filter Operation chapter in the [viss2-core] documentation.
Example:
Request:
{
"action": "subscribe",
"path": "Vehicle.Drivetrain.FuelSystem.Level",
"filter": "filter":{"type":"range","parameter":[{"boundary-op":"lt","boundary":"50","combination-op":"OR"},{"boundary-op":"gt","boundary":"55"}]},
"requestId": "6578"
}
Successful response:
{
"action": "subscribe",
"subscriptionId": "12345",
"requestId": "6578",
"ts": "2020-04-15T13:37:00Z"
}
Event:
{
"action": "subscription",
"subscriptionId": "12345",
“data”:{“path”: ”Vehicle.Drivetrain.FuelSystem.Level”,
“dp”:{“value”: ”51”, “ts”: ”2020-04-15T14:00:00Z”},
"ts": "2020-04-15T14:00:00Z"
}
Subscription to when a signal has changed between two sequential captures. For a more information how to use change of values, refer the Change Filter Operation chapter in the [viss2-core] documentation.
Example:
Request:
{
"action": "subscribe",
"path": "Vehicle.Drivetrain.FuelSystem.Level",
"filter": "filter":{"type":"change","parameter":{"logic-op":"gt","diff":"10"}},
"requestId": "6578"
}
Successful response:
{
"action": "subscribe",
"subscriptionId": "12345",
"requestId": "6578",
"ts": "2020-04-15T13:37:00Z"
}
Event:
{
"action": "subscription",
"subscriptionId": "12345",
“data”:{“path”: ”Vehicle.Drivetrain.FuelSystem.Level”,
“dp”:{“value”: ”101”, “ts”: ”2020-04-15T14:00:00Z”},
"ts": "2020-04-15T14:00:00Z"
}
To unsubscribe from a subscription, the client SHALL send an
unsubscribeRequest message to the server.
If the server is able to satisfy the request it returns an
unsubscribeSuccessResponse message.
If an error occurs, for example because an invalid subscriptionId is passed to the server, an
unsubscribeErrorResponse message is returned.
If the client has created more than one WebSocket instance, it MUST always unsubscribe
using the same WebSocket instance that was originally used to create the subscription.
Object Name | Attribute | Type | Required |
---|---|---|---|
unsubscribeRequest | action | Action | Yes |
subscriptionId | string | Yes | |
requestId | string | Yes |
Object Name | Attribute | Type | Required |
---|---|---|---|
unsubscribeSuccessResponse | action | Action | Yes |
subscriptionId | string | Yes | |
requestId | string | Yes | |
ts | string | Yes |
Object Name | Attribute | Type | Required |
---|---|---|---|
unsubscribeErrorResponse | action | Action | Yes |
subscriptionId | string | Yes | |
requestId | string | Yes | |
error | Error | Yes | |
ts | string | Yes |
Example:
Request:
{
"action": "unsubscribe",
"subscriptionId": "12345",
"requestId": "5786"
}
Successful response:
{
"action": "unsubscribe",
"subscriptionId": "12345",
"requestId": "5786",
"ts": "2020-04-15T13:37:00Z"
}
Error response:
{
"action": "unsubscribe",
"requestId": "6578",
"error": {"number": 404, "reason": "invalid_subscriptionId", "message": "The specified subscription was not found"},
"ts": "2020-04-15T13:37:00Z"
}
For MQTT to support the complete VISSv2 interface, as decribed in the interface chapter of the [viss2-core] specification,
an application level protocol that runs on top of MQTT is added.
It is described in the following, please also see the sequence diagram below.
To emulate the client-server pattern that is described in the [viss2-core] specification, the vehicle server, via its vehicle client,
issues a subscribe request to the broker on a topic named VID/Vehicle,
where VID is an identity that uniquely links to the vehicle in the access control ecosystem.
This vehicle identity is not necessarily the manufacturer's Vehicle Identification Number (VIN).
The client on the "cloud side" of the broker is expected to have access to this vehicle identity.
How it obtains it is out of scope for this specification.
When the cloud client wants to issue a request to the vehicle server it first generates a unique topic name,
which it subscribes to at the broker. It then generates a JSON formatted payload with the general structure
{"topic":"aUniqueTopic", "request":"VISSv2Request"}
where "aUniqueTopic" is the uniques topic name it just subscribed to, and "VISSv2Request" is the request for the vehicle server.
This request MUST follow the payload format that is specified in the Websocket chapter of this specification.
This JSON message is then issued to the broker, associated to the topic VID/Vehicle.
This message will then be forwarded by the broker to the vehicle client, which forwards the string being the value of the
"request" key in the message to the vehicle server. When the vehicle client receives the response to this request,
it publishes it to the broker associated with the topic name that was the string value of the "topic" key name in the
message it previously received from the broker.
The broker will then forward this message to the cloud side client that earlier subscribed to this topic name,
which concludes the client-server based request-response as described in the [viss2-core] specification.
In the case of subscription requests the vehicle client needs to save the subscriptionId found in the subscribe response,
together with the topic name associated to the subscribe request. When the vehicle server later issues event messages,
the vehicle client must parse the subscriptionId from it, and retrieve the topic name associated to it.
The vehicle client shall delete the saved topic name and subscriptionId when it receives
an unsubscribe request in a message from the broker.
In following requests from the cloud side client, the unique topic name may be reused from the previous request-response cycle,
or a new unique topic name may be generated. If a new topic name is generated, an unsubscribe should be issued on the old topic name.
The vehicle client can continue to use the topic name it subscribes to.
The payload format of the response/event messages SHALL follow the payload format that is specified
in the Websocket chapter of this specification.
The access control model is applicable also over this transport alternative.
The Access Token server should then implement its own version of the application level protocol described here,
using the topic name "VID/ATS". The Access Grant Token server may also do the same, with the topic name "VID/AGTS",
or if it is deployed in the cloud it may expose the HTTP interface that is defined in this specification.
The MQTT architecture mandates a "broker" that acts as a middleman in between the client and server endpoints (the subscriber and the publisher in MQTT terminology). This broker has full access to the plaintext communication between the two endpoints as each of the endpoint's TLS channel terminates at the broker. This aspect should be considered when selecting to use the MQTT protocol.
As mentioned in the "Application Level Protocol" chapter, the "request" messages issued to the broker contains two JSON formatted key-value pairs, where the value of the "request" key is a string that contains the request the vehicle server will respond to. The format of this request MUST follow the payload format that is specified in the Websocket chapter of this specification.
Attribute | Type | Description |
---|---|---|
action | Action | The type of action requested by the client or delivered by the server. |
path | String | The path to a node in the VSS tree, as defined by the Vehicle Signal Specification (VSS). |
requestId | String | Unique id value specified by the client. Returned by the server in the response and used by the client to link the request and response messages. The value MAY be an integer or a Universally Unique Identifier (UUID). |
subscriptionId | String | Value returned by the server to uniquely identify each subscription. The value MAY be an integer or a Universally Unique Identifier (UUID). |
authorization | string | A JWT formatted security token. |
data | object/array | Contains a path and one or more data points. |
dp | object/array | The data point contains a value and a timestamp. |
ts | string | The Coordinated Universal Time (UTC) time stamp that represents the capture of the value. |
value | string | The data value associated with the path. |
filter | string | Provides a filtering mechanism to reduce the demands of a subscription on the server. Query format, see [viss2-core], Filter Request chapter. |
metadata | object | Metadata describing the potentially available signal (sub)tree. |
error | Error | Returns an error code, reason and message. |
The payload that is sent over the supported transport protocols SHALL use the JSON definitions in this appendix,
unless otherwise specified in the VISSv2 TRANSPORT specification.
The definitions within this section describe the datatypes referenced within the JSON Schema for the VISSv2 WebSocket interfaces,
and for the VISSv2 HTTP payloads.
{
"definitions": {
"action": {
"enum": [ "get", "set", "subscribe", "subscription", "unsubscribe"],
"description": "The type of action requested by the client and/or delivered by the server",
},
"path": {
"description": "The path to the desired vehicle signal(s). It may require synthesis with additional path data, see [[viss2-core]], Paths Filter Operation chapter.",
"type": "string"
},
"ts": {
"description": "The time of the issuance of the message. For its format, see [[viss2-core]], Timestamps chapter.",
"type": "string"
},
"filter": {
"description": "May be specified in order to throttle the demands of subscriptions on the server. See [[viss2-core]], Filter Request chapter.",
"type": "object/array",
"properties": {
"type": {
"description": "The different filter types.",
"type": "string"
},
"parameter": {
"description": "Parameter(s) for the different filter types",
"type": "object/array",
}
}
},
"data": {
"description": "Data including path(s) and one or more data point(s).",
"type": "object/array",
"properties": {
"path": {
"description": "The path to the vehicle signal.",
"type": "string"
},
"dp": {
"description": "Data point including one or more value and time samp",
"type": "object/array",
"properties": {
"value": {
"description": "The value related to the associated path.",
"type": "string"
},
"ts": {
"description": "Time of the value capture. For its format, see [[viss2-core]], Timestamps chapter.",
"type": "string"
}
}
}
}
},
"subscriptionId":{
"description": "Integer handle value which is used to uniquely identify a subscription session.",
"type": "string"
},
"metadata":{
"description": "Static or dynamic metadata.",
"type": "object"
},
"requestId": {
"description": "Returned by the server in the response and used by the client to link the request and response messages.",
"type": "string"
},
"error": {
"description": "Server response for error cases",
"type": "object",
"properties": {
"number": {
"description": "HTTP Status Code Number",
"type": "integer"
},
"reason": {
"description": "Pre-defined string value that can be used to distinguish between errors that have the same code",
"type": "string"
},
"message": {
"description": "Message text describing the cause in more detail",
"type": "string"
}
}
}
}
}
The Action enumeration is used to define the type of action requested by the client. All client messages MUST contain a JSON structure that has an action name/value pair and the value of the action property MUST be one of the values specified in the enumeration:
The error number SHOULD be a status code defined in [RFC2616], c. f. chapter "Status codes". The error reason SHOULD be the corresponding reason-phrase from [RFC2616]. The error message is meant to give a more precise description of the error.
Object Name | Attribute | Type | Required |
---|---|---|---|
Error | number | integer | Yes |
reason | string | Yes | |
message | string | Yes |
Referenced in:
Referenced in:
Referenced in: