Device API overview

There are two step connection:

1.Get the server address by calling GET http://zerver.io/api/v1/node/host/<8char Data Source Type><8char data source id><4char pin> this will return server host if device is registered or 4 ZERO-byte array if not. Also this will add pending datasource in your organization's datasource folder, in case you connecting from same subnet. You have to register this datasource by clicking register button and input pin number provided via this API call.

2.When you have registered your datasource, the API call described earlier will return server host. This server host name you should use for TCP/IP transport connection to zerver cloud.

  1. supported transports:
  • MQTT broker TCP/IP is 1883, TTCP/IO SSL port 8883
  • MQTT web socket ws://<your org server host>/mqtt or wss://<your org server host>/mqtt for secure web socket.
  • port for plain TCP/IP transport is 8787 and for SSL transport 9797.

Connecting to MQTT broker with system user

To start using MQTT broker you can login with you registered account or create new user in admin menu. For user authentication you are responsible for generating unique client id, for login set you user name, for password you should use hash found in you user's profile information in MQ Pass field.

Connecting to MQTT broker with datasource id

To connect devices to MQTT transport is better to use autgenerated datasource ids. You can generate one when manually creating device in administration console - not specify device ID. Second optin is to call API:GET http://zerver.io/api/v1/node/host/<8-Char Data Source Type><8-Char Data Source Type><4char pin> - you should place 7 char datasource type id 2 times. This will return 7 char datasource id. See code sample for more information Link

When you connect device with system it auto creates following topic listener: Posting path to device: ds/<devId>/in/<MsgTypeId> Subsrcibing path to device: ds/<devId>/out/<MsgTypeId> , if device is defined, messages from this topic are stored in database:

1.Get the server address by calling GET http://zerver.io/api/v1/node/host/<8-Char Data Source Type><8-Char data source id><4char pin> this will return server host if device is registered or 4 ZERO-byte array if not. Also this will add pending datasource in your organization's datasource folder, in case you connecting from same subnet. You have to register this datasource by clicking register button and input pin number provided via this API call.

System Defined Message format for MQTT transport (TCP/Websocket)

7-TRAP Message format for frozen datasources

Trap messages and event messages is written to database and this is actual data what you can later see in graphs. topic: ds/<devId>/out/7

If datasource type NOT frozen then before field data you should specify field Id els if type is frozen then you should specify every field defined in datasource type and in proper order.

!NOTE payload of trap message should fit with device type field defination,

  • BYTE - 8bit integer = 1byte; (only supported in frozen datasources)
  • SHORT - 16bit integer = 2byte;
  • INT - 32bit integer = 4byte;
  • LONG - 64bit integer = 8byte;
  • BINARY - 8bit = 1byte;
  • DOUBLE - 64bit double precision = 8byte;

8-event Message format

events are written to database along with your trap data. topic: ds/<devId>/out/8 payload:

  • 8 byte 64bit long integer epoch time
  • 2 byte 16bit integer event code or id.
  • n byte text

9-Log Message format

Log Message are not written to databse, but you can receive them when connecting to server by WebSocket and subscribe to device. topic: ds/<devId>/out/9 payload:

  • 8 byte 64bit long integer epoch time
  • 2 byte 16bit integer event code or id.
  • n byte text

Message format for TCP/IP plain transport

System reserved message types:

SUB = 1; Client subscribe/unsubscribe message to server, to subscribe to another device's data . SUB_DATA = 2; data received by subscritions. DISCONNECT = 3; Client sends disconnect to server. Or server reject new client connection in case do data found. ACK = 4; Server sends acknowledge after receiving any message except ENQ ENQ = 5; Client sends enquiry message just after creating TCP connection with server CONN_ACK = 6; Server sends acknowledge after device ENQ TRAP = 7; Client sends metrics data sent to server ANNOT = 8; Client sends event data sent to server LOG = 9; Client sends log data sent to server DAT = 10; data interexcahange for extending You are free to use ids greater than 10.

all messages coming to cloud except ENQ and DISCONNECT type messages should meet following message format:

  • 1byte message type
  • 2 byte 16bit message Id.
  • 2 byte 16bit integer remaining message length
  • max 16bit int payload

Message length parameter and payload is mandatory only if you sending message from client to server except DISCONNECT and ENQ messages which has 1 byte value 3 for disconnect and described below format for enq message.

1-SUB Message format

  • 1 byte ENQ message type 1
  • 2 byte 16bit message Id.
  • 2 byte 16bit integer length = 18
  • 1 byte SUBSCRIBE 1 ; UNSUBSCRIBE 0; SUBDEVICE 2
  • 1 byte message type to subscribe, default 0 - all messages
  • 2 byte 16bit int map to DeviceId.
  • 14 byte DeviceType and DeviceId combination.

2-SUB_DATA Message format

  • 1 byte ENQ message type 2
  • 2 byte 16bit message Id.
  • 2 byte 16bit integer remaining message length
  • 2 byte 16bit int map to DeviceId.
  • n-byte max 16bit integer original command data (first byte comes original cmd)

3-DISCONNECT Message format

  • 1 byte ENQ message type 1

4-ACK Message format

  • 1 byte ENQ message type 4
  • 2 byte 16bit Acked message Id.

5-ENQ Message format

After creating socket connection you should send ENQ message in following format:

  • 1 byte ENQ message type 5
  • 7 byte device type
  • 7 byte device id
  • 4 byte pin code
  • 2 byte 16bit integer device version

After sending ENQ message to server, it should respond with 6 - CONN_ACK. After receiving conn ack you can start talking to server.

6-CONN_ACK Message format

  • 1 byte ENQ message type 6

7-TRAP Message format for frozen datasources

Trap messages and event messages is written to database and this is actual data what you can later see in graphs.

  • 1 byte message type 7
  • 2 byte 16bit message Id.
  • 2 byte 16bit integer remaining message length
  • fixed depend on device type definition n-byte stats data from your sensor reading or output state

!NOTE payload of trap message should fit with device type field defination

  • BYTE - 8bit integer = 1byte; (only supported in frozen datasources)
  • SHORT - 16bit integer = 2byte;
  • INT - 32bit integer = 4byte;
  • LONG - 64bit integer = 8byte;
  • BINARY - 8bit = 1byte;
  • DOUBLE - 64bit double precision = 8byte;

7-TRAP Message format for non-frozen datasources

Trap messages and event messages is written to database and this is actual data what you can later see in graphs.

  • 1 byte message type 7
  • 2 byte 16bit message Id.
  • 2 byte 16bit integer remaining message length
  • variable count 16bit 2byte integer column id and value pairs

!NOTE payload of trap message should fit with device type field defination

  • SHORT - 16bit integer = 2byte;
  • INT - 32bit integer = 4byte;
  • LONG - 64bit integer = 8byte;
  • BINARY - 8bit = 1byte;
  • DOUBLE - 64bit double precision = 8byte;

8-event Message format

events are written to database along with your trap data. events should have following format:

  • 1 byte message type 8
  • 2 byte 16bit message Id.
  • 2 byte 16bit integer remaining message length
  • 8 byte 64bit long integer epoch time
  • 2 byte 16bit integer event code or id.
  • n byte text

9-Log Message format

Log Message are not written to databse, but you can receive them when connecting to server by WebSocket and subscribe to device. Log Message should have following format:

  • 1 byte message type 9
  • 2 byte 16bit message Id.
  • 2 byte 16bit integer remaining message length
  • 8 byte 64bit long integer epoch time
  • 2 byte 16bit integer event code or id.
  • n byte text

REST API overview

The zerver API uses HTTP verbs and RESTFul endpoint structure. Token based authorization is used. Request and response payloads are formatted in JSON.

Api reponses

OK reponses

OK are returned with HTTP status 200 and JSON payload {message:"Message text" }.

Erors

Validation errors are returned with HTTP status 400 and JSON payload {message:"Message text" }. Authorization errors are in same format but with HTTP status 401. Unexpected errors are returned with status 500.

Authorization

URL: POST

Request payload:
{ username:"username", password:"********", }
Response payload:
{ token:"**************", server:"XXXXX.zerver.io", }
response token should included in further requests in Authorization header:
Authorization: Bearer <token>

in AngularJS you can write following code:

app.factory('authInterceptor', function ($rootScope, $q, contextSrv) { return { request: function (config) { config.headers = config.headers || {}; if (contextSrv.token) {` config.headers.Authorization = 'Bearer ' + contextSrv.token; } return config; }, response: function (response) { return response || $q.when(response); } }; });

When you Authorize yourself you also get in response server host name. All further request for this organization session should be directed to this server.
You get following base URL for further requests:
https://<server>/api/v1

NOTE! use URL pefix https://<server>/api/v1 for all api calls if you work outside browser.

Auth token authorization

Auth tokens you can crete in Dasgboard Amin/menu/<Your org>/API keys window. They are limited to Viewer role set by default.
URL: GET /auth/apiz/{id}
URL param id - api key goes there
Response - same as for API call described below: /auth/getusersess.

User and Organization data is first thing you will need after authorization, because you are allowed to work with one specific organization, until you switch one.

URL: GET /auth/getusersess
Request:none
Response: 200

{ "user":{ "isSignedIn":true, "isSideMenu":true, "login":"your-user", "email":"your-login@yourdomain.com", "name":"Administrator", "orgRole":"Admin", "orgName":"YourOrgName", "orgid":"********", "dashid":"xxxxxxxxx", "orgs":{ "orgIdThere":"Role-Admin" }, "message":"User logged in", "token":"xAuthTokenx", "server":"zerver.io" } }

URL: GET /auth/logout
Request:none
Response: 401 {"message": "Not logged in"}

Datasources

Get datasource list.
URL: GET /datasources
Request:none
Response:

[ { "orgId":"xxxxxxxx", "id":"DsTypeDsKey", "name":"DsName", "type":"DsType", "assigned":true, "online":false, "cols":{ "1":"ColName", ....... "20":"ColName" }, "expires":2, "loc_lat":0.0, "loc_long":0.0, "recfreq":0, "storage":0, "qlimit":0, "pin":"1111", "timeidx":0, "version":0 },... ]

Get datsource by ID.
URL: GET /datasources/{id}
URL param id - Data Source id = Data Source Type + Data Source Key
Response - same as for API call described before: GET /datasources. but single datasource not array

Get datasource by name.
URL: GET /datasources/name/{name}
URL param id - Data Source id = Data Source Type + Data Source Key
Response - same as for API call described before: GET /datasources. but single datasource not array

Register datasource.
URL: POST /datasources/reg
Request:

{ "id":"DsTypeDsKey", "name":"DsName", "type":"DsType", "pin":"1111", "version":0 }

Response: 200 {"message": "DS registered"}

Create datasource.
URL: POST /datasources
Request:

{ "id":"DsTypeDsKey", "name":"DsName", "type":"DsType", "pin":"1111", "version":0 }

Response: 200 {"message": "DS registered"}

Update column names.
URL: PUT /datasources/col/{id}
URL param id - Data Source id = Data Source Type + Data Source Key
Request:

{ "1":"ColName", ....... "20":"ColName" }

Response: 200 {"message": "Column name updated"}

Update datasource.
URL: PUT /datasources
Request:

{ "id":"DsTypeDsKey", "name":"DsName", "type":"DsType", "cols":{ "1":"ColName", ....... "20":"ColName" }, "expires":2, "loc_lat":0.0, "loc_long":0.0, "recfreq":0, "qlimit":0, "pin":"1111" }

Response: 200 {"message": "DS updated"}

Delete datasource.
URL: DELETE /datasources/{id}
URL param id - Data Source id = Data Source Type + Data Source Key
Response: 200 {"message": "DS removed and deleted data"}

Delete data only.
URL: DELETE /datasources/delData/{id}
URL param id - Data Source id = Data Source Type + Data Source Key
Response: 200 {"message": "DS data deleted"}

Users

Organizations

Admin API