Updating to Openweathermap 3 and Json 7

I'm updating an older weather station project to the newer Openweathermap3.0 Onecall and JSON 7. The following code compiles but I get a Null reading on my LCD.

// Weather update //

void getWeather() {
  if (client.connect(servername, 80)) {
    client.println("GET /data/3.0/onecall/weather?id=" + apiKey + lat + lon + "&units=metric&APPID=");   // 3.0
    client.println("Host: api.openweathermap.org");
    client.println("User-Agent: ArduinoWiFi/1.1");
    client.println("Connection: close");
    client.println();
  } else {
    Serial.println("connection failed");
    Serial.println();
  }

  while (client.connected() && !client.available())
    delay(1);
  while (client.connected() || client.available()) {
    char c = client.read();
    result = result + c;
  }

  client.stop();
  result.replace('[', ' ');
  result.replace(']', ' ');

  char jsonArray[result.length() + 1];
  result.toCharArray(jsonArray, sizeof(jsonArray));
  jsonArray[result.length() + 1] = '\0';

  JsonDocument doc;

  DeserializationError error = deserializeJson(doc, jsonArray);

 if (error) {
  Serial.print("deserializeJson() failed: ");
  Serial.println(error.c_str());
  return;
}

bool weather_0_description = doc["weather"][0]["description"]; // true
bool main_temp = doc["main"]["temp"]; // true

//  const char* weather_0_main = doc["weather"][0]["description"];  // eg "Clouds"
//  float main_temp = doc["main"]["temp"];

  String weather = doc["weather"]["description"];  // eg "Clouds"
  int temperature = doc["main"]["temp"];

  Serial.println();
  Serial.println(weather);
  Serial.printf("Temp: %d°C\r\n", main_temp);

  display.clearDisplay();
  display.setCursor(0, 0);
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.print(weather);
  display.setCursor(0, 8);
  display.println();
  display.print(main_temp);
  display.print((char)247);
  display.print("C     ");

}

Welcome to the forum

Thank you for using code tags on your first post but please post your full sketch so that what you are doing can be seen in context

/* 
Jonathan Robson 2025 updated from 2023 OpenWeatherMap 2.5 to 3.0
Board: ESP32-WROOM-DA Module. Stuff that helped:
http://arduino-er.blogspot.com/2020/05/esp8266-nodemcu-get-current-weather.html (openweathermap + json)
https://how2electronics.com/internet-clock-esp32-lcd-display-ntp-client/ (readable time and date from NTP)
https://simple-circuit.com/arduino-gps-clock-local-time-neo-6m/ (Auto change to BST. With ChatGPT solution in the if statement)
https://randomnerdtutorials.com/esp32-dc-motor-l298n-motor-driver-control-speed-direction/ (L298)
https://arduinojson.org/v7/tutorial/deserialization/
 */

#include <WiFi.h>
#include <ArduinoJson.h> // 7.4.2
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <TimeLib.h>
#include "arduino_secrets.h"

#define time_GMT 0
#define time_BST 3600

const int waterOn = 14;    // Water valve
const int rainLED = 5;     // rain LED - red
const int tempLED = 4;     // temperature LED - blue
const int valveLED = 12;   // Valve LED - green
const int switchLED = 13;  // override switch

Adafruit_SSD1306 display(128, 64, &Wire, -1);

char ssid[] = SECRET_SSID;     //  network SSID CommunityFibre
char password[] = SECRET_PSW;  //  network PASSWORD CommunityFibre
//char ssid[] = SECRET_SSID1;     //  network SSID Devolo
//char password[] = SECRET_PSW1;  //  network PASSWORD Devolo
String apiKey = SECRET_APIKEY;  //  SECRET_APIKEY;
//String CityID = "2643741";      //  Penge, SE London
// String openweather_lat = "51.4147";     //  Penge, SE London
//String openweather_lon = "-0.0534";
String lat = "51.4147000";     //  lat/lon for Penge, SE London, on OpenweatherMap
String lon = "-0.0534000";

boolean updateWeather = true;
bool id = false;
WiFiClient client;
char servername[] = "api.openweathermap.org";
String result;

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");  // GMT

char Time[] = "TIME:00:00:00";
char Date[] = "DATE:00/00/2000";
byte last_second, second_, minute_, hour_, day_, month_;
int year_;

void setup() {

  pinMode(valveLED, OUTPUT);   // set the valve LED pin out so that its state can be read
  pinMode(rainLED, OUTPUT);    // set the rain LED pin out so that its state can be read
  pinMode(tempLED, OUTPUT);    // set the temp LED pin out so that its state can be read
  pinMode(waterOn, OUTPUT);    // set pin 14 as output to turn water on
  pinMode(switchLED, OUTPUT);  // valve override (catFlush) on pin 13

  Serial.begin(115200);
  Serial.print("Connecting to ");
  WiFi.mode(WIFI_STA);
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  delay(200);
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.print("Connecting.");
  display.display();
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    display.print(".");
    display.display();
  }

  Serial.println("");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Connected ");
  display.println("IP Address: ");
  display.println(WiFi.localIP());
  display.display();
  delay(1000);
  display.clearDisplay();

  timeClient.begin();
}

void loop()

{
  timeClient.update();

  // switch between GMT and BST time zones based on a condition
  int offset = time_GMT;              // set the default offset to GMT
  if (month_ >= 4 && month_ <= 10) {  // if April 1st to October 31st
    offset = time_BST;                // set the offset to BST
  }

  // apply the offset to the current time
  time_t adjustedTime = timeClient.getEpochTime() + offset;

  unsigned long unix_epoch = timeClient.getEpochTime() + offset;
  second_ = second(unix_epoch);
  if (last_second != second_) {

    minute_ = minute(unix_epoch);
    hour_ = hour(unix_epoch);
    day_ = day(unix_epoch);
    month_ = month(unix_epoch);
    year_ = year(unix_epoch);

    Time[12] = second_ % 10 + 48;
    Time[11] = second_ / 10 + 48;
    Time[9] = minute_ % 10 + 48;
    Time[8] = minute_ / 10 + 48;
    Time[6] = hour_ % 10 + 48;
    Time[5] = hour_ / 10 + 48;

    Date[5] = day_ / 10 + 48;
    Date[6] = day_ % 10 + 48;
    Date[8] = month_ / 10 + 48;
    Date[9] = month_ % 10 + 48;
    Date[13] = (year_ / 10) % 10 + 48;
    Date[14] = year_ % 10 % 10 + 48;

    Serial.println(Time);
    Serial.println(Date);

    display.setCursor(0, 46);
    display.setTextSize(1);
    display.println(Date);
    display.setCursor(0, 56);
    display.println(Time);
    last_second = second_;
    display.display();
  }

  // Get a weather update. Openweathermap 3.0 OneCall. Max 1,000 calls / 24 hrs //

 if ((minute_ == 0 && second_ == 20) || (minute_ == 20 && second_ == 20) || (minute_ == 40 && second_ == 20)) { //every 20 minutes
    updateWeather = true;
  }

  if (updateWeather == true) {
    getWeather();
    updateWeather = false;
  }

  // catFlush. Turn on watering to get neighbourhood cats out of the borders :-)

  while (digitalRead(switchLED) == HIGH) {  // read override switch LED state
    digitalWrite(waterOn, HIGH);            // turn it on
    digitalWrite(valveLED, HIGH);

    if (digitalRead(switchLED) == LOW) {  // turn it off
      digitalWrite(waterOn, LOW);
      digitalWrite(valveLED, LOW);
    }
  }

  // Spring watering schedule. April 1st to May 31st. //

  if ((month_ >= 4 && month_ <= 5) && hour_ == 18 && minute_ == 0 && second_ == 0) {  // if time 6pm 
    if (digitalRead(rainLED) == HIGH) {                                                // if it rained..
      digitalWrite(rainLED, LOW);                                                      // turn off rain LED
      delay(1000);
    }  else if (digitalRead(rainLED) == LOW) {  // if it didn't rain...
      digitalWrite(waterOn, HIGH);             // turn on valve
      digitalWrite(valveLED, HIGH);            // turn on valve LED
      delay(1000);
    }
  }

  if ((month_ >= 4 && month_ <= 5) && hour_ == 18 && minute_ == 5 && second_ == 0 && digitalRead(valveLED) == HIGH) {  // turn water off after 5 minutes
    digitalWrite(waterOn, LOW);
    digitalWrite(valveLED, LOW);
    delay(500);
  }

  // Summer watering schedule. June 1st to Sept 30th. //

  if ((month_ >= 6 && month_ <= 9) && hour_ == 18 && minute_ == 0 && second_ == 0) {  // if time 6pm
    if (digitalRead(rainLED) == HIGH) {                                               // if it rained..
      digitalWrite(rainLED, LOW);                                                     // turn off rain LED
      delay(1000);

    } else if (digitalRead(rainLED) == LOW) {  // if it didn't rain...
      digitalWrite(waterOn, HIGH);             // turn on valve
      digitalWrite(valveLED, HIGH);            // turn on valve LED
      delay(1000);
    }
  }

  if ((month_ >= 6 && month_ <= 9) && hour_ == 18 && minute_ == 10 && second_ == 0 && digitalRead(valveLED) == HIGH) {  // turn water off after 10 minutes
    digitalWrite(waterOn, LOW);
    digitalWrite(valveLED, LOW);
    delay(500);
  }

  // Winter1 watering schedule. Oct 1st to Dec 31st. //

  if (month_ >= 10 && hour_ == 16 && minute_ == 0 && second_ == 0) {  // if time 4pm

    if (digitalRead(rainLED) == LOW) {         // if it didn't rain...
      digitalWrite(waterOn, HIGH);             // turn on valve
      digitalWrite(valveLED, HIGH);            // turn on valve LED
      delay(1000);
    }
   
      else if (digitalRead(rainLED) == HIGH) {             // if it rained..
      digitalWrite(rainLED, LOW);                   // turn off rain LED
      delay(1000);
    }  

       else if (digitalRead(tempLED) == HIGH) {             // if it froze..
      digitalWrite(tempLED, LOW);                    // turn off temp LED
      delay(1000);
    }  
  }

  if (month_ >= 10 && hour_ == 16 && minute_ == 3 && second_ == 0 && digitalRead(valveLED) == HIGH) {  // turn water off after 3 minutes
    digitalWrite(waterOn, LOW);
    digitalWrite(valveLED, LOW);
    delay(500);
  }

// Winter2 watering schedule. Jan 1st to March 31st. //

  if (month_ <= 3 && hour_ == 16 && minute_ == 0 && second_ == 0) {  // if time 4pm

    if (digitalRead(rainLED) == LOW) {         // if it didn't rain...
      digitalWrite(waterOn, HIGH);             // turn on valve
      digitalWrite(valveLED, HIGH);            // turn on valve LED
      delay(1000);
    }

       else if (digitalRead(rainLED) == HIGH) {             // if it rained..
      digitalWrite(rainLED, LOW);                   // turn off rain LED
      delay(1000);
    }  

     else if (digitalRead(tempLED) == HIGH) {             // if it froze..
      digitalWrite(tempLED, LOW);                    // turn off temp LED
      delay(1000);
    }  
  }

  if (month_ <= 3 && hour_ == 16 && minute_ == 3 && second_ == 0 && digitalRead(valveLED) == HIGH) {  // turn water off after 3 minutes
    digitalWrite(waterOn, LOW);
    digitalWrite(valveLED, LOW);
    delay(500);
  }
}

// Weather update //

void getWeather() {
  if (client.connect(servername, 80)) {
    client.println("GET /data/3.0/onecall/weather?id=" + apiKey + lat + lon + "&units=metric&APPID=");   // 3.0
    client.println("Host: api.openweathermap.org");
    client.println("User-Agent: ArduinoWiFi/1.1");
    client.println("Connection: close");
    client.println();
  } else {
    Serial.println("connection failed");
    Serial.println();
  }

  while (client.connected() && !client.available())
    delay(1);
  while (client.connected() || client.available()) {
    char c = client.read();
    result = result + c;
  }

  client.stop();
  result.replace('[', ' ');
  result.replace(']', ' ');

  char jsonArray[result.length() + 1];
  result.toCharArray(jsonArray, sizeof(jsonArray));
  jsonArray[result.length() + 1] = '\0';

  JsonDocument doc;

  DeserializationError error = deserializeJson(doc, jsonArray);

 if (error) {
  Serial.print("deserializeJson() failed: ");
  Serial.println(error.c_str());
  return;
}

bool weather_0_description = doc["weather"][0]["description"]; // true
bool main_temp = doc["main"]["temp"]; // true

//  const char* weather_0_main = doc["weather"][0]["description"];  // eg "Clouds"
//  float main_temp = doc["main"]["temp"];

  String weather = doc["weather"]["description"];  // eg "Clouds"
  int temperature = doc["main"]["temp"];

  Serial.println();
  Serial.println(weather);
  Serial.printf("Temp: %d°C\r\n", main_temp);

  display.clearDisplay();
  display.setCursor(0, 0);
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.print(weather);
  display.setCursor(0, 8);
  display.println();
  display.print(main_temp);
  display.print((char)247);
  display.print("C     ");

  if (weather == "Rain") {        // if "Rain"...
    digitalWrite(rainLED, HIGH);  // turn on rain LED
  }
  if (temperature <= 0) {         // if temp 0°C or below...
    digitalWrite(tempLED, HIGH);  // turn on temp LED
  }
}

here I have a stripped down version of a openweather sketch

may be you want to try and compare.

I can get yours to run on my board using my key etc but I'm still getting a null response from openweathermap. This is what prints in the serial port:
summary:
current temp: 0.00
feels like: 0.00
pressure: 0
humidity: 0
wind speed: 0.00
main:
description:

Is it likely this is due to a problem with my API key?
Thanks

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.