Serial.println("\n\nDisplay Meteo Online\n");
Serial.println("Connecting to network");
WiFi.begin(ssid, password);
int counter = 0;
while (WiFi.status() != WL_CONNECTED)
{
delay(200);
if (++counter > 100)
ESP.restart();
Serial.print( "." );
}
Serial.println("\nWiFi connected");
printWifiStatus();
}
void loop()
{
if (millis() - lastCallTime > postingInterval)
{
updateWeather();
}
}
void updateWeather()
{
// In caso di connessione stabilita
if (client.connect("api.openweathermap.org", 80))
{
Serial.println("Connessione al server OpenWeatherMap...");
// Invia la richiesta HTTP PUT:
client.println("GET /data/2.5/weather?q=" + NameOfCity + "&units=metric&APPID=" + APIKEY + "HTTP/1.1");
client.println("Host: api.openweathermap.org");
client.println("Connection: close");
client.println();
// Controlla lo stato HTTP
char status[32] = {0};
client.readBytesUntil('\r', status, sizeof(status));
// Dovrebbe essere "HTTP/1.0 200 OK" o "HTTP/1.1 200 OK"
if (strcmp(status + 9, "200 OK") != 0)
{
Serial.print(F("Unexpected response: "));
Serial.println(status);
return;
}
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!client.find(endOfHeaders))
{
Serial.println(F("Invalid response"));
return;
}
// Allocate the JSON document
// Use arduinojson.org/v6/assistant to compute the capacity.
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + 2*JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(13) + 270;
DynamicJsonDocument doc(capacity);
// Parse JSON object
DeserializationError error = deserializeJson(doc, client);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
int weatherId = doc["weather"][0]["id"].as<int>();
float weatherTemperature = doc["main"]["temp"].as<float>();
int weatherHumidity = doc["main"]["humidity"].as<int>();
//Disconnect
client.stop();
Serial.println(F("Response:"));
Serial.print("Weather: ");
Serial.println(weatherId);
Serial.print("Temperature: ");
Serial.println(weatherTemperature);
Serial.print("Humidity: ");
Serial.println(weatherHumidity);
Serial.println();
char scrollText[15];
sprintf(scrollText, "Humidity:%3d%%", weatherHumidity);
if(weatherId == 800) //clear
{
draw(scrollText, SUN, weatherTemperature);
}
else
{
switch(weatherId/100)
{
case 2: //Thunderstorm
draw(scrollText, THUNDER, weatherTemperature);
break;
case 3: //Drizzle
case 5: //Rain
draw(scrollText, RAIN, weatherTemperature);
break;
case 7: //Sun with clouds
draw(scrollText, SUN_CLOUD, weatherTemperature);
break;
case 8: //clouds
draw(scrollText, CLOUD, weatherTemperature);
break;
default: //Sun with clouds
draw(scrollText, SUN_CLOUD, weatherTemperature);
break;
}
}
}
else
{
// if you couldn't make a connection:
Serial.println("connection failed");
}
// note the time that this function was called
lastCallTime = millis();
}
void printWifiStatus()
{
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
void drawWeatherSymbol(u8g2_uint_t x, u8g2_uint_t y, uint8_t symbol)
{
// fonts used:
// u8g2_font_open_iconic_embedded_6x_t
// u8g2_font_open_iconic_weather_6x_t
// encoding values, see: https://github.com/olikraus/u8g2/wiki/fntgrpiconic
switch(symbol)
{
case SUN:
u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
u8g2.drawGlyph(x, y, 69);
break;
case SUN_CLOUD:
u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
u8g2.drawGlyph(x, y, 65);
break;
case CLOUD:
u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
u8g2.drawGlyph(x, y, 64);
break;
case RAIN:
u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
u8g2.drawGlyph(x, y, 67);
break;
case THUNDER:
u8g2.setFont(u8g2_font_open_iconic_embedded_6x_t);
u8g2.drawGlyph(x, y, 67);
break;
}
}
void drawWeather(uint8_t symbol, int degree)
{
drawWeatherSymbol(0, 48, symbol);
u8g2.setFont(u8g2_font_logisoso32_tf);
u8g2.setCursor(48+3, 42);
u8g2.print(degree);
u8g2.print("°C"); // requires enableUTF8Print()
}
/*
Draw a string with specified pixel offset.
The offset can be negative.
Limitation: The monochrome font with 8 pixel per glyph
*/
void drawScrollString(int16_t offset, const char *s)
{
static char buf[36]; // should for screen with up to 256 pixel width
size_t len;
size_t char_offset = 0;
u8g2_uint_t dx = 0;
size_t visible = 0;
len = strlen(s);
if ( offset < 0 )
{
char_offset = (-offset)/8;
dx = offset + char_offset*8;
if ( char_offset >= u8g2.getDisplayWidth()/8 )
return;
visible = u8g2.getDisplayWidth()/8-char_offset+1;
strncpy(buf, s, visible);
buf[visible] = '\0';
u8g2.setFont(u8g2_font_8x13_mf);
u8g2.drawStr(char_offset*8-dx, 62, buf);
}
else
{
char_offset = offset / 8;
if ( char_offset >= len )
return; // nothing visible
dx = offset - char_offset*8;
visible = len - char_offset;
if ( visible > u8g2.getDisplayWidth()/8+1 )
visible = u8g2.getDisplayWidth()/8+1;
strncpy(buf, s+char_offset, visible);
buf[visible] = '\0';
u8g2.setFont(u8g2_font_8x13_mf);
u8g2.drawStr(-dx, 62, buf);
}
}
void draw(const char *s, uint8_t symbol, int degree)
{
int16_t offset = -(int16_t)u8g2.getDisplayWidth();
int16_t len = strlen(s);
for(;;)
{
u8g2.firstPage();
do {
drawWeather(symbol, degree);
drawScrollString(offset, s);
} while ( u8g2.nextPage() );
delay(20);
offset+=2;
if ( offset > len*8+1 )
break;
}
}