Webhook widget

It’s off to a bad start :smile:

09:35:22.516 -> ........................................................................
09:37:02.384 -> WiFi connected
09:37:02.384 -> IP address: 
09:37:02.384 -> 192.168.0.19
09:37:02.384 -> Waiting for NTP time sync: .
09:37:02.901 -> Current time: Mon Jun 21 07:37:03 2021
09:37:02.901 -> Connecting to https://fra1.blynk.cloud/external/api/get?token=xxxxxxxxx&v1
09:37:02.901 -> Using certificate: 
09:37:02.901 -> -----BEGIN CERTIFICATE-----
09:37:02.901 -> MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
09:37:02.901 -> EwJSMzAeFw0yMTA1MjUxMTQ5NDBaFw0yMTA4MjMxMTQ5NDBaMBYxFDASBgNVBAMT
09:37:02.901 -> 9ZJZBE/67xMbhoaIwUAkhZEZuVa2+V+AJSBWceWb4HiwRr0ZOBLC/Iv6m1Zhdxc/
09:37:02.949 -> aLLsEdgAwgAxvHGLrE/e/7Woy+HwtHJClagQxPZ2eCGw/SYOkE2X2aoACG1oESUl
09:37:02.949 -> dELwDAuRe0TNX59/0DIdIhfbl5rGGYgyEElzDMYvS+n9IJjc/ntE/Sa0CGgUvxDH
09:37:02.949 -> X4h1oWGnqbxfZK2vAEwSnhIJ2gaBe4UVDxiPW1doRFO/y3HJz3yu0Epkj6miE4r6
09:37:02.949 -> 1NeoSQwgwR0LfqN3t2Fq0Lefd8BpxQiMbTpfaPx2lRGC3ARRXdN29jAtajkWvdOx
09:37:02.949 -> nI7pPvPKB+kUYbS1hQIDAQABo4ICRjCCAkIwDgYDVR0PAQH/BAQDAgWgMB0GA1Ud
09:37:02.949 -> BBRucogk1UO/72z0nb5/Jf9EWIfUnjAfBgNVHSMEGDAWgBQULrMXt1hWy65QCUDm
09:37:02.949 -> H6+dixTCxjBVBggrBgEFBQcBAQRJMEcwIQYIKwYBBQUHMAGGFWh0dHA6Ly9yMy5v
09:37:02.949 -> LmxlbmNyLm9yZzAiBggrBgEFBQcwAoYWaHR0cDovL3IzLmkubGVuY3Iub3JnLzAW
09:37:02.996 -> Lm9yZzCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB2AH0+8viP/4hVaCTCwMqeUol5
09:37:02.996 -> K8UOeAl/LmqXaJl+IvDXAAABeaOS13AAAAQDAEcwRQIgcjIVZTZ5USA11qpACq1k
09:37:02.996 -> bfuH4MRVlsNJqCROUsdZD4kCIQCRNuHwisa4DnhiaFh/8Ozft2fNazLCtW6nIw7j
09:37:02.996 -> IGWZzQB2AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kTAAABeaOS2JkA
09:37:02.996 -> AAQDAEcwRQIhAL7lJHCRAG6KmmmLKLx+PvjxriKyJoU+19kzRpCAS0bCAiBobP+/
09:37:02.996 -> S0Nx4qbDFGgJSE/qPRa+0j98z/iQ9OG2n51nQjANBgkqhkiG9w0BAQsFAAOCAQEA
09:37:03.042 -> -----END CERTIFICATE-----
09:37:03.042 -> 
09:37:10.074 -> Connection failed

to be continue :smile:

You can use http, not https.

1 Like

that works well !!!

11:01:33.496 → Code : 200
11:01:33.496 → API : 11:1:33
11:01:34.296 → Current time: 11:1:34 21 6 2021
11:01:35.320 → Current time: 11:1:35 21 6 2021
11:01:36.324 → Current time: 11:1:36 21 6 2021

But https is better as it is secured :slight_smile:

Yes but it does not work read my previous post :stuck_out_tongue_winking_eye:

Only @vshymanskyy could know why

1 Like

Okay, I’ve been doing some testing this afternoon.

I’ve been using an ESP32 and the HTTPClient.h library. I’ve not tested with an ESP8266 and the ESP8266HTTPClient.h library, but I wouldn’t expect the results to be much different.

I’ve managed to use the HTTPS API call with both the BlynkSimpleEsp32.h and BlynkSimpleEsp32_SSL.h libraries, however, the response times from the HTTPS API call are much longer than when using the HTTP API call. I guess this is what was causing @Blynk_Coeur’s -5 error, and I have seen this and a -1 error when I’ve been testing.

Response times with the HTTPS API are usually around the 2.5 second mark, but I’ve seen some as high as 46.561 seconds in testing!

HTTP response times are generally around 70ms, so I’d say that using the HTTP API url is the preferred option.

Here’s my test code, with the HTTP url…

#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "REDACTED"  
#define BLYNK_DEVICE_NAME "REDACTED"
#include <BlynkSimpleEsp32_SSL.h>
#include <HTTPClient.h>

char auth[] = "REDACTED"; // Auth token for this device
char ssid[] = "REDACTED";
char pass[] = "REDACTED";

String server_name = "http://fra1.blynk.cloud/external/api/"; // <<< SEE COMMENTS

String bridge_token_1 = "REDACTED"; // token for the receiving device

float temperature = 10.0; // Used for testing, will be incremented in the "push_some_data" function

BlynkTimer timer;

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

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


void push_some_data()
{
  api_bridge(bridge_token_1,3,temperature); // Token for receiving device, virtual pin number, value to send

  // Increment the temperature value to simulate changing data...  
  temperature = temperature + 0.3;
  if (temperature >= 50)
  {
    temperature = 10.0;
  }
}


void api_bridge(String token, int virtual_pin, float value_to_send)
{
  HTTPClient http;

  String server_path = server_name + "update?token=" + token + "&pin=v" + String(virtual_pin) + "&value=" +  float(value_to_send);

  // Your Domain name with URL path or IP address with path
  http.begin(server_path.c_str());
  
  // Send HTTP GET request
  Serial.print("Sending ");
  Serial.print(value_to_send);
  Serial.print(" to pin V");
  Serial.println(virtual_pin); 
  
  long request_time = millis();
  int httpResponseCode = http.GET();
  
  if (httpResponseCode>0)
  {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    String payload = http.getString();
  }
  else
  {
    Serial.print("Error code: ");
    Serial.print(httpResponseCode);
    Serial.print(" <-----------------------------------");    
  }
 
  Serial.print("Response time = ");
  Serial.print(millis() - request_time);
  Serial.println(" milliseconds");
  Serial.println(); 
  
  // Free resources
  http.end();
}

Note that the server declared here (Line 11):

String server_name = "http://fra1.blynk.cloud/external/api/"; // <<< SEE COMMENTS

will need to be changed depending on which Blynk cloud server your project sits on. The server is shown in the bottom right hand corner of your web portal:

image

Mine is fra1, but the options are currently:

fra1 – Frankfurt
lon1 – London
ny3 – New York
sgp1 – Singapore
blr1 – Bangalore

Don’t forget that your receiving device needs to have a datastream set up for the virtual pin that you’re sending the data to, and it needs to have the correct data type and suitable min-max values.

As you’ll see, the void push_some_data() function increments the temperature variable and sends it to the void api_bridge() function every 10 seconds. You’d replace this with whatever code you currently use to take sensor readings.

Hope this helps.

Pete.

3 Likes

I was working on the bridge function, but yours is the most successful, I will use it. :stuck_out_tongue_winking_eye:

1 Like

Thank you @PeteKnight :stuck_out_tongue_winking_eye:

For those who want to use an ESP8266 , I tested :

#include <BlynkSimpleEsp8266.h>
#include <ESP8266HTTPClient.h>

void api_bridge(String token, int virtual_pin, float value_to_send)
{
WiFiClient client;
http.begin(client,server_path.c_str());
2 Likes

Great, thanks for trying that, and I’m glad to hear its working.

I guess the next thing for someone to try is making multiple api_bridge calls one after another to send temperature, humidity etc data to different pins and see how it coped with doing that.
Once its working reliably then all the serial print stuff can be ripped out.

Pete.

1 Like

Blynkers.

I’m moving my old Blynk sketches and devices to Blynk 2.0. The loss of the Bridge and Webhook widgets slowed me down, initially.

Thanks to @PeteKnight for the nudge. Thanks to @Blynk_Coeur for a code snippet that got me going.

Helpful Blynk doc for both GET and UPDATE are also cited in the sketches.

Two routines follow, both written for ESP32. (ESP8266 mods are small, but I didn’t want to complicate.)
• getBlynkDatastreamInfo - get data from another datastream (read from)
• updateBlynkDatastreamInfo - update data in another datastream (write to)

getBlynkDatastreamInfo
This sketch gets or pulls the current value from a remote Blynk datastream on another device. The sketch, below, is written as a float function, delivering a float value. It returns a value of -123.45 (or whatever you set it as) on an error.

updateBlynkDatastreamInfo
This sketch updates or pushes a value to a remote Blynk datastream on another device. The sketch is written as a Boolean function, returning true or false on success.

For both routines…
Parameters

  • BlynkAuthcode of the remote device you are getting data from or updating data to.
  • Datastream number (Virtual pin) you are getting data from or updating data to
  • Value ( updateBlynkDatastreamInfo only ) is the value to update the datastream with

#includes

  • On ESP32, all we need is the usual Blynk #includes PLUS #include <HTTPClient.h>

#defines

  • #define HTTP_CODE_OK 200 // Good HTTP return code for code clarity

Timing

  • I timed the HTTP.GETs using millis() as in @PeteKnight 's sketch, above.
    Mine came in at 900-1000 ms, mixing gets and updates to and from multiple devices using this code.
    (I get very similar timing when POSTing to IFTTT using my previously posted code.)

Comments
This code over-uses Strings for clarity. Feel free to simplify.
This code over-uses Serial.prints, as well. Helps me keep sane.
I use the general blynk.cloud domain without issues.
I tried both Content types for the HTTP GETs: “text/plain”,
and “application/x-www-form-urlencoded”. Both work. No noted change in elapsed runtimes.

I have also posted these sketches on my github
https://github.com/thorathome/Blynk_Examples

Hope this helps the cause.
All comments welcome.

I upgraded to Blynk PLUS. Please keep the pace of improvements high. Thanks.

#include <HTTPClient.h>
#define HTTP_CODE_OK 200  // Good HTTP return code


// https://docs.blynk.io/en/blynk.cloud/get-datastream-value
float getBlynkDatastreamInfo ( const String& BlynkAuthcode, int datastream ) 
{
  // String BlynkAuthcode = Blynk authcode of device we are getting data FROM
  // int datastream = Blynk Datastream we are getting data FROM
  // example float value = getBlynkDatastreamInfo ( "authcode", V6 )
  //         if ( value == -123.45 ) Serial.println ( "Error" );  
  
  float returnedValue = -123.45; // default error value

  Serial.print ( "\ngetBlynkDatastreamInfo called on datastream V" ); Serial.print ( datastream ); 
  Serial.print (  " on device with authcode " ); Serial.println ( BlynkAuthcode ); 

  // Set up an HTTP client object for the Blynk get 
  HTTPClient getBlynkHTTPclient;  
  
  // Server name URL
  String BlynkGetServerName = "https://blynk.cloud/external/api/get";
  //String BlynkGetServerName = "https://ny3.blynk.cloud/external/api/get"; // Didn't find I needed this

  // Blynk's GET payload for getting data is "?token={token}&V8"
  String BlynkRequest = "?&token=" + String ( BlynkAuthcode ) + "&V" + String ( datastream ); 

  // Blynk datastream get uses GET and a single request string
  String fullRequest = BlynkGetServerName + BlynkRequest; 
  
  Serial.print ( "BlynkGetServerName <" ); Serial.print ( BlynkGetServerName ); Serial.println ( ">" ); 
  Serial.print ( "  BlynkRequest     <" ); Serial.print ( BlynkRequest ); Serial.println ( ">" ); 
  Serial.print ( "  fullRequest is   <" ); Serial.print ( fullRequest ); Serial.println ( ">" ); 

  getBlynkHTTPclient.begin ( fullRequest );  //Specify URL AND request

  getBlynkHTTPclient.addHeader ( "Content-Type", "text/plain" );
  //getBlynkHTTPclient.addHeader ( "Content-Type", "application/x-www-form-urlencoded" );
  
  long elapsed = millis();  
  
  int BlynkReturnCode = getBlynkHTTPclient.GET();     // POST the request to IFTTT
  Serial.print ( " elapsed time in ms = " ); Serial.println ( millis() - elapsed ); 

  Serial.print ( "  return code: " ); Serial.println ( BlynkReturnCode ); 

  if ( BlynkReturnCode > 0 ) //Check the returning code (200 is AOK)
  {
    String payload = getBlynkHTTPclient.getString();   //Get the request response payload
    Serial.print ( "  response string: " ); Serial.println ( payload );  

    if ( BlynkReturnCode == HTTP_CODE_OK )
    {
      returnedValue = payload.toFloat();   
      Serial.print ( "  Returning value: " ); Serial.println ( returnedValue ); Serial.println();  
    }
  }
  
  getBlynkHTTPclient.end();   //Close HTTP connection

  return returnedValue;
  
} // end getBlynkDatastreamInfo




// https://docs.blynk.io/en/blynk.cloud/update-datastream-value
bool updateBlynkDatastreamInfo ( const String& BlynkAuthcode, int datastream, float value ) 
{
  // String BlynkAuthcode = Blynk authcode of device we are writing TO
  // int datastream = Blynk Datastream we are writing TO
  // float value = value to write into external datastream
  // example if ( ! updateBlynkDatastreamInfo ( "authcode", V6, 267.8 ) ) Serial.println ( "Error" );

  bool returnCode; // = false on fail/true on success
  
  Serial.print ( "\nupdateBlynkDatastreamInfo called on datastream V" ); Serial.println ( datastream ); 
  Serial.print (  " on device with authcode " ); Serial.println ( BlynkAuthcode ); 
  Serial.print (  " with data " ); Serial.println ( value ); 
  
  // Set up an HTTP client object for the Blynk update 
  HTTPClient updateBlynkHTTPclient;  
  
  // Server name URL
  String BlynkUpdateServerName = "https://blynk.cloud/external/api/update";
  //String BlynkUpdateServerName = "https://ny3.blynk.cloud/external/api/update";  // Didn't find I needed this

  // Blynk's GET payload for an update is "?token={token}&dataStreamId={id}&value={value}"
  String BlynkRequest = "?token=" + BlynkAuthcode          // Authcode of device to be updated
                       + "&v"     + String ( datastream )  // Virtual pin to update
                       + "="      + String ( value );      // value to update

  // Blynk datastream update uses GET and a single request string
  String fullRequest = BlynkUpdateServerName + BlynkRequest; 
  
  Serial.print ( "BlynkUpdateServerName <" ); Serial.print ( BlynkUpdateServerName ); Serial.println ( ">" ); 
  Serial.print ( "  BlynkRequest        <" ); Serial.print ( BlynkRequest );          Serial.println ( ">" ); 
  Serial.print ( "  fullRequest    is   <" ); Serial.print ( fullRequest);            Serial.println ( ">" ); 

  long elapsed = millis();  
  updateBlynkHTTPclient.begin ( fullRequest );  // Blynk GET wants the URL AND request

  updateBlynkHTTPclient.addHeader ( "Content-Type", "text/plain" );
  //updateBlynkHTTPclient.addHeader ( "Content-Type", "application/x-www-form-urlencoded" );
  
  int BlynkReturnCode = updateBlynkHTTPclient.GET();         // use GET to send the update request to Blynk
  Serial.print ( " elapsed time in ms = " ); Serial.println ( millis() - elapsed ); 

  Serial.print ( "  return code: " ); Serial.println ( BlynkReturnCode ); 
  if ( BlynkReturnCode > 0 ) //Check the returning code (200 is AOK)
  {
    String payload = updateBlynkHTTPclient.getString();   //Get the request response payload
    Serial.print ( "  response string: " ); Serial.println ( payload );  
  }
  
  if ( BlynkReturnCode == HTTP_CODE_OK ) returnCode = true; else returnCode = false;
  return returnCode;  
  
} // end updateBlynkDatastreamInfo
5 Likes

I’m now seeing these ESP32 HTTPS GET calls taking up to 1.5 seconds to complete. I’m querying 6 sensors on 4 devices and it takes 9 seconds using the code I posted above. Seems excessive.

Any ideas?

Try to check ping to Blynk server. :thinking:

Pete.

In order to measure correctly, you need to remove all Serial.print parts and test without them. As they may affect the measuring.

HTTPS could be slow, but not that much. Usually it’s 4-10x slower than HTTP. For the low end hardware it could be much worth. It depends on the firmware + hardware part a lot.
So you need to experiment with HTTP as well and check the results. If you still see the huge latency, you’ll need to check ping blynk.cloud so we can be sure it’s not a far server problem.

Also, it depends on the TLS version is used. For example, TLSv1.3 is ~30% faster than TLSv1.2 as it has 1 request less during the handshake. Currently ESP firmware uses 1.2 version.

1 Like

Thanks for the helpful responses and suggestions. It’s the ESP32 HTTPS implementation that I have used - without root certificates - that takes all the time. I’ll try to figure out how to make it faster - all help welcome.

Good ol’ fashioned HTTP GETs are taking 50 ms. HTTPS GETs, as I’ve implemented, are taking 1500 ms. So I move back to HTTP and try to learn more.

Thanks, all.

Hm… interesting. @vshymanskyy do you know - is HTTPS expected to be so slow on ESP32?

Yes unfortunately creating a connection eats up a lot of time, but then it works quite fast (the data transfer/latency). That’s why you don’t experience lags with the Blynk protocol.

Hi @PeteKnight and Blynk_Coeur,

I see you apply API bridge method with static provisioning. Have you tested it with dinamic provisioning?
I can’t make it work. Not sure, but I guess it is because BlinkSimpleEsp8266.h has to be removed. Otherwise, using it with BlynkEdgent gives me compilation error.

Any idea how to bridge devices with dinamic provisioning?

I just used static provisioning because it was a simple way to do a quick test, no other reason.

I’d suggest you look at what that error is telling you, and fix the issues.

Pete.