JAVA | Cayenne REST API TUTORIAL

Hi again! This time I will make a tutorial in an actual programming language, Java.
Well, my code can look like a little tricky and complicated, but I didn’t wanted to use any external library, so this tutorial will be in vanilla Java, except for JSON library, you can make your own json parser, but you know im lazy. Making REST API calls would be easier with libraries like apache and gson to parse…
Hope you like it! (PD: Im not a Java expert so my code can be improved a lot, and I know there are lots of variables that you really don’t need, but I extracted the code directly from one of my projects.

LIBRARIES

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;

import org.json.JSONObject; (OPTIONAL)

GETTING AUTH TOKEN [POST]

Firstly, if we want to make any API call we need an auth token, which will be granted if we make a post call with our credentials.

URL: https://auth.mydevices.com/oauth/token
HEADERS: content-type value application/json
BODY: {"grant_type":"password","email":"YOUR EMAIL","password":"YOUR PASSWORD"}

This are our global variables:

public static final String AUTH_URL = "https://auth.mydevices.com/oauth/token";
public static final String AUTH_HEADER = "content-type";
public static final String AUTH_HEADER_VALUE = "application/json; charset=UTF-8";
public static final String AUTH_HELPER1 = "{\"grant_type\":\"password\",\"email\":\"";
public String cayenneEmail = "";
public static final String AUTH_HELPER2 = "\",\"password\":\"";
public String cayennePass = "";
public static final String AUTH_HELPER3 = "\"}";

The code:

String bodyConstructor = AUTH_HELPER1 + cayenneEmail + AUTH_HELPER2 + cayennePass + AUTH_HELPER3; //Makes the POST BODY
String rawToken = "";

try {
            URL url = new URL(AUTH_URL); //Creates and url object
			URLConnection con = url.openConnection(); 
			HttpURLConnection http = (HttpURLConnection)con; //Creates HttpURLConnection object from URL Object
			http.setRequestMethod("POST"); //Sets the method: POST, GET, PUT...
            http.setDoOutput(true); //Sets that we are sending a Body with the request

            byte[] out =  bodyConstructor .getBytes(StandardCharsets.UTF_8);
            int length = out.length;
            http.setFixedLengthStreamingMode(length);
			http.setRequestProperty(AUTH_HEADER, AUTH_HEADER_VALUE); //Sets Headers
            http.connect(); //Connects
            
            try {
                OutputStream os = http.getOutputStream();
                os.write(out); //Writes Body
            } catch (Exception e) {
                //Do something
            }

            rawToken = parseResponse(http.getInputStream(), "UTF-8"); //Parses the response
            http.disconnect(); //Disconnects
            JSONObject obj = new JSONObject(rawToken); //Creates a JSONObject Object
            rawToken = obj.getString("access_token"); //Finds Auth Token with access_token tag

        } catch (Exception e) {
            //Do something
        }

FUNCTION TO PARSE THE RESPONSE
PD: is not mine, i just googled how to parse InputStream responses (I have to learn more Java hehe).

public static String parseResponse(InputStream inputStream, String encoding) throws IOException {
        return readFully(inputStream).toString(encoding);
    }

    public static ByteArrayOutputStream readFully(InputStream inputStream) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length = 0;
        while ((length = inputStream.read(buffer)) != -1) {
            baos.write(buffer, 0, length);
        }
        return baos;
    }

GETTING SENSOR DATA [GET]

To get sensor’s data we need the Auth Token we got before and send a GET request to the API.

URL: https://platform.mydevices.com/v1.1/telemetry/DEVICE ID/sensors/SENSOR ID/summaries?type=latest
HEADERS: Authorization value Bearer AUTHTOKEN

This are our global variables:

public static final String DATA_URL = "https://platform.mydevices.com/v1.1/telemetry/";
public static final String DATA_HELPER1 = "/sensors/";
public static final String DATA_HELPER2 = "/summaries?type=";
public String DATA_SUMMARYTYPE = "latest";
public static final String DATA_HEADER = "Authorization";
public String DATA_HEADER_VALUE = "Bearer ";
public String deviceID = "";
public String sensorID = "";
public String authToken = "";

The code: (The explanation of code is the same as you saw before)

String urlConstructor = DATA_URL + deviceID + DATA_HELPER1 + sensorID + DATA_HELPER2 + DATA_SUMMARYTYPE;
DATA_HEADER_VALUE = "Bearer " + authToken;
String rawValue = "";

try {
            URL url2 = new URL(urlConstructor);
			URLConnection con2 = url2.openConnection();
			HttpURLConnection http2 = (HttpURLConnection)con2;
			http2.setRequestMethod("GET");
            http2.setRequestProperty(DATA_HEADER, DATA_HEADER_VALUE);
            http2.connect();

            try {

                rawValue = parseResponse2(http2.getInputStream(), "UTF-8");
                rawValue = rawValue.replace("[",""); //Just removing things to correctly parse the JSON
                rawValue = rawValue.replace("]","");
                JSONObject obj2 = new JSONObject(rawValue);
                http2.disconnect();
                rawValue = obj2.getString("v"); //Finds the sensor's value with v tag

            } catch (Exception e) {
                //Do something
            }
        } catch (Exception e) {
            //Do something
        }

The Function to parse the response is the same as before

SENDING DATA TO CAYENNE DASHBOARD / CONTROLLING AN ACTUATOR [POST]

To send data or cotrol an actuator you need the Auth Token we got before and send a POST request to the API.

URL: https://platform.mydevices.com/v1.1/things/DEVICE ID/cmd
HEADERS: Authorization value Bearer AUTHTOKEN and content-type value application/json; charset=UTF-8
BODY: {"channel":CHANNEL,"value":VALUE}

This are our global variables:

public static final String ACTU_URL = "https://platform.mydevices.com/v1.1/things/";
public static final String ACTU_HELPER1 = "/cmd";
public static final String BODY_ACTU_HELPER1 = "{\"channel\":";
public static final String BODY_ACTU_HELPER2 = ",\"value\":";
public static final String BODY_ACTU_HELPER3 = "}";
public static final String ACTU_HEADER = "Authorization";
public String ACTU_HEADER_VALUE = "Bearer ";
public static final String ACTU_HEADER2 = "content-type";
public static final String ACTU_HEADER_VALUE2 = "application/json; charset=UTF-8";

The code: (The explanation of code is the same as you saw before)

String ACTU_bodyConstructor = BODY_ACTU_HELPER1 + Channel + BODY_ACTU_HELPER2 + Value + BODY_ACTU_HELPER3; //Makes the POST BODY
String ACTU_urlConstructor = ACTU_URL + DeviceID + ACTU_HELPER1;
ACTU_HEADER_VALUE = "Bearer " + AuthToken;
String rawConfirm = "";

try {
        URL url3 = new URL(ACTU_urlConstructor);
        URLConnection con3 = url3.openConnection();
        HttpURLConnection http3 = (HttpURLConnection)con3;
        http3.setRequestMethod("POST");
        http3.setDoOutput(true);

        byte[] out3 =  ACTU_bodyConstructor .getBytes(StandardCharsets.UTF_8);
        int length3 = out3.length;
        http3.setFixedLengthStreamingMode(length3);
        http3.setRequestProperty(ACTU_HEADER, ACTU_HEADER_VALUE);
        http3.setRequestProperty(ACTU_HEADER2, ACTU_HEADER_VALUE2);
        http3.connect();
        
        try {
            OutputStream os3 = http3.getOutputStream();
            os3.write(out3);
        } catch (Exception e) {
            controlActuatorConfirm("[POST]ERROR WRITING DATA! : " + e);
        }
        rawConfirm = parseResponse(http3.getInputStream(), "UTF-8");
        http3.disconnect();
        JSONObject obj3 = new JSONObject(rawConfirm);
        rawConfirm = obj3.getString("success"); //Finds the success variable with success tag

    } catch (Exception e) {
        //Do something
    }

The Function to parse the response is the same as before

1 Like