Status

Date

Doc Version

Applicable

Confidentiality

RELEASED

v4.12

Wirepas Network Tool Backend v4.x

PUBLIC


Introduction

This document describes the Wirepas Network Tool (WNT) server backend API and is intended for Wirepas licensee to implement own services on top of the WNT server. Prerequisites include overall knowledge of Wirepas Mesh and WNT client. APIs are implemented on top of web sockets and HTTP connections using JSON and Protocol Buffers (version 2) data encoding.

This document is compliant with WNT backend version 4.x. See Revision history for more details about changes compared to previous versions.

Below figure depicts an overview of WNT backend interfaces towards related components. Wirepas Mesh interaction is done via Gateway’s towards the network data. Wirepas Positioning Engine (WPE) services are used for node location calculations in Smart tracking use cases. Actual WNT backend APIs are used by WNT client for visualization and by customer systems for application specific data processing. The WNT backend APIs are introduced in more detail in following sections.

Backend interface components

Below figure (Figure 2) illustrates the high level architecture of WNT backend. The WNT backend consists of services that implement WNT backend API.

The WNT backend API is accessed via multiple API endpoints that are described in Table 1 and discussed in more detail in following sections.

Table: Components

Component

Protocol

Port

Data encoding

Authentication

Web socket

8813

JSON

Metadata

Web socket

8812

JSON

Real time situation

Web socket

8811

Protocol Buffers *

Time series

HTTP

8886

JSON **

MQTT JSON API

MQTT over TCP

MQTT over Websocket***

8883

9002

JSON

*Authentication is done by using JSON

**Queries are sent via HTTP GET

*** In this configuration a Websocket compatible MQTT client is required.

The MQTT connection between the gateway and WNT backend is described in document: WP-RM-128 - API between a Gateway and Wirepas Backends.

MQTT JSON API is provided via WNT MQTT broker. It allows applications to receive solely per node metadata and location change events with complete node objects encoded in JSON.

Authentication service

The service handles user management and access control towards metadata and real time situation services. Credentials can only be changed via authentication service. Other clients are notified about the users related changes (except password changes) via real time situation connection.

In WNT < 4.4 time series database Influx shares the same credentials as the authentication service, and any credentials changes made through authentication service are propagated automatically to it, but in WNT >= 4.4 separate token is used to query the data. The token is returned in the login message response.

Metadata service

Metadata service provides access to:

  • node metadata
  • buildings
  • floor plans
  • areas
  • network information
  • downlink communication with the nodes

The clients are notified about the metadata changes via real time situation connection.

Real time situation service

The real time information of all the nodes and changes to metadata are available from the real time situation service. After the connection is established, and authentication has succeeded, the service will send all real time information via the connection. After the initiation, when the service receives new information from the nodes it forwards only the data that has changed to the client connections. In other words, during an active client connection, client will receive only partial data updates that contains the delta against last known situation.

The actual service logic is implemented by clustered realtime situation service instances, while a frontend router composes the data provided by the service instances towards clients via a single API endpoint.

Time series service

Time series service contains diagnostics - and auxiliary data. It is implemented as direct access to the Influx database. For more information please see Section “Time series service data”.

Protocol version

Authentication, metadata and real time situation (authentication) messages contain protocol version field. This field needs to match the correct protocol version supported by the WNT backend. At the moment the backend cannot handle messages of older protocol version.

Table: Protocol versions

Protocol version

Backend version

2

1.6, 1.7

3

2.0

4

3.0

5

4.x

Authentication service messages

Authentication service works in request / response principle. The service will return session id that is used to connect to other services except Influx. The session id cannot be used after the authentication service connection is closed, but the connections that are already opened will stay open.

Access to methods depends on user's role.

Table: Roles

Role

Number

Administrator

1

Operator

2

Simple rule between the roles is that operator can only query data, but administrator can also make changes.
 All requests have common version field which denotes the protocol version and distinct type field per message type.

Table: Message types

Message

Type

Role

Login

1

All

Get users

11

Administrator

Create user

12

Administrator

Update user

13

Administrator

Delete user

14

Administrator

Due to possibility that the information about the change comes earlier from the real time situation connection than the response from the authentication service, some methods contain an originator_token field which can be used to check if the change was originated from the current client. The token can be e.g. UUID (version 1 / 4) as string.
Responses contains result field which contains information if any error occurred.

Table: Result codes

Message

Code

Ok

1

Generic error

2

Invalid credentials while logging in

3

Wrong protocol version

4

User does not have rights to perform the action

5

Invalid user id

6

User which was tried to create already exists

7

Received message was invalid

8

Invalid session id

9

User information fields have minimum and maximum lengths in characters.

Table: Minimum and maximum lengths

Field

Minimum

Maximum

username

1

63

password

6

255

full_name

1

255

Login

Login message is used to login to the services and it returns a session id that shall be used to authenticate to the metadata and real time situation services. WNT 4.4 updated the time series database Influx to version 2 which requires separate token to fetch data. This token is returned in the data section of the login response.

Table: Login message < WNT 4.4

Request

Response

{                                  
“data”: {
“username”: “<user name>“,
“password”: “<password>“
},
“type”: 1,
”version”: 5
 }

{
“data”: {
“role”: 1,
“session_id”: “<session id>“
},
“result”: 1,
“type”: 1,
”version”: 5
 }

Table: Login message >= WNT 4.4

Request

Response

{                                  
“data”: {
“username”: “<user name>“,
“password”: “<password>“
},
“type”: 1,
”version”: 5
 }

{
“data”: {
“role”: 1,
“session_id”: “<session id>“,
“influx_token”: “<influx_token>“
},
“result”: 1,
“type”: 1,
”version”: 5
 }

Get users

Message returns list of users and users' information.

Table: Get users message

Request

Example response

{
“data”: {},
“session_id”: “<session id>“,
“type”: 11,
”version”: 5
 }

{
“data”: {
“users”: [
{
“full_name”: “John Doe”,
“role”: 2,
“username”: “johndoe”
},
{
“full_name”: “Jane Doe”,
“role”: 1,
“username”: “janedoe”
}
]
},
“result”: 1,
“type”: 11,
”version”: 5
 }

Create user

New user can be created with create user message. Only a single user can be created with the message although users field is an array.
Updates are sent to clients via real time situation connection using metadata_update_message -> added_or_changed_users message.

Table: Create user message

Request

Response

{
“data”: {
“originator_token”: “<token>“,
“users”: [
{
“full_name”: “<first last>“,
“password”: “<password>“,
“role”: <role>,
“username”: “<user name>“
}
]
},
“session_id”: “<session id>“,
“type”: 12,
”version”: 5
 }

{                
“data”: {},
“result”: 1,
“type”: 12,
”version”: 5
 }

Update user

User can be updated with update user message. Only a single user can be updated with the message although users field is an array. In user data only username field is required and it needs to identify an existing user to be updated.
Updates are sent to clients via real time situation connection using metadata_update_message -> added_or_changed_users message.

Table: Update user message

Request

Response

{
“data”: {
“originator_token”: “<token>“,
“users”: [
{
“full_name”: “<new first last>“,
“password”: “<new password>“,
“role”: <new role>,
“username”: “<user name>“
}
]
},
“session_id”: “<session id>“,
“type”: 13,
”version”: 5
 }

{
“data”: {},
“result”: 1,
“type”: 13,
”version”: 5
 }

Delete user

User can be deleted with delete user message. Only a single user can be deleted with the message although users field is an array.
Updates are sent to clients via real time situation connection using metadata_update_message -> deleted_users message.

Table: Delete user message

Request

Response

{
“data”: {
“originator_token”: “<token>“,
“users”: [
{
“username”: “<user name>“
}
]
},
“session_id”: “<session id>“,
“type”: 14,
”version”: 5
 }

{
“data”: {},
“result”: 1,
“type”: 14,
”version”: 5
 }

Metadata service messages

Metadata service works in request / response principle. All the messages require session id, which can be gotten from the authentication service.
All requests have a common version field which denotes the protocol version and distinct type field per message type.

Table: Message types

Message

Type

Role

Get buildings

1001

All

Create building

1002

Administrator

Update building

1003

Administrator

Delete building

1004

Administrator

Get building's floor plans

1011

All

Create floor plan

1012

Administrator

Update floor plan

1013

Administrator

Delete floor plan

1014

Administrator

Get floor plan image data

1021

All

Set floor plan image data

1022

Administrator

Get areas

1031

All

Create area

1032

Administrator

Update area

1033

Administrator

Delete area

1034

Administrator

Get networks

1041

All

Create network metadata

1042

Administrator

Update network metadata

1043

Administrator

Delete network metadata

1044

Administrator

Add node to floor plan

1051

Administrator

Remove node from floor plan

1052

Administrator

Set node metadata

1061

Administrator

Change node id and / or network id *

1062

Administrator

Delete node

1063

Administrator

Set network persistent data

1071

Administrator

Send Remote API request *

1072

Administrator

Get scratchpad status

1074

Administrator

Get components information

1081

All

Due to possibility that the information about the change comes earlier from the real time situation connection than the response from the metadata service, some methods contain an originator_token field. This field can be used to check if the change was originated from the current client. The token can be e.g. UUID (version 1 / 4) as string.
Responses contains result field which contains information if any error occurred.

Table: Result codes

Message

Code

Ok

1

Generic error

2

Wrong protocol version

4

User does not have rights to perform the action

5

Invalid id (building, floor plan, area etc.)

6

Received message was invalid

8

Invalid session id

9

Get buildings

The message returns name and id of all the buildings.

Table: Get buildings message

Request

Example response

{

    “data”: {},
“session_id”: “<session id>“,
“type”: 1001,
”version”: 5
 }

{
“data”: {
“buildings”: [
{
“id”: “c6ddb790-24e4-6449-075a-a6638f147812”,
“name”: “Main building”
},
{
“id”: “e936d185-42db-ff18-57b5-4deb02d05c58”,
“name”: “Other building”
}
]
},
“result”: 1,
“type”: 1001,
”version”: 5
 }

Create building

New building can be created with create building message which returns building id that can be used later to reference the building. Only a single building can be created with the message although buildings field is an array.
Updates are sent to clients via real time situation connection using metadata_update_message -> added_or_changed_buildings message.

Table: Create building message

Request

Response

{
“data”: {
“buildings”: [
{
“name”: “<building name>“
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1002,
”version”: 5
 }

{
“data”: {
“buildings”: [
{
“id”: “<building id>“
}
]
},
“result”: 1,
“type”: 1002,
”version”: 5
 }


 Update building

Building name can be updated with update building message. Only a single building can be updated with the message although buildings field is an array.
Updates are sent to clients via real time situation connection using metadata_update_message -> added_or_changed_buildings message.

Table: Update building message

Request

Response

{
“data”: {
“buildings”: [
{
“id”: “<building id>“,
“name”: “<updated building name>“
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1003,
”version”: 5
 }

{
“data”: {},
“result”: 1,
“type”: 1003,
”version”: 5
 }

Delete building

Building can be deleted with delete building message. Only a single building can be deleted with the message although buildings field is an array.
Updates are sent to clients via real time situation connection using metadata_update_message -> deleted_buildings message.

Table: Delete building message

Request

Response

{
“data”: {
“buildings”: [
{
“id”: “<building id>“
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1004,
”version”: 5
 }

{
“result”: 1,
“type”: 1004,
”version”: 5
 }

Get building's floor plans

The message returns information about the floor plans in a building. Only a single building's floor plans can be fetched with the message although buildings field is an array.
The rotation_matrix, offset_ecef_to_local, offset_local_to_ecef and pixels_per_meter fields are used for mapping between WGS84 and pixel coordinates. For more information please see Section “Coordinate conversions”.

Table: Get building's floor plans message

Request

Example response (only one floor plan)

{
“data”: {
“buildings”: [
{
“id”: “<building id>“
}
]
},
“session_id”: “<session id>“,
“type”: 1011,
”version”: 5
 }

{
“data”: {
“buildings”: [
{
“id”: “3b326217-676d-f547-019b-6d8e0e1fc5dc”,
“floor_plans”: [
{
“id”: “1e19239c-bcd2-829a-44a1-900e083f0bfe”,
“name”: “New floor plan”,
“level”: 0,
“image_width”: null,
“image_height”: null,
“image_id”: null,
“image_thumbnail_id”: null,
“altitude_leftbottom”: null,
“altitude_lefttop”: null,
“altitude_rightbottom”: null,
“altitude_righttop”: null,
“distance_in_m”: 1,
“latitude_leftbottom”: null,
“latitude_lefttop”: null,
“latitude_rightbottom”: null,
“latitude_righttop”: null,
“longitude_leftbottom”: null,
“longitude_lefttop”: null,
“longitude_rightbottom”: null,
“longitude_righttop”: null,
“x_distance_point1”: 0.3,
“x_distance_point2”: 0.7,
“x_normcoord_leftbottom”: 0,
“x_normcoord_lefttop”: 0,
“x_normcoord_rightbottom”: 1,
“x_normcoord_righttop”: 1,
“y_distance_point1”: 0.5,
“y_distance_point2”: 0.5,
“y_normcoord_leftbottom”: 1,
“y_normcoord_lefttop”: 0,
“y_normcoord_rightbottom”: 1,
“y_normcoord_righttop”: 0,
“rotation_matrix”: {
“m11”: null,
“m12”: null,
“m13”: null,
“m21”: null,
“m22”: null,
“m23”: null,
“m31”: null,
“m32”: null,
“m33”: null
},
“offset_ecef_to_local”: {
“x”: null,
“y”: null,
“z”: null
},
“offset_local_to_ecef”: {
“x”: null,
“y”: null,
“z”: null
},
“pixels_per_meter”: null
}
]
}
]
},
“result”: 1,
“type”: 1011,
”version”: 5
 }

Create floor plan

New floor plan can be created with create floor plan message which returns floor plan id that can be used later to reference the floor plan. It is recommended to use the values defined below when creating a new floor plan. Only a single floor plan can be created to a single building with the message although buildings and floor_plans fields are arrays.
The rotation_matrix, offset_ecef_to_local, offset_local_to_ecef and pixels_per_meter fields are used for mapping between WGS84 and pixel coordinates. For more information please see Section “Coordinate conversions”.
Updates are sent to clients via real time situation connection using metadata_update_message -> added_or_changed_floor_plans message.

Table: Create floor plan message

Request

Response

{
“data”: {
“buildings”: [
{
“id”: “<building id>“,
“floor_plans”: [
{
“name”: “<floor plan name>“,
“level”: <level>,
“image_width”: null,
“image_height”: null,
“altitude_leftbottom”: null,
“altitude_lefttop”: null,
“altitude_rightbottom”: null,
“altitude_righttop”: null,
“distance_in_m”: 1,
“latitude_leftbottom”: null,
“latitude_lefttop”: null,
“latitude_rightbottom”: null,
“latitude_righttop”: null,
“longitude_leftbottom”: null,
“longitude_lefttop”: null,
“longitude_rightbottom”: null,
“longitude_righttop”: null,
“x_distance_point1”: 0.3,
“x_distance_point2”: 0.7,
“x_normcoord_leftbottom”: 0,
“x_normcoord_lefttop”: 0,
“x_normcoord_rightbottom”: 1,
“x_normcoord_righttop”: 1,
“y_distance_point1”: 0.5,
“y_distance_point2”: 0.5,
“y_normcoord_leftbottom”: 1,
“y_normcoord_lefttop”: 0,
“y_normcoord_rightbottom”: 1,
“y_normcoord_righttop”: 0
}
]
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1012,
”version”: 5
 }

{
“data”: {
“buildings”: [
{
“id”: “<building id>“,
“floor_plans”: [
{
“id”: “<floor plan id>“,
“name”: “<floor plan name>“,
“level”: <level>,
“image_width”: null,
“image_height”: null,
“image_id”: null,
“image_thumbnail_id”: null,
“altitude_leftbottom”: null,
“altitude_lefttop”: null,
“altitude_rightbottom”: null,
“altitude_righttop”: null,
“distance_in_m”: 1,
“latitude_leftbottom”: null,
“latitude_lefttop”: null,
“latitude_rightbottom”: null,
“latitude_righttop”: null,
“longitude_leftbottom”: null,
“longitude_lefttop”: null,
“longitude_rightbottom”: null,
“longitude_righttop”: null,
“x_distance_point1”: 0.3,
“x_distance_point2”: 0.7,
“x_normcoord_leftbottom”: 0,
“x_normcoord_lefttop”: 0,
“x_normcoord_rightbottom”: 1,
“x_normcoord_righttop”: 1,
“y_distance_point1”: 0.5,
“y_distance_point2”: 0.5,
“y_normcoord_leftbottom”: 1,
“y_normcoord_lefttop”: 0,
“y_normcoord_rightbottom”: 1,
“y_normcoord_righttop”: 0,
“rotation_matrix”: {
“m11”: null,
“m12”: null,
“m13”: null,
“m21”: null,
“m22”: null,
“m23”: null,
“m31”: null,
“m32”: null,
“m33”: null
},
“offset_ecef_to_local”: {
“x”: null,
“y”: null,
“z”: null
},
“offset_local_to_ecef”: {
“x”: null,
“y”: null,
“z”: null
},
“update_time”: <epoch timestamp>
}
]
}
]
},
“result”: 1,
“type”: 1013,
”version”: 5
 }

Update floor plan

Floor plan information can be updated with update floor plan message. Only a single floor plan in single building can be updated with the message although buildings and floor_plans fields are arrays. Request below shows how a floor plan image and thumbnail are bound to the floor plan.
The rotation_matrix, offset_ecef_to_local, offset_local_to_ecef and pixels_per_meter fields are used for mapping between WGS84 and pixel coordinates. For more information please see Section “Coordinate conversions”.
Updates are sent to clients via real time situation connection using metadata_update_message -> added_or_changed_floor_plans message.

Table: Update floor plan message example

Example request

Response

{
"data": {
"buildings": [
{
"floor_plans": [
{
"altitude_leftbottom": 0,
"altitude_lefttop": 0,
"altitude_rightbottom": 0,
"altitude_righttop": 0,
"distance_in_m": 25.1,
"id": "5d6fd05a-e598-3bb2-428b-a71f82796ec5",
"image_height": 4432,
"image_id": "8e67ece4-7604-4b85-6741-a9db46718fb8",
"image_thumbnail_id": "91aad35b-5269-3cc7-65e6-d1fc864af6ab",
"image_width": 8989,
"latitude_leftbottom": 61.454612,
"latitude_lefttop": 61.454823,
"latitude_rightbottom": 61.454562,
"latitude_righttop": 61.454773,
"level": 0,
"longitude_leftbottom": 23.884503,
"longitude_lefttop": 23.884526,
"longitude_rightbottom": 23.88607,
"longitude_righttop": 23.886096,
"x_distance_point1": 0.450065006833406,
"x_distance_point2": 0.449649314572983,
"x_normcoord_leftbottom": 0.0747559429065484,
"x_normcoord_lefttop": 0.0748329808357999,
"x_normcoord_rightbottom": 0.904069882566427,
"x_normcoord_righttop": 0.903860782456575,
"y_distance_point1": 0.203192686229106,
"y_distance_point2": 0.780260953915855,
"y_normcoord_leftbottom": 0.780014805319742,
"y_normcoord_lefttop": 0.203506328386351,
"y_normcoord_rightbottom": 0.78039444527477,
"y_normcoord_righttop": 0.203571943827163
}
]
}
],
"originator_token": "sometoken"
},
"session_id": "fe778fc2-22a4-47ea-9c09-eaf4d1f9ab78-34fa569d-94d0-4ec4-b1c6-d1ce67e9a9d8",
"type": 1013,
"version": 5
 }

{
"data": {
"buildings": [
{
"floor_plans": [
{
"altitude_leftbottom": 0,
"altitude_lefttop": 0,
"altitude_rightbottom": 0,
"altitude_righttop": 0,
"distance_in_m": 25.1,
"id": "5d6fd05a-e598-3bb2-428b-a71f82796ec5",
"image_height": 4432,
"image_id": "8e67ece4-7604-4b85-6741-a9db46718fb8",
"image_thumbnail_id": "91aad35b-5269-3cc7-65e6-d1fc864af6ab",
"image_width": 8989,
"latitude_leftbottom": 61.454612,
"latitude_lefttop": 61.454823,
"latitude_rightbottom": 61.454562,
"latitude_righttop": 61.454773,
"level": 0,
"longitude_leftbottom": 23.884503,
"longitude_lefttop": 23.884526,
"longitude_rightbottom": 23.88607,
"longitude_righttop": 23.886096,
"name": "New floor plan",
"offset_ecef_to_local": {
"x": -1131.9634231370248,
"y": -17909.761013701293,
"z": 6361641.711841517
},
"offset_local_to_ecef": {
"x": 2794017.4452389725,
"y": 1237234.93622025,
"z": 5579742.24664715
},
"pixels_per_meter": 101.89519091846172,
"rotation_matrix": {
"m11": -0.3515134508753164,
"m12": 0.9356611258540328,
"m13": -0.03124982270814286,
"m21": 0.8279681283416568,
"m22": 0.2951293517595499,
"m23": -0.47683062420570416,
"m31": -0.4369291387675352,
"m32": -0.19348623541624782,
"m33": -0.8784395280270055
},
"update_time": 1666868318,
"x_distance_point1": 0.450065006833406,
"x_distance_point2": 0.449649314572983,
"x_normcoord_leftbottom": 0.0747559429065484,
"x_normcoord_lefttop": 0.0748329808357999,
"x_normcoord_rightbottom": 0.904069882566427,
"x_normcoord_righttop": 0.903860782456575,
"y_distance_point1": 0.203192686229106,
"y_distance_point2": 0.780260953915855,
"y_normcoord_leftbottom": 0.780014805319742,
"y_normcoord_lefttop": 0.203506328386351,
"y_normcoord_rightbottom": 0.78039444527477,
"y_normcoord_righttop": 0.203571943827163
}
]
}
]
},
"result": 1,
"type": 1013,
"version": 5
 }

Delete floor plan

Floor plan can be deleted with delete floor plan message. Only a single floor plan in single building can be deleted with the message although buildings and floor_plans fields are arrays.
Updates are sent to clients via real time situation connection metadata_update_message -> deleted_floor_plans message.

Table: Delete floor plan message

Request

Response

{
“data”: {
“buildings”: [
{
“floor_plans”: [
{
“id”: “<floor plan id>“
}
]
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1014,
”version”: 5
 }

{
“result”: 1,
“type”: 1014,
”version”: 5
 }

Get floor plan image data

The method can be used to fetch floor plan image or thumbnail data. The image binary data is encoded using Base64 (RFC 3548) encoding.

Table: Get floor plan image data message

Request

Response

{
“data”: {
“image_id”: “<image or thumbnail id>“
},
“session_id”: “<session id>“,
“type”: 1021,
”version”: 5
 }

{
“data”: {
“image_base64”: “<data>“
},
“result”: 1,
“type”: 1021,
”version”: 5
 }

Set floor plan image data

The method can be used to upload floor plan image or thumbnail data. The image binary data needs to be encoded using Base64 (RFC 3548) encoding. The method returns image id which can be used to reference the image later. Supported image formats are BMP, TIFF, JPEG, GIF, PNG and JPEG XR.

Table: Set floor plan image data message

Request

Response

{
“data”: {
“image_base64”: “<data>“,
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1022,
”version”: 5
 }

{
“data”: {
“image_id”: “<image id>“
},
“result”: 1,
“type”: 1022,
”version”: 5
 }

Get areas

The message returns areas for given floor plan id. Only a single floor plan's areas in a single building can be queried with the message although buildings and floor_plans fields are arrays. Area color values (alpha, red, green and blue) are integers between 0…255. llas is an array of area corner points' coordinates in WGS84 format and can contain 3…n items. altitude is in meters.

Table: Get areas message

Request

Response

{
“data”: {
“buildings”: [
{
“floor_plans”: [
{
“id”: “<floor plan id>“
}
]
}
]
},
“session_id”: “<session id>“,
“type”: 1031,
”version”: 5
 }

{
“data”: {
“buildings”: [
{
“floor_plans”: [
{
“id”: “<floor plan id>“,
“areas”: [
{
“id”: “<area id>“,
“name”: “<area name>“,
“a”: <area color alpha>,
“r”: <area color red>,
“g”: <area color green>,
“b”: <area color blue>,
“llas”: [
{
“altitude”: <point altitude>,
“latitude”: <point latitude>,
“longitude”: <point longitude>
},
{
“altitude”: <point altitude>,
“latitude”: <point latitude>,
“longitude”: <point longitude>
},
{
“altitude”: <point altitude>,
“latitude”: <point latitude>,
“longitude”: <point longitude>
}
]
}
]
}
]
}
]
},
“result”: 1,
“type”: 1031,
”version”: 5
 }

Create area

New area can be created with create area message which returns area id that can be used later to reference the area. Only a single area in a single floor plan and single building can be created with the message although buildings, floor_plans and areas fields are arrays. Area color values (alpha, red, green and blue) are integers between 0…255. llas is an array of area corner points' coordinates in WGS84 format and can contain 3…n items. altitude is in meters.
Updates are sent to clients via real time situation connection using metadata_update_message -> added_or_changed_areas message.

Table: Create area message

Request

Response

{
“data”: {
“buildings”: [
{
“floor_plans”: [
{
“id”: “<floor plan id>“,
“areas”: [
{
“name”: “<area name>“,
“a”: <area color alpha>,
“r”: <area color red>,
“g”: <area color green>,
“b”: <area color blue>,
“llas”: [
{
“altitude”: <point altitude>,
“latitude”: <point latitude>,
“longitude”: <point longitude>
},
{
“altitude”: <point altitude>,
“latitude”: <point latitude>,
“longitude”: <point longitude>
},
{
“altitude”: <point altitude>,
“latitude”: <point latitude>,
“longitude”: <point longitude>
}
]
}
]
}
]
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1032,
”version”: 5
 }

{
“data”: {
“buildings”: [
{
“floor_plans”: [
{
“id”: “<floor plan id>“,
“areas”: [
{
“id”: “<area id>“
}
]
}
]
}
]
},
“result”: 1,
“type”: 1032,
”version”: 5
 }

Update area

Existing area can be updated with update area message. Area color values (alpha, red, green and blue) are integers between 0…255. llas is an array of area corner points' coordinates in WGS84 format and can contain 3…n items. altitude is in meters.
Updates are sent to clients via real time situation connection using metadata_update_message -> added_or_changed_areas message.

Table: Update area message

Request

Response

{
“data”: {
“buildings”: [
{
“floor_plans”: [
{
“id”: “<floor plan id>“,
“areas”: [
{
“id”: “<area id>“,
“name”: “<area name>“,
“a”: <area color alpha>,
“r”: <area color red>,
“g”: <area color green>,
“b”: <area color blue>,
“llas”: [
{
“altitude”: <point altitude>,
“latitude”: <point latitude>,
“longitude”: <point longitude>
},
{
“altitude”: <point altitude>,
“latitude”: <point latitude>,
“longitude”: <point longitude>
},
{
“altitude”: <point altitude>,
“latitude”: <point latitude>,
“longitude”: <point longitude>
}
]
}
]
}
]
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1033,
”version”: 5
 }

{
“result”: 1,
“type”: 1033,
”version”: 5
 }

Delete area

Area can be deleted with delete building message. Only a single area can be deleted with the message although buildings, floor_plans and areas fields are arrays.
Updates are sent to clients via real time situation connection using metadata_update_message -> deleted_areas message.

Table: Delete building message

Request

Response

{
“data”: {
“buildings”: [
{
“floor_plans”: [
{
“id”: “<floor plan id>“,
“areas”: [
{
“id”: “<area id>“
}
]
}
]
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1034,
”version”: 5
 }

{
“result”: 1,
“type”: 1034,
”version”: 5
 }

Get networks

The message returns network id and name mappings.

Note: only networks which have a name explicitly set via the WNT API will be reported.

In the following cases a network will not be present in a “Get networks“ response:

  • network was automatically created as some packets from nodes which belong to it were received by the backend
  • nodes were created via the “Set Node metadata“ request and bound to a network which does not exist yet

To get the list of networks not reported by this API please use the Realtime Situation interface, store all network_id fields received and compare with “Get networks” response.

Table: Get networks message

Request

Example response

{                                    
“data”: {},
“session_id”: “<token>“,
“type”: 1041,
”version”: 5
 }                                     

{
“data”: {
“networks”: [
{
“id”: <network id>,
“name”: “<network name>“
},
{
“id”: <network id>,
“name”: “<network name>“
}
]
},
“result”: 1,
“type”: 1041,
”version”: 5
 }

Create network metadata

The message is used to create a new network id to name mapping. Only a single network mapping can be created with the message although networks field is an array.
Updates are sent to clients via real time situation connection using metadata_update_message -> added_or_changed_networks message.

Table: Create network message

Request

Response

{
“data”: {
“networks”: [
{
“id”: <network id>,
“name”: “<network name>“
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1042,
”version”: 5
 }

{
“result”: 1,
“type”: 1042,
”version”: 5
 }

Update network metadata

Network name can be updated with update network message. Only a single network can be updated with the message although networks field is an array.
Updates are sent to clients via real time situation connection using metadata_update_message -> added_or_changed_networks message.

Table: Update network message

Request

Response

{                                      
“data”: {
“networks”: [
{
“id”: <network id>,
“name”: “<new network name>“
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1043,
”version”: 5
 }  

{              
“result”: 1,
“type”: 1043,
”version”: 5
 }

Delete network metadata

Network id to name mapping can be deleted with delete network message. Only a single network can be deleted with the message although networks field is an array. It is possible to delete also nodes within the deleted network by setting is_delete_nodes flag to true.
Updates are sent to clients via real time situation connection using metadata_update_message -> deleted_networks message.

Table: Delete network message

Request

Response

{
“data”: {
“networks”: [
{
“id”: <network id>
“is_delete_nodes“: false
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1044,
”version”: 5
 }

{              
“result”: 1,
“type”: 1044,
”version”: 5
 }

Add node to floor plan

Node can be bound to a floor plan with add node to floor plan message. Single message can be used add one or multiple nodes to floor plans based on the information in the nodes array. The floor plan for each node is specified per node, thus each node can be added to differing floor plans. If the node was previously added to a different floor plan, the association will be changed (removed from the old and added to new). Note however, that in order to see node in the floor plan the node needs to be approved with valid location information with set node metadata message.
Updates are sent to clients via real time situation connection using node_metadata message.

Table: Add node to floor plan message

Request

Response

{
“data”: {
“nodes”: [
{
“floor_plan_id”: “<floor plan id>“,
“id”: <node id>,
“network_id”: <network id>
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1051,
”version”: 5
 }

{
“result”: 1,
“type”: 1051,
”version”: 5
 }

Remove node from floor plan

Node can be removed from floor plan with remove node from floor plan message. Similarly to the addition, a single message can be used to remove one or multiple nodes based on the information in nodes array.
Updates are sent to clients via real time situation connection using node_metadata message.

Table: Remove node from floor plan message

Request

Response

{
“data”: {
“nodes”: [
{
“id”: <node id>,
“network_id”: <network id>
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1052,
”version”: 5
 }

{
“result”: 1,
“type”: 1052,
”version”: 5
 }

Set node metadata

The method is used set node related metadata. is_virtual denotes the planning node feature in WNT client [2] and is_anchor can be used to define the positioning role of the node. rssi_offset is an integer [-127; +127] meant for node with positioning role set as “anchor”. This tells how much the RSSI value is differing from the other anchors in the network. This can have a positive impact on the tag’s location accuracy. A single message can be used to modify one or multiple nodes. For each node, id and network_id are mandatory fields, otherwise the message can contain only changed fields.
Updates are sent to clients via real time situation connection using node_metadata message.

Table: Set node metadata message

Example request

Response

{
“data”: {
“nodes”: [
{
“id”: <node id>,
“network_id”: <network id>,
“name”: “<node name>”,
“description”: “<node description>”,
“is_approved”: true,
“is_virtual”: false,
           “is_anchor”: true,
“latitude”: 61.4547593371768,
“longitude”: 23.8856021513505,
           “altitude”: 0.0,

“rssi_offset“: -10
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1061,
”version”: 5
 }

{
“result”: 1,
“type”: 1061,
”version”: 5
 }

Delete node

The method is used to delete node real time situation and metadata. With a single message, either one or multiple nodes can be deleted based on the identification information in nodes array. Note that if node sends any data afterwards it will be shown again.
Updates are sent to clients via real time situation connection using node_metadata message.

Table: Delete node message

Request

Response

{
“data”: {
“nodes”: [
{
“id”: <node id>,
“network_id”: <network id>
}
],
“originator_token”: “<token>“
},
“session_id”: “<session id>“,
“type”: 1063,
”version”: 5
 }

{
“result”: 1,
“type”: 1063,
”version”: 5
 }

Set network persistent data

The method can be used to set network persistent data (NPD) including the diagnostics interval (previously application configuration data) [1]. Only a single network's NPD can be set with the message although networks field is an array. Within the network, NPD can be set either globally to whole network or at a per sink level.
is_override_on property is used to define will WNT server override the network data if it is changed from outside of WNT.
Updates are sent to clients per sink via real time situation connection using app_config message.

Table: Set network data message for the whole network

Example request

Response

{  
“data”: {
“networks”: [
{
“id”: <network_id>,
“application_data”: “112233445566778899AABBCCDDEEFF”,
“diagnostics_interval”: 60,
“is_override_on”: false
}
]
},
“originator_token”: “<token>“,
“session_id”: “<session id>“,
“type”: 1071,
”version”: 5
 }

{
“result”: 1,
“type”: 1071,
”version”: 5
 }


Table: Set network data message for the specific sinks

Example request

Response

{  
“data”: {
“networks”: [
{
“id”: <network_id>,
“application_data”: “112233445566778899AABBCCDDEEFF”,
“diagnostics_interval”: 60,
“is_override_on”: false,
“sink_node_ids”: [1, 10]
}
]
},
“originator_token”: “<token>“,
“session_id”: “<session id>“,
“type”: 1071,
“version”: 5
 }

{
“result”: 1,
“type”: 1071,
“version”: 5
 }

Get scratchpad status

The method can be used to query scratchpad status from the nodes in the network. Only a single network's data can be get with the message although networks field is an array. With is_sink_only flag the query can be targeted only to sink nodes in the network. Further, the query can be a single shot or continuous. Continuous query sending interval can be defined by setting resend_interval_s property with options described in below table.

Table: Scratchpad query types

Query

resend_interval_s

is_close

Single shot

0

false

Start continuous

Interval

false

Stop continuous

0

true

Data is sent to clients per node via real time situation connection using scratchpad_status message.

Table: Get scratchpad status message

Example request

Response

{  
“data”: {
“networks”: [
{
“id”: <network id>,
“resend_interval_s”: 180,
“is_close”: false,
“is_sink_only”: false
}
]
},
“session_id”: “<session id>“,
“type”: 1074,
”version”: 5
 }

{
“result”: 1,
“type”: 1074,
”version”: 5
 }

Get components information

The method can be used to query backend components' and gateways' information.
Responses are sent to clients via the real time situation connection using backend_component_info and gateway_info messages.
NOTE: Please note that the backend component information is returned only from the metadata service, and originator_token is not yet returned via the real time situation connection.

Table: Get components information message

Example request

Response

{                                    
“data”: {
“originator_token”: “<token>“
},
“session_id”: “<token>“,
“type”: 1081,
”version”: 5
 }

{
“result”: 1,
“type”: 1081,
”version”: 5
 }

Real time situation service authentication

The service provides all nodes related data and changes to the metadata. Authentication is done in the start by sending the session id received from the authentication service.

Table: Authentication

Request

Response

{
“session_id”: “<session id>“,
”version”: 5
 }

{              
“result”: 1,
”version”: 5
 }

After a successful authentication the service starts to send Protocol Buffers encoded data and moves into write only mode. First message(s) will contain the node count per real time situation cluster cell. This information can be used to determine how much data needs to be received before the initial data is received. After this only the changed information is sent to client.

Table: Node count message

Path

Data

Message -> rtsituation_metadata

cluster_no
cluster_size
 node_count

Note that all received Protocol Buffers messages has message "Message" as a root item (message.proto).

Time series service data

Time series data is provided by direct access to Influx database. WNT < 4.4 uses Influx v1, and the same credentials used to login to authentication service can be used also to access the database. WNT >= 4.4 uses Influx v2, where separate token is required to query data from the database. This token is returned in the authentication manager’s login message response. Please note that the token is reset every time when the WNT services are restarted. If there is need to have static token then it can be added directly to the database by using Influx v2 management API [6]. The use of Influx query language is documented in [4].

NOTE: It is not recommended to constantly query data from Influx as it may overload the backend server. Instead Real Time Situation (RTS) or MQTT JSON API shall be used.

The "wirepas" database contains several measurements (Influx equivalent of database table).

Table: Database measurements

Measurement

Description

analytics_boot

Node boot / startup related diagnostics **

analytics_next_hop

WNT calculated hop count to sink

analytics_nodestate

Node online information *

analytics_packet

High level information about every received packet (packet counts, end points, addresses, payload size and time related information).

analytics_traveltime_kpi

Processed information about packets' travel times (min/avg/max per QoS level).

location_measurement

Positioning measurements received from the nodes ** (node positioning message payloads).

location_update

Computed positions from WPE† ** (lat/lon/alt, building, floor plan and areas).

node_metadata

Node metadata changes ** (lat/lon/alt and building change from WNT, name, description etc.)

remote_api_response

Remote API response information ** (Remote API message payloads).

*Online state uses the values defined in OnlineStatus message (internal.proto).

** Column names use numbering from the WNT Protocol Buffers files (id of the message field).

WPE needs to be running and connected to the WNT MQTT broker.

Example CURL command to query data WNT < 4.4

curl.exe -G https://someaddresswnt.domain.com:8886/query --data-urlencode "u=<username>" --data-urlencode "p=<password>" --data-urlencode "pretty=true" --data-urlencode "epoch=ns" --data-urlencode "db=wirepas" --data-urlencode "q=show measurements"

Example CURL command to query data WNT >= 4.4

curl.exe -G https://someaddresswnt.domain.com:8886/query -H "Authorization: Token <token>" --data-urlencode "epoch=ns" --data-urlencode "db=wirepas" --data-urlencode "q=show measurements"

Example column names decoding

In the example the query used to query data is "q=select * from endpoint_247".

Table: Example response

Response from Influx

{    “results”: [         {            “series”: [                 {                    “name”: “endpoint_247”,                     "columns": [                         "time",                         "Message_160_1",                         "Message_2",                         "Message_3",                         "Message_4",                         "Message_5",                         "Message_50_100",                         "Message_50_101",                         "Message_50_12",                         "Message_50_18",                         "Message_50_19",                         "Message_50_2",                         "Message_50_23",                         "Message_50_24",                         "Message_50_3",                         "Message_50_33",                         "Message_50_34",                         "Message_50_35",                         "Message_50_36",                         "Message_50_37",                         "Message_50_38",                         "Message_50_39",                         "Message_50_4",                         "Message_50_40",                         "Message_50_41",                         "Message_50_42",                         "Message_50_43",                         "Message_50_44",                         "Message_50_45",                         "Message_50_46",                         "Message_50_48",                         "Message_50_49",                         "Message_50_5",                         "Message_50_50",                         "Message_50_51",                         "Message_50_54",                         "Message_50_55",                         "Message_50_56",                         "Message_50_57",                         "Message_50_58",                         "Message_50_59",                         "Message_50_6",                         "Message_50_60",                         "Message_50_61",                         "Message_50_63",                         "Message_50_65",                         "Message_50_66",                         "Message_50_69",                         "Message_50_7",                         "Message_50_70",                         "Message_50_71",                         "Message_50_72",                         "Message_50_73",                         "Message_50_74",                         "Message_50_75",                         "Message_50_76",                         "Message_50_77",                         "Message_50_79",                         "Message_50_8",                         "Message_50_80",                         "Message_50_81",                         "Message_50_82",                         "Message_50_83",                         "Message_50_84",                         "Message_50_85",                         "Message_50_86",                         "Message_50_88",                         "Message_50_9",                         "Message_50_90",                         "Message_50_91",                         "Message_50_92",                         "Message_50_93",                         "Message_50_94",                         "Message_50_95",                         "Message_50_96",                         "Message_50_97",                         "Message_50_98",                         "Message_50_99",                         "Message_51_10",                         "Message_51_2",                         "Message_51_4",                         "Message_51_5",                         "Message_51_7",                         "Message_7",                         "Message_8",                         "Message_9",                         "network_id",                         "nodegroup",                         "nodeid”                     ],                     “values”: [                         [                             1622642051777000057,                             4.166666507720947,                             1703680,                             "",                             1622642051777,                             1622642064534,                             null,                             null,                             126,                             "[Message_50_18_2=201612,Message_50_18_3=5,Message_50_18_4=100.0]",                             null,                             8000,                             2472,                             96.47058868408203,                             2,                             16.66666603088379,                             25,                             null,                             null,                             null,                             null,                             null,                             false,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             8.333333015441895,                             51,                             false,                             35,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             false,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             null,                             -4,                             1.5686274766921997,                             -63,                             null,                             null,                             null,                             null,                             null,                             1,                             34,                             0.3921568691730499,                             null,                             null,                             null,                             null,                             88.23529052734375,                             null,                             null,                             null,                             -5,                             null,                             3,                             247,                             255,                             0,                             "",                             201618,                             51,                             12757,                             "1703680",                             "201",                             201618                         ]                     ]                 }             ]         }     ] }

The link between column name and description can be found from the WNT Protocol Buffers file message.proto [5].

For example to decode column Message_2, open main WNT Protocol Buffers file message.proto and look for message called Message. This message is used as base of all columns starting with Message_ and the number after the underscore is the field number of the corresponding message. In this case Message_2 can be decoded to network_id as shown in below table


Table: Part of message.proto

message.proto

message Message {
repeated uint32 id = 1 [packed=true];
optional uint32 network_id = 2;
optional string gateway_id = 3;
.
.
     .

For nested proto messages e.g Message_50_2, the ids are separated with underscore.

For example, in Message_50_2, the first number (50) denotes DiagnosticsData within the Message and the latter number (2) refers corresponding field number within the DiagnosticsData, i.e. access_cycle_ms in this case. The table below provides an extract of the various fields for this example.


Table: Part of message.proto

message.proto

message Message {
.
.
.
optional DiagnosticsData diagnostics = 50;
optional RxData rx_data = 51;
optional AppConfigData app_config = 52;
.
.
.
 }

message DiagnosticsData {
repeated Neighbor neighbors = 1 [(nanopb).max_count = 32];
optional float access_cycle_ms = 2;
optional BaseRole role = 3;
.
.
.
 }

Basic data flow and real time situation data

Basic data flow to get continuous data

  • Generate e.g. UUID (version 4) which is used as originator token for metadata changes.
  • Connect to authentication service and send loginmessage.
    1. Authentication service sends back session id.
    2. Do not close the connection as the session id will become invalid.
  • Connect to the real time situation service and authenticate with the session id.
    1. Real time situation service starts to push the initial real time data.
  • Query needed information from the metadata service and use the session idfor the authentication.
    1. If you need this non-node metadata in your application, you need to store the related information as the real time situation connection message's metadata_update_message will only contain the changed information.
  • Close the authentication service connection.
    1. Real time situation connection will still continue to work.
  • Read the data from the real time situation.
    1. Get the initial node data
      • Sum up the node counts from the real time situation services.
        • When the distinct received node count is the same as the sum of the node counts, the initial real time situation is received.
    2. Get the changed node data
      • From now on the real time situation component will only send changed information (aka delta) when compared to the previous node data.
      • You need to keep the initial node state and then apply the changed fields incrementally.
      • Each message will contain network_id and source_address fields to distinguish between the nodes.
    3. Any metadata change will be provided via the connection.
      • You can use the originator_token to distinct the changes made by you.
  • When you wish to stop receiving the real time data please close the real time situation connection.


If you wish to do metadata changes after authentication service connection is closed, you need to connect and login again to the authentication service, and the service will provide a new session id.

Real time situation data

Real time situation components use Protocol Buffers messages to send the data. All the incoming messages have a message of type MessageCollection as a root item. The MessageCollection contains a list of messages packaged as Message type (please see message.proto).

Table: Important message fields

Field name

Description

network_id

Network id of the node which sent the message.

source_address

Node id of the node which sent the message.

gateway_id

Id of the gateway which routed the message.

tx_time

Time when the packet was generated by the node.

rx_time

Time when the packet was received by the gateway.

travel_time_ms

How long it took for gateway to receive the packet (rx_time – tx_time).

diagnostics *

Diagnostics data that the node has generated. Contains also the node role and mode.

rx_data *

Data message information (end points, qos etc.).

app_config *

Network persistent data, including application configuration and diagnostics interval (sent only by the sinks).

network_channel

Network channel (sent only by the sinks).

security_enabled

Are cipher and encryption keys set for the network (sent only by the sinks).

app_config_response *

Response for setting of the network persistent data (sent only by the sinks).

gateway_info *

Gateway information response data (sent only by the sinks).

scratchpad_status *

Scratchpad status response data.

online_status *

Node online status determined by the backend. Please note that for non-sink nodes this field is missing if there are no incoming messages after the backend has restarted. It is safe to assume that the node is in the offline state if the field is missing from the initial node data.

node_metadata *

Node metadata (location, name, description, positioning role etc.)

rtsituation_metadata *

Information about real time situation manager (node count).

metadata_update_message *

Non-node related metadata update information.

calculated_values_from_diagnostics *

Derived diagnostics metrics calculated at the backend

* Sub-message

 Each real time situation service cluster member processes its data periodically. Control operations related data is handled every five seconds and changes/responses received from networks are indicated to clients in message collections directly. For actual network traffic, incoming messages from the nodes are taken to batch processing every 30 seconds. As the per node delta is calculated over the changes during that period, a single incoming message in the message collection can contain merged information from several messages of the given node.

MQTT JSON API

MQTT JSON API is a simple integration API provided mainly for smart tracking use cases. It consists of single MQTT topic (node_data_json), to which WNT backend publishes changes in node metadata and location information (see below section for more details about changes triggering the message). All messages are published to the topic with MQTT QoS level 1 (at least once).

Compared to real time situation service APIs, the MQTT JSON API has following differences:

  • As name implies, data is encoded as JSON (instead of protocol buffer encoding)
  • Each node message contains all data fields for node with their last known value (instead of delta packet)

API implementation

Within the WNT backend, the MQTT JSON API is implemented by real time situation service. On the service startup, each real time situation cluster member publishes the initial state for all the nodes it manages after the internal caches has been populated. During the active operation, each cluster member publishes changes within the node set it manages periodically every five seconds. A publication is a single JSON message containing a list of all nodes with changes in published data content.

The activation and operation of MQTT JSON API can be controlled via real time situation service startup configuration. Following table shows the relevant configuration parameters with the environment variable and corresponding Wirepas Services installer variable.

Table: Part of message.proto

Environment variable

Installer variable *

Description

MQTT_JSON_IS_ON

wnt_mqtt_json_is_on

Set to true to enable the API

MQTT_JSON_IS_OPTIMIZED_ON

wnt_mqtt_json_is_optimized_on

Set to true in order to receive only WPE originated location updates for tags (see below) and battery voltage for anchors.

MQTT_JSON_FORWARD_CALCULATED_ANCHOR_LOCATIONS

wnt_mqtt_json_forward_calculated_anchor_locations

Set to true to forward WPE calculated anchor locations in the corresponding nodes. For more information please see the next chapter.

*) Please see Wirepas Services Installer Guide for more information [7]

The conditions that trigger per node update message sending via MQTT JSON API depend on the operation mode:

  • In optimized mode, an update message is generated only when related location information of a tag changes i.e one or multiple fields among Latitude, Longitude, Altitude and Positioning time. In addition, an update message is generated to report the battery voltage of anchors. The default periodicity for such message depends on the vendor.
  • In normal mode the set of condition is more versatile.

Below table describes what type of changes will be sent to clients in both modes.

Table: Changes triggering message sending to MQTT JSON API per operation mode

Change type / sending condition

Normal

Optimized

Applicable for nodes with Tag positioning role

X

X

Applicable for nodes with Anchor positioning role

X


Initial state update for all nodes on service startup

X

X

Tag location change (calculated by WPE)

X

X

Node battery voltage level change (threshold 0.1V)

X

X*

Metadata or online status (node, building, floorplan, area) change

X


* Anchors report their battery voltage. These are published even if the system is set in Optimized mode and the reporting periodicity depends on the vendor.

MQTT JSON API messages

A client can receive MQTT JSON API messages by subscribing to node_data_json topic. A dedicated MQTT user profile (mqttjsonuser) is automatically created for accessing the topic. The received content type is application/json. WNT backend publishes messages with MQTT QoS level 1, which assures at least once delivery of a message. Thus, clients shall be able to handle possible duplicates.

Each JSON message contains a list of nodes, each having the fields depicted in following example. Please note that gateway_id in WNT 4.1 data is only valid for sinks.

WNT 4.4 added support for getting WPE calculated location for anchors' which have opportunistic scan mode enabled. The location is defined in the anchor_calculated_latitude, anchor_calculated_longitude and anchor_calculated_altitude fields. anchor_location_error_m field contains the location error in meters between the set and calculated location. The error is calculated only from the latitude and longitude values.

Table: Example data of the MQTT JSON API (WNT 4.0)

MQTT JSON API data

{
"version": 1,
"nodes": [
{
"network_name": "test_network",
"node_name": "test_node_40",
"is_approved": true,
"is_virtual": false,
"online_status": 2,
"online_status_string": "online",
"voltage": null,
"latitude": 60.164978,
"longitude": 24.9654064,
"altitude": 5,
"position_pixel_x": 1596.98,
"position_pixel_y": 906.25,
"position_meter_x": 27.11,
"position_meter_y": 15.38,
"positioning_role": 2,
"positioning_role_string": "tag",
"measurement_time_epoch": 1622783051507,
"measurement_time": "6/4/2021, 5:04:11 AM",
"positioning_time_epoch": 1622783054773,
"positioning_time": "6/4/2021, 5:04:14 AM",
"building_id": “98509c65-8bad-9390-0ce8-b58ceef7fc52”,
"building_name": “Example building”,
"floor_plan_id": "2accb5e6-9e09-0e77-187c-afe1149ab911”,
"floor_plan_name": “first_floor“,
 "areas": [ 
{
"id" : "17624e1c-61b3-b7b9-3f55-5645496d95a5",
"name" : "area_4"
}, {
"id" : "53274b41-93b6-5b09-03bc-6a9c70cb184d",
"name" : "area_5"
}
],
"node_address": 40,
"network_address": 777555
},
{
"network_name": "test_network",
"node_name": "test_node_50",
"is_approved": true,
"is_virtual": false,
"online_status": 2,
"online_status_string": "online",
"voltage": null,
"latitude": 60.1645164,
"longitude": 24.9672318,
"altitude": 5,
"position_pixel_x": 2532.16,
"position_pixel_y": 584.98,
"position_meter_x": 42.98,
"position_meter_y": 9.93,
"positioning_role": 2,
"positioning_role_string": "tag",
"measurement_time_epoch": 1622783055510,
"measurement_time": "6/4/2021, 5:04:15 AM",
"positioning_time_epoch": 1622783058775,
"positioning_time": "6/4/2021, 5:04:18 AM",
"building_id": “98509c65-8bad-9390-0ce8-b58ceef7fc52”,
"building_name": “Example building”,
"floor_plan_id": "2accb5e6-9e09-0e77-187c-afe1149ab911”,
"floor_plan_name": “first_floor“,
 "areas": [ 
{
"id" : "ef03ff8d-ff97-fff4-182b-b9fdbdf9a3c8",
"name" : "area_2"
}, {
"id" : "9dd7dc3c-c389-57e0-1ba5-c16d56634483",
"name" : "area_3"
}
],
"node_address": 50,
"network_address": 777555
}
]
 }

Table: Example data of the MQTT JSON API (WNT 4.1)

MQTT JSON API data

{
"version": 1,
"nodes": [
{
"sink_address":107,
"network_name": "test_network",
"node_name": "test_node_40",
"is_approved": true,
"is_virtual": false,
"online_status": 2,
"online_status_string": "online",
"voltage": null,
"latitude": 60.164978,
"longitude": 24.9654064,
"altitude": 5,
"position_pixel_x": 1596.98,
"position_pixel_y": 906.25,
"position_meter_x": 27.11,
"position_meter_y": 15.38,
"positioning_role": 2,
"positioning_role_string": "tag",
"measurement_time_epoch": 1622783051507,
"measurement_time": "6/4/2021, 5:04:11 AM",
"positioning_time_epoch": 1622783054773,
"positioning_time": "6/4/2021, 5:04:14 AM",
"building_id": “98509c65-8bad-9390-0ce8-b58ceef7fc52”,
"building_name": “Example building”,
"floor_plan_id": "2accb5e6-9e09-0e77-187c-afe1149ab911”,
"floor_plan_name": “first_floor“,
 "areas": [ 
{
"id" : "17624e1c-61b3-b7b9-3f55-5645496d95a5",
"name" : "area_4"
}, {
"id" : "53274b41-93b6-5b09-03bc-6a9c70cb184d",
"name" : "area_5"
}
],
"node_address": 40,
"network_address": 777555,
"gateway_id": null
},
{
"sink_address":107,
"network_name": "test_network",
"node_name": "test_node_50",
"is_approved": true,
"is_virtual": false,
"online_status": 2,
"online_status_string": "online",
"voltage": null,
"latitude": 60.1645164,
"longitude": 24.9672318,
"altitude": 5,
"position_pixel_x": 2532.16,
"position_pixel_y": 584.98,
"position_meter_x": 42.98,
"position_meter_y": 9.93,
"positioning_role": 2,
"positioning_role_string": "tag",
"measurement_time_epoch": 1622783055510,
"measurement_time": "6/4/2021, 5:04:15 AM",
"positioning_time_epoch": 1622783058775,
"positioning_time": "6/4/2021, 5:04:18 AM",
"building_id": “98509c65-8bad-9390-0ce8-b58ceef7fc52”,
"building_name": “Example building”,
"floor_plan_id": "2accb5e6-9e09-0e77-187c-afe1149ab911”,
"floor_plan_name": “first_floor“,
 "areas": [ 
{
"id" : "ef03ff8d-ff97-fff4-182b-b9fdbdf9a3c8",
"name" : "area_2"
}, {
"id" : "9dd7dc3c-c389-57e0-1ba5-c16d56634483",
"name" : "area_3"
}
],
"node_address": 50,
"network_address": 777555,
"gateway_id": null
}
]
 }

Table: Example data of the MQTT JSON API with calculated anchor location (WNT 4.4)

MQTT JSON API data

{
"version": 1,
"nodes": [
{
"sink_address": 107,
"network_name": "test_network",
"node_name": "test_node_50",
"is_approved": true,
"is_virtual": false,
"online_status": 2,
"online_status_string": "online",
"voltage": 3.39,
"latitude": 61.446486,
"longitude": 23.8623236,
"altitude": 5,
"position_pixel_x": 2085.24,
"position_pixel_y": 1312.17,
"position_meter_x": 35.4,
"position_meter_y": 22.27,
"positioning_role": 1,
"positioning_role_string": "anchor",
"measurement_time_epoch": 1703000241124,
"measurement_time": "12/19/2023, 3:37:21 PM",
"positioning_time_epoch": 1703000242984,
"positioning_time": "12/19/2023, 3:37:22 PM",
"building_id": "98509c65-8bad-9390-0ce8-b58ceef7fc52",
"building_name": "Example building",
"floor_plan_id": "2accb5e6-9e09-0e77-187c-afe1149ab911",
"floor_plan_name": "first_floor",
"areas": [],
"node_address": 50,
"network_address": 777555,
"gateway_id": null,
"anchor_calculated_latitude": 61.4464899,
"anchor_calculated_longitude": 23.8623549,
"anchor_calculated_altitude": 5,
"anchor_location_error_m": 0.7756
}
]
 }

Coordinate conversions

Introduction

When a floor plan is added into WNT it is required to input the latitude/longitude/altitude (WGS84) of four reference points (A, B, C, D) and a scaling value. The reference points are used to determine the rotation and translation of the floor plan to the corresponding position on the Earth. Scaling is used to determine the relation between floor plan image pixels and the real world distance. The floor plan information retrieved from the WNT backend includes the rotation and translation information required to make the conversion from/to WGS84 coordinate to/from pixels. The coordinate conversion assumes that the top-left floor plan image corner has the coordinate (0,0) pixels. Given the floor plan information provided by the WNT API the following matrices/vectors are used:

  • Rotation matrix (using rotation_matrix):

  • Translation matrix (using offset_local_to_ecef ):

  • Scaling:

WGS84 to pixels

To convert a WGS84 coordinate to pixels the following steps are required:

  1. Convert the WGS84 coordinate to ECEF (see Section “Coordinate conversions” for the conversion method)
  2. Given E the ECEF coordinate vector compute the pixel coordinates P as:


 The matrix operations can be equivalently expressed as:


 where:

Pixels to WGS84

To convert a pixel coordinate (px, py) to WGS84 the following steps are required:

  1. Compute the ECEF coordinate as:


 where:


 and R' denote the transpose matrix.

  1. Convert the ECEF coordinate to WGS84 as shown in Section “Coordinate conversions”.

WGS84 to ECEF conversion

Given a WGS84 coordinate as: φ latitude in radians, λ longitude in radians, η altitude in meters the ECEF coordinate E=xyz in meters is computed as:


 where:

ECEF to WGS84 conversion

The conversion from ECEF to WGS84 is an iterative process.
 Starting from an initial state computed as:


Iterate the following equations until Δφ<10-12 and Δh< 10-5:


where |∙| denotes the absolute value and e2 is the same as in Section “Coordinate conversions”.
 Finally compute longitude as:


 Note that the latitude and longitude values are in radians and the altitude in meters.

Example implementation

You can find an example implementation of the calculations in C from Wirepas Backend-APIs project [3].

References

[1] Wirepas Connectivity Dual-MCU API Reference Manual

[2] Wirepas Network Tool - Client User Guide

[3] https://github.com/wirepas/wirepas-networktool-messaging-python/tree/main/examples/cpp/floor_plan_pixel_conversion

[4] Influx v1 Query Language

[5] WNT Protocol Buffer files

[6] Influx v2 Token Management

[7] Wirepas Services Installer Guide

Revision History

Date

Version

Notes


v1.6

Initial version


v1.7

Updated for WNT 1.7

  • Removed warning from Get areas chapter and updated the response, as the issue was fixed.
  • Removed note about Set node metadata method only to accept single entry, as it is not true anymore.

v2.0

Updated for WNT 2.0

  • Added protocol version table.
  • Updated protocol version to 3.
  • Added note about analytics_packet measurement change.
  • Added Get components information and Get scratchpad status methods.
  • Added floor plan image size to Create and Update floor plan messages.
  • Changed Create and Update floor plan messages to return all floor plan fields.
  • Added coordinate conversion related data to Create and Update floor plan messages.
  • Changed network id to number in Create, Update and Delete network.
  • Removed pixel_location_x and pixel_location_y from Set node metadata message.
  • Added remote_api_response to Influx measurements.
  • Split analytics_packet Influx measurement's travel_time_ms column to travel_time_ms_qos0 and travel_time_ms_qos1.

v3.0

Updated for WNT 3.0

  • Updated protocol version to 4.
  • Updated Set network data message.
  • Added reference to endpoint_247 Influx measurement.

v4.0

Updated for WNT 4.0

  • Updated protocol version to 5.
  • Updated architecture figures.
  • Added MQTT JSON API description.
  • Added message ids for Set OTAP state and Set scratchpad action messages.
  • Removed unnecessary originator_token fields from all Get messages.
  • Renamed create, update and delete network messages to create, update and delete network metadata for clarity.
  • Added is_delete_nodes field to Delete network metadata.
  • Updated add/remove node to/from floor plan messages to accept array of nodes.
  • Updated Set node metadata and Delete node messages to accept array of nodes.
  • Added is_anchor field to set node metadata message.
  • Removed is_sink field from the Delete node message.
  • Renamed Set network data message to Set network persistent data.
  • Added is_sink_only field and renamed rerun_interval_s field to resend_interval_s in Get scractchpad status message.
  • Added analytics_boot and node_metadata measurements to time series data
  • Added calculated_values_from_diagnostics to real time situation messages

v4.1

Minor fix on json output snippet

v4.2

Updated for WNT 4.1

  • Added WNT 4.1 version of MQTT JSON example with sink_address and gateway_id fields.

v4.3

Removed message ids for Set OTAP state and Set scratchpad action messages

v4.4

Removed deprecated Send data message description from metadata service messages

v4.5

Added

  • details about the response content generated by the “Get networks“ request
  • rssi_offset field in the “Set Node Metadata” API call
  • MQTT over websocket server port

Minor content fixes

v4.6

Updated for WNT 4.2

  • Added WNT 4.2 to the version information.
  • Added field examples to the Influx measurement table.
  • Added real example to the floor plan update message.

v4.7

Clarified information about MQTT JSON API in optimized mode with regards to anchors battery voltage reports.

v4.8

Replaced references to “Wirepas Massive“ by “Wirepas Mesh“

Removed “WM“ acronym

v4.9

Clarified field type in the MQTT JSON examples

v4.10

Simplified WNT 4.0/4.1/4.2/4.3 to WNT 4.x, and cosmetic changes.

v4.11

Remove diagnostics reference manual.

Update reference links.

v4.12

Updated for WNT 4.4

  • Added MQTT JSON calculated anchor location information.
  • Added information about Influx access token to login message response and time series service data - chapter.

Legal Notice

Use of this document is strictly subject to Wirepas’ Terms of Use and Legal Notice.

Copyright © 2024 Wirepas Oy