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?


  • administrators

    I think the best way to get the time from the Net is to

    1. Register for a free account at timezonedb.
    2. 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 the timestamp) by using setDataReadyCallback on the client. You can just attach a regular C function that takes a reference to a constant HttpResponseData 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 be true) , and simply dig out the timestamp from bodyChunk.



  • Hi @nicolai I have a complete solution pasted below.

    This code snippet is Arduino code, and does:

    1. Setup UI views for debug console and clock text label
    2. Setup a refresh timer for the clock text label
    3. Initialize wifi (insert your own access point data)
    4. In wifiReady the HTTP request is initialized, insert your own API Key in the URL
    5. In dataReady the http response is parsed with e regular expression
    6. Convert the unix timestamp to a Lib C broken down time
    7. Convert the time to mono's DateTime object
    8. 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
    }
    

    0_1508489442508_IMG_2916.jpg


Log in to reply