---
# System prepended metadata

title: NVT Joints inspection

---

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

