HTTP GET Request Client
-
After doing the IFTTT example, I want to use a HTTP GET to obtain date and time from a web server like in this example and set the Mono RTC so that I can timestamp my events.
I'm having a tough time understanding HttpClient well enough to implement it in the Arduino-framework. Anyone who can shed some light on this?
-
I think the best way to get the time from the Net is to
- Register for a free account at timezonedb.
- Use the API key it gives you to query their API for the time, like
http://api.timezonedb.com/v2/get-time-zone?key=YOUR_API_KEY_HERE&format=json&fields=timestamp&by=zone&zone=CET
which will give you something like
{"status": "OK","message": "","timestamp": 1508269236}
To do that in Mono, you will need to create a
HttpClient
with the URL above as argument, and then attach a function (that can filter out thetimestamp
) by usingsetDataReadyCallback
on the client. You can just attach a regular C function that takes a reference to a constantHttpResponseData
as argument.The
HttpResponseData
can in general come in several chunks, but by using the API as described above, you can probably ignore chunks (i.e.Finished
will always betrue
) , and simply dig out the timestamp frombodyChunk
.
-
Hi @nicolai I have a complete solution pasted below.
This code snippet is Arduino code, and does:
- Setup UI views for debug console and clock text label
- Setup a refresh timer for the clock text label
- Initialize wifi (insert your own access point data)
- In
wifiReady
the HTTP request is initialized, insert your own API Key in the URL - In
dataReady
the http response is parsed with e regular expression - Convert the unix timestamp to a Lib C broken down time
- Convert the time to mono's
DateTime
object - Set the systems datetime
#include <mono.h> mono::io::Wifi *wifi = 0; mono::network::HttpClient *client = 0; mono::ui::ConsoleView<176,110> *console; mono::ui::TextLabelView *clockLbl; mono::Timer *tim; void setup() { // init console view console = new mono::ui::ConsoleView<176,110>(); console->show(); // init clock label clockLbl = new mono::ui::TextLabelView(mono::geo::Rect(10,120,156,45), "-"); clockLbl->setAlignment(mono::ui::TextLabelView::ALIGN_CENTER); clockLbl->show(); tim = new mono::Timer(999); tim->setCallback(&updateClock); updateClock(); tim->start(); // start wifi wifi = new mono::io::Wifi("YOUR_SSID_HERE", "YOUR_PASSPHRASE_HERE"); wifi->setConnectedCallback(&wifiReady); console->WriteLine("Connecting wifi..."); wifi->connect(); } void updateClock() { // repaint the clock label clockLbl->setText(mono::String::Format("%s\n%s", mono::DateTime::now().toTimeString()(), DateTime::now().toDateString()())); } void wifiReady() { if (client == 0) { delete client; } // fetch the time stamp from the HTTP API console->WriteLine("http fetch..."); client = new mono::network::HttpClient("http://api.timezonedb.com/v2/get-time-zone?key=YOUR_API_KEY_HERE&format=json&zone=CEST&by=zone&fields=timestamp"); client->setDataReadyCallback(&dataReady); } void dataReady(const mono::network::HttpClient::HttpResponseData &data) { // debug print the received data console->WriteLine(mono::String::Format("--> %s",data.bodyChunk())); // use a regular expression to extract the timestamp from the JSON mono::Regex timeReg("\"timestamp\":([0-9]+)"); mono::Regex::Capture caps[1]; // see if there is a match if (timeReg.Match(data.bodyChunk, caps, 1)) { //extract the timestamp as a string mono::String timeStr = timeReg.Value(caps[0]); // convert the string to a Lib C time_t time_t utime; sscanf(timeStr(), "%li", &utime); console->WriteLine(mono::String::Format("Parsed %li", utime)); // convert to a Lib C brokendown time structure struct tm *broken = localtime(&utime); // create a mono DateTime object from the brokendown time mono::DateTime time(broken, true); console->WriteLine(time.toString()); // set the system clock from the DateTime mono::DateTime::setSystemDateTime(time); clockLbl->setText(mono::display::GreenColor); } } void loop() { // Leave this empty }