Alexander Rao / Mbed 2 deprecated weather_clock

Dependencies:   mbed MbedJSONValue mbed-rtos 4DGL-uLCD-SE ESP8266NodeMCUInterface

Files at this revision

API Documentation at this revision

Comitter:
alexhrao
Date:
Sun Mar 31 15:39:50 2019 +0000
Parent:
3:7bf41989ff8f
Child:
5:b77a717feada
Commit message:
Add credentials

Changed in this revision

ESP8266NodeMCUInterface.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/ESP8266NodeMCUInterface.lib	Sun Mar 31 03:08:51 2019 +0000
+++ b/ESP8266NodeMCUInterface.lib	Sun Mar 31 15:39:50 2019 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/teams/ESP8266/code/ESP8266NodeMCUInterface/#f484783b8a34
+https://os.mbed.com/teams/ESP8266/code/ESP8266NodeMCUInterface/#c8c727b413d9
--- a/main.cpp	Sun Mar 31 03:08:51 2019 +0000
+++ b/main.cpp	Sun Mar 31 15:39:50 2019 +0000
@@ -32,15 +32,17 @@
 // Time
 Thread time_thread;
 
-// Weather
-Thread weather_thread;
-char weather_api_key[256];
-
 // Location
-char ip_api_key[256];
 double latitude = 0;
 double longitude = 0;
 
+// Credentials
+char ssid[256];
+char pass[256];
+char ip_api_key[256];
+char time_api_key[256];
+char weather_api_key[256];
+
 void time_updater() {
     // We're not an interrupt, so take as much time as we need. Infinite loop
     // but wait 1 second between each loop
@@ -51,9 +53,10 @@
     ltm = localtime(&now);
     
     // Buffer for time string. Max length is 23:59 + \0
-    int max_time_len = 6;
+    int max_time_len = 8;
     char ftime[max_time_len];
-    
+    ftime[0] = ' ';
+    ftime[1] = ' ';
     int min = -1;
     
     while (true) {
@@ -62,7 +65,7 @@
         ltm = localtime(&now);
         if(ltm->tm_min != min) {
             // Get the new time
-            strftime(ftime, max_time_len, "%H:%M", ltm); 
+            strftime(ftime + 2, max_time_len, "%H:%M", ltm); 
             // Update time! Lock the lcd mutex
             lcd_lock.lock();
             uLCD.text_width(2);
@@ -77,53 +80,54 @@
     }   
 }
 
+/*
 void weather_updater() {
-    // We can take as long as we want
+    // get the weather
+    // first get the current weather
+    // Weather data is _long_
+    dev.printf("Hello, World!\n");
+
+    char forecast_buf[4096];
+    TCPSocketConnection forecast_sck;
+    // http://api.openweathermap.org/data/2.5/forecast?lat=33.7485&lon=-84.3871&appid=6971e1ebfcc60f29c8dcc617c532b1b6&cnt=8
+    forecast_sck.connect("api.openweathermap.org", 80);
+    char cmd[256];
+    sprintf(cmd,
+        "GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=6971e1ebfcc60f29c8dcc617c532b1b6&cnt=8\r\nHost: api.openweathermap.org\r\n\r\n",
+        latitude, longitude);
+    forecast_sck.send_all(cmd, strlen(cmd));
+    wait(10);
+    int len_read = wifi.recv(forecast_buf, 4096 - 1, 0);
+    forecast_buf[len_read] = '\0';
+    dev.printf(forecast_buf);
     return;
-    while (true) {
-        // get the weather
-        // first get the current weather
-        // Weather data is _long_
-        
-        char forecast_buf[2];
-        TCPSocketConnection sck;
-        // http://api.openweathermap.org/data/2.5/forecast?lat=33.7485&lon=-84.3871&appid=6971e1ebfcc60f29c8dcc617c532b1b6
-        sck.connect("api.openweathermap.org", 80);
-        char cmd[1024];
-        sprintf(cmd,
-            "GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n",
-            latitude, longitude, weather_api_key);
-        sck.send_all(cmd, strlen(cmd));
-        wait(10);
-        int buf_len = wifi.recv(forecast_buf, 16384 - 1, 0);
-        forecast_buf[buf_len] = '\0';
-        
-        // Get current weather
-        char current_buf[8192];
-        sprintf(cmd,
-            "GET /data/2.5/forecast?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n",
-            latitude, longitude, weather_api_key);
-        sck.send_all(cmd, strlen(cmd));
-        wait(10);
-        buf_len = wifi.recv(current_buf, 8192 - 1, 0);
-        current_buf[buf_len] = '\0';
-        // we'll always want to update the LCD - don't worry about the previous
-        // weather
-        int curr_temp = 0;
-        int high_temp = 0;
-        int low_temp = 0;
-        char buf[12];
-        sprintf(buf, "%d %d/%d", curr_temp, high_temp, low_temp);
-        // lock
-        lcd_lock.lock();
-        uLCD.text_width(2);
-        uLCD.text_height(2);
-        // include null!
-        uLCD.text_string(buf, 0, 5, FONT_7X8, WHITE);
-        // done! unlock
-        lcd_lock.unlock();
-    }
+    // http://api.openweathermap.org/data/2.5/forecast?lat=33.7485&lon=-84.3871&appid=6971e1ebfcc60f29c8dcc617c532b1b6
+    // Get current weather
+    char current_buf[4096];
+    sprintf(cmd,
+        "GET /data/2.5/forecast?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n",
+        latitude, longitude, weather_api_key);
+    sck.send_all(cmd, strlen(cmd));
+    wait(10);
+    int buf_len = wifi.recv(current_buf, 4096 - 1, 0);
+    current_buf[buf_len] = '\0';
+    // we'll always want to update the LCD - don't worry about the previous
+    // weather
+    int curr_temp = 0;
+    int high_temp = 0;
+    int low_temp = 0;
+    char buf[12];
+    sprintf(buf, "%d %d/%d", curr_temp, high_temp, low_temp);
+    // lock
+    lcd_lock.lock();
+    uLCD.text_width(2);
+    uLCD.text_height(2);
+    // include null!
+    uLCD.text_string(buf, 0, 5, FONT_7X8, WHITE);
+    // done! unlock
+    lcd_lock.unlock();
 }
+*/
 
 void dev_recv() {
     // Continually check if we have stuff...
@@ -151,7 +155,11 @@
     }
 }
 
-int main() {
+int kelvin2farenheit(int temp) {
+     return (int)((((temp - 273.15f) * 9.0f) / 5.0f) + 32.0f);
+}
+
+void clock_init() {
     // Set up bluetooth
     dev.baud(9600);
     pc.baud(9600);
@@ -164,17 +172,12 @@
     lcd_lock.unlock();
     
     // Need to get wifi settings. If we don't have local file, then ask!
-    FILE* fid = NULL;//fopen("/local/settings.txt", "r");
-    char ssid[256];
-    char pass[256];
-    char api_key[256];
+    FILE* fid = fopen("/local/settings.txt", "r");
     
-    if (true) {
-        
-    } else if (fid != NULL) {
+    if (fid != NULL) {
         // Read WiFi Settings
         char settings_buf[1024];
-        // Guaranteed to be 256, 256, 512 AT MOST + two new lines
+        // Guaranteed to be 5 lines
         // 
         fgets(settings_buf, 1024, fid);
         // find \n
@@ -185,17 +188,33 @@
         }
         ssid[settings_ind] = '\0';
         settings_ind = 0;
-        counter++;
+        fgets(settings_buf, 1024, fid);
+        counter = 0;
         while (settings_buf[counter] != '\n') {
             pass[settings_ind++] = settings_buf[counter++];
         }
         pass[settings_ind] = '\0';
         settings_ind = 0;
-        counter++;
+        fgets(settings_buf, 1024, fid);
+        counter = 0;
+        while (settings_buf[counter] != '\n') {
+            ip_api_key[settings_ind++] = settings_buf[counter++];
+        }
+        ip_api_key[settings_ind] = '\0';
+        settings_ind = 0;
+        fgets(settings_buf, 1024, fid);
+        counter = 0;
         while (settings_buf[counter] != '\n') {
-            api_key[settings_ind++] = settings_buf[counter++];
+            time_api_key[settings_ind++] = settings_buf[counter++];
         }
-        api_key[settings_ind] = '\0';
+        time_api_key[settings_ind] = '\0';
+        settings_ind = 0;
+        fgets(settings_buf, 1024, fid);
+        counter = 0;
+        while (settings_buf[counter] != '\n') {
+            weather_api_key[settings_ind++] = settings_buf[counter++];
+        }
+        weather_api_key[settings_ind] = '\0';
         fclose(fid);
     } else {
         lcd_lock.lock();
@@ -249,7 +268,7 @@
         pass[ind] = '\0';
         
         // Get the API key
-        dev.printf("Please provide the API key\n");
+        dev.printf("Please provide the IP Stack API key\n");
         while (!dev.readable()) {
             wait(0.001);
         }
@@ -259,117 +278,298 @@
             if (tmp == '\n' || tmp == '\r') {
                 break;
             }
-            api_key[ind++] = tmp;
+            ip_api_key[ind++] = tmp;
+            wait(0.01);
+        }
+
+        ip_api_key[ind] = '\0';
+        
+        dev.printf("Please provide the TimeZoneDB API key\n");
+        while (!dev.readable()) {
+            wait(0.001);
+        }
+        ind = 0;
+        while (ind < 255) {
+            char tmp = dev.getc();
+            if (tmp == '\r' || tmp == '\n') {
+                break;
+            }
+            time_api_key[ind++] = tmp;
             wait(0.01);
         }
-        api_key[ind] = '\0';
+        time_api_key[ind] = '\0';
+        
+        dev.printf("Please provide the OpenWeather API key\n");
+        while (!dev.readable()) {
+            wait(0.001);
+        }
+        ind = 0;
+        while (ind < 255) {
+            char tmp = dev.getc();
+            if (tmp == '\r' || tmp == '\n') {
+                break;
+            }
+            weather_api_key[ind++] = tmp;
+            wait(0.01);
+        }
+        weather_api_key[ind] = '\0';
+
+        
+        
         // Because this is a simple proof of concept, we store the password in 
         // plaintext. It should be noted, however, that you **should never do 
         // this in "real life"**
-        //fid = fopen("/local/settings.txt", "w");
-        //fprintf(fid, "%s\n%s\n%s\n", ssid, pass, api_key);
-        //fclose(fid);
+        fid = fopen("/local/settings.txt", "w");
+        fprintf(fid, "%s\n%s\n%s\n%s\n%s\n", ssid, pass, ip_api_key, time_api_key, weather_api_key);
+        fclose(fid);
     }
-    char* tmp = "af9319bf6435ddd9bb640f763ff64d34";
-    for (int i = 0; i < strlen(tmp); i++) {
-        api_key[i] = tmp[i];
-    }
+    
+    dev.printf("\r\n** CREDENTIALS **\r\n");
+    dev.printf("SSID: **%s** (%d)\r\n", ssid, strlen(ssid));
+    dev.printf("PASS: **%s** (%d)\r\n", pass, strlen(pass));
+    dev.printf("IP STACK: **%s**\r\n", ip_api_key);
+    dev.printf("TIMEZONEDB: **%s**\r\n", time_api_key);
+    dev.printf("WEATHERMAP: **%s**\r\n", weather_api_key);
+    
     bool res = wifi.init();
-    //dev.printf("Reset: %d\n", res);
+
     // Set up the WiFi Access Point
     dev.printf("Connecting to WiFi %s with Password %s\n", ssid, pass);
+    
     res = wifi.connect("Alex's iPhone", "mbedlookhere");
     if (!res) {
         dev.printf("Connection Failed... Resetting Device\n");
         err_led = 1;
         mbed_reset();
     }
+    
     dev.printf("Connected with IP Address: %s\n", wifi.getIPAddress());
     
-    // Get the time & location
+    /** API REQUESTS **/
+    
+    int header_ind = 0;
+    int footer_ind = 0;
+    int read_len = 0;
+    char buffer[BUF_SIZE];
+    char cmd[512];
+
     dev.printf("Getting the current location...\n");
     TCPSocketConnection tcp;
     tcp.connect("api.ipstack.com", 80);
+    //af9319bf6435ddd9bb640f763ff64d34
+    sprintf(cmd, 
+        "GET /check?access_key=%s HTTP/1.1\r\nHost: api.ipstack.com\r\n\r\n",
+        ip_api_key);
+    tcp.send_all(cmd, strlen(cmd));
     
-    char tcp_cmd[256];
-    sprintf(tcp_cmd, 
-        "GET /check?access_key=af9319bf6435ddd9bb640f763ff64d34 HTTP/1.1\r\nHost: api.ipstack.com\r\n\r\n");
-    tcp.send_all(tcp_cmd, strlen(tcp_cmd));
+    wait(5);
     
-    wait(10);
-    
-    char buffer[BUF_SIZE];
-    int read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
+    read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
     buffer[read_len] = '\0';
     
+    // Cleanup
+    
+    while (header_ind < read_len) {
+        // if we are \r, look ahead to see \n\r\n:
+        if(buffer[header_ind] == '\r' &&
+           buffer[header_ind+1] == '\n' &&
+           buffer[header_ind+2] == '\r' &&
+           buffer[header_ind+3] == '\n') {
+            // Increment header_ind, look for JSON
+            // Now just look for {
+            header_ind += 4;
+            while (header_ind < read_len) {
+                if (buffer[header_ind] == '{') {
+                    // we got it!
+                    break;
+                }
+                header_ind++;
+            }
+            break;
+        }
+        header_ind++;
+    }
+    for (footer_ind = read_len - 1; footer_ind > header_ind; footer_ind--) {
+        if(buffer[footer_ind] == '}') {
+            break;
+        }
+    }
+    buffer[footer_ind + 1] = '\0';
+    dev.printf(buffer);
     MbedJSONValue parser;
-    parse(parser, buffer);
-    // for now, just print...
+    parse(parser, buffer + header_ind);
     
-    latitude = parser["latitude"].get<double>();
+    latitude =  parser["latitude"].get<double>();
     longitude = parser["longitude"].get<double>();
 
-    /*
-    TCPSocketConnection weather_sck;
-    //http://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=6971e1ebfcc60f29c8dcc617c532b1b6
-    //http://api.openweathermap.org/data/2.5/forecast?lat=33.7485&lon=-84.3871&appid=6971e1ebfcc60f29c8dcc617c532b1b6
-    weather_sck.connect("api.openweathermap.org", 80);
-    sprintf(tcp_cmd,
-        "GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n",
-        lat, lng, "6971e1ebfcc60f29c8dcc617c532b1b6");
-    sprintf(weather_api_key,
-        "%s", "6971e1ebfcc60f29c8dcc617c532b1b6");
-    weather_sck.send_all(tcp_cmd, strlen(tcp_cmd));
-    wait(15);
-    int read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
+    // Get the Time
+    TCPSocketConnection time_tcp;
+
+    //http://api.timezonedb.com/v2.1/get-time-zone?key=YOUR_API_KEY&format=json&by=zone&zone=America/Chicago
+    time_tcp.connect("api.timezonedb.com", 80);
+    //VFHNS0FSUJVN
+    sprintf(cmd,
+        "GET /v2.1/get-time-zone?key=%s&format=json&by=position&lat=%0.4f&lng=%0.4f HTTP/1.1\r\nHost: api.timezonedb.com\r\n\r\n",
+        time_api_key,
+        latitude,
+        longitude);
+
+    time_tcp.send_all(cmd, strlen(cmd));
+    wait(5);
+    read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
     buffer[read_len] = '\0';
-    dev.printf(buffer);
-    */
-    // dev.printf("Connection: %d\n", con_res);
-    //sprintf
-    //int con_res = weather_sck.connect("api.weather.gov", 443);
-    //    dev.printf("Connection: %d\n", con_res);
-    //sprintf(tcp_cmd,
-    //    "GET /points/%0.4f,%0.4f HTTP/1.1\r\nHost: api.weather.gov\r\n\r\n",
-    //    lat, lng);
-    //weather_sck.send_all(tcp_cmd, strlen(tcp_cmd));
-    //wait(5);
-    //wait(10);
-    //int read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
-    //buffer[read_len] = '\0';
-    //dev.printf(buffer);
-    set_time(1256729737);
+    
+    // Cleanup
+    
+    // Clean up front
+    // Read through headers (\r\n\r\n)
+    header_ind = 0;
+    while (header_ind < read_len) {
+        // if we are \r, look ahead to see \n\r\n:
+        if(buffer[header_ind] == '\r' &&
+           buffer[header_ind+1] == '\n' &&
+           buffer[header_ind+2] == '\r' &&
+           buffer[header_ind+3] == '\n') {
+            // Increment header_ind, look for JSON
+            // Now just look for {
+            header_ind += 4;
+            while (header_ind < read_len) {
+                if (buffer[header_ind] == '{') {
+                    // we got it!
+                    break;
+                }
+                header_ind++;
+            }
+            break;
+        }
+        header_ind++;
+    }
+
+    for (footer_ind = read_len - 1; footer_ind > header_ind; footer_ind--) {
+        if(buffer[footer_ind] == '}') {
+            break;
+        }
+    }
+    buffer[footer_ind + 1] = '\0';
     
-    // Clear the LCD Screen first
+    MbedJSONValue time_parser;
+    parse(time_parser, buffer + header_ind);
+
+    // Add 5 so that we make up for the wait(5)
+    set_time(time_parser["timestamp"].get<int>() + 5);
+    // Now that we know what time it is, set up our Time Thread
+    time_thread.start(time_updater);
+    TCPSocketConnection forecast_sck;
+    // http://api.openweathermap.org/data/2.5/forecast?lat=33.7485&lon=-84.3871&appid=6971e1ebfcc60f29c8dcc617c532b1b6&cnt=8
+    forecast_sck.connect("api.openweathermap.org", 80);
+    //6971e1ebfcc60f29c8dcc617c532b1b6
+    sprintf(cmd,
+        "GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=%s&cnt=8\r\nHost: api.openweathermap.org\r\n\r\n",
+        latitude, longitude, weather_api_key);
+    forecast_sck.send_all(cmd, strlen(cmd));
+    wait(5);
+    int len_read = wifi.recv(buffer, BUF_SIZE - 1, 0);
+    buffer[len_read] = '\0';
+    
+
+    //buffer[footer_ind + 1] = '\0';
+    char* ind = strstr(buffer, "temp");
+    for (int m = 0; m < 15; m++) {
+        dev.putc(ind[m]);
+    }
+    char num_buf[16];
+    int num_ind = 0;
+    // go until we find numbers
+    while (char tmp = *ind++) {
+        if (tmp > '0' && tmp < '9') {
+            num_buf[num_ind++] = tmp;
+            break;
+        }
+    }
+    // Keep moving until no more numbers
+    while (char tmp = *ind++) {
+        if (tmp > '9' || tmp < '0') {
+            num_buf[num_ind] = '\0';
+            break;
+        } else {
+            num_buf[num_ind++] = tmp;
+        }
+    }
+    int temp = atoi(num_buf);
+    // Convert
+    temp = (((temp - 273.15f) * 9.0f) / 5.0f) + 32.0f;
+    char temp_buf[12];
+    sprintf(temp_buf, "   %dF", temp);
     lcd_lock.lock();
-    uLCD.cls();
+    uLCD.text_width(2);
+    uLCD.text_height(2);
+    uLCD.text_string(temp_buf, 0, 5, FONT_8X8, WHITE);
+    // done! unlock
     lcd_lock.unlock();
     
-    // Now that we know what time it is, set up our Time Thread
-    time_thread.start(time_updater);
-    
-    // Make the request to get the forecast link
-
-    // Now, make a single request to nws and get the forecast link - we can 
-    // store this link for later!
     
     // Start up weather service!
     //weather_thread.start(weather_updater);
     
-    //weather_ticker.attach(&weather_tick, 900000.0f);
     // Listen on bluetooth.
-    dev_thread.start(dev_recv);
-    dev.printf("Hello, World!\n");
-    time_t prev_time = time(NULL);
+    //dev_thread.start(dev_recv);
     while(true) {
         time_t curr_time = time(NULL);
-        // if it's been an hour (divide by 3600 >= 60), pause and get weather:
-        if (((int)(curr_time - prev_time) / 3600) >= 60) {
-            //weather_updater();
-            prev_time = curr_time;
+        if (true) {
+            sprintf(cmd,
+                "GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n",
+                latitude, longitude, weather_api_key);
+            forecast_sck.connect("api.openweathermap.org", 80);
+            wait(10);
+            forecast_sck.send_all(cmd, strlen(cmd));
+            wait(5);
+
+            len_read = wifi.recv(buffer, BUF_SIZE - 1, 0);
+
+            buffer[len_read] = '\0';
+
+    
+            dev.printf(buffer);
+
+            ind = strstr(buffer, "temp");
+            for (int m = 0; m < 15; m++) {
+                dev.putc(ind[m]);
+            }
+            num_ind = 0;
+            // go until we find numbers
+            while (char tmp = *ind++) {
+                dev.printf("CHAR: %c\r\n", tmp);
+                if (tmp > '0' && tmp < '9') {
+                    num_buf[num_ind++] = tmp;
+                    break;
+                }
+            }
+            // Keep moving until no more numbers
+            while (char tmp = *ind++) {
+                if (tmp > '9' || tmp < '0') {
+                    num_buf[num_ind] = '\0';
+                    break;
+                } else {
+                    num_buf[num_ind++] = tmp;
+                }
+            }
+            temp = atoi(num_buf);
+            dev.printf("Temperature: %s (%d)\r\n", num_buf, temp);
+            // Convert
+            temp = (((temp - 273.15f) * 9.0f) / 5.0f) + 32.0f;
+            sprintf(temp_buf, "   %dF", temp);
+            lcd_lock.lock();
+            uLCD.text_width(2);
+            uLCD.text_height(2);
+            uLCD.text_string(temp_buf, 0, 5, FONT_8X8, WHITE);
+            // done! unlock
+            lcd_lock.unlock();
         }
+
         err_led = !err_led;
-        //dev.printf("Connection Status: %d\n", wifi.is_connected());
-        wait(0.5);
     }
 }
+
+int main() {
+    clock_init();
+}