Itron's Reference Application - CoAP Client

Use Java CoAP Client to Communicate with your HDK and Sensors

Get the Itron Java CoAP Client App on GitHub
Learn how to use the Java CoAP Client to send requests to your Milli Developer Kit and obtain sensor data and push sensor data to Itron Data Platform.

Overview

Now that you have your Milli based HDK assembled and running, you will need a CoAP client to send CoAP requests to your device. In this section we will use the the Java CoAP Client.

The Java CoAP Client will run on any platform (Windows, Mac OS, Linux). It supports finer grained control over CoAP requests and can be used to build up complex CoAP requests. This client is command line based and requires command line options or request files that direct the clients actions. The Java CoAP Client makes managing Gateway sessions easier for complex CoAP request patterns. In addition, the Java CoAP Client records the CoAP headers in its logging output (which is very handy to debug CoAP problems and device access issues). The Java CoAP Client requires Java 8. You can obtain the source code for the Java client from the (see the Software References sidebar). The Java CoAP Client uses the nCoAP implementation of CoAP core.

You are free to base your CoAP client on the Java CoAP Client source code, or use it as is. The Java CoAP client is also available as a pre-built all-in-one jar file which obviates the need to build the client. You may download the app using:

 

Note: To use Itron's CoAP and Data Platform APIs, you will need your API key credentials.  Go to the My Account Overview section of this portal and retrieve your ClientID and Secret from the Data Platform tab.

While the Java CoAP Client is a component of Itron's Developer Program, the Java CoAP client is a standalone command line utility that can be used to communicate with any Itron CoAP based IoT device such as any of the Developer Kits available on this Dev Portal.

Sensor measurements are "read" by a CoAP server running on the Arduino's microprocessor. The Java CoAP Client communicates with the CoAP Server and "gets" the sensor data returning it for use by your application.

A few example CoAP requests are:

  • Create a Gateway session
  • Get a sensor reading
  • Get a sensor observation sequence
  • Put a sensor configuration
  • Put CoAP server time
  • Delete a Gateway session

 

Check List

In addition to providing a reference on using the Java CoAP Client, you will specifically be able to confirm communication with your HDK and read sensor data. Specifically you will accomplish these tasks:

  • Create a Gateway session
  • Ping your HDK
  • Read the temperature sensor
  • Request a CoAP observe on the temperature sensor (and push the data to the Data Platform)

 

Software Needed

This tutorial uses the pre-built Java CoAP Client, an all-in-one jar file. If you prefer to clone the source code and build the Java Client, detailed instructions are included in the Readme.md file in the Java CoAP Client portion of the Itron GitHub repository.

You will need to install Java 8 and either download or build the sdkcoapclient:

  • Java 8
  • sdkcoapclient-1.4.0.one-jar.jar

 

Hardware Needed

You will need a laptop or desktop computer to run the Java CoAP client and a working internet connection.

 

Milli Firmware Version

There were changes made to the default CoAP URI strings for accessing a sensor CoAP server on the micro controller connected to the Milli. The URI proxied from CoAP clients to the sensor controller CoAP server resources were changed in firmware version 1.2.1000 builds 117958 and later. In build versions lower than 117958 the default URI prefix of "/sensor" was used to access resources on the sensor CoAP server.  In firmware build 117958 and later the default prefix was changed to "/snsr".  The examples below and the source code and configuration files available on GitHub contain /sensor. If you have a later firmware version build you will need to modify the source code and configuration files accordingly.

 

Refer to the Firmware Update page for instructions on how to determine your firmware version if you do not know what is on your Milli device.

Prerequisites

 

Using the Java CoAP Client

The Java CoAP Cleint jar is built as an all in one jar, it contains all libraries and dependencies need to run the client. To test the client, use the following command in a shell window:

 

java -jar C:\tools\sdkcoapclient-1.0.0-SNAPSHOT.one-jar.jar  --help

 

A list of all command options should be displayed.

 

Command Options and Request Files

Typically many command options are required to carry out a CoAP request to a device or resource. You can include these options on the command line or incorporated them into a request file. A request file is a json representation of the options. By defining a CoAP request in a request file, it is easy to build up complex request patterns. A complete description of options is provided below. To reference a request file use the --conf option.

 

Create a Gateway Session

The first CoAP request you will always make is to get a Gateway session. To obtain a session, you will need your Itron account client-id and client-secret (your credentials). A typical session request file is shown below. You must replace the <clientId> and <clientSecret> placeholders with your credentials. Go to the Account Settings tab in My Account on the Developer Portal to retrieve your client-id and client-secret .

{
  "clientPort": "6000",
  "method" : "POST",
  "timeout": "30",
  "clientId": "<clientId>",
  "clientSecret": "<clientSecret>",
  "devices": [
    {
      "deviceId": "gateway",
      "deviceHost": "api.coap-staging.developer.ssni.com",
      "devicePort": "5683",
      "devicePath": "/sessions"
    }
  ]
}

How it Works

Save the above request json in a request file and name it getsession.json. Pass the file to the Java CoAP Client as follows:

java -jar C:\tools\sdkcoapclient-1.0.0-SNAPSHOT.one-jar.jar --conf getsession.json

 

The Java CoAP Client will use your credentials to obtain an authentication token (using the Data Platform tokens API). The token is passed as the payload to a POST CoAP request made to the Gateway /sessions resource. In this case, the device we are accessing is the Gateway, thus the deviceHost option is set to the Gateway's host. Gateway resources are always on port 5683. Note the clientPort option is set to 6000. You may choose any port number. However, all future CoAP requests made must use the same clientPort number.

Refer to the security and authentication section of API Overview to get more details on client-id and client-secret and their use.

 

About Gateway Sessions

Gateway sessions cause a lot of confusion. When you get a Gateway session, the session will last until you delete the session or there is no activity on the session (session timeout is four hours). The Gateway tracks your session by using the requesting IP (source IP) and the clientPort you specified. Thus, you can establish multiple sessions by givin each a different cleintPort.

You can get the Gateway session again and again. However, be aware that the Gateway will only allow a small number of sessions to be established on a requesting IP and clientPort combination.

 

Using Gateway Sessions

Once you get a Gateway session, you may issue as many other CoAP requests as you wish without getting a new session. Just make sure your clientPort in your requests match the clientPort used to get the Session. Once you application has completed its pattern of CoAP requests you can delete the Gateway session. Here is a typical complex request pattern:

  • get session
  • CoAP request 1
  • CoAP request 2
  • ...
  • CoAP request N
  • delete session

 

Ping an HDK

Once you have been able to get a session, the next thing you should do is to ping you HDK. This is just a get on the "/" resource. The "/" resource is served by the CoAP proxy in the Milli shield. It should return the version string for the Milli CoAP proxy. This is a great way to determin if you can reach your HDK.

All CoAP requests directed to an IoT device on the Itron network require specifying the Gateway as a CoAP proxy. Thus you must include proxyHost and proxyPort. The proxy options in the request below are standard.

{
  "proxyHost": "api.coap-staging.developer.ssni.com",
  "proxyPort": "5683",
  "clientPort": "6000",
  "method" : "GET",
  "timeout": "1000",
  "clientId": "<clientId>",
  "clientSecret": "<clientSecret>",
  "devices": [
    {
      "deviceId": "<deviceId>",
      "deviceHost": "SSN<macAddress>.SG.YEL01.SSN.SSNSGS.NET",
      "devicePort": "4849",
      "devicePath": "/"
    }
  ]
}

You will need to obtain and fill in the following four items:

  • clientId - use the same clientId used to get a Gateway Session (see above)
  • clientSecret - use the same clientSecretused to get a Gateway Session (see above)
  • deviceId - use the Itron devices API to get details on your HDK (see below)
  • macAddress - use the Itron Solutions devices API to get details on your HDK (see below)

 

How it Works

Save the above request json in a request file and name it get_hdk_ping.json. Pass the file to the Java CoAP Client as follows:

java -jar C:\tools\sdkcoapclient-1.0.0-SNAPSHOT.one-jar.jar  --conf get_hdk_ping.json

 

The Java CoAP Client will form a CoAP Request and send it to the proxy (in this case the Gateway). The Gateway will do an authorization check to make sure you can access the device specified by the deviceHost option. Once validated, the Gateway will proxy the CoAP request to the Milli shield. The CoAP proxy in the Milli shield maps the resouce "/" to its CoAP proxy version string. A CoAP response is formed and returned to the Gateway which forwards the response to the Java CoAP Client that made the request.

CoAP requests made on a device that has not registered with the network DNS will return a BAD REQUEST return status by the Gateway.

 

About Timeouts

Note that Milli based Itron devices can take a long time to respond. As the transport is UDP, CoAP requests can be lost. As the Milli depends on RF to communicate with it's miniAP, CoAP requests can be lost. Both the miniAP and the Gateway will retry sending a CoAP request if the response times out. So it is a good idea (and considered good CoAP form) to use really long CoAP timeouts. A typical value is usally 1000 to 2000 seconds.

However, when accessing Gateway resources (such as /sessions) a short timeout is sufficient (we use 30 seconds).

Note: Itron no longer supports the miniAP and strongly recommends that developers use the IoT Edge Router solution instead. 

 

Request and Response Headers

These are the CoAP headers and responses you can expect when doing an HDK ping:

 

DEBUG | Finished transmission #2: [Header: (V) 1, (T) CON (0), (TKL) 8, (C) GET (1), (ID) 52337 | (Token) 0xCCDB22EC5289B440 | Options: (No. 23) 3 (No. 35) coap://SSN001350050047dd3b.SG.YEL01.SSN.SSNSGS.NET:4849/ (No. 124) 0xCE358385 | Content: <no content>]
DEBUG | HANDLE INBOUND MESSAGE: [Header: (V) 1, (T) ACK (2), (TKL) 0, (C) EMPTY (0), (ID) 52337 | (Token) <EMPTY> | Options: | Content: <no content>]
INFO  | Received #: CoAP: [Header: (V) 1, (T) NON (1), (TKL) 8, (C) CONTENT (69), (ID) 65535 | (Token) 0xCCDB22EC5289B440 | Options: (No. 12) 0 | Content: SSNI MilliNIC CoAP s... ( 29 bytes)]
INFO  | ***Payload As String: <SSNI MilliNIC CoAP server 1.0>

 

  • The first line provides the CoAP request headers
  • The second line provides the CoAP response headers for the Gateway's empy ACK
  • The third line provides the CoAP response headers for the HDK's response
  • The fourth line is a string dump of the payload.

 

Get Sensor Data

Before proceeding with the following this section you must complete setting up the CoAP server temperature sensor on the Arduino.

After a successful HDK ping, the next thing to do is to read the sensor data.  This is just a get on the "/sensor/arduino/temp" resource with a "sens" query string. The "/sensor/arduino/temp" resource is served by the CoAP server running on the Arduino. It should return the tempurature sensor response string. This is a great way to confirm you sensor is working correctly.

All CoAP requests directed to an IoT device on the Itron network require specifying the Gateway as a CoAP proxy. Thus you must include proxyHost and proxyPort. The proxy options in the request below are standard.

{
  "proxyHost": "api.coap-staging.developer.ssni.com",
  "proxyPort": "5683",
  "clientPort": "6000",
  "method" : "GET",
  "timeout": "1000",
  "clientId": "<clientId>",
  "clientSecret": "<clientSecret>",
  "devices": [
    {
      "deviceId": "<deviceId>",
      "deviceHost": "SSN<macAddress>.SG.YEL01.SSN.SSNSGS.NET",
      "devicePort": "4849",
      "devicePath": "/sensor/arduino/temp",
      "deviceQuery": "sens"
    }
  ]
}

You will need to obtain and fill in the following four items (same procedure as used for the HDK Ping above):

  • clientId - use the same clientId used to get a Gateway Session (see above)
  • clientSecret - use the same clientSecretused to get a Gateway Session (see above)
  • deviceId - use the Itron devices API to get details on your HDK (see below)
  • macAddress - use the Itron devices API to get details on your HDK (see below)

 

NOTE: if your Milli device has firmware build 1.2.1000.117958 or later devicepath in the above example should be changed to "/snsr/arduino/temp".

 

How it Works

Save the above request json in a request file and name it get_hdk_sensor.json. Pass the file to the Java CoAP Client as follows:

java -jar C:\tools\sdkcoapclient-1.0.0-SNAPSHOT.one-jar.jar  --conf get_hdk_sensor.json

 

The Java CoAP Client will form a CoAP Request and send it to the proxy (in this case the Gateway). The Gateway will do an authorization check to make sure you can access the device specified by the deviceHost option. Once validated, the Gateway will proxy the CoAP request to the Milli shield. The CoAP proxy in the Milli shield routes the resource "/sensor/arduino/temp" (or "/snsr/arduino/temp" for firmware versions 1.2.1000.117958 or later) to the CoAP server running in the Arduino. The Arduino CoAP server handshakes with the sensor and forms a CoAP response which is proxied by the Milli back to the Gateway which forwards the response to the Java CoAP Client that made the request

 

Request and Response Headers

These are the CoAP headers and responses you can expect when doing a Get on a sensor:

 

DEBUG | Finished transmission #2: [Header: (V) 1, (T) CON (0), (TKL) 8, (C) GET (1), (ID) 52337 | (Token) 0xCCDB22EC5289B440 | Options: (No. 23) 3 (No. 35) coap://SSN001350050047dd3b.SG.YEL01.SSN.SSNSGS.NET:4849/ (No. 124) 0xCE358385 | Content: <no content>]
DEBUG | HANDLE INBOUND MESSAGE: [Header: (V) 1, (T) ACK (2), (TKL) 0, (C) EMPTY (0), (ID) 52337 | (Token) <EMPTY> | Options: | Content: <no content>]
INFO  | Received #: CoAP: [Header: (V) 1, (T) NON (1), (TKL) 8, (C) CONTENT (69), (ID) 65535 | (Token) 0xCCDB22EC5289B440 | Options: (No. 12) 0 | Content: SSNI MilliNIC CoAP s... ( 29 bytes)]
INFO  | ***Payload As String: <SSNI MilliNIC CoAP server 1.0>

 

  • The first line shows the CoAP request headers
  • The second line shows the CoAP response headers for the Gateway's empy ACK
  • The third line provides the CoAP response headers for the HDK tempurature sensor  response
  • The fourth line is a string dump of the payload.

 

Get Sensor Observations

Before proceeding with the following this section you must complete setting up the CoAP server temperature sensor on the Arduino.

Once you are able to successfuly read your sensors data, you may set up a CoAP observe. A CoAP observe request tells the CoAP server that "owns" the resource to push CoAP notifications with the sensor data as a payload to the CoAP client that originated the request. This is a get on the "/sensor/arduino/temp" resource (just like that used with Get of sensor data above) but with the observe header set. The "/sensor/arduino/temp" resource is served by the CoAP server running on the Arduino. The CoAP server running in the Arduino will post notification responses to the CoAP client.

Note that the Java CoAP Client will auomatically push sensor data received as observe notifcations to the Data Platform. You may use the Data Platform APIs to retrieve this data or use the sensor plotting application provided along with the example application to display the sensor data.

All CoAP requests directed to an IoT device on the Itron network require specifying the Gateway as a CoAP proxy. Thus you must include proxyHost and proxyPort. The proxy options in the request below are standard.

{
  "proxyHost": "api.coap-staging.developer.ssni.com",
  "proxyPort": "5683",
  "clientPort": "6000",
  "observe": "true",
  "maxNotifications": "5",
  "method" : "GET",
  "timeout": "1000",
  "clientId": "<clientId>",
  "clientSecret": "<clientSecret>",
  "devices": [
    {
      "deviceId": "<deviceId>",
      "deviceHost": "SSN<macAddress>.SG.YEL01.SSN.SSNSGS.NET",
      "devicePort": "4849",
      "devicePath": "/sensor/arduino/temp",
      "deviceQuery": "sens"
    }
  ]
}

You will need to obtain and fill in the following four items (same procedure as used for the HDK Ping above):

  • clientId - use the same clientId used to get a Gateway Session (see above)
  • clientSecret - use the same clientSecretused to get a Gateway Session (see above)
  • deviceId - use the Itron devices API to get details on your HDK (see below)
  • macAddress - use the Itron API to get details on your HDK (see below)

 

NOTE: if your Milli device has firmware build 1.2.1000.117958 or later devicepath in the above example should be changed to "/snsr/arduino/temp".

 

How it Works

Save the above request json in a request file and name it get_hdk_observe.json. Pass the file to the Java CoAP Client as follows:

java -jar C:\tools\sdkcoapclient-1.0.0-SNAPSHOT.one-jar.jar  --conf get_hdk_observe.json

 

The Java CoAP Client will form a CoAP Request and send it to the proxy (in this case the Gateway). The Gateway will do an authorization check to make sure you can access the device specified by the deviceHost option. Once validated, the Gateway will proxy the CoAP request to the Milli shield. The CoAP proxy in the Milli shield routes the resouce "/sensor/arduino/temp" to the CoAP server running in the Arduino. The Arduino CoAP server notes that an observe is being requested on the resource. It notes the originator of the request (in this case the Java CoAP Client).

Based on the sensor logic, at periodic intervals, the Arduino CoAP server will handshake with the sensor and form a CoAP notification response which is pushed  through the CoAP proxy in the Milli back to the Gateway which forwards the notification response to the Java CoAP Client that made the request

 

Request and Response Headers

These are the CoAP headers and responses you can expect when doing a Get on a sensor:

 

DEBUG | Finished transmission #2: [Header: (V) 1, (T) CON (0), (TKL) 8, (C) GET (1), (ID) 53929 | (Token) 0xD2A937E3332A1061 | Options: (No. 6) 0 (No. 23) 3 (No. 35) coap://SSN001350050047dc98.SG.YEL01.SSN.SSNSGS.NET:4849/sensor/arduino/temp?sens (No. 124) 0xCD862899 | Content: <no content>]
DEBUG | HANDLE INBOUND MESSAGE: [Header: (V) 1, (T) ACK (2), (TKL) 0, (C) EMPTY (0), (ID) 53929 | (Token) <EMPTY> | Options: | Content: <no content>]
INFO  | Notification #1: CoAP: [Header: (V) 1, (T) NON (1), (TKL) 8, (C) CONTENT (69), (ID) 51291 | (Token) 0xD2A937E3332A1061 | Options: (No. 6) 8960 | Content: <no content>]
INFO  | Notification #2: CoAP: [Header: (V) 1, (T) NON (1), (TKL) 8, (C) CONTENT (69), (ID) 51292 | (Token) 0xD2A937E3332A1061 | Options: (No. 6) 9216 (No. 12) 2 (No. 14) 1509949440 | Content: 946686720,59.00,F... ( 17 bytes)]
INFO  | ***Payload As String: <946686720,59.00,F>
INFO  | Notification #13: CoAP: [Header: (V) 1, (T) NON (1), (TKL) 8, (C) CONTENT (69), (ID) 51304 | (Token) 0xD2A937E3332A1061 | Options: (No. 6) 12800 (No. 12) 2 (No. 14) 1509949440 | Content: 946687140,62.60,F... ( 17 bytes)]
INFO  | ***Payload As String: <946687140,62.60,F>

 

  • The first line shows the CoAP request headers
  • The second line shows the CoAP response headers for the Gateway's empy ACK
  • The third line provides the CoAP response headers for first notification response (note the empty payload)
  • The fourth line provides the CoAP response headers for second notification response
  • The fifth line is a string dump of the payload
  • The sixth line provides the CoAP response headers for 13th second notification response
  • The seventh line is a string dump of the payload

 

Deleting a Gateway Session

To delete a gateway session, use the following request file:

{
  "clientPort": "6000",
  "method" : "DELETE",
  "timeout": "30",
  "devices": [
    {
      "deviceId": "gateway",
      "deviceHost": "api.coap-staging.developer.ssni.com",
      "devicePort": "5683",
      "devicePath": "/sessions"
    }
  ]
}

 

How it Works

Save the above request json in a request file and name it deletesession.json. Pass the file to the Java CoAP Client as follows:

java -jar C:\tools\sdkcoapclient-1.0.0-SNAPSHOT.one-jar.jar  --conf deletesession.json

 

In this case, the device we are accessing is the Gateway, thus the deviceHost option is set to the Gateway's host. Gateway resources are always on port 5683. The Gateway resource we are acessing is /sessions. Note the clientPort option is set to 6000. Make sure that you use the same clientPort you used when you established the session.

CoAP requests made after you delete a session will return an UNAUTHORIZED return status.

 

Handy Reference Material

 

Getting Device Details

The only way you can get details on your device (as you need the device Id and the mac address) is to use the Starfish Studio. Here is the process:

  • Open the Starfish Studio from the developer portal. You should autmatically be logged in. Click on the "API" tab. You'll see a list of Itron APi's.
  • Get an Itron token using the /tokens API. You'll need your clientId and ClientSecret.
  • Using the token determine the device ID. Expand the GET devices API seciton. Type 'sandbox' in the solutions field and paste the token retrieved in the previous step into the token field. Click on the Try It Out button. The results should look something like this:

 

Data Platform Devices API Output

 

  • Usually you will have two devices listed in the response. One for your access point and one for your HDK (deviceType will be MILLI). Determine the deviceID and mac address. Use these values in your request files as needed.

 

Java CoAP Client Options

Here is a summary of the Java CoAP Client command line options. Note that these options can be "rolled up" into a request file.

Option Name
Description
proxyHost
The IP address or hostname of a CoAP proxy. When using the client to communicate with Itron IoT devices you must always use the developer program CoAP proxy.
proxyPort
The port number of the CoAP proxy.
clientPort
The UDP listening port used by the client. Default is 6000.
method
The CoAP method (GET, PUT, POST, DELETE). Default is GET.
observe
Used in conjunction with the GET method. Include to establish an observe on a CoAP resource. Default is false.
maxNotifications
Sets a limit on how many observe notifications are read by the client. Default is 1. Note that after the client shuts down after maxNotifications have been received, the CoAP resources observe is not cancelled.
timeout
The time in seconds allowed for a response from a CoAP activity. If an observe has been established the client will shutdown on after the timeout has expired even if maxNotifications have not been received. It is up to the user to set the timeout value accordingly. Default is 1000 seconds.
clientId
Your Itron account client id.
clientSecret
Your Itron account client secret.
deviceId
Itron device Id for the Itron IoT device (HDK). Required when posting observation responses to the Itron Network Solutions Data Platform.
deviceHost
Host name for your Itron IoT device.
devicePort
UDP port of your devices CoAP server URI. Default is 4849.
devicePath
Path part of your devices CoAP server resource URI. Default is "/".
deviceQuery
Query part of your devices CoAP server resource URI (the stuff that follows the ?).