+ integers, which is why we are not using a numerical data type. Each byte in
+ the string *must* be represented with 2 characters, e.g. `0x1` is `0x01` - the
+ complete string must have an even number of characters.
+
+### Diagnostic Messages
+
+#### Requests
+
+A request to add or update a diagnostic request is sent to a vehicle interface
+with this command format:
+
+ { "command": "diagnostic_request",
+ "request": {
+ "bus": 1,
+ "id": 1234,
+ "mode": 1,
+ "pid": 5,
+ "payload": "0x1234",
+ "multiple_responses": false,
+ "frequency": 1,
+ "name": "my_pid"
+ }
+ }
+ }
+
+**bus** - the numerical identifier of the CAN bus where this request should be
+ sent, most likely 1 or 2 (for a vehicle interface with 2 CAN controllers).
+
+**id** - the CAN arbitration ID for the request.
+
+**mode** - the OBD-II mode of the request - 1 through 15 (1 through 9 are the
+ standardized modes).
+
+**pid** - (optional) the PID for the request, if applicable.
+
+**payload** - (optional) up to 7 bytes of data for the request's payload
+ represented as a hexidecimal number in a string. Many JSON parser cannot
+ handle 64-bit integers, which is why we are not using a numerical data type.
+ Each byte in the string *must* be represented with 2 characters, e.g. `0x1`
+ is `0x01` - the complete string must have an even number of characters.
+
+**name** - (optional, defaults to nothing) A human readable, string name for
+ this request. If provided, the response will have a `name` field (much like a
+ normal translated message) with this value in place of `bus`, `id`, `mode` and
+ `pid`.
+
+**multiple_responses** - (optional, false by default) if true, request will stay
+ active for a full 100ms, even after receiving a diagnostic response message.
+ This is useful for requests to the functional broadcast arbitration ID
+ (`0x7df`) when you need to get responses from multiple modules. It's possible
+ to set this to `true` for non-broadcast requests, but in practice you won't
+ see any additional responses after the first and it will just take up memory
+ in the VI for longer.
+
+**frequency** - (optional, defaults to 0) The frequency in Hz to send this
+ request. To send a single non-recurring request, set this to 0 or leave it
+ out.
+
+**decoded_type** - (optional, defaults to "obd2" if the request is a recognized
+OBD-II mode 1 request, otherwise "none") If specified, the valid values are
+`"none"` and `"obd2"`. If `obd2`, the payload will be decoded according to the
+OBD-II specification and returned in the `value` field. Set this to `none` to
+manually override the OBD-II decoding feature for a known PID.
+
+A diagnostic request's `bus`, `id`, `mode` and `pid` (or lack of a `pid`)
+combine to create a unique key to identify a recurring request. This means that
+you cannot simultaneosly have recurring requests at 2Hz and 5Hz for the same PID
+from the same ID.
+
+If you send a new `diagnostic_request` command with a `bus + id + mode + pid`
+key matching an existing recurring request, it will update it with whatever
+other parameters you've provided (e.g. it will change the frequency if you
+specify one).
+
+To cancel a recurring request, send a `diagnostic_request` command with the
+matching request information (i.e. the `bus`, `id`, `mode` and `pid`) but a
+frequency of 0.
+
+Non-recurring requests may have the same `bus+id+mode(+pid)` key as a recurring
+request, and they will co-exist without issue. As soon as a non-recurring
+request is either completed or times out, it is removed from the active list.
+
+If you're just requesting a PID, you can use this minimal field set for the
+`request` object:
+
+ {"bus": 1, "id": 1234, "mode": 1, "pid": 5}
+
+#### Responses
+
+The response to a successful request:
+
+ {"bus": 1,
+ "id": 1234,
+ "mode": 1,
+ "pid": 5,
+ "success": true,
+ "payload": "0x1234",
+ "value": 4660}
+
+and to an unsuccessful request, with the `negative_response_code` and no `pid`
+echo:
+
+ {"bus": 1,
+ "id": 1234,
+ "mode": 1,
+ "success": false,
+ "negative_response_code": 17}