Difference between IPv4/IPv6? no server connection with ESP32

Any attempt to contact the host

const char* host = "https://api.brightsky.dev/current_weather?lat=52&lon=7.6" 

with an ESP32 fails. However, if I use an ESP8266 processor, I can connect to this host. :confused:The author of brightsky has suggested that it could be because brightsky can be reached via IPv4 and IPv6. Here is the minimalist program for establishing a connection:

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
 
const char* ssid = "***";
const char* password = "***";

const char* host = "https://api.brightsky.dev/current_weather?lat=52&lon=7.6";
//const char* host = "www.howsmyssl.com"; //
   
int nowifi;

void setup()
{
  Serial.begin(115200);
   Serial.printf("\n\nCompiled from: %s at: %s %s", __FILE__, __DATE__, __TIME__);
   Serial.println("\nESP32_brightsky");
   
   WiFi.mode(WIFI_STA);
   WiFi.begin(ssid, password);

   Serial.println("connectet to WiFi");
   while (WiFi.status() != WL_CONNECTED) {
       delay(1000);
       nowifi++;
       Serial.print(nowifi);
        if(nowifi > 4) {
            ESP.restart();
        }
   }
   Serial.println("");
   Serial.println(WiFi.localIP());
   Serial.println(WiFi.RSSI());
}
 
void loop() {
   Serial.println("Connecting to " + String(host));
   WiFiClientSecure client;
   client.setInsecure();

   if (client.connect(host, 443)) {
     Serial.println("Successful connection!");
     while(true){yield(); delay(100);};
   } else {
     Serial.println("\nConnection to " + String(host) + " failed");
     while(true){yield(); delay(100);};
   }
   client.stop();
   delay(10000);
}

Unfortunately, I have no in-depth knowledge of network protocols.
Please take this into account in your answers.

The WiFiClientSecure object is basically a TLS client. Its “host” needs to be a pure hostname, aka "api.brightsky.dev". It would then connect to TCP port 443 and execute a TLS handshake. You would then need to construct the HTTP request to send over that connection, aka., GET /current_weather?lat=52&lon=7.6 and all the HTTP headers etc.

What you have with

is a URL, not a host.

What you seem to want is just a HTTPS client. But you’re using a pure TLS client (HTTPS = HTTP over TLS) instead. For that, you should be pairing the WiFiClientSecure class with the HTTPClient class. This will give you an HTTPS client.

Arduino-ESP32 has an example for this, see

(You can use setInsecure() instead of setCACert if you don’t care about verifying the secure connection.)

Just to prove my point. The following sketch outputs

Compiled from: src/main.cpp at: Jan 27 2024 16:19:31
ESP32_brightsky
connectet to WiFi
123
192.168.0.190
-37
Doing HTTP GET on https://api.brightsky.dev/current_weather?lat=52&lon=7.6
[HTTPS] begin...
[HTTPS] GET...
[HTTPS] GET... code: 200
GOT API RESPONSE
{"weather":{"source_id":238685,"timestamp":"2024-01-27T15:00:00+00:00","cloud_cover":25,"condition":"dry","dew_point":0.96,"solar_10":0.016,"solar_30":0.058,"solar_60":0.147,"precipitation_10":0.0,"precipitation_30":0.0,"precipitation_60":0.0,"pressure_msl":1035.7,"relative_humidity":64,"visibility":34047,"wind_direction_10":230,"wind_direction_30":230,"wind_direction_60":233,"wind_speed_10":13.0,"wind_speed_30":12.6,"wind_speed_60":14.8,"wind_gust_direction_10":240,"wind_gust_direction_30":240,"wind_gust_direction_60":240,"wind_gust_speed_10":18.4,"wind_gust_speed_30":18.4,"wind_gust_speed_60":27.7,"sunshine_30":30.0,"sunshine_60":60.0,"temperature":7.3,"fallback_source_ids":{},"icon":"partly-cloudy-day"},"sources":[{"id":238685,"dwd_station_id":"01766","observation_type":"synop","lat":52.1344,"lon":7.69686,"height":47.8,"station_name":"Muenster/Osnabrueck","wmo_station_id":"10315","first_record":"2024-01-26T08:30:00+00:00","last_record":"2024-01-27T15:00:00+00:00","distance":16364.0}]}

Waiting 10s before the next round...

With zero problems.

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>

const char *ssid = "*****";
const char *password = "*******";

const char *URL = "https://api.brightsky.dev/current_weather?lat=52&lon=7.6";

int nowifi;

void setup()
{
    Serial.begin(115200);
    Serial.printf("\n\nCompiled from: %s at: %s %s", __FILE__, __DATE__, __TIME__);
    Serial.println("\nESP32_brightsky");

    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);

    Serial.println("connectet to WiFi");
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(1000);
        nowifi++;
        Serial.print(nowifi);
        if (nowifi > 10)
        {
            ESP.restart();
        }
    }
    Serial.println("");
    Serial.println(WiFi.localIP());
    Serial.println(WiFi.RSSI());
}

void loop()
{
    Serial.println("Doing HTTP GET on " + String(URL));
    WiFiClientSecure *client = new WiFiClientSecure;
    if (client)
    {
        client->setInsecure();
        {
            // Add a scoping block for HTTPClient https to make sure it is destroyed before WiFiClientSecure *client is
            HTTPClient https;
            Serial.print("[HTTPS] begin...\n");
            if (https.begin(*client, URL))
            {
                Serial.print("[HTTPS] GET...\n");
                // start connection and send HTTP header
                int httpCode = https.GET();
                // httpCode will be negative on error
                if (httpCode > 0)
                {
                    // HTTP header has been send and Server response header has been handled
                    Serial.printf("[HTTPS] GET... code: %d\n", httpCode);

                    // file found at server
                    if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY)
                    {
                        String payload = https.getString();
                        Serial.println("GOT API RESPONSE");
                        Serial.println(payload);
                    }
                }
                else
                {
                    Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
                }
                https.end();
            }
            else
            {
                Serial.printf("[HTTPS] Unable to connect\n");
            }
            // End extra scoping block
        }

        delete client;
    }
    else
    {
        Serial.println("Unable to create client");
    }

    Serial.println();
    Serial.println("Waiting 10s before the next round...");
    delay(10000);
}

platformio.ini

[env:esp32dev]
platform = espressif32@6.5.0
board = esp32dev
framework = arduino
monitor_speed = 115200

maxgerhardt
chapeau! I am blown away by your explanation and example! Thank you very very much! I had to try your example immediately and - voila - it works perfectly.strong text

1 Like