# KZV to Patrol Inspection Systems interface
This document describes the communication between the KZV SW (referred to as `KZV` in the rest of the document, and the Patrol Inspection System (referred to as `PIS` in the rest of the document)
## Communication overview
The communication protocol is a simple stateless request-response protocol carried over TCP. The two communicating parties are
- The KZV SW (`KZV`)
- The Patrol Inspection System (`PIS`)
`KZV` will act as a TCP server, spawning the server as soon as it starts up. The `PIS` will connect to it as a client.
`KZV` should support having multiple TCP clients connected at the same time (event from different IPs).
Communication is strictly request-response, that is, the client (`PIS`) sends a request/command message, and the server (`KZV`) responds with a single response message. If the `PIS` doesn't receive a response in 1 second, it may timeout, disconnect and connect again, this is considered to be a failure on the `KZV` side.
Messages exchanged between the two parties are JSON-encoded. Each message must be formatted on single line. The message delimiter is the newline character (LF, single `0x0A` byte). Thus, each party will read bytes until it reaches a single `0x0A` byte in order to read a whole single message. For clarity, messages in this document may be formatted on multiple lines, but they must be transmitted on a single line only during actual communication.
## Messages overview
`PIS` messages are conceptually either
- commands ([StartMeasurement](#startmeasurement), [StopMeasurement](#stopmeasurement))
- requests ([GetState](#getstate))
Commands initiate an action on the `KZV` side, they are responded to with [CommandResponse](#commandresponse). Requests are used to retrieve information from `KZV`, each request message has a single corresponding response message.
Each message has a `messageType` field uniquely identifying the message.
`KZV` may also respond to any command or request with either [BadRequest](#badrequest) - the `PIS` message is unknown or badly formatted, or an [Error](#error) - `KZV` was unable to fulfill the command/request because of runtime error.
**All values are transmitted in basic SI values, that is, meters.**
Timestamps (build date) are encoded using the RFC 3339 format.
## Generic messages
### BadRequest
This message can be returned by the `KZV` as a response to **any** `PIS` message. It denotes that the `KZV` was unable to understand the `PIS` message - unknown message, invalid parameters etc. The `error` field should contain precise description of the problem.
**Example**
```json
{
"messageType": "BadRequest",
"error": "Request has unknown format (details)/Unknown request/..."
}
```
### Error
This message can be returned by the `KZV` as a response to **any** `PIS` message. It denotes that the `KZV` was unable to perform the action requested by `PIS`. This will usually indicate HW problems, but can be used to any other fitting purposes.
**Example**
```json
{
"messageType": "Error",
"error": "Error communicating with the camera"
}
```
### CommandResponse
This message is a response to `PIS` commands (like [StartMeasurement](#startmeasurement), [StopMeasurement](#stopmeasurement)). If the command was successfully executed, `"success": true` is returned and the `error` field may be absent. If the command failed, `"success": false` is returned and the `error` field must be present and contain an explanation of why the command failed. An example of failure may be the `PIS` issuing a [StartMeasurement](#startmeasurement) command while the `KZV` is already measuring.
```json
{
"messageType": "CommandResponse",
"success": false,
"error": "Optional error message (this field may not be present if Ok) in case of a failure"
}
```
## GetVersion
`PIS` sends this request to obtain information about the `KZV SW` version
### Request
```json
{ "messageType": "GetVersion" }
```
### Response
- `product` is up to `KZV`
- `version` should be in the [SemVer](https://semver.org/) format
- `buildDate` should be in the RFC 3339 format
- `protocolVersion`: The protocol version reported by `KZV` must match the protocol version implemented by the `PIS`, otherwise `PIS SW` should stop any further communication.
```json
{
"messageType": "Version",
"product": "KZV rail detector",
"version": "1.2.3",
"buildDate": "2022-03-05T08:40:51.620Z",
"protocolVersion": 1
}
```
## GetState
### Request
`PIS` uses this to obtain info about the `KZV` state. It may repeatedly (even several times a second) query the `KZV` state using this message.
```json
{ "messageType": "GetState" }
```
### Response
`KZV` reports the state of the measurement
```json
{
"messageType": "State",
"state": "NotReady|Ready|Starting|Measuring|Stopping",
}
```
## StartMeasurement
### Request
This command instructs the `KZV` to a start new measurement. `startKm` is given in meters.
```json
{
"messageType": "StartMeasurement",
"startKm": 123.4,
"orientation": "Up|Down",
"kmDirection": "Up|Down"
}
```
### Response
[CommandResponse](#commandresponse).
`Ok` if measurement was started successfully, `Failure` if there was a problem (HW problem, measurement already running, ...)
## StopMeasurement
This command instructs `KZV` to stop current measurement.
### Request
```json
{ "messageType": "StopMeasurement" }
```
### Response
[CommandResponse](#commandresponse).
`Ok` if measurement was stopped successfully, `Failure` if there was a problem (HW problem, measurement not running, ...)