Fork from Alex

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

Committer:
alexhrao
Date:
Sat May 18 17:57:20 2019 +0000
Revision:
10:16356570821e
Parent:
9:299eb69af04e
Cleanup

Who changed what in which revision?

UserRevisionLine numberNew contents of line
alexhrao 0:4ffa136585a2 1 #include "mbed.h"
alexhrao 1:0620ba35d2e8 2 #include "uLCD_4DGL.h"
alexhrao 1:0620ba35d2e8 3 #include "ESP8266Interface.h"
alexhrao 1:0620ba35d2e8 4 #include "TCPSocketConnection.h"
alexhrao 1:0620ba35d2e8 5 #include "rtos.h"
alexhrao 3:7bf41989ff8f 6 #include "MbedJSONValue.h"
alexhrao 3:7bf41989ff8f 7 #include <string>
alexhrao 3:7bf41989ff8f 8
alexhrao 3:7bf41989ff8f 9 #define BUF_SIZE 4096
alexhrao 1:0620ba35d2e8 10
alexhrao 1:0620ba35d2e8 11 // We need this for being able to reset the MBED (similar to watch dogs)
alexhrao 1:0620ba35d2e8 12 extern "C" void mbed_reset();
alexhrao 1:0620ba35d2e8 13
alexhrao 1:0620ba35d2e8 14 // LCD Screen
alexhrao 1:0620ba35d2e8 15 uLCD_4DGL uLCD(p9, p10, p11);
alexhrao 1:0620ba35d2e8 16 Mutex lcd_lock;
alexhrao 1:0620ba35d2e8 17
alexhrao 1:0620ba35d2e8 18 // File System
alexhrao 1:0620ba35d2e8 19 LocalFileSystem fs("local");
alexhrao 1:0620ba35d2e8 20
alexhrao 1:0620ba35d2e8 21 // Bluetooth
alexhrao 1:0620ba35d2e8 22 RawSerial pc(USBTX, USBRX);
alexhrao 1:0620ba35d2e8 23 RawSerial dev(p28,p27);
alexhrao 1:0620ba35d2e8 24
alexhrao 1:0620ba35d2e8 25 // Error LED
alexhrao 1:0620ba35d2e8 26 DigitalOut err_led(LED1);
alexhrao 1:0620ba35d2e8 27
alexhrao 1:0620ba35d2e8 28 // WiFi
alexhrao 1:0620ba35d2e8 29 ESP8266Interface wifi(p13, p14, p15, 9600, 10000);
alexhrao 1:0620ba35d2e8 30
alexhrao 1:0620ba35d2e8 31 // Time
alexhrao 1:0620ba35d2e8 32 Thread time_thread;
alexhrao 1:0620ba35d2e8 33
alexhrao 3:7bf41989ff8f 34 // Location
alexhrao 3:7bf41989ff8f 35 double latitude = 0;
alexhrao 3:7bf41989ff8f 36 double longitude = 0;
alexhrao 0:4ffa136585a2 37
alexhrao 4:55f0c303f56a 38 // Credentials
alexhrao 4:55f0c303f56a 39 char ssid[256];
alexhrao 4:55f0c303f56a 40 char pass[256];
alexhrao 4:55f0c303f56a 41 char ip_api_key[256];
alexhrao 4:55f0c303f56a 42 char time_api_key[256];
alexhrao 4:55f0c303f56a 43 char weather_api_key[256];
alexhrao 4:55f0c303f56a 44
alexhrao 8:d323c6406b47 45 void time_updater()
alexhrao 8:d323c6406b47 46 {
alexhrao 1:0620ba35d2e8 47 // We're not an interrupt, so take as much time as we need. Infinite loop
alexhrao 1:0620ba35d2e8 48 // but wait 1 second between each loop
alexhrao 1:0620ba35d2e8 49 struct tm* ltm;
alexhrao 1:0620ba35d2e8 50 time_t now;
alexhrao 8:d323c6406b47 51
alexhrao 1:0620ba35d2e8 52 now = time(NULL);
alexhrao 1:0620ba35d2e8 53 ltm = localtime(&now);
alexhrao 8:d323c6406b47 54
alexhrao 1:0620ba35d2e8 55 // Buffer for time string. Max length is 23:59 + \0
alexhrao 4:55f0c303f56a 56 int max_time_len = 8;
alexhrao 1:0620ba35d2e8 57 char ftime[max_time_len];
alexhrao 4:55f0c303f56a 58 ftime[0] = ' ';
alexhrao 4:55f0c303f56a 59 ftime[1] = ' ';
alexhrao 1:0620ba35d2e8 60 int min = -1;
alexhrao 8:d323c6406b47 61
alexhrao 1:0620ba35d2e8 62 while (true) {
alexhrao 1:0620ba35d2e8 63 // if the minute has changed, update.
alexhrao 1:0620ba35d2e8 64 now = time(NULL);
alexhrao 1:0620ba35d2e8 65 ltm = localtime(&now);
alexhrao 1:0620ba35d2e8 66 if(ltm->tm_min != min) {
alexhrao 1:0620ba35d2e8 67 // Get the new time
alexhrao 8:d323c6406b47 68 strftime(ftime + 2, max_time_len, "%H:%M", ltm);
alexhrao 1:0620ba35d2e8 69 // Update time! Lock the lcd mutex
alexhrao 1:0620ba35d2e8 70 lcd_lock.lock();
alexhrao 1:0620ba35d2e8 71 uLCD.text_width(2);
alexhrao 1:0620ba35d2e8 72 uLCD.text_height(2);
alexhrao 1:0620ba35d2e8 73 uLCD.text_string(ftime, 0, 2, FONT_8X8, GREEN);
alexhrao 1:0620ba35d2e8 74 // Done updating - unlock!
alexhrao 1:0620ba35d2e8 75 lcd_lock.unlock();
alexhrao 1:0620ba35d2e8 76 min = ltm->tm_min;
alexhrao 1:0620ba35d2e8 77 }
alexhrao 1:0620ba35d2e8 78 // Wait 1 second
alexhrao 1:0620ba35d2e8 79 Thread::wait(1.0f);
alexhrao 8:d323c6406b47 80 }
alexhrao 1:0620ba35d2e8 81 }
alexhrao 1:0620ba35d2e8 82
alexhrao 8:d323c6406b47 83 void dev_recv()
alexhrao 8:d323c6406b47 84 {
alexhrao 1:0620ba35d2e8 85 // Continually check if we have stuff...
alexhrao 1:0620ba35d2e8 86 char buf[1024];
alexhrao 1:0620ba35d2e8 87 int ind = 0;
alexhrao 1:0620ba35d2e8 88 while (true) {
alexhrao 10:16356570821e 89 while (ind < 1023) {
alexhrao 1:0620ba35d2e8 90 // get stuff. If we encounter \r or \n, that's a complete command!
alexhrao 1:0620ba35d2e8 91 char tmp = dev.getc();
alexhrao 1:0620ba35d2e8 92 if (tmp == '\n' || tmp == '\r') {
alexhrao 1:0620ba35d2e8 93 break;
alexhrao 1:0620ba35d2e8 94 }
alexhrao 1:0620ba35d2e8 95 buf[ind++] = tmp;
alexhrao 1:0620ba35d2e8 96 Thread::wait(0.01);
alexhrao 1:0620ba35d2e8 97 }
alexhrao 1:0620ba35d2e8 98 buf[ind] = '\0';
alexhrao 1:0620ba35d2e8 99 // read command and respond
alexhrao 10:16356570821e 100 if (strcmp(buf, "reset wifi") == 0) {
alexhrao 10:16356570821e 101 dev.printf("Are you sure? y/[n]\n");
alexhrao 10:16356570821e 102 if (dev.getc() == 'y') {
alexhrao 10:16356570821e 103 // Remove the WIFI.TXT file
alexhrao 10:16356570821e 104 remove("/local/wifi.txt");
alexhrao 10:16356570821e 105 mbed_reset();
alexhrao 10:16356570821e 106 }
alexhrao 10:16356570821e 107 } else if (strcmp(buf, "reset api") == 0) {
alexhrao 1:0620ba35d2e8 108 dev.printf("Are you sure? y/[n]\n");
alexhrao 10:16356570821e 109 if (dev.getc() == 'y') {
alexhrao 10:16356570821e 110 // Remove api_keys.txt
alexhrao 10:16356570821e 111 remove("/local/api_keys.txt");
alexhrao 10:16356570821e 112 mbed_reset();
alexhrao 10:16356570821e 113 }
alexhrao 10:16356570821e 114 } else if (strcmp(buf, "info") == 0) {
alexhrao 10:16356570821e 115 // Print basic info
alexhrao 10:16356570821e 116 dev.printf("WiFi Connected with Address %s\r\n",
alexhrao 10:16356570821e 117 wifi.getIPAddress());
alexhrao 10:16356570821e 118 time_t curr_time = time(NULL);
alexhrao 10:16356570821e 119 dev.printf("Current Time: %s\r\n", ctime(&curr_time));
alexhrao 1:0620ba35d2e8 120 }
alexhrao 1:0620ba35d2e8 121 buf[0] = '\0';
alexhrao 1:0620ba35d2e8 122 ind = 0;
alexhrao 1:0620ba35d2e8 123 Thread::wait(0.01);
alexhrao 1:0620ba35d2e8 124 }
alexhrao 2:f7d19812bdc5 125 }
alexhrao 0:4ffa136585a2 126
alexhrao 8:d323c6406b47 127 int kelvin2farenheit(int temp)
alexhrao 8:d323c6406b47 128 {
alexhrao 8:d323c6406b47 129 return (int)((((temp - 273.15f) * 9.0f) / 5.0f) + 32.0f);
alexhrao 4:55f0c303f56a 130 }
alexhrao 4:55f0c303f56a 131
alexhrao 8:d323c6406b47 132 void clock_init()
alexhrao 8:d323c6406b47 133 {
alexhrao 1:0620ba35d2e8 134 // Set up bluetooth
alexhrao 1:0620ba35d2e8 135 dev.baud(9600);
alexhrao 1:0620ba35d2e8 136 pc.baud(9600);
alexhrao 8:d323c6406b47 137
alexhrao 1:0620ba35d2e8 138 // Tell user we're initializing...
alexhrao 1:0620ba35d2e8 139 lcd_lock.lock();
alexhrao 1:0620ba35d2e8 140 uLCD.cls();
alexhrao 1:0620ba35d2e8 141 uLCD.text_height(2);
alexhrao 6:ec7829f7cd38 142 uLCD.text_width(2);
alexhrao 6:ec7829f7cd38 143 uLCD.text_string("PLEASE", 0, 2, FONT_7X8, WHITE);
alexhrao 6:ec7829f7cd38 144 uLCD.text_string("WAIT", 0, 5, FONT_7X8, WHITE);
alexhrao 1:0620ba35d2e8 145 lcd_lock.unlock();
alexhrao 8:d323c6406b47 146
alexhrao 1:0620ba35d2e8 147 // Need to get wifi settings. If we don't have local file, then ask!
alexhrao 10:16356570821e 148 FILE* fid = fopen("/local/api_keys.txt", "r");
alexhrao 10:16356570821e 149 char settings_buf[1024];
alexhrao 10:16356570821e 150 int settings_ind = 0;
alexhrao 10:16356570821e 151 int counter = 0;
alexhrao 10:16356570821e 152 if (fid == NULL) {
alexhrao 10:16356570821e 153 lcd_lock.lock();
alexhrao 10:16356570821e 154 uLCD.cls();
alexhrao 10:16356570821e 155 uLCD.text_height(2);
alexhrao 10:16356570821e 156 uLCD.text_width(2);
alexhrao 10:16356570821e 157 uLCD.text_string("SEE", 0, 2, FONT_7X8, RED);
alexhrao 10:16356570821e 158 uLCD.text_string("DEVICE", 0, 5, FONT_7X8, RED);
alexhrao 10:16356570821e 159 lcd_lock.unlock();
alexhrao 10:16356570821e 160 // Ask
alexhrao 10:16356570821e 161 // Get the API key
alexhrao 10:16356570821e 162 dev.printf("Please provide the IP Stack API key\n");
alexhrao 10:16356570821e 163 while (!dev.readable()) {
alexhrao 10:16356570821e 164 wait(0.001);
alexhrao 10:16356570821e 165 }
alexhrao 10:16356570821e 166 int ind = 0;
alexhrao 10:16356570821e 167 while (ind < 255) {
alexhrao 10:16356570821e 168 char tmp = dev.getc();
alexhrao 10:16356570821e 169 if (tmp == '\n' || tmp == '\r') {
alexhrao 10:16356570821e 170 break;
alexhrao 10:16356570821e 171 }
alexhrao 10:16356570821e 172 ip_api_key[ind++] = tmp;
alexhrao 10:16356570821e 173 wait(0.01);
alexhrao 10:16356570821e 174 }
alexhrao 10:16356570821e 175
alexhrao 10:16356570821e 176 ip_api_key[ind] = '\0';
alexhrao 8:d323c6406b47 177
alexhrao 10:16356570821e 178 dev.printf("Please provide the TimeZoneDB API key\n");
alexhrao 10:16356570821e 179 while (!dev.readable()) {
alexhrao 10:16356570821e 180 wait(0.001);
alexhrao 10:16356570821e 181 }
alexhrao 10:16356570821e 182 ind = 0;
alexhrao 10:16356570821e 183 while (ind < 255) {
alexhrao 10:16356570821e 184 char tmp = dev.getc();
alexhrao 10:16356570821e 185 if (tmp == '\r' || tmp == '\n') {
alexhrao 10:16356570821e 186 break;
alexhrao 10:16356570821e 187 }
alexhrao 10:16356570821e 188 time_api_key[ind++] = tmp;
alexhrao 10:16356570821e 189 wait(0.01);
alexhrao 2:f7d19812bdc5 190 }
alexhrao 10:16356570821e 191 time_api_key[ind] = '\0';
alexhrao 10:16356570821e 192
alexhrao 10:16356570821e 193 dev.printf("Please provide the OpenWeather API key\n");
alexhrao 10:16356570821e 194 while (!dev.readable()) {
alexhrao 10:16356570821e 195 wait(0.001);
alexhrao 2:f7d19812bdc5 196 }
alexhrao 10:16356570821e 197 ind = 0;
alexhrao 10:16356570821e 198 while (ind < 255) {
alexhrao 10:16356570821e 199 char tmp = dev.getc();
alexhrao 10:16356570821e 200 if (tmp == '\r' || tmp == '\n') {
alexhrao 10:16356570821e 201 break;
alexhrao 10:16356570821e 202 }
alexhrao 10:16356570821e 203 weather_api_key[ind++] = tmp;
alexhrao 10:16356570821e 204 wait(0.01);
alexhrao 10:16356570821e 205 }
alexhrao 10:16356570821e 206 weather_api_key[ind] = '\0';
alexhrao 10:16356570821e 207 // Create file
alexhrao 10:16356570821e 208 fid = fopen("/local/api_keys.txt", "w");
alexhrao 10:16356570821e 209 fprintf(fid, "%s\n%s\n%s\n", ip_api_key, time_api_key, weather_api_key);
alexhrao 10:16356570821e 210 fclose(fid);
alexhrao 10:16356570821e 211 } else {
alexhrao 10:16356570821e 212 // Read from file
alexhrao 4:55f0c303f56a 213 fgets(settings_buf, 1024, fid);
alexhrao 4:55f0c303f56a 214 counter = 0;
alexhrao 4:55f0c303f56a 215 while (settings_buf[counter] != '\n') {
alexhrao 4:55f0c303f56a 216 ip_api_key[settings_ind++] = settings_buf[counter++];
alexhrao 4:55f0c303f56a 217 }
alexhrao 4:55f0c303f56a 218 ip_api_key[settings_ind] = '\0';
alexhrao 4:55f0c303f56a 219 settings_ind = 0;
alexhrao 4:55f0c303f56a 220 fgets(settings_buf, 1024, fid);
alexhrao 4:55f0c303f56a 221 counter = 0;
alexhrao 2:f7d19812bdc5 222 while (settings_buf[counter] != '\n') {
alexhrao 4:55f0c303f56a 223 time_api_key[settings_ind++] = settings_buf[counter++];
alexhrao 2:f7d19812bdc5 224 }
alexhrao 4:55f0c303f56a 225 time_api_key[settings_ind] = '\0';
alexhrao 4:55f0c303f56a 226 settings_ind = 0;
alexhrao 4:55f0c303f56a 227 fgets(settings_buf, 1024, fid);
alexhrao 4:55f0c303f56a 228 counter = 0;
alexhrao 4:55f0c303f56a 229 while (settings_buf[counter] != '\n') {
alexhrao 4:55f0c303f56a 230 weather_api_key[settings_ind++] = settings_buf[counter++];
alexhrao 4:55f0c303f56a 231 }
alexhrao 4:55f0c303f56a 232 weather_api_key[settings_ind] = '\0';
alexhrao 2:f7d19812bdc5 233 fclose(fid);
alexhrao 10:16356570821e 234 }
alexhrao 10:16356570821e 235
alexhrao 10:16356570821e 236 fid = fopen("/local/wifi.txt", "r");
alexhrao 10:16356570821e 237
alexhrao 10:16356570821e 238 if (fid != NULL) {
alexhrao 10:16356570821e 239 // Read WiFi Settings
alexhrao 10:16356570821e 240 // Guaranteed to be 2 lines
alexhrao 10:16356570821e 241 //
alexhrao 10:16356570821e 242 fgets(settings_buf, 1024, fid);
alexhrao 10:16356570821e 243 // find \n
alexhrao 10:16356570821e 244 settings_ind = 0;
alexhrao 10:16356570821e 245 counter = 0;
alexhrao 10:16356570821e 246 while (settings_buf[counter] != '\n') {
alexhrao 10:16356570821e 247 ssid[settings_ind++] = settings_buf[counter++];
alexhrao 10:16356570821e 248 }
alexhrao 10:16356570821e 249 ssid[settings_ind] = '\0';
alexhrao 10:16356570821e 250 settings_ind = 0;
alexhrao 10:16356570821e 251 fgets(settings_buf, 1024, fid);
alexhrao 10:16356570821e 252 counter = 0;
alexhrao 10:16356570821e 253 while (settings_buf[counter] != '\n') {
alexhrao 10:16356570821e 254 pass[settings_ind++] = settings_buf[counter++];
alexhrao 10:16356570821e 255 }
alexhrao 10:16356570821e 256 pass[settings_ind] = '\0';
alexhrao 10:16356570821e 257 fclose(fid);
alexhrao 1:0620ba35d2e8 258 } else {
alexhrao 1:0620ba35d2e8 259 lcd_lock.lock();
alexhrao 1:0620ba35d2e8 260 uLCD.cls();
alexhrao 1:0620ba35d2e8 261 uLCD.text_height(2);
alexhrao 1:0620ba35d2e8 262 uLCD.text_width(2);
alexhrao 1:0620ba35d2e8 263 uLCD.text_string("SEE", 0, 2, FONT_7X8, RED);
alexhrao 1:0620ba35d2e8 264 uLCD.text_string("DEVICE", 0, 5, FONT_7X8, RED);
alexhrao 1:0620ba35d2e8 265 lcd_lock.unlock();
alexhrao 8:d323c6406b47 266
alexhrao 1:0620ba35d2e8 267 // Ask!
alexhrao 1:0620ba35d2e8 268 dev.printf("Please provide the name of a WiFi Network\n");
alexhrao 8:d323c6406b47 269
alexhrao 1:0620ba35d2e8 270 // Wait for them to respond
alexhrao 1:0620ba35d2e8 271 while (!dev.readable()) {
alexhrao 1:0620ba35d2e8 272 wait(0.001);
alexhrao 1:0620ba35d2e8 273 }
alexhrao 1:0620ba35d2e8 274 int ind = 0;
alexhrao 8:d323c6406b47 275
alexhrao 1:0620ba35d2e8 276 // Read response
alexhrao 1:0620ba35d2e8 277 while (ind < 255) {
alexhrao 1:0620ba35d2e8 278 char tmp = dev.getc();
alexhrao 1:0620ba35d2e8 279 if (tmp == '\n' || tmp == '\r') {
alexhrao 1:0620ba35d2e8 280 break;
alexhrao 1:0620ba35d2e8 281 }
alexhrao 1:0620ba35d2e8 282 ssid[ind++] = tmp;
alexhrao 1:0620ba35d2e8 283 wait(0.01);
alexhrao 1:0620ba35d2e8 284 }
alexhrao 1:0620ba35d2e8 285 ssid[ind] = '\0';
alexhrao 8:d323c6406b47 286
alexhrao 1:0620ba35d2e8 287 // flush device
alexhrao 1:0620ba35d2e8 288 while (dev.readable()) {
alexhrao 1:0620ba35d2e8 289 dev.getc();
alexhrao 1:0620ba35d2e8 290 wait(0.01);
alexhrao 1:0620ba35d2e8 291 }
alexhrao 8:d323c6406b47 292
alexhrao 2:f7d19812bdc5 293 // Get the password
alexhrao 1:0620ba35d2e8 294 dev.printf("Please provide the password\n");
alexhrao 1:0620ba35d2e8 295 while (!dev.readable()) {
alexhrao 1:0620ba35d2e8 296 wait(0.001);
alexhrao 1:0620ba35d2e8 297 }
alexhrao 1:0620ba35d2e8 298 ind = 0;
alexhrao 1:0620ba35d2e8 299 while (ind < 255) {
alexhrao 1:0620ba35d2e8 300 char tmp = dev.getc();
alexhrao 1:0620ba35d2e8 301 if (tmp == '\n' || tmp == '\r') {
alexhrao 1:0620ba35d2e8 302 break;
alexhrao 1:0620ba35d2e8 303 }
alexhrao 1:0620ba35d2e8 304 pass[ind++] = tmp;
alexhrao 1:0620ba35d2e8 305 wait(0.01);
alexhrao 1:0620ba35d2e8 306 }
alexhrao 1:0620ba35d2e8 307 pass[ind] = '\0';
alexhrao 8:d323c6406b47 308 // Because this is a simple proof of concept, we store the password in
alexhrao 8:d323c6406b47 309 // plaintext. It should be noted, however, that you **should never do
alexhrao 1:0620ba35d2e8 310 // this in "real life"**
alexhrao 10:16356570821e 311 fid = fopen("/local/wifi.txt", "w");
alexhrao 10:16356570821e 312 fprintf(fid, "%s\n%s\n", ssid, pass);
alexhrao 4:55f0c303f56a 313 fclose(fid);
alexhrao 1:0620ba35d2e8 314 }
alexhrao 6:ec7829f7cd38 315 /*
alexhrao 4:55f0c303f56a 316 dev.printf("\r\n** CREDENTIALS **\r\n");
alexhrao 4:55f0c303f56a 317 dev.printf("SSID: **%s** (%d)\r\n", ssid, strlen(ssid));
alexhrao 4:55f0c303f56a 318 dev.printf("PASS: **%s** (%d)\r\n", pass, strlen(pass));
alexhrao 4:55f0c303f56a 319 dev.printf("IP STACK: **%s**\r\n", ip_api_key);
alexhrao 4:55f0c303f56a 320 dev.printf("TIMEZONEDB: **%s**\r\n", time_api_key);
alexhrao 4:55f0c303f56a 321 dev.printf("WEATHERMAP: **%s**\r\n", weather_api_key);
alexhrao 6:ec7829f7cd38 322 */
alexhrao 1:0620ba35d2e8 323 bool res = wifi.init();
alexhrao 4:55f0c303f56a 324
alexhrao 1:0620ba35d2e8 325 // Set up the WiFi Access Point
alexhrao 1:0620ba35d2e8 326 dev.printf("Connecting to WiFi %s with Password %s\n", ssid, pass);
alexhrao 8:d323c6406b47 327
alexhrao 5:b77a717feada 328 res = wifi.connect(ssid, pass);
alexhrao 2:f7d19812bdc5 329 if (!res) {
alexhrao 2:f7d19812bdc5 330 dev.printf("Connection Failed... Resetting Device\n");
alexhrao 2:f7d19812bdc5 331 err_led = 1;
alexhrao 2:f7d19812bdc5 332 mbed_reset();
alexhrao 2:f7d19812bdc5 333 }
alexhrao 8:d323c6406b47 334
alexhrao 2:f7d19812bdc5 335 dev.printf("Connected with IP Address: %s\n", wifi.getIPAddress());
alexhrao 8:d323c6406b47 336
alexhrao 4:55f0c303f56a 337 /** API REQUESTS **/
alexhrao 8:d323c6406b47 338
alexhrao 4:55f0c303f56a 339 int header_ind = 0;
alexhrao 4:55f0c303f56a 340 int footer_ind = 0;
alexhrao 4:55f0c303f56a 341 int read_len = 0;
alexhrao 4:55f0c303f56a 342 char buffer[BUF_SIZE];
alexhrao 4:55f0c303f56a 343 char cmd[512];
alexhrao 4:55f0c303f56a 344
alexhrao 3:7bf41989ff8f 345 TCPSocketConnection tcp;
alexhrao 3:7bf41989ff8f 346 tcp.connect("api.ipstack.com", 80);
alexhrao 8:d323c6406b47 347
alexhrao 8:d323c6406b47 348 sprintf(cmd,
alexhrao 8:d323c6406b47 349 "GET /check?access_key=%s HTTP/1.1\r\nHost: api.ipstack.com\r\n\r\n",
alexhrao 8:d323c6406b47 350 ip_api_key);
alexhrao 4:55f0c303f56a 351 tcp.send_all(cmd, strlen(cmd));
alexhrao 8:d323c6406b47 352
alexhrao 4:55f0c303f56a 353 wait(5);
alexhrao 8:d323c6406b47 354
alexhrao 4:55f0c303f56a 355 read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
alexhrao 3:7bf41989ff8f 356 buffer[read_len] = '\0';
alexhrao 8:d323c6406b47 357
alexhrao 4:55f0c303f56a 358 // Cleanup
alexhrao 8:d323c6406b47 359
alexhrao 4:55f0c303f56a 360 while (header_ind < read_len) {
alexhrao 4:55f0c303f56a 361 // if we are \r, look ahead to see \n\r\n:
alexhrao 4:55f0c303f56a 362 if(buffer[header_ind] == '\r' &&
alexhrao 8:d323c6406b47 363 buffer[header_ind+1] == '\n' &&
alexhrao 8:d323c6406b47 364 buffer[header_ind+2] == '\r' &&
alexhrao 8:d323c6406b47 365 buffer[header_ind+3] == '\n') {
alexhrao 4:55f0c303f56a 366 // Increment header_ind, look for JSON
alexhrao 4:55f0c303f56a 367 // Now just look for {
alexhrao 4:55f0c303f56a 368 header_ind += 4;
alexhrao 4:55f0c303f56a 369 while (header_ind < read_len) {
alexhrao 4:55f0c303f56a 370 if (buffer[header_ind] == '{') {
alexhrao 4:55f0c303f56a 371 // we got it!
alexhrao 4:55f0c303f56a 372 break;
alexhrao 4:55f0c303f56a 373 }
alexhrao 4:55f0c303f56a 374 header_ind++;
alexhrao 4:55f0c303f56a 375 }
alexhrao 4:55f0c303f56a 376 break;
alexhrao 4:55f0c303f56a 377 }
alexhrao 4:55f0c303f56a 378 header_ind++;
alexhrao 4:55f0c303f56a 379 }
alexhrao 4:55f0c303f56a 380 for (footer_ind = read_len - 1; footer_ind > header_ind; footer_ind--) {
alexhrao 4:55f0c303f56a 381 if(buffer[footer_ind] == '}') {
alexhrao 4:55f0c303f56a 382 break;
alexhrao 4:55f0c303f56a 383 }
alexhrao 4:55f0c303f56a 384 }
alexhrao 4:55f0c303f56a 385 buffer[footer_ind + 1] = '\0';
alexhrao 6:ec7829f7cd38 386
alexhrao 9:299eb69af04e 387 MbedJSONValue* parser = new MbedJSONValue();
alexhrao 9:299eb69af04e 388 parse(*parser, buffer + header_ind);
alexhrao 8:d323c6406b47 389
alexhrao 9:299eb69af04e 390 latitude = (*parser)["latitude"].get<double>();
alexhrao 9:299eb69af04e 391 longitude = (*parser)["longitude"].get<double>();
alexhrao 9:299eb69af04e 392 delete(parser);
alexhrao 4:55f0c303f56a 393 // Get the Time
alexhrao 4:55f0c303f56a 394 TCPSocketConnection time_tcp;
alexhrao 4:55f0c303f56a 395
alexhrao 4:55f0c303f56a 396 time_tcp.connect("api.timezonedb.com", 80);
alexhrao 6:ec7829f7cd38 397
alexhrao 4:55f0c303f56a 398 sprintf(cmd,
alexhrao 8:d323c6406b47 399 "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",
alexhrao 8:d323c6406b47 400 time_api_key,
alexhrao 8:d323c6406b47 401 latitude,
alexhrao 8:d323c6406b47 402 longitude);
alexhrao 4:55f0c303f56a 403
alexhrao 4:55f0c303f56a 404 time_tcp.send_all(cmd, strlen(cmd));
alexhrao 6:ec7829f7cd38 405
alexhrao 4:55f0c303f56a 406 wait(5);
alexhrao 6:ec7829f7cd38 407
alexhrao 4:55f0c303f56a 408 read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
alexhrao 3:7bf41989ff8f 409 buffer[read_len] = '\0';
alexhrao 8:d323c6406b47 410
alexhrao 4:55f0c303f56a 411 // Cleanup
alexhrao 8:d323c6406b47 412
alexhrao 4:55f0c303f56a 413 // Clean up front
alexhrao 4:55f0c303f56a 414 // Read through headers (\r\n\r\n)
alexhrao 4:55f0c303f56a 415 header_ind = 0;
alexhrao 4:55f0c303f56a 416 while (header_ind < read_len) {
alexhrao 4:55f0c303f56a 417 // if we are \r, look ahead to see \n\r\n:
alexhrao 4:55f0c303f56a 418 if(buffer[header_ind] == '\r' &&
alexhrao 8:d323c6406b47 419 buffer[header_ind+1] == '\n' &&
alexhrao 8:d323c6406b47 420 buffer[header_ind+2] == '\r' &&
alexhrao 8:d323c6406b47 421 buffer[header_ind+3] == '\n') {
alexhrao 4:55f0c303f56a 422 // Increment header_ind, look for JSON
alexhrao 4:55f0c303f56a 423 // Now just look for {
alexhrao 4:55f0c303f56a 424 header_ind += 4;
alexhrao 4:55f0c303f56a 425 while (header_ind < read_len) {
alexhrao 4:55f0c303f56a 426 if (buffer[header_ind] == '{') {
alexhrao 4:55f0c303f56a 427 // we got it!
alexhrao 4:55f0c303f56a 428 break;
alexhrao 4:55f0c303f56a 429 }
alexhrao 4:55f0c303f56a 430 header_ind++;
alexhrao 4:55f0c303f56a 431 }
alexhrao 4:55f0c303f56a 432 break;
alexhrao 4:55f0c303f56a 433 }
alexhrao 4:55f0c303f56a 434 header_ind++;
alexhrao 4:55f0c303f56a 435 }
alexhrao 4:55f0c303f56a 436
alexhrao 4:55f0c303f56a 437 for (footer_ind = read_len - 1; footer_ind > header_ind; footer_ind--) {
alexhrao 4:55f0c303f56a 438 if(buffer[footer_ind] == '}') {
alexhrao 4:55f0c303f56a 439 break;
alexhrao 4:55f0c303f56a 440 }
alexhrao 4:55f0c303f56a 441 }
alexhrao 4:55f0c303f56a 442 buffer[footer_ind + 1] = '\0';
alexhrao 9:299eb69af04e 443 parser = new MbedJSONValue();
alexhrao 9:299eb69af04e 444 parse(*parser, buffer + header_ind);
alexhrao 4:55f0c303f56a 445
alexhrao 4:55f0c303f56a 446 // Add 5 so that we make up for the wait(5)
alexhrao 6:ec7829f7cd38 447 // Add 3 so that we make up for TCP request - empirically...
alexhrao 9:299eb69af04e 448 set_time((*parser)["timestamp"].get<int>() + 5 + 3);
alexhrao 9:299eb69af04e 449 delete(parser);
alexhrao 9:299eb69af04e 450 lcd_lock.lock();
alexhrao 9:299eb69af04e 451 uLCD.cls();
alexhrao 9:299eb69af04e 452 lcd_lock.unlock();
alexhrao 4:55f0c303f56a 453 // Now that we know what time it is, set up our Time Thread
alexhrao 4:55f0c303f56a 454 time_thread.start(time_updater);
alexhrao 8:d323c6406b47 455
alexhrao 4:55f0c303f56a 456 TCPSocketConnection forecast_sck;
alexhrao 6:ec7829f7cd38 457
alexhrao 4:55f0c303f56a 458 forecast_sck.connect("api.openweathermap.org", 80);
alexhrao 6:ec7829f7cd38 459
alexhrao 4:55f0c303f56a 460 sprintf(cmd,
alexhrao 9:299eb69af04e 461 "GET /data/2.5/forecast?lat=%0.4f&lon=%0.4f&APPID=%s&cnt=1\r\nHost: api.openweathermap.org\r\n\r\n",
alexhrao 8:d323c6406b47 462 latitude, longitude, weather_api_key);
alexhrao 4:55f0c303f56a 463 forecast_sck.send_all(cmd, strlen(cmd));
alexhrao 6:ec7829f7cd38 464
alexhrao 4:55f0c303f56a 465 wait(5);
alexhrao 4:55f0c303f56a 466
alexhrao 9:299eb69af04e 467 read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
alexhrao 6:ec7829f7cd38 468 buffer[read_len] = '\0';
alexhrao 8:d323c6406b47 469
alexhrao 6:ec7829f7cd38 470 // We don't have enough memory for another parser (why?), so just
alexhrao 6:ec7829f7cd38 471 // look for the word "temp" 0 hopefully won't have a city named "temp"!
alexhrao 4:55f0c303f56a 472 char* ind = strstr(buffer, "temp");
alexhrao 4:55f0c303f56a 473 char num_buf[16];
alexhrao 4:55f0c303f56a 474 int num_ind = 0;
alexhrao 4:55f0c303f56a 475 // go until we find numbers
alexhrao 4:55f0c303f56a 476 while (char tmp = *ind++) {
alexhrao 4:55f0c303f56a 477 if (tmp > '0' && tmp < '9') {
alexhrao 4:55f0c303f56a 478 num_buf[num_ind++] = tmp;
alexhrao 4:55f0c303f56a 479 break;
alexhrao 4:55f0c303f56a 480 }
alexhrao 4:55f0c303f56a 481 }
alexhrao 4:55f0c303f56a 482 // Keep moving until no more numbers
alexhrao 4:55f0c303f56a 483 while (char tmp = *ind++) {
alexhrao 4:55f0c303f56a 484 if (tmp > '9' || tmp < '0') {
alexhrao 4:55f0c303f56a 485 num_buf[num_ind] = '\0';
alexhrao 4:55f0c303f56a 486 break;
alexhrao 4:55f0c303f56a 487 } else {
alexhrao 4:55f0c303f56a 488 num_buf[num_ind++] = tmp;
alexhrao 4:55f0c303f56a 489 }
alexhrao 4:55f0c303f56a 490 }
alexhrao 4:55f0c303f56a 491 int temp = atoi(num_buf);
alexhrao 9:299eb69af04e 492
alexhrao 4:55f0c303f56a 493 // Convert
alexhrao 6:ec7829f7cd38 494 temp = kelvin2farenheit(temp);
alexhrao 4:55f0c303f56a 495 char temp_buf[12];
alexhrao 4:55f0c303f56a 496 sprintf(temp_buf, " %dF", temp);
alexhrao 8:d323c6406b47 497
alexhrao 2:f7d19812bdc5 498 lcd_lock.lock();
alexhrao 4:55f0c303f56a 499 uLCD.text_width(2);
alexhrao 4:55f0c303f56a 500 uLCD.text_height(2);
alexhrao 4:55f0c303f56a 501 uLCD.text_string(temp_buf, 0, 5, FONT_8X8, WHITE);
alexhrao 2:f7d19812bdc5 502 lcd_lock.unlock();
alexhrao 6:ec7829f7cd38 503
alexhrao 6:ec7829f7cd38 504 time_t prev_time = time(NULL);
alexhrao 1:0620ba35d2e8 505 while(true) {
alexhrao 3:7bf41989ff8f 506 time_t curr_time = time(NULL);
alexhrao 6:ec7829f7cd38 507 // Wait for 60 seconds
alexhrao 6:ec7829f7cd38 508 if ((prev_time + 60) < curr_time) {
alexhrao 4:55f0c303f56a 509 sprintf(cmd,
alexhrao 8:d323c6406b47 510 "GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n",
alexhrao 8:d323c6406b47 511 latitude, longitude, weather_api_key);
alexhrao 4:55f0c303f56a 512 forecast_sck.connect("api.openweathermap.org", 80);
alexhrao 4:55f0c303f56a 513 wait(10);
alexhrao 4:55f0c303f56a 514 forecast_sck.send_all(cmd, strlen(cmd));
alexhrao 4:55f0c303f56a 515 wait(5);
alexhrao 4:55f0c303f56a 516
alexhrao 6:ec7829f7cd38 517 read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
alexhrao 4:55f0c303f56a 518
alexhrao 6:ec7829f7cd38 519 buffer[read_len] = '\0';
alexhrao 4:55f0c303f56a 520
alexhrao 4:55f0c303f56a 521 ind = strstr(buffer, "temp");
alexhrao 4:55f0c303f56a 522 num_ind = 0;
alexhrao 4:55f0c303f56a 523 // go until we find numbers
alexhrao 4:55f0c303f56a 524 while (char tmp = *ind++) {
alexhrao 4:55f0c303f56a 525 if (tmp > '0' && tmp < '9') {
alexhrao 4:55f0c303f56a 526 num_buf[num_ind++] = tmp;
alexhrao 4:55f0c303f56a 527 break;
alexhrao 4:55f0c303f56a 528 }
alexhrao 4:55f0c303f56a 529 }
alexhrao 4:55f0c303f56a 530 // Keep moving until no more numbers
alexhrao 4:55f0c303f56a 531 while (char tmp = *ind++) {
alexhrao 4:55f0c303f56a 532 if (tmp > '9' || tmp < '0') {
alexhrao 4:55f0c303f56a 533 num_buf[num_ind] = '\0';
alexhrao 4:55f0c303f56a 534 break;
alexhrao 4:55f0c303f56a 535 } else {
alexhrao 4:55f0c303f56a 536 num_buf[num_ind++] = tmp;
alexhrao 4:55f0c303f56a 537 }
alexhrao 4:55f0c303f56a 538 }
alexhrao 4:55f0c303f56a 539 temp = atoi(num_buf);
alexhrao 6:ec7829f7cd38 540
alexhrao 4:55f0c303f56a 541 // Convert
alexhrao 6:ec7829f7cd38 542 temp = kelvin2farenheit(temp);
alexhrao 4:55f0c303f56a 543 sprintf(temp_buf, " %dF", temp);
alexhrao 4:55f0c303f56a 544 lcd_lock.lock();
alexhrao 4:55f0c303f56a 545 uLCD.text_width(2);
alexhrao 4:55f0c303f56a 546 uLCD.text_height(2);
alexhrao 4:55f0c303f56a 547 uLCD.text_string(temp_buf, 0, 5, FONT_8X8, WHITE);
alexhrao 4:55f0c303f56a 548 lcd_lock.unlock();
alexhrao 3:7bf41989ff8f 549 }
alexhrao 0:4ffa136585a2 550 }
alexhrao 0:4ffa136585a2 551 }
alexhrao 4:55f0c303f56a 552
alexhrao 8:d323c6406b47 553 int main()
alexhrao 8:d323c6406b47 554 {
alexhrao 4:55f0c303f56a 555 clock_init();
alexhrao 4:55f0c303f56a 556 }