# 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, ...)