I have learnt tons from the folks on this forum, so I want to give something back.
And since I am new to Arduino and programming, I welcome advice on improvement.
I have explored several ways to get the date and local time on a Wemos D Mini board / ESP8266 board.
Most involve lots of conversions from utc to something humans understand to local timezone to DST and whatnot. Finally settled on using timezonedb.com as source and found it to work well.
Here is the sketch with lots of comments.
/*
Get date and local time with ESP8266-based boards over WiFi from timezonedb.com
Tested on Wemos D1 Mini; Arduino IDE V1.8.2 (Mac)
Getting your board set up:
If you need to install a CH340G driver, get them here: https://wiki.wemos.cc/downloads.
To add ESP8266-based boards to the Arduino IDE, paste http://arduino.esp8266.com/stable/package_esp8266com_index.json into Arduino: Preferences: Add'l. Boards Mngr.
Install under Tools: Board: Boards Manager: select "ESP8266 by ESP8266 community".
Select your ESP8266-based board under Tools: Board.
Include libraries under Sketch: Include library.
Make sure your serial monitor is set to 115200.
Set up free account @ timezonedb.com to get your API key.
Insert your API key into host URL below.
In the URL, leave format=xml, fields=formatted; adjust zone to your location.
Check https://timezonedb.com/references/get-time-zone for zone (and other) options.
Process is broken down into three separate functions:
- connect to WiFi
- connect to timezonedb
- parse data, convert to int and store it in y, mo, d, h, mi, s.
Setup goes through three functions once; loop refreshes every 30 seconds.
Bits and pieces of this sketch were collected from all over the internet.
Thank you to all the folks who pointed me towards the solution.
Aggertroll - Feb 8, 2018
*/
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
const char* ssid = "*********"; // The SSID (name) of your Wi-Fi network
const char* password = "*********"; // The password of the Wi-Fi network
const char* host = "http://api.timezonedb.com/v2/get-time-zone?key=******&format=xml&fields=formatted&by=zone&zone=Europe/Berlin";
String payload; // Variables to accept data
String nowday;
String nowmonth;
String nowyear;
String nowhour;
String nowmin;
String nowsec;
unsigned long prevMillis = millis();
unsigned long interval = 30000; // Refresh in loop every 30 seconds
void setup() {
Serial.begin(115200); // Start serial communication
delay(10);
Serial.println('\n');
wifi();
tzdb();
parse_response();
}
void wifi() {
WiFi.mode(WIFI_STA);
WiFi.disconnect(); // Clear any existing connection
WiFi.begin(ssid, password); // Access WiFi
Serial.print("Connecting to ");
Serial.print(ssid);
Serial.print(" ...");
while (WiFi.status() != WL_CONNECTED) { // Wait for WiFi to connect
delay(1000);
Serial.print(".");
}
Serial.println('\n');
Serial.println("WiFi connection established");
Serial.print("Device's IP address is ");
Serial.println(WiFi.localIP()); // Show device's IP address
}
void tzdb() {
int httpCode = 0; // Variable to hold received data
HTTPClient http; // Declare an object of class HTTPClient
Serial.println("Connecting to TimezoneDB...");
http.begin(host); // Connect to site
httpCode = http.GET(); // Check if data is coming in
while (httpCode == 0) { // if no data is in
delay(1000); // wait a sec
http.begin(host); // and try again
httpCode = http.GET();
}
payload = http.getString(); // Save response as string
Serial.println(payload); // Show response
//Sample response:
//<?xml version="1.0" encoding="UTF-8"?>
//<result><status>OK</status><message/><formatted>2018-02-08 14:24:16</formatted></result>
http.end(); // Close connection to timezonedb
WiFi.mode(WIFI_OFF); // Close connection to WiFi
}
void parse_response() {
int colon = payload.indexOf(':'); // Set the first colon in time as reference point
int d; // Variables to hold data as integers
int mo;
int y;
int h;
int mi;
int s;
nowday = payload.substring(colon - 5, colon - 3); // Get data as substring
d = nowday.toInt(); // and convert to int
nowmonth = payload.substring(colon - 8, colon - 6);
mo = nowmonth.toInt();
nowyear = payload.substring(colon - 13, colon - 9);
y = nowyear.toInt();
nowhour = payload.substring(colon - 2, colon);
h = nowhour.toInt();
nowmin = payload.substring(colon + 1, colon + 3);
mi = nowmin.toInt();
nowsec = payload.substring(colon + 4, colon + 6);
s = nowsec.toInt();
// Print integers without leading zeros - use in calculations
Serial.print("Today's date is: ");
Serial.print(y);
Serial.print("-");
Serial.print(mo);
Serial.print("-");
Serial.println(d);
Serial.print("Current local time is: ");
Serial.print(h);
Serial.print(":");
Serial.print(mi);
Serial.print(":");
Serial.println(s);
Serial.println();
/*Print characters with leading zeros - use for lcd etc.
Serial.print("Today's date is: ");
Serial.print(nowyear);
Serial.print("-");
Serial.print(nowmonth);
Serial.print("-");
Serial.println(nowday);
Serial.print("Current local time is: ");
Serial.print(nowhour);
Serial.print(":");
Serial.print(nowmin);
Serial.print(":");
Serial.println(nowsec);
Serial.println();
*/
}
void loop() {
if (millis() - prevMillis > interval) { // refresh
wifi();
tzdb();
parse_response();
prevMillis = millis();
}
}
Maybe this is helpful to someone - and let me know how it can be improved.