Fork from Alex
Dependencies: mbed MbedJSONValue mbed-rtos 4DGL-uLCD-SE ESP8266NodeMCUInterface
Diff: main.cpp
- Revision:
- 4:55f0c303f56a
- Parent:
- 3:7bf41989ff8f
- Child:
- 5:b77a717feada
diff -r 7bf41989ff8f -r 55f0c303f56a main.cpp --- 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(); +}