Help with extraction of data from API response

Hi, I need some help with part of my project. It’s a 700W Solar panel sun tracking bed.
This project.has been up and running for 6 months but with problems, random off line events, random OTA update not responding.
I think the mathematical model tracking the sun has some unknown error and I have had enough looking for it. So I have found a workaround. Using webhooks and an API response from a website. https://app.ipgeolocation.io/

(The bit I need help with)
I need to save two results in two variables to use to compare the the panels actual angle.
The sun_altitude response and sun_azimuth response.

The API response is:

{“location”:{“latitude”:50.31962,“longitude”:-4.90284},“date”:“2020-09-30”,“current_time”:“08:23:34.557”,“sunrise”:“07:18”,“sunset”:“18:59”,“sun_status”:"-",“solar_noon”:“13:09”,“day_length”:“11:41”,“sun_altitude”:9.319119668392078,“sun_distance”:1.4981037116339523E8,“sun_azimuth”:106.34114510574415,“moonrise”:“19:02”,“moonset”:“05:23”,“moon_status”:"-",“moon_altitude”:-26.902708303098045,“moon_distance”:400770.9905656442,“moon_azimuth”:290.6823542744472,“moon_parallactic_angle”:30.750670872240985}

Hardware:
Custom tilting frame
Two 350W solar panels
Two linear actuators
Esp32
4 channel relay shield (opto isolated)
Two lm2596 DC to DC buck converter (one powers ESP32 the other the relays)
Triple-axis Accelerometer LSM303

Concept:
The LSM303 measures the tilt on the panels,

Using a Blynk local server.

A mathematical model calculated the sun’s path giving elevation and azimuth. (Not 100% reliable changing to a API response)

Compare the two and move the linear actuators accordingly.

Store power in 20x 110Ah batteries

Additional power source 8x fixed angle 350w solar panels.

1.5kw custom made wind turbine and blynk controled dump load.

8kw 24v to 240v inverter.

You need Json library to extract the data. :stuck_out_tongue_winking_eye:

Thanks for the response.
I am unable to locate the library quoted in the document.
Is it possible to use a webhook get to obtain the API response. If so how. Your help is greatly appreciated.

To access library, use manage library in ide menu and search for JSON
Yes you can use webhook

You have been a great help and im getting close.
A URL in webhook app is conected to V0
my code

#define BLYNK_PRINT Serial

#include <ArduinoJson.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
char auth[] = "*******************";
char ssid[] = "**************";
char pass[] = "**************";
BlynkTimer timer;  

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,120), 8080);
  delay (3000);
   int rssi = WiFi.RSSI() ; //get signal strenth in DB
 Blynk.virtualWrite(V51,rssi);
 Blynk.virtualWrite(V0, 1); //update for webhooks
 Serial.println("Booting");
 timer.setInterval(6000L, APIupdate);
}

void loop()
{
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
}

void APIupdate(){
   Blynk.virtualWrite(V0, 1); //update for webhooks
}

BLYNK_WRITE(V0){
  String webhookdata = param.asStr();
  Serial.println(webhookdata);

const size_t capacity = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(18) + 320;
DynamicJsonDocument doc(capacity);


//const char* json = "{\"location\":{\"latitude\":*****,\"longitude\":***********},\"date\":\"2020-09-30\",\"current_time\":\"19:06:46.27\",\"sunrise\":\"07:18\",\"sunset\":\"18:59\",\"sun_status\":\"-\",\"solar_noon\":\"13:09\",\"day_length\":\"11:41\",\"sun_altitude\":-2.0393480763745733,\"sun_distance\":149810371.16339526,\"sun_azimuth\":267.4597814448824,\"moonrise\":\"19:02\",\"moonset\":\"05:23\",\"moon_status\":\"-\",\"moon_altitude\":1.0738509355096701,\"moon_distance\":402084.5279459498,\"moon_azimuth\":100.76227521973334,\"moon_parallactic_angle\":-38.56220668133565}";
const char* json = "(webhookdata)";


deserializeJson(doc, json);

float location_latitude = doc["location"]["latitude"]; // **********
float location_longitude = doc["location"]["longitude"]; // ***********
const char* date = doc["date"]; // "2020-09-30"
const char* current_time = doc["current_time"]; // "19:06:46.27"
const char* sunrise = doc["sunrise"]; // "07:18"
const char* sunset = doc["sunset"]; // "18:59"
const char* sun_status = doc["sun_status"]; // "-"
const char* solar_noon = doc["solar_noon"]; // "13:09"
const char* day_length = doc["day_length"]; // "11:41"
float sun_altitude = doc["sun_altitude"]; // -2.0393480763745733
float sun_distance = doc["sun_distance"]; // 149810371.16339526
float sun_azimuth = doc["sun_azimuth"]; // 267.4597814448824
const char* moonrise = doc["moonrise"]; // "19:02"
const char* moonset = doc["moonset"]; // "05:23"
const char* moon_status = doc["moon_status"]; // "-"
float moon_altitude = doc["moon_altitude"]; // 1.0738509355096701
float moon_distance = doc["moon_distance"]; // 402084.5279459498
float moon_azimuth = doc["moon_azimuth"]; // 100.76227521973334
float moon_parallactic_angle = doc["moon_parallactic_angle"]; // -38.56220668133565
//this is the data i need
Serial.println(sun_altitude);
Serial.println(sun_azimuth);
}

serial data gives

{“location”:{“latitude”:50.31962,“longitude”:4.90284},“date”:“2020-10-01”,“current_time”:“18:14:06.706”,“sunrise”:“07:41”,“sunset”:“19:18”,“sun_status”:“-”,“solar_noon”:“13:29”,“day_length”:“11:37”,“sun_altitude”:9.159721065741726,“sun_distance”:1.4976747508724377E8,“sun_azimuth”:252.9900742689972,“moonrise”:“19:39”,“moonset”:“06:49”,“moon_status”:“-”,“moon_altitude”:-13.289035678181165,“moon_distance”:404222.30977818527,“moon_azimuth”:76.46545135056584,“moon_parallactic_angle”:-38.74063317622075}
0.00
0.00

Serial.println(sun_altitude);
Serial.println(sun_azimuth);

this should print returned results from API but only prints out 0.00 0.00
I dont know what to try next, and help would be great.

1 Like

What is the result for :
Serial.println(location_latitude)

in my code i just blanked out Lon and Lat.
i just added

Serial.println(location_latitude)

gives 0.00

So, it seems that json string is empty :thinking:

How do i populate the Json with the API data

Do you know how to use HTTPClient instead of webhook ?
For me, webhook never works :shushing_face:

Have no idea

I use this function for my forecast station :

HTTPClient http;  //Declare an object of class HTTPClient

    http.begin("http://api.openweathermap.org/data/2.5/weather?id=3032869&APPID=**key****&units=metric&lang=fr");  //Specify request destination

    int httpCode = http.GET();     //Send the request

    if (httpCode > 0) { //Check the returning code

      payload = http.getString();   //Get the request response payload
      }

    http.end();   //Close connection

The Json result is in payload string

don’t forget #include <ESP8266HTTPClient.h>

so replace

  String webhookdata = param.asStr();
  Serial.println(webhookdata);

const size_t capacity = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(18) + 320;
DynamicJsonDocument doc(capacity);

with you code and change

String webhookdata = param.asStr();

to

 String payload = param.asStr();

and add the ESP8266HTTPClient.h

1 Like

No, don’t use

String payload = param.asStr();

use

String payload = http.getString(); 

new code


#define BLYNK_PRINT Serial

#include <ArduinoJson.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#incluse <ESP8266HTTPClient.h>
char auth[] = "*****************";
char ssid[] = "******0";
char pass[] = "**************************";
BlynkTimer timer;  

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,120), 8080);
  delay (3000);
   int rssi = WiFi.RSSI() ; //get signal strenth in DB
 Blynk.virtualWrite(V51,rssi);
 Blynk.virtualWrite(V0, 1); //update for webhooks
 Serial.println("Booting");
 timer.setInterval(6000L, APIupdate);
}

void loop()
{
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
}

void APIupdate(){
   Blynk.virtualWrite(V0, 1); //update for webhooks
}

BLYNK_WRITE(V0){
  HTTPClient http;  //Declare an object of class HTTPClient

    http.begin("https://api.ipgeolocation.io/astronomy?apiKey=c5f0ed1688714f2eaa25a37a8c720912&lat=51.31962&long=-4.80284");  //Specify request destination

    int httpCode = http.GET();     //Send the request

    if (httpCode > 0) { //Check the returning code

      payload = http.getString();   //Get the request response payload
      }

    http.end();   //Close connection
  String payload = http.getString(); 
  Serial.println(payload);

const size_t capacity = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(18) + 320;
DynamicJsonDocument doc(capacity);


const char* json = "(payload)";


deserializeJson(doc, json);

float location_latitude = doc["location"]["latitude"]; // 
float location_longitude = doc["location"]["longitude"]; // 
const char* date = doc["date"]; // "2020-09-30"
const char* current_time = doc["current_time"]; // "19:06:46.27"
const char* sunrise = doc["sunrise"]; // "07:18"
const char* sunset = doc["sunset"]; // "18:59"
const char* sun_status = doc["sun_status"]; // "-"
const char* solar_noon = doc["solar_noon"]; // "13:09"
const char* day_length = doc["day_length"]; // "11:41"
float sun_altitude = doc["sun_altitude"]; // -2.0393480763745733
float sun_distance = doc["sun_distance"]; // 149810371.16339526
float sun_azimuth = doc["sun_azimuth"]; // 267.4597814448824
const char* moonrise = doc["moonrise"]; // "19:02"
const char* moonset = doc["moonset"]; // "05:23"
const char* moon_status = doc["moon_status"]; // "-"
float moon_altitude = doc["moon_altitude"]; // 1.0738509355096701
float moon_distance = doc["moon_distance"]; // 402084.5279459498
float moon_azimuth = doc["moon_azimuth"]; // 100.76227521973334
float moon_parallactic_angle = doc["moon_parallactic_angle"]; // -38.56220668133565
Serial.println(sun_altitude);
Serial.println(sun_azimuth);
Serial.println(location_latitude);
}

getting an error

ESP32_newCleanStart2HTTP:8:2: error: invalid preprocessing directive #incluse
#incluse <ESP8266HTTPClient.h>

You have to use ESP32HTTPClient instead of ESP8266HTTPClient

This should say include

Pete.

Yes but he has esp32 too.
So double mistake :joy:

opps typo, well spotted,
im having real problems finding the ESP32HTTPClient.h i have hunted guthub without any luck, any ideas?

Try #include <HTTPClient.h>
:wink: