Webhook ... Read all the documentation but still having issues

Hi guys

Running Arduino Uno + Wifi Shield here.
I have used Blynk for quite some time, no problems getting my hardware to connect and run multiple types of projects. But then there’s webhook … :slight_smile:

Here is my simple sketch:

#define BLYNK_PRINT Serial
#define BLYNK_MAX_READBYTES 1024
#include <BlynkSimpleWifi.h>

BlynkTimer timer;

char auth[] = "myBlynkKey";
char ssid[] = "myNetwork";
char pass[] = "myNetworkKey";

void setup()
{
 Serial.begin(9600);
 Blynk.begin(auth, ssid, pass);
 timer.setInterval(10000L, getWeather);
}

void loop()
{
  Blynk.run();
  timer.run();
  // Up to this point everything connects as expected and I can make multiple projects from here on that work well.
}

void getWeather()
{ 
 Blynk.virtualWrite(V0,1);
 Serial.println("TestPoint1"); // This prints OK every 10 seconds as expected
}

BLYNK_WRITE(V0)
{
   Serial.println("TestPoint2"); // This does not print
   String WebHook = param.asStr();
   Serial.println(WebHook); 
}

The Blynk documentation here says that “every time there is a “write” command to V0 pin (e.g. with Blynk.virtualWrite(V0, 1) from hardware or from app widget assigned to V0 ), BLYNK_WRITE(V0) construction will be triggered and processed.”

As you can see in the sketch, I am running a timer every 10 seconds to write the value 1 to port V0, but I do not experience the BLYNK_WRITE(V0) trigger the way I understood that Blynk describes it.
The function Serial.println(“TestPoint2”) never runs, which means the rest of it does not run either and everything I have configured on the webhook widget is irrelevant at this point.

Did I understand the instructions correctly?
Many thanks in advance!

@murilopicanco please edit your post, using the pencil icon at the bottom, and add triple backticks at the beginning and end of your code so that it displays correctly. Triple backticks look like this:
```

Pete.

Sincere apologies Pete! It’s edited now. I really did not know that.

I’m not sure where the Webhook widget comes in to this.

The behaviour you’re experiencing is intentional. It prevents your code going in to a continuous loop.

If you attached a widget (a switch for example) to V0 then changes to the switch in the app will trigger the BLYNK_WRITE(V0) callback function in your code.
A Blynk.VirtualWrite(V0) from your code won’t trigger the callback.

Maybe if you explained more about what it is that you’re trying to achieve then we’d be able to point you in the right direction.

Pete.

Hi Pete

The Webhook widget is connected to V0 on the the app side, and it contains a URL that I can successfully use on a browser and get a perfect response about the weather in my location.

The Blynk documentation states what I said about the use of virtualWrite and its relationship to BLYNK_WRITE, but I agree with you that it does not work hence I made this post.

In my code, instead of using a button that I press to send a value of 1 to the Webhook on V0, I built a timer that sends 1 to V0 every 10 seconds as you can see. But of course, since this does not trigger BLYNK_WRITE, even if the Webhook is sending the command to the URL correctly, I won’t be able to read the response.

Murilo

Okay, now that you’ve explained m,ore about where the webhook widget come in to the equation you can ignore my previous answer.

The BLYNK_WRITE(V0) callback in your code won’t be triggered by a Blynlk.virtualWrite(V0) from your code, but it will be triggered by a response from the weather service API.
My guess is that the app setup is incorrect, so you aren’t getting a response from the server.

I assume that the ** characters at the beginning and end of this line, and other lines in your code, are because you didn’t format your code correctly first time around?

Pete.

Hi Pete

You are correct about the use of **. They are not part of my code on the Arduino board.

So to summarise the code:

  • It writes a value of 1 to port V0 every 10 seconds (since the blynk documentation states that’s how to trigger a webhook.

  • Webhook widget connected to port V0 pointing to URL http://api.openweathermap.org/data/2.5/forecast?q=singapore,SG&cnt=3&appid=MYPERSONALKEY&units=metric and when I press the test button avaulable on the widget it return ‘test OK’

  • URL returns the expected values when I use a browser to test it

  • I do seem to be able to read the returned values and print them to serial as you see me trying in the code

  • I don’t understand how to trigger BLYNK_WRITE(V0) and cant find documentation that tells me to try anything else. All that blynk says is what I mentioned in my original post.

Murilo

Dear Pete

I believe my code is correct and this is the issue:

"#define BLYNK_MAX_READBYTES 1024. Where 1024` - is maximum allowed message size."

The response I am getting from my weather service is 1307 bytes, which exceeds the webhook limit. I tested the same code with another weather service that returns a smaller response and it works as expected.

This means that Blynk.virtualWrite(V0,1) does trigger the function BLYNK_WRITE(V0) as described in the Blynk documentation. And in my case, using a timer to run Blynk.virtualWrite(V0,1) every 10 seconds also works since it’s no different from pressing a button every 10 seconds for example.

Thanks for all your help. Case closed :slight_smile:

You beat me to it!
I just registered an openweathermap.org account and came to the same conclusion.

If you add a #define BLYNK_MAX_READBYTES 2048 line to your sketch does it work?

Pete.

I use openweathermap too, webhook isn’t needed at all.

this my snippet, I don’t know if it can help :thinking:

void forecast(){
    HTTPClient http;  //Declare an object of class HTTPClient
    http.begin("http://api.openweathermap.org/data/2.5/weather?id=YourId&APPID=YourKeyHere&   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
      JsonRequest();//call Json to decript weather
} 


void JsonRequest() {

  DynamicJsonDocument doc(976);
  deserializeJson(doc, payload);

  float coord_lon = doc["coord"]["lon"]; 
  float coord_lat = doc["coord"]["lat"];

  JsonObject weather_0 = doc["weather"][0];
  int weather_0_id = weather_0["id"]; 
  const char* weather_0_main = weather_0["main"];
  const char* weather_0_description = weather_0["description"]; 
  const char* weather_0_icon = weather_0["icon"]; 
  const char* base = doc["base"]; // "stations"


  JsonObject weather_1 = doc["weather"][1];
  int weather_1_id = weather_1["id"]; 
  const char* weather_1_description = weather_1["description"];

  JsonObject main = doc["main"];
  float main_temp = main["temp"]; 
  float main_feels_like = main["feels_like"];
  float main_temp_min = main["temp_min"]; 
  int main_temp_max = main["temp_max"]; 
  int main_pressure = main["pressure"];
  int main_humidity = main["humidity"]; 
  int visibility = doc["visibility"];
  float wind_speed = doc["wind"]["speed"];
  int wind_deg = doc["wind"]["deg"]; 
  int clouds_all = doc["clouds"]["all"]; 
  long dt = doc["dt"]; // 1587889504

  JsonObject sys = doc["sys"];
  int sys_type = sys["type"]; 
  int sys_id = sys["id"]; 
  const char* sys_country = sys["country"]; 

  char buff[32];

  long sys_sunrise = sys["sunrise"]; // 1587875670
  String Sunrise = String(hour(sys_sunrise))+ ":" +String(MyPrintDigits(minute(sys_sunrise)));
  sendToNextion(1, "home.Sunrise", Sunrise);

  long sys_sunset = sys["sunset"]; // 1587926436
  String Sunset = String(hour(sys_sunset))+ ":" + String(MyPrintDigits(minute(sys_sunset)));
  sendToNextion(1, "home.Sunset", Sunset);

  int timezone = doc["timezone"];
  long id = doc["id"]; 
  const char* name = doc["name"]; 
  int cod = doc["cod"];

  // temp Ext
  String T_Ext = String(main_temp);
  T_Ext = T_Ext.substring(0, 2);
  sendToNextion(1, "home.T_Ext", T_Ext);

  String D_Ext = String(main_temp);
  D_Ext = D_Ext.substring(2, 4);
  sendToNextion(1, "home.D_Ext", D_Ext);

  //Hum ext
  String H_Ext = String(main_humidity);
  sendToNextion(1, "home.H_Ext", H_Ext);
 
  String description = weather_0_description;
  sendToNextion(1, "home.weather_desc", description);
  setWeatherPicture(weather_0_id);
}
2 Likes

Hi @Pete

No it does not. It seems that 1024 is a hard coded maximum limit defined by Blynk for the webhook. If the response exceeds it, nothing comes through regardless of your sketch setup.

I need to find a free API based weather forecast service that returns up to 1024 bytes, if I am to avoid bringing all the code to the board itself similar to what @Blynk_Coeur posted.

The whole point of the webhook is to move most of that code from your microcontroller to the Blynk servers and keep your sketch small, but with a 1024 bytes limit it rules out several potential use cases.

1 Like

With openweather , less than 1024 bytes are required.

DynamicJsonDocument doc(976);
1 Like

@murilopicanco Hi may i know how to solve this issue. My serial monitor shows buffer overflow after I include the BLYNK_MAX_READBYTE. My sketch no issue just the openweathermap info doesnt print out.

Several solutions are mentioned above …

  1. don’t use the webhook at all, and use @Blynk_Coeur’S code in your sketch.

  2. use a weather service that returns a smaller data package such as openweather

Pete.

1 Like

@PeteKnight I am using openweather but the data couldn’t print out at my serial monitor.

Let us see your sketch and your serial monitor.
Else we can’t help you.

#define BLYNK_PRINT Serial

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>

char auth[] = "xxx";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxx";
char pass[] = "xxx";

// or Software Serial on Uno, Nano...
#include <SoftwareSerial.h>
SoftwareSerial EspSerial(2, 3); // RX, TX

// Your ESP8266 baud rate:
#define ESP8266_BAUD 9600

ESP8266 wifi(&EspSerial);

BLYNK_WRITE(V0)
{
  Serial.println("WebHook data:");
  Serial.println(param.asStr());
}

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

  // Set ESP8266 baud rate
  EspSerial.begin(ESP8266_BAUD);
  delay(10);

  Blynk.begin(auth, wifi, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, wifi, ssid, pass, "blynk.cloud", 80);
  //Blynk.begin(auth, wifi, ssid, pass, IPAddress(192,168,1,100), 8080);

  // You can perform HTTPS requests even if your hardware alone can't handle SSL
  // Blynk  can also fetch much bigger messages,
  // if hardware has enough RAM (set BLYNK_MAX_READBYTES to 4096)
  Blynk.virtualWrite(V0, "https://api.openweathermap.org/data/2.5/weather?id=xxx&appid=xxx");
}

void loop()
{
  Blynk.run();
}

@Blynk_Coeur @PeteKnight the API keys and auth token I key in correctly but the results still same

@Kyle_Gee please edit your post, using the pencil icon at the bottom, and add triple backticks at the beginning and end of your code so that it displays correctly.
Triple backticks look like this:
```

Pete.

You aren’t using openweather, you’re using openweathermap

Pete.

1 Like