Upcoming REST API Decommission

Hello,

Just received an email today about the intent to decomission the REST API integration with Cayenne on March 31/2020

If this is to be decommissioned, what is the best option for me to query temperature settings and remotely set relays on/off if I cannot do it through the REST API?

Thanks
Robert

I would seem to me that you could have a middle-ground between the teenager who will fiddle with his arduino for a few weeks (and get the free service), and the professional setting up monitoring on a chain of restaurants.

I’m guessing the REST-API users are 99% just fetching data to use or present in a more useful way than looking at the couple of graphs on the website or downloading a csv. And then once in a while sending a command to control something. All the REST-API functions for adding/listing rules, devices, users, … and all the fancy functionality of the OAuth system would get little use. That is for the middle-user, not the chain-of-restaurants user.

So perhaps you could charge a fee for just that – rather than pursue the corporate contract for a full system.

You can get nearly free databases from Amazon, Microsoft, Google or just set it all up on a $20 Raspberry PI and skip the internet entirely.

I don’t think I fit into the “chain of restaurants” model.

https://iotinabox.docs.apiary.io/#reference/history/list/get-paginated-history-that-returns-the-first-page-entries.

Hi @retovell,

You may still gather such information using the following API under this host: cayenne.mydevices.com. The authentication to obtain JWT tokens are the same as previous examples.

History/Telemetry API:

Get latest history for a sensor:
GET /cayenne/api/cayenneapi/history/{THING_ID}/{SENSOR_ID}?type=latest

curl --request GET \
  --url 'https://cayenne.mydevices.com/cayenne/api/cayenneapi/history/THING_ID/SENSOR_ID?type=latest' \
  --header 'authorization: Bearer JWT_TOKEN'

Query custom date range:
GET /cayenne/api/cayenneapi/history/{THING_ID}/{SENSOR_ID}?endDate={}&startDate={}&type=custom

Query params: endDate & startDate are in UTC milliseconds.

Looking into the command API for you and will provide updates.

Thanks

1 Like

Thanks for your comments @jameszahary, but the IoT in a Box is not just for restaurant use cases, its for a broader industry. Also, the IoT in a box is not compatible with Cayenne.

We will be bringing a lot of cool features from Cayenne to IoT in a Box.

Hi, I used REST API with ESP8266. Can you help me, how i need set the authentication now. In my code I have those credentials

// cayenne server names
const char cayaddr = “mqtt.mydevices.com”;
const char cayserver = “platform.mydevices.com”;
const char cayauthserver = “accounts.mydevices.com”;

those endpoints are not supported. you will have to use this.

Thansk for your answer. But I am amateur and I would like to asked you about help. We have solved this problem in the past ( Read data from Dashboard every 10 minutes), could you refer me to some example project?

Here is the example

I read it, but I need help with my code. Here is an important part of my example:

// your wifi name and password
const  char ssid[] = 
const  char wifipassword[] = 

// cayenne username and password for MQTT
const char cayusername[] = 
const char caypassword[] = 

// cayenne device name and sensor name
const  char cayclientID[] = 
const  char caycycles[] =   


// cayenne server names
const  char cayaddr[] =        "mqtt.mydevices.com";
const  char cayserver[] =      "platform.mydevices.com";
const  char cayauthserver[] =  "accounts.mydevices.com";

// cayenne username and password to access REST API
const char client_id[] =    
const char client_secret[] =
const char username[] =      
const char password[] =      

// the access token JWT for actual access
char access_token[1200] = "";
char refresh_token[700]  = "";


// get currect value of device and sensor, returned in global variables v, ts, unit, device_type
int rest_query_cayenne(const char caydev[], const char caysen[]);

//int rest_query_cayenne1(const char caydev[], const char caysen1[]);
// get a day of history of the device and sensor -- just print it out
//int rest_query_cayenne_day(const char caydev[], const char caysen[]);


void setup() {
  do_access_token();
}

void loop() {
  Cayenn();
  delay(60000);
}
void Cayenn() {
  if ( rest_query_cayenne( cayclientID,  caycycles) == 1) {
    temp = v;
    Serial.println("Temperature");
    Serial.print(temp, 1);
    Serial.println(" °C");
  } else {
    Serial.println("Couldn't access REST API");
  }
void do_access_token() {

  WiFiClientSecure cayclient;
  HTTPClient cayhttp;

  cayclient.setInsecure();

  if (cayclient.connect(cayauthserver, 443)) {

    if (cayhttp.begin(cayclient, "https://accounts.mydevices.com/auth/realms/cayenne/protocol/openid-connect/token")) {

      cayhttp.addHeader("Content-Type", "application/x-www-form-urlencoded");
      cayhttp.addHeader("cache-control", "no-cache");

      String body = "grant_type=password&client_id=" + String(client_id) + "&client_secret=" + String(client_secret) + "&username=" + String(username) + "&password=" + String(password) ;

      int httpCode = cayhttp.POST(body);

      if (httpCode > 0) {

        // HTTP header has been send and Server response header has been handled
        //Serial.printf("[HTTPS] POST... code: %d\n", httpCode);

        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {

          String payload = cayhttp.getString();
          //Serial.println(payload);

          DynamicJsonBuffer  jsonBuffer(2000);
          JsonObject& root = jsonBuffer.parseObject(payload);

          if (!root.success()) {
            Serial.println("parseObject failed");
            return ;

          } else {

            String at = root["access_token"];
            String rt = root["refresh_token"];

            Serial.println("access token =" + at);
            //Serial.println("");
            //Serial.println("refresh token =" + rt);

            at.toCharArray(access_token, 1200);
            rt.toCharArray(refresh_token, 700);

          }
        } else {
          Serial.printf("[HTTPS] POST... failed, error: %s\n", cayhttp.errorToString(httpCode).c_str());
        }
      }

      cayhttp.end();

    } else {
      Serial.printf("[HTTPS] Unable to connect\n");
    }
  } else {
    Serial.println("Cay Auth Server failed to connect");
  }
  cayclient.stop();
}

int rest_query_cayenne(const char caydev[], const char caysen[]) {

  WiFiClientSecure cayclient;
  HTTPClient cayhttp;

  cayclient.setInsecure();

  int ret = 0;

  if (!cayclient.connect(cayserver, 443)) {
    Serial.println("Cayserver failed to connect");
  } else {

    String get = "https://platform.mydevices.com/v1.1/telemetry/" + String(caydev) + "/sensors/" + String(caysen) + "/summaries?endDateLatest=true&type=latest";
    //Serial.println(get);

    if (cayhttp.begin(cayclient, get)) {

      cayhttp.addHeader("Authorization" , "Bearer " + String(access_token));

      int httpCode = cayhttp.GET();

      if (httpCode > 0) {

        //Serial.printf("[HTTPS] GET... code: %d\n", httpCode);

        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {

          String payload = cayhttp.getString();
          //Serial.println(payload);

          int payload_length = payload.length();
          //Serial.print("Payload length is "); Serial.println(payload_length);

          //  [{"v":"1526700604","ts":"2018-05-19T03:30:05.283Z","unit":"seconds","device_type":"analog"}]

          DynamicJsonBuffer  arrayBuffer(100);
          DynamicJsonBuffer  jsonBuffer(100);

          JsonArray& array = arrayBuffer.parseArray(payload, 2);

          int size = array.size();
          //Serial.print("Array Size is "); Serial.println(size);

          String onejson = array[0];
          JsonObject& root = jsonBuffer.parseObject(onejson);

          if (!root.success()) {
            Serial.println("parseObject failed");

          } else {
            double xv  = root["v"];
            String xts = root["ts"];
            String xdevice_type = root["device_type"];
            String xunit = root["unit"];

            v = xv;
            ts = xts;
            device_type = xdevice_type;
            unit = xunit;

            return 1;
          }
          jsonBuffer.clear();
        }

      } else {
        String payload = cayhttp.getString();
        Serial.println(httpCode);
        Serial.println(payload);
      }
    }
  }

  cayhttp.end();
  cayclient.stop();
}


int rest_query_cayenne_day(const char caydev[], const char caysen[]) {

  // results   v, ts, device, unit

  WiFiClientSecure cayclient;
  HTTPClient cayhttp;

  cayclient.setInsecure();

  int ret = 0;

  if (!cayclient.connect(cayserver, 443)) {
    Serial.println("Cayserver failed to connect");
  } else {

    String get = "https://platform.mydevices.com/v1.1/telemetry/" + String(caydev) + "/sensors/" + String(caysen) + "/summaries?endDateLatest=true&type=day";
    //Serial.println(get);

    if (cayhttp.begin(cayclient, get)) {

      cayhttp.addHeader("Authorization" , "Bearer " + String(access_token));

      int httpCode = cayhttp.GET();

      if (httpCode > 0) {

        //Serial.printf("[HTTPS] GET... code: %d\n", httpCode);

        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {

          String payload = cayhttp.getString();
          //Serial.println(payload);

          int payload_length = payload.length();
          Serial.print("Payload length is "); Serial.println(payload_length);

          //  [{"v":"1526700604","ts":"2018-05-19T03:30:05.283Z"},{"v":"1526700604","ts":"2018-05-19T03:30:05.283Z"}]

          DynamicJsonBuffer  arrayBuffer(500);
          DynamicJsonBuffer  jsonBuffer(100);

          JsonArray& array = arrayBuffer.parseArray(payload, 2);

          int size = array.size();
          Serial.print("Array Size is "); Serial.println(size);

          for (int ii = 0; ii < size; ii++ ) {

            String onejson = array[ii];
            JsonObject& root = jsonBuffer.parseObject(onejson);

            //Serial.print(ii); Serial.print(" >");  Serial.print(onejson); Serial.println("<");

            if (!root.success()) {
              Serial.println("parseObject failed");

            } else {
              double xv  = root["v"];
              String xts = root["ts"];
              Serial.print("index  "); Serial.print(ii);
              Serial.print("\t v      "); Serial.print(xv);
              Serial.print("\t ts     "); Serial.print(xts);
              Serial.println("");
              v = xv;
              ts = xts;
            }
          }
        }

      } else {
        String payload = cayhttp.getString();
        Serial.println(httpCode);
        Serial.println(payload);
      }
    }
  }
  cayhttp.end();
  cayclient.stop();
}

where did you get this code from?

I found it on the Internet in the past and modified it for my use, but I do not remember the source

1 Like

most of the code will be same to get the JWT token. you need to modify this:

with:

curl --request GET \
  --url 'https://cayenne.mydevices.com/cayenne/api/cayenneapi/history/THING_ID/SENSOR_ID?type=latest' \
  --header 'authorization: Bearer JWT_TOKEN'

Is It right?

String get = “https://cayenne.mydevices.com/cayenne/api/cayenneapi/history/THING_ID/SENSOR_ID?type=latest”;
if (cayhttp.begin(cayclient, get)) {
cayhttp.addHeader(“Authorization” , "Bearer JWT_TOKEN " + String(access_token));
int httpCode = cayhttp.GET();

you need to pass the value here

String get = “https://cayenne.mydevices.com/cayenne/api/cayenneapi/history/" + String(THING_ID )+ String(SENSOR_ID) + “?type=latest”

I don’t know where I’m making a mistake, but it doesn’t seem to work

did you make the changes i mentioned above. can you share the code.

if (!cayclient.connect(cayserver, 443)) {
Serial.println(“Cayserver failed to connect”);
} else {
String get = “https://cayenne.mydevices.com/cayenne/api/cayenneapi/history/” + String(caydev) + String(caysen) + “?type=latest”;
if (cayhttp.begin(cayclient, get)) {
cayhttp.addHeader(“Authorization” , "Bearer JWT_TOKEN " + String(access_token));
int httpCode = cayhttp.GET();

I apologize for stupid questions, but I’m a beginner. I read temperature data (ESP8266+DS18B20) and send to dashboard. With other ESP8266 I need read temperature from dashboard and display on OLED display ones per 10 minutes. During 10 minutes is ESP disconnected from dashboard and is reconnected every 10 minutes.

change

to:

"Bearer "

It has moved a bit, but it still does not work, the serial monitor displays:
Payload length is 2
Array Size is 0
parseObject failed
Couldn’t access REST API