Fork from Alex

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

main.cpp

Committer:
alexhrao
Date:
2019-03-31
Revision:
2:f7d19812bdc5
Parent:
1:0620ba35d2e8
Child:
3:7bf41989ff8f

File content as of revision 2:f7d19812bdc5:

#include "mbed.h"
#include "uLCD_4DGL.h"
#include "ESP8266Interface.h"
#include "TCPSocketConnection.h"
#include "rtos.h"

// We need this for being able to reset the MBED (similar to watch dogs)
extern "C" void mbed_reset();

// LCD Screen
uLCD_4DGL uLCD(p9, p10, p11);
Mutex lcd_lock;

// File System
LocalFileSystem fs("local");

// Bluetooth
RawSerial pc(USBTX, USBRX);
RawSerial dev(p28,p27);
Thread dev_thread;

// Error LED
DigitalOut err_led(LED1);

// WiFi
ESP8266Interface wifi(p13, p14, p15, 9600, 10000);

// Time
Thread time_thread;

// Weather
Thread weather_thread;
char* forecast_link;

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
    struct tm* ltm;
    time_t now;
    
    now = time(NULL);
    ltm = localtime(&now);
    
    // Buffer for time string. Max length is 23:59 + \0
    int max_time_len = 6;
    char ftime[max_time_len];
    
    int min = -1;
    
    while (true) {
        // if the minute has changed, update.
        now = time(NULL);
        ltm = localtime(&now);
        if(ltm->tm_min != min) {
            // Get the new time
            strftime(ftime, max_time_len, "%H:%M", ltm); 
            // Update time! Lock the lcd mutex
            lcd_lock.lock();
            uLCD.text_width(2);
            uLCD.text_height(2);
            uLCD.text_string(ftime, 0, 2, FONT_8X8, GREEN);
            // Done updating - unlock!
            lcd_lock.unlock();
            min = ltm->tm_min;
        }
        // Wait 1 second
        Thread::wait(1.0f);
    }   
}

void weather_updater() {
    // We can take as long as we want
    while (true) {
        // get the weather
        // 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();
        Thread::wait(3600);
    }
}

void dev_recv() {
    // Continually check if we have stuff...
    char buf[1024];
    int ind = 0;
    while (true) {
        while (true) {
            // get stuff. If we encounter \r or \n, that's a complete command!
            char tmp = dev.getc();
            if (tmp == '\n' || tmp == '\r') {
                break;
            }
            buf[ind++] = tmp;
            Thread::wait(0.01);
        }
        buf[ind] = '\0';
        // read command and respond
        if (strcmp(buf, "reset") == 0) {
            dev.printf("Are you sure? y/[n]\n");
        }
        buf[0] = '\0';
        ind = 0;
        //if (strcmp(buf, "reset") != 0) {
        Thread::wait(0.01);
    }
}

int main() {
    // Set up bluetooth
    dev.baud(9600);
    pc.baud(9600);
    
    // Tell user we're initializing...
    lcd_lock.lock();
    uLCD.cls();
    uLCD.text_height(2);
    uLCD.text_string("PLEASE WAIT", 0, 2, FONT_7X8, WHITE);
    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];
    if (true) {
        
    } else if (fid != NULL) {
        // Read WiFi Settings
        char settings_buf[1024];
        // Guaranteed to be 256, 256, 512 AT MOST + two new lines
        // 
        fgets(settings_buf, 1024, fid);
        // find \n
        int settings_ind = 0;
        int counter = 0;
        while (settings_buf[counter] != '\n') {
            ssid[settings_ind++] = settings_buf[counter++];
        }
        ssid[settings_ind] = '\0';
        settings_ind = 0;
        counter++;
        while (settings_buf[counter] != '\n') {
            pass[settings_ind++] = settings_buf[counter++];
        }
        pass[settings_ind] = '\0';
        settings_ind = 0;
        counter++;
        while (settings_buf[counter] != '\n') {
            api_key[settings_ind++] = settings_buf[counter++];
        }
        api_key[settings_ind] = '\0';
        fclose(fid);
    } else {
        lcd_lock.lock();
        uLCD.cls();
        uLCD.text_height(2);
        uLCD.text_width(2);
        uLCD.text_string("SEE", 0, 2, FONT_7X8, RED);
        uLCD.text_string("DEVICE", 0, 5, FONT_7X8, RED);
        lcd_lock.unlock();
        
        // Ask!
        dev.printf("Please provide the name of a WiFi Network\n");
        
        // Wait for them to respond
        while (!dev.readable()) {
            wait(0.001);
        }
        int ind = 0;
        
        // Read response
        while (ind < 255) {
            char tmp = dev.getc();
            if (tmp == '\n' || tmp == '\r') {
                break;
            }
            ssid[ind++] = tmp;
            wait(0.01);
        }
        ssid[ind] = '\0';
        
        // flush device
        while (dev.readable()) {
            dev.getc();
            wait(0.01);
        }
        
        // Get the password
        dev.printf("Please provide the password\n");
        while (!dev.readable()) {
            wait(0.001);
        }
        ind = 0;
        while (ind < 255) {
            char tmp = dev.getc();
            if (tmp == '\n' || tmp == '\r') {
                break;
            }
            pass[ind++] = tmp;
            wait(0.01);
        }
        pass[ind] = '\0';
        
        // Get the API key
        dev.printf("Please provide the API key\n");
        while (!dev.readable()) {
            wait(0.001);
        }
        ind = 0;
        while (ind < 255) {
            char tmp = dev.getc();
            if (tmp == '\n' || tmp == '\r') {
                break;
            }
            api_key[ind++] = tmp;
            wait(0.01);
        }
        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);
    }
    
    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
    dev.printf("Getting the current time & location...\n");
    
    set_time(1256729737);
    
    // Clear the LCD Screen first
    lcd_lock.lock();
    uLCD.cls();
    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
    TCPSocketConnection tcp;
    int tcp_res = tcp.connect("alexhrao.com", 80);
    dev.printf("Connection: %d\n", tcp_res);
    //int sent = tcp.send("GET / HTTP/1.1\r\nHost: alexhrao.com\r\nUser-Agent: curl/7.54.0\r\nAccept: */*", 73);
    tcp.set_blocking(true, 10000);
    char* cmd = "GET / HTTP/1.1\r\nHost: alexhrao.com\r\n\r\n";
    int sent = tcp.send_all(cmd, strlen(cmd));
    dev.printf("Sent %d\n", sent);
    char buf[128];
    for (int i = 0; i < 32; i++) {
        buf[i] = 0;
    }
//    wifi.send(cmd, strlen(cmd));
//    wifi.recv(buf, 2048);
//wait(15);
    //tcp.receive(buf, 16);
    int to_rec = 7;
    //wifi.getc();
    while (true) {
        wifi.recv(buf, &to_rec);
        dev.printf("To Receive: %d\n", to_rec);
        to_rec = 7;
        buf[7] = '\0';
        dev.printf("%s", buf);
        wait(15);
    }
    wifi.recv(buf, &to_rec);
    dev.printf("%s\n", buf);
    wifi.recv(buf, &to_rec);
    int recv2 = tcp.receive_all(buf, 4);
    dev.printf("Received (%d):\n%s\n", recv2, buf);
    // Where are we & What time is it?
    // Create the TCP connection, request from ipstack. Get the request,
    // and store the current time (FORMAT?)
    set_time(1256729737);
    // Now that we know what time it is, set up our Time Thread
    time_thread.start(time_updater);
    // 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);
    while(true) {
        err_led = !err_led;
        //dev.printf("Connection Status: %d\n", wifi.is_connected());
        wait(0.5);
    }
}