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 discuss the use of the reference Java CoAP Client application.
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 request patterns. This client is command line based and requires command line options or a "conf" file that specifies the CoAP request. 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 developer program GitHub repo (see the Software References sidebar). The Java CoAP Client uses the nCoAP framework.
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.
The Java CoAP Client can be downloaded from the Itron Developer Portal Document Center (under IOT....Reference Applications....Java CoAP and MQTT Tools).
While the Java CoAP Client is a component of Itron's Reference Application suite, 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.
You can use the Java CoAP Client to access the Gateway API as well as send CoAP requests to a CoAP server running on an HDK (or your own hardware) application processor.
A few example CoAP requests are:
- Create a Gateway session
- Get a sensor reading
- Enable a sensor observation
- 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)
- Delete a Gateway session
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.6.one-jar.jar
Hardware Needed
You will need a laptop or desktop computer to run the Java CoAP client and a working internet connection.
REFERENCE RESOURCES
Prerequisites
- Install Oracle Java Platform, Standard Edition 8. The Java 8 runtime package and installation instructions are available from the Oracle Java website at http://www.oracle.com/technetwork/java/javase/overview/index.html. Don't forget to add the JAVA_HOME environment variable to your shell environment script and add the Java bin directory to your PATH environment variable.
- Install the sdkcoapclient (the Java CoAP Client). As noted above, The Java CoAP Client can be downloaded from the Itron Developer Portal Document Center (under IOT....Reference Applications....Java CoAP and MQTT Tools). We assume the jar file is place in hte
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.4.6.one-jar.jar --help
A list of all command options should be displayed.
Command Options and Request Configuration Files
Typically, many command options are required to carry out a CoAP request to a MIlli device or a CoAP server resource. You can include these options on the command line or incorporated them into a request configuration file. A request file is a json representation of the options. By defining a CoAP request in a request file, it is easy to script complex request patterns. A complete description of options is provided below. To reference a request configuration file, use the --conf option.
Create a Gateway Session
The first CoAP request you will always make is to get a Gateway session (you need to do this no matter what CoAP client you use). 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.itron.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.4.6.one-jar.jar --conf getsession.json
The Java CoAP Client will use your credentials to establish a Gateway session. First, the client will obtain an authentication token (using the Data Platform tokens API) based on your credentials.
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 idle timeout is ten hours). The Gateway tracks your session by using the CoAP Clients requesting IP (source IP) and the clientPort you specified. Thus, you can establish multiple sessions by giving 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 successfully gotten a session, the next thing you should do is to ping your HDK. This is just a get on the "/" resource. The "/" resource is served by the CoAP server that runs in the Milli NIC. It should return the version string for the Milli CoAP proxy. This is a great way to determine 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.itron.com", "proxyPort": "5683", "clientPort": "6000", "method" : "GET", "timeout": "330", "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.4.6.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 (based on your session credentials). Once validated, the Gateway will proxy the CoAP request to the Milli NIC. The CoAP proxy in the Milli NIC maps the resouce "/" to a handler which returns a 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 access point, CoAP requests can be lost. Both the access point 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. In these examples we use a timeout of 330 seconds (5.5 minutes).
However, when accessing Gateway resources (such as /sessions) a short timeout is sufficient (we use 30 seconds).
Request and Response Headers
These are the CoAP headers and responses you can expect when doing an HDK ping (taken from the Java CoAP Client logging output):
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 section you must complete setting up the Sensor API reference application on your HDK.
After a successful HDK ping, the next thing to do is to read the sensor data. This is just a GET on the "/snsr/arduino/temp" resource with a "sens" query string. The "/snsr/arduino/temp" resource is served by the CoAP server running on the application process (in this case the Adafruit Metro M0 Express). 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.itron.com", "proxyPort": "5683", "clientPort": "6000", "method" : "GET", "timeout": "330", "clientId": "<clientId>", "clientSecret": "<clientSecret>", "devices": [ { "deviceId": "<deviceId>", "deviceHost": "SSN<macAddress>.SG.YEL01.SSN.SSNSGS.NET", "devicePort": "4849", "devicePath": "/snsr/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)
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.4.6.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 request to the CoAP server running in the application process (based on the /snsr in the resource path). The Sensor API handles the request and handshakes with the sensor to form a CoAP response which is ultimatly forwarded by the Gateway to the Java CoAP Client.
Request and Response Headers
These are the CoAP headers and responses you can expect when doing a Get on a sensor:
INFO | CoapMessage to be encoded: [Header: (V) 1, (T) NON (1), (TKL) 8, (C) GET (1), (ID) 26168 | (Token) 0x6B4FC7C8CC16F378 | Options: (No. 23) 3 (No. 35) coap://SSN001350050047dc98.SG.YEL01.SSN.SSNSGS.NET:4849/snsr/arduino/temp?sens (No. 124) 0x7AFF68C1 | Content: <no content>]
INFO | Decoded Message: [Header: (V) 1, (T) NON (1), (TKL) 8, (C) CONTENT (69), (ID) 26168 | (Token) 0x6B4FC7C8CC16F378 | Options: (No. 12) 60 | Content: � dtempr1627683745,... ( 27 bytes)]
INFO | Received #: CoAP: [Header: (V) 1, (T) NON (1), (TKL) 8, (C) CONTENT (69), (ID) 26168 | (Token) 0x6B4FC7C8CC16F378 | Options: (No. 12) 60 | Content: � dtempr1627683745,... ( 27 bytes)]
DEBUG | CBOR Raw Temp Payload Hex: <a2006474656d700172313632373638333734352c38322e34302c46>
- The first line shows the CoAP request headers
- The second and third line shows 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 section you must complete setting up the Sensor API reference application on your HDK.
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 "/snsr/arduino/temp" resource (just like that used with Get of sensor data above) but with the observe header set. The "/snsr/arduino/temp" resource is served by the Sensor API package running on the application process of you HDK.
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.itron.com", "proxyPort": "5683", "clientPort": "6000", "observe": "true", "maxNotifications": "10", "method" : "GET", "timeout": "1000", "clientId": "<clientId>", "clientSecret": "<clientSecret>", "devices": [ { "deviceId": "<deviceId>", "deviceHost": "SSN<macAddress>.SG.YEL01.SSN.SSNSGS.NET", "devicePort": "4849", "devicePath": "/snsr/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)
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.4.6.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 request to the CoAP server running in the application process (based on the /snsr in the resource path). The Sensor API handles the request and registers the observe.
Based on Sensor API logic, at periodic intervals, Sensor API 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 configuration file:
{ "clientPort": "6000", "method" : "DELETE", "timeout": "30", "devices": [ { "deviceId": "gateway", "deviceHost": "api.coap-staging.developer.itron.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.4.6.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:
- 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
Following 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 data that follows the "?").
|