How to read specific header from the response body (HttpClient)

Hello,

I tried to look for this answer, but I couldnā€™t find itā€¦
Maybe one of you guys can help me.

Iā€™m sending a ā€œGETā€ and I receive an answer. The answer includes few headers and I want to read specific header from it and write the value to new String or Int (if itā€™s a number).

In my code now, Iā€™m reading the answer and going to the 'nā€™s Char in the String and copy it to Char/transfer to Int. The problem starts when the size changed. Iā€™m looking for better waysā€¦

Thanks for the help,
Itay

Hello @itayd100,
If you share the code here, I can help!

Hey @marcus!

I thought itā€™s a general question and because of that I didnā€™t add the code.
I did air pollution station that takes the value from breezometer.com (Iā€™m going to share the project when ill finish)

Here is the code:

    String statusCode = raw_response.substring(43,45); //the place of the number.
    char tensC = raw_response.charAt(43+3); ///FIX the change in answer from USA(3) to Israel(6)
    char onesC = raw_response.charAt(44+3); ///FIX the change in answer from USA(3) to Israel(6)
    String color = raw_response.substring(43+3+27,44+3+27+5);
    Serial.println(color);

    String Tcolor;

     int Rcolor;
     int Gcolor;
     int Bcolor;
     int temp;

    char C_color;

    C_color = color[0];
    Rcolor = hexToDec(C_color,1);
    C_color = color[1];
    Rcolor = (hexToDec(C_color,0)) + Rcolor;
    Serial.println(Rcolor);

    C_color = color[2];
    Gcolor = hexToDec(C_color,1);
    C_color = color[3];
    Gcolor = (hexToDec(C_color,0)) + Gcolor;
    Serial.println(Gcolor);

    C_color = color[4];
    Bcolor = hexToDec(C_color,1);
    C_color = color[5];
    Bcolor = (hexToDec(C_color,0)) + Bcolor;
    Serial.println(Bcolor);

    //String num2c = raw_response.substring(44,45);
    int tensI = tensC - '0';
    int onesI = onesC - '0';
    int AQI = tensI*10+onesI;

and this is the answer I get from breezometer:

I want to get the value of the headers ā€œnicelyā€.

Thanks,
Itay


Iā€™ve edited your post to properly format the code. Please check out this post, so you know how to do this yourself in the future. Thanks in advance! ~Jordy

THanks @itayd100,
but this is only the formatting code, where is the code around the ā€˜getā€™ request?

@marcus you got it all :wink:


include "HttpClient/HttpClient.h"


iinclude "LiquidCrystal/LiquidCrystal.h"


String token = "--------------------------------------";

//button
int button = D6;

//LEDs
int RedLED = A3;
int GreenLED = A5;
int BlueLED = A6;

//parameters
int AQI;
String num1;

//libraries 
////LCD
LiquidCrystal lcd(D0, D1, D2, D3, D4, D5);
////HttpClient
HttpClient http;
http_header_t headers[] = {
    //  { "Content-Type", "application/json" },
    //  { "Accept" , "application/json" },
    { "Accept" , "*/*"},
    { NULL, NULL }
};

 http_request_t request;
 http_response_t response;

 //String search_on = String("\"breezometer_aqi\": ");//To check if a switch is pressed or not

void setup() {
  Serial.begin(9600);
  while(!Serial.available()) SPARK_WLAN_Loop();
  Serial.println("Hello!");

  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(3, 0);
  //lcd.print("Hello, Itay!");
  lcd.print("Breezometer");
  lcd.setCursor(3, 1);
  lcd.print("AQI Station");


  //PINs SET
  pinMode(RedLED, OUTPUT);
  pinMode(GreenLED, OUTPUT);
  pinMode(BlueLED, OUTPUT);
  pinMode(button, INPUT_PULLDOWN);
}

void loop() {

    //delay(5*1000); //cant establish http get after deep sleep or power on

    if (!digitalRead(button)) AQI_Check();

    //delay(20*1000);


}



void AQI_Check(){

    //reset the LEDS
    digitalWrite(RedLED, LOW);
    digitalWrite(GreenLED, LOW);
    digitalWrite(BlueLED, LOW);
    Serial.println("Asking Breezometer about the air pollution NOW ");
    Serial.println(AQI);

    lcd.clear();
    delay(500);

    lcd.setCursor(0, 0);
    lcd.print("Breezometer AQI:");


    //Serial.println("Application>\tStart of Loop.");
    request.hostname = "api-beta.breezometer.com";
    request.port = 80;

    request.path = "/baqi/?location=Tel+Aviv-Yafo&key=" + token ;



    // Get request
    http.get(request, response, headers);
    String raw_response(response.body);

    ////////changing the AQI in the response msg to int//////
    String statusCode = raw_response.substring(43,45); //the place of the number.
    char tensC = raw_response.charAt(43+3); ///FIX the change in answer from USA(3) to Israel(6)
    char onesC = raw_response.charAt(44+3); ///FIX the change in answer from USA(3) to Israel(6)
    String color = raw_response.substring(43+3+27,44+3+27+5);
    Serial.println(color);

    String Tcolor;

     int Rcolor;
     int Gcolor;
     int Bcolor;
     int temp;

    char C_color;

    C_color = color[0];
    Rcolor = hexToDec(C_color,1);
    C_color = color[1];
    Rcolor = (hexToDec(C_color,0)) + Rcolor;
    Serial.println(Rcolor);

    C_color = color[2];
    Gcolor = hexToDec(C_color,1);
    C_color = color[3];
    Gcolor = (hexToDec(C_color,0)) + Gcolor;
    Serial.println(Gcolor);

    C_color = color[4];
    Bcolor = hexToDec(C_color,1);
    C_color = color[5];
    Bcolor = (hexToDec(C_color,0)) + Bcolor;
    Serial.println(Bcolor);




    //String num2c = raw_response.substring(44,45);
    int tensI = tensC - '0';
    int onesI = onesC - '0';
    int AQI = tensI*10+onesI;
    //int Statei = atoi(State);
    //Serial.print("INT:");

    /////Write in Serial and LCD
    Serial.println("Breezometer AQI:");
    Serial.println(AQI);

    lcd.clear();
    delay(500);

    lcd.setCursor(0, 0);
    lcd.print("Breezometer AQI:");
    if (response.status==200){ //if the status is good write to the LCD
        Serial.println("response.status is GOOD");
        lcd.setCursor(7, 1);
        Serial.println(statusCode);
        lcd.print(AQI);
    }
    else  Serial.println("response.status is NOT good");



        analogWrite(RedLED, Rcolor);
        analogWrite(GreenLED, Gcolor);
        analogWrite(BlueLED, Bcolor);

    ///Trun ON the RGB LIGHT accordingly to the air pollution
    if (AQI>70){
        delay(3*1000);
        lcd.clear();
        lcd.setCursor(7, 0);
        lcd.print(AQI);
        lcd.setCursor(0, 1);
        lcd.print("Time To Go Out!");
    }
    else if (AQI>50){
        delay(3*1000);
        lcd.clear();
        lcd.setCursor(7, 0);
        lcd.print(AQI);
        lcd.setCursor(3, 1);
        lcd.print("Comsi Comsa");

    }

    else {
        delay(3*1000);
        lcd.clear();
        lcd.setCursor(7, 0);
        lcd.print(AQI);
        lcd.setCursor(0, 1);
        lcd.print("Stay Home...");



    }


    //Serial.print("Application>\tResponse status: ");
    //Serial.println(response.status);

    //Serial.print("Application>\tHTTP Response Body: ");
    //Serial.println(response.body); 


}



int hexToDec(char hexString,int x) {

  int decValue = 0;
  int tempvalue =0;

  if ((hexString != 'A') && (hexString != 'B') && (hexString != 'C') && (hexString != 'D') && (hexString != 'E') && (hexString != 'F')){

      int tempvalue = hexString - '0';
      if (x==1){
        decValue=tempvalue *16;
      } else {
          decValue=tempvalue + decValue;
      }
    }

    else {
        if (hexString == 'A'){
        tempvalue=10; } 
        if (hexString == 'B'){
          tempvalue=11; }
        if (hexString == 'C'){
          tempvalue=12; } 
        if (hexString == 'D'){
          tempvalue=13; } 
        if (hexString == 'E'){
        tempvalue=14; }
        if (hexString == 'F'){
          tempvalue=15; } 

        if (x==1){
        decValue=tempvalue *16;
      } else {
          decValue=tempvalue + decValue;
        }
    }

return decValue;
}

Iā€™ve edited your post to properly format the code. Please check out this post, so you know how to do this yourself in the future. Thanks in advance! ~Jordy

@itayd100, unless Iā€™m mistaken, the response from ā€œapi-beta.breezometer.comā€ seems to be in JSON compatible format. You could use a webhook coupled with the new JSON parsing feature to get only the fields you need. So no httpClient and less parsing! :smile:

1 Like

OK, thank you for your answer.

Iā€™ll keep it like that for now and share it.

1 Like

Just getting it to work on my sparkā€¦

Hmm, It will not work on my end either. I edited the HttpClient.cpp file added:

#include "application.h" 

at the beginning, so it compiled. I replaced the url api-beta.breezometer.com" with their ip address.

    IPAddress ipBreezometer = {192,185,35,154}; //api-beta ip
    request.ip= ipBreezometer;

That helped, I now have a connectionā€¦ but with a 404 response. That makes sense, we need the port number of the ā€˜api-betaā€™. I did this just to test the connection.
So, I have a DNS error when connecting from the spark, not from browser. If anyone has a good advice, let me know.
And like @peekay123 mentioned, the response is a JSON array. Without going in this to deep, you can filter your wanted data with substring, but that is denagerous, there is no garanty the data is all ways at the same location, better is it to use ā€˜indexOf()ā€™ to find the start location and end locations, and than substring. You can implement it like this:

//This is an example: not tested or compiled
int start = str.IndexOf("name:") + 5; //5= len 'name:'  name should be 
                                         //replaced with an actual
int end = str.IndexOf("nextname:") // existing field name
String number = str.subString(start,end-start);

Succes!

2 Likes

@marcus thanks for the answer!