Dreamforce Heroku Sample mbed application for the FRDM-K64F. This application uses SocketIO to connect and communicate with Heroku.

Dependencies:   BufferedSerial C12832 EthernetInterface HTTPClient-SSL LM75B MMA7660 SocketIO-k64f WebSocketClient-ThermostatDemo mbed-rtos mbed picojson

Fork of df-2013-minihack-thermostat-complete by MBED_DEMOS

Files at this revision

API Documentation at this revision

Comitter:
ansond
Date:
Tue Nov 05 21:31:01 2013 +0000
Child:
1:3faa003ad6e6
Commit message:
initial checkin

Changed in this revision

C12832_lcd.lib Show annotated file Show diff for this revision Revisions of this file
EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
HTTPClient.lib Show annotated file Show diff for this revision Revisions of this file
LM75B.lib Show annotated file Show diff for this revision Revisions of this file
MMA7660.lib Show annotated file Show diff for this revision Revisions of this file
README.txt Show annotated file Show diff for this revision Revisions of this file
SocketIO.lib Show annotated file Show diff for this revision Revisions of this file
Thermostat-BaseUtils.h Show annotated file Show diff for this revision Revisions of this file
Thermostat-LEDUtils.h Show annotated file Show diff for this revision Revisions of this file
Thermostat-Location.h Show annotated file Show diff for this revision Revisions of this file
Thermostat.cpp Show annotated file Show diff for this revision Revisions of this file
Thermostat.h Show annotated file Show diff for this revision Revisions of this file
ThermostatSocketIO.cpp Show annotated file Show diff for this revision Revisions of this file
ThermostatSocketIO.h Show annotated file Show diff for this revision Revisions of this file
WebSocketClient.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
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
picojson.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C12832_lcd.lib	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/dreschpe/code/C12832_lcd/#c9afe58d786a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetInterface.lib	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/EthernetInterface/#cba86db5ab96
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPClient.lib	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/HTTPClient/#be61104f4e91
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LM75B.lib	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/chris/code/LM75B/#6a70c9303bbe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA7660.lib	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/Sissors/code/MMA7660/#a8e20db7901e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.txt	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,25 @@
+Instructions:
+
+1). Complete the “hands-on” exercises first
+    - Required to get setup with an mbed account and the compiler environment
+
+2). Import the “df-2013-minihack-thermostat” project into your mbed project workspace
+    - Be sure to add and make current the “mbed LPC1768” board as the current board 
+      to compile to. You can modify the GPS coords and devie name in the same manner
+      that you did in the hands-on session - this will enable you to quickly and easily
+      identify your device on the map
+
+3). Examine Thermostat.cpp in your project
+    - In the top of the file, examine the Mini-hack challenge statement 
+    - Follow those instructions to modify the code to create a way to write text from the
+      Heroku webservice  
+
+A successful implementation will:
+    - Enable you to see your mbed device on the map
+    - Clicking on the device name (its a URL link) you should be able to go to the Devices
+    - page on the website and enter "text" for the message name followed by a text message
+    - after a brief delay, the text message should pop up briefly on the mbed device LCD
+
+References:
+    - Project Source:  http://mbed.org/teams/MBED_DEMOS/code/df-2013-minihack-thermostat/ 
+    - Completed Code: http://mbed.org/teams/MBED_DEMOS/code/df-2013-minihack-thermostat-complete/ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SocketIO.lib	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/ansond/code/SocketIO/#997b8c5d2d46
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Thermostat-BaseUtils.h	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,68 @@
+/* Thermostat-BaseUtils.h */
+/* Copyright (C) 2013 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+ 
+#ifndef THERMOSTAT_BASEUTILS_H_
+#define THERMOSTAT_BASEUTILS_H_
+
+// AppBoard LCD Support
+#include "C12832_lcd.h"
+C12832_LCD lcd;
+
+// Serial Console Support (main.cpp)
+extern Serial pc;
+
+// log messages to appropriate outputs
+void Thermostat::logMessage(bool do_lcd) {    
+    // print to LCD panel
+    if (do_lcd) {
+        lcd.cls();
+        lcd.locate(0,0);
+        lcd.printf(this->m_display_message);
+    }
+    else {
+        // print to serial console
+        pc.printf(this->m_display_message);
+        pc.printf("\r\n");
+    }
+    
+    // wait a bit so that the message can be read
+    wait(0.5);
+}
+
+// display output
+void Thermostat::display(const char *format, ...) {   
+    memset(this->m_display_message,'\0',MAX_MESSAGE_LENGTH+1);
+    va_list args;
+    va_start(args, format);
+    vsprintf(this->m_display_message, format, args);
+    va_end(args);
+    this->logMessage(false);
+}
+
+// display output
+void Thermostat::display_lcd(const char *format, ...) {
+    memset(this->m_display_message,'\0',MAX_MESSAGE_LENGTH+1);
+    va_list args;
+    va_start(args, format);
+    vsprintf(this->m_display_message, format, args);
+    va_end(args);
+    this->logMessage(true);
+}
+
+#endif // THERMOSTAT_BASEUTILS_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Thermostat-LEDUtils.h	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,183 @@
+/* Thermostat-LEDUtils.h */
+/* Copyright (C) 2013 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+ 
+#ifndef THERMOSTAT_LEDUTILS_H_
+#define THERMOSTAT_LEDUTILS_H_
+
+// LEDs to toggle with control messages
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+// Joystick button (to create an error condition)
+DigitalIn joystick_pressed(p14);
+DigitalIn joystick(p15);        
+
+// Pot 1 for dialing up and down the temperature
+AnalogIn Pot1(p19);
+
+// Pot 2 for dialing up and down the battery level
+AnalogIn Pot2(p20);
+
+// the led's are connected to vcc, so a PwmOut of 100% will shut off the led and 0% will let it shine
+PwmOut r (p23);
+PwmOut g (p24);
+PwmOut b (p25);
+
+// get the int value of the joystick state
+int Thermostat::getErrorState() {
+    if (this->m_error_state)
+        return 1;
+    else
+        return 0;
+}
+
+// function to convert hue , saturation and  value to RGB - then update the RGB LED
+// see http://en.wikipedia.org/wiki/HSL_and_HSV
+void Thermostat::updateRGBLED(float H, float S, float V) {
+    float f,h,p,q,t;
+    int i;
+    if( S == 0.0) {
+        r = 1.0 - V;  // invert pwm !
+        g = 1.0 - V;
+        b = 1.0 - V;
+        return;
+    }
+    if(H > 360.0) H = 0.0;   // check values
+    if(S > 1.0) S = 1.0; 
+    if(S < 0.0) S = 0.0;
+    if(V > 1.0) V = 1.0;
+    if(V < 0.0) V = 0.0;
+    h = H / 60.0;
+    i = (int) h;
+    f = h - i;
+    p = V * (1.0 - S);
+    q = V * (1.0 - (S * f));
+    t = V * (1.0 - (S * (1.0 - f)));
+
+    switch(i) {
+        case 0:
+            r = 1.0 - V;  // invert pwm !
+            g = 1.0 - t;
+            b = 1.0 - p;
+            break;
+        case 1:
+            r = 1.0 - q;
+            g = 1.0 - V;
+            b = 1.0 - p;
+            break;
+        case 2:
+            r = 1.0 - p;
+            g = 1.0 - V;
+            b = 1.0 - t;
+            break;
+        case 3:
+            r = 1.0 - p;
+            g = 1.0 - q;
+            b = 1.0 - V;
+            break;
+        case 4:
+            r = 1.0 - t;
+            g = 1.0 - p;
+            b = 1.0 - V;
+            break;
+        case 5:
+        default:
+            r = 1.0 - V;
+            g = 1.0 - p;
+            b = 1.0 - q;
+            break;
+    }
+}
+
+// set all the LEDs
+void Thermostat::setAllLEDs(int state) {
+    led1.write(state);
+    led2.write(state);
+    led3.write(state);
+    led4.write(state);
+}
+
+// set all the LEDs
+void Thermostat::resetAllLEDs() {
+    this->setAllLEDs(0);
+}
+
+// set all the LEDs
+void Thermostat::blinkAllLEDs() {
+    for(int i=0;i<4;++i) {
+        wait(1.0);
+        this->setAllLEDs(1);
+        this->display("Blinking on...");
+        wait(1.0);
+        this->setAllLEDs(0);
+        this->display("Blinking off...");
+    }
+}
+
+// set the RGB LED color and brightness
+void Thermostat::setRGBLED(double color, double bright) {
+    // set the RGB LED value
+    this->updateRGBLED(color,1.0,bright);
+}
+
+// turn the RGB LED Red
+void Thermostat::turnRGBLEDRed() {
+    this->m_rgbLEDColor = 0.0;
+    this->m_rgbLEDBright = 0.2;
+    this->setRGBLED(this->m_rgbLEDColor,this->m_rgbLEDBright); 
+    this->m_error_state = true;
+}
+
+// turn the RGB LED Green
+void Thermostat::turnRGBLEDGreen() {
+    this->m_rgbLEDColor = 120.0;
+    this->m_rgbLEDBright = 0.2;
+    this->setRGBLED(this->m_rgbLEDColor,this->m_rgbLEDBright); 
+    this->m_error_state = false;
+}
+
+// turn the RGB LED Blue (initializing state)
+void Thermostat::turnRGBLEDBlue() {
+    this->m_rgbLEDColor = 200.0;
+    this->m_rgbLEDBright = 0.2;
+    this->setRGBLED(this->m_rgbLEDColor,this->m_rgbLEDBright); 
+    this->m_error_state = false;
+}
+
+// blink an LED
+void Thermostat::blinkLED(DigitalOut led) {
+    led = 1;
+    wait(0.2);
+    led = 0;
+}
+
+// blink the Transport TX LED
+void Thermostat::blinkTransportTxLED() {
+    this->blinkLED(led1);
+}
+
+// blink the Transport RX LED
+void Thermostat::blinkTransportRxLED() {
+    this->blinkLED(led2);
+}
+
+
+#endif // THERMOSTAT_LEDUTILS_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Thermostat-Location.h	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,36 @@
+/* Thermostat-Location.h */
+/* Copyright (C) 2013 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+ 
+#ifndef THERMOSTAT_LOCATION_H_
+#define THERMOSTAT_LOCATION_H_
+
+// initialize our location
+void Thermostat::initLocation() {
+}
+
+// update our location coordinates
+void Thermostat::updateCoordinates() {
+    this->m_latitude = DEFAULT_LATITUDE;
+    this->m_longitude = DEFAULT_LONGITUDE;
+    
+    this->display("Location: Latitude:%2.4f Longitude:%2.4f",this->m_latitude,this->m_longitude);
+    this->display_lcd("Location Coordinates\r\nLatitude: %2.4f\r\nLongitude: %2.4f",this->m_latitude,this->m_longitude);
+}
+
+#endif // THERMOSTAT_LOCATION_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Thermostat.cpp	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,458 @@
+/* Thermostat.cpp */
+/* Copyright (C) 2013 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+ 
+//
+// 2013 DreamForce MiniHack - 
+// Look for the method: Thermostat::parseAndActOnControlMessage(char *json)
+// From there, add code to look for a "text" message - send its contents to the LCD panel
+// using the this->display(char *) method. You can use the other messages as a reference.
+// 
+
+ /*
+  * Operation: with the MBED appboard - the following is available:
+  *     1. connect/disconnect: push and hold the joystick forward (towards potentiometer) until a connect/disconnect message is seen
+  *     2. control messages  
+  *         "led1" --> "on" or "off" (led1 is also used as the TX status...)
+  *         "led2" --> "on" or "off" (led2 is also used as the RX status...)
+  *         "led3" --> "on" or "off"
+  *         "led4" --> "on" or "off"
+  *         "blink" --> <dont care> should blink all 4 LEDs a few times
+  *         "reset" --> <dont care> will reset the simulated error state for the device
+  *     3. simulated error state: depress and hold the joystick until the RGB LED turns red
+  *     4. rotate the potentiometer closest to the LCD panel to manipulate the battery level (0 - 100%)
+  *     5. rotate the potentiometer nearest the RGB LED to add/subtract 10 degrees from the current ambient temperature
+  */
+
+// Primary include
+#include "Thermostat.h"
+
+// DreamForce 2013 Tunables START
+
+//
+// Our default Latitude and Longitude
+//
+#define DEFAULT_LATITUDE                     37.7842
+#define DEFAULT_LONGITUDE                   -122.4016  
+
+//
+// Name our endpoint something unique
+//
+#define DEFAULT_ENDPOINT_NAME               "DreamForce Thermostat"
+
+// DreamForce 2013 Tunables END
+
+// Wait Loop default sleep per iteration
+#define DEFAULT_MAIN_LOOP_WAIT              2.0     // 2 seconds
+
+// JSON parsing support
+#include "picojson.h"
+
+//
+// Accelerometer Support
+//
+#include "MMA7660.h"
+MMA7660 acc(p28, p27);
+
+//
+// Temperature Sensor Support
+//
+#include "LM75B.h"
+LM75B temp_sensor(p28,p27);
+
+//
+// Ethernet support
+//
+#include "EthernetInterface.h"
+EthernetInterface ethernet;
+
+//
+// Thermostat SocketIO Support
+//
+#include "ThermostatSocketIO.h"
+ThermostatSocketIO socketio(DEFAULT_ENDPOINT_NAME);
+
+// Include LED Utils
+#include "Thermostat-LEDUtils.h"
+
+// Include Base Utils
+#include "Thermostat-BaseUtils.h"
+
+// Include Location Stubs
+#include "Thermostat-Location.h"
+
+// Default constructor
+Thermostat::Thermostat() {
+    this->m_temperature = 0.0;
+    this->m_battery = 50.0;
+    this->m_status = "OK";
+}
+
+// Destructor
+Thermostat::~Thermostat() {
+    // close down connections
+    socketio.close();
+    ethernet.disconnect();
+    this->turnRGBLEDBlue();
+}
+
+// get the temp
+float Thermostat::getTemperature() {
+    // get Pot 2 an additive/subtractive value to the ambient temp
+    float scale = Pot2.read();
+    scale = scale * 20.0;    // scale to 0 - 20
+    scale = scale - 10.0;    // scale -10 to +10
+        
+    // Get the Temperature (in C)
+    float c = temp_sensor.read();
+    float f = ((9/5) * c ) + 32;
+    
+    // now get the ambient temp and scale it
+    this->m_temperature =  c + scale;    
+    this->display("Temp %.1f C (%.1f F)",this->m_temperature,f);
+    this->display_lcd("Temp: %.1f C (%.1f F)",this->m_temperature,f);
+     
+    // return the temperature    
+    return this->m_temperature;
+}
+
+// get the current battery level
+float Thermostat::getBatteryLevel() {  
+    // get Pot 1 an additive/subtractive value to simulate battery level
+    this->m_battery = Pot1.read();
+    this->m_battery = this->m_battery * 100.0;  // scale to 0 - 100;
+        
+    // return the battery level
+    return this->m_battery;
+}
+
+// receive from the heroku SocketIO web service
+char *Thermostat::receiveFromWSService(char *buffer) {
+    bool success = socketio.read(buffer);
+    if (success == true)
+        this->display("SocketIO: Read success");
+    else
+        this->display("SocketIO: Read failure");
+    
+    return buffer;
+}    
+
+// translate the LED status 
+int Thermostat::translateLEDStatus(const char *status, int current) {
+   int i_status = current; 
+     
+   if (status != NULL && strlen(status) > 0) {
+        if (strcmp(status,"on") == 0 || strcmp(status,"ON") == 0 || strcmp(status,"On") == 0 || strcmp(status,"1") == 0 || strcmp(status,"oN") == 0)
+            i_status = 1;
+        if (strcmp(status,"off") == 0 || strcmp(status,"OFF") == 0 || strcmp(status,"Off") == 0 || strcmp(status,"0") == 0 || strcmp(status,"oFF") == 0 || strcmp(status,"oF") == 0 || strcmp(status,"ofF") == 0)
+            i_status = 0;
+   }
+   
+   // return the status
+   return i_status; 
+}
+
+// reset the device status to OK
+void Thermostat::resetDeviceStatus() {
+    this->turnRGBLEDGreen();
+    this->m_status = "OK";
+    socketio.resetMessageCounter();
+    this->resetAllLEDs();
+}
+
+// basic parsing and processing of the control message
+//
+// Control Message Format: 5:::{"name":"control-device","args":[{"hello":"world"}]}
+//
+void Thermostat::parseAndActOnControlMessage(char *json) {
+   picojson::value v;
+      
+   if (json != NULL && strlen(json) > 0 && strstr(json,"{") != NULL) {
+       // move past the socket.io header
+       char *json_proper = strstr(json,"{");
+       
+       // parse the packet
+       string err = picojson::parse(v, json_proper, json_proper + strlen(json_proper));
+       
+       // the args value is an array of json values
+       picojson::array list = v.get("args").get<picojson::array>();
+       
+       // loop through the array and parse/process each element
+       for (picojson::array::iterator iter = list.begin(); iter != list.end(); ++iter) {
+            // Toggle LEDs
+            if ((*iter).get("led1") != NULL) led1.write(this->translateLEDStatus((*iter).get("led1").get<string>().c_str(),(int)led1));
+            if ((*iter).get("led2") != NULL) led2.write(this->translateLEDStatus((*iter).get("led2").get<string>().c_str(),(int)led2));
+            if ((*iter).get("led3") != NULL) led3.write(this->translateLEDStatus((*iter).get("led3").get<string>().c_str(),(int)led3));
+            if ((*iter).get("led4") != NULL) led4.write(this->translateLEDStatus((*iter).get("led4").get<string>().c_str(),(int)led4));
+            if ((*iter).get("reset") != NULL) this->resetDeviceStatus();
+            if ((*iter).get("text") != NULL) this->display((*iter).get("text").get<string>().c_str());
+            if ((*iter).get("blink") != NULL) this->blinkAllLEDs();
+            
+            //
+            // 2013 DreamForce MiniHack - add code to look for a "text" message - send its contents to the LCD panel
+            // using the this->display(char *) method
+            //
+            // Answer:
+            //
+            if ((*iter).get("text") != NULL) this->display((*iter).get("text").get<string>().c_str()); 
+        }
+   }
+}
+
+// recv and process a control message
+void Thermostat::processControlMessage() {
+    
+    if (socketio.is_connected()) {
+        char message[SOCKETIO_MESSAGE_LENGTH];
+        if (socketio.read(message)) {
+            // log the message
+            this->display("Received control message: %s",message);
+            
+            // process the message
+            this->parseAndActOnControlMessage(message);
+            
+            // blink the RX led
+            this->blinkTransportRxLED();
+        }
+        else {
+            // no messages received - log
+            this->display("No control message received. OK");
+        }
+    }
+}
+
+// send status (no params) to the service
+void Thermostat::sendStatus() {         
+    // send the status
+    this->sendStatus(this->getTemperature(),this->getBatteryLevel());
+}
+
+// send status (temp & battery) to the service
+void Thermostat::sendStatus(float temp, int bat) { 
+    // incorporate location coordinates 
+    this->sendStatus(temp,this->m_latitude,this->m_longitude,bat);
+}
+
+// send status (temp, lat/long, battery) to the service
+void Thermostat::sendStatus(float temp, float latitude, float longitude, float bat) {         
+    // Announce 
+    this->display("Send: status...");
+    this->display_lcd("Sending status...");
+                    
+    // now send...
+    int sent = socketio.emit(temp,latitude,longitude,bat,this->getErrorState(),this->m_status);
+     
+    // Log
+    if (sent > 0) {
+       this->display("Send success. Ready...");
+       this->display_lcd("Send status: OK.\r\nSleeping...");
+    }
+    else {
+       this->display("Send Failed: sent=%d",sent);
+       this->display_lcd("Send status: FAILED.\r\nSleeping...");
+    }
+    
+    // blink the TX led
+    this->blinkTransportTxLED();
+}
+
+// connect to the heroku WebService
+bool Thermostat::connectWebSocketService() {    
+    // Log
+    this->display("Connecting to SocketIO...");
+    this->display_lcd("SocketIO connecting...");
+    
+    // only connect if we are not already so
+    if (!socketio.is_connected()) socketio.connect();
+    
+    // check connection status
+    bool connected = socketio.is_connected();
+            
+    // log 
+    if (connected == true) {
+        this->display("SocketIO: Connected!");
+        this->display_lcd("SocketIO: Connected.");
+    }
+    else { 
+        this->display("SocketIO: Not connected!");
+        this->display_lcd("SocketIO: Connect FAILED.");
+    }
+        
+    // return the status
+    return connected;
+}
+
+// Connect up Ethernet
+bool Thermostat::connectEthernet() { 
+    bool connected = false;
+    char *ipAddr = NULL;
+    
+    // Use DHCP
+    this->display("Initializing Ethernet...");
+    this->display_lcd("Ethernet: Initializing...");
+    ethernet.init(); 
+    
+    // attempt connection
+    this->display("Connecting Ethernet...");
+    this->display_lcd("Ethernet: Connecting...");
+    if (ethernet.connect() == 0) connected = true;
+    
+    // check connection status
+    if (connected) {
+        ipAddr = ethernet.getIPAddress();
+        if (ipAddr != NULL && strlen(ipAddr) > 0)
+            connected = true;
+    }
+   
+    // log 
+    if (connected == true) {
+        this->display("Ethernet: Connected.\r\nIP: %s", ipAddr);
+        this->display_lcd("Ethernet: Connected\r\nIP: %s",ipAddr);
+    }
+    else {
+        this->display("Ethernet: Not connected");
+        this->display_lcd("Ethernet: Connect FAILED.");
+    }
+    
+    // return the status
+    return connected; 
+}
+
+// gracefully de-register and close down the WS connection
+void Thermostat::gracefullyDisconnect() {    
+    // disconnect
+    if (socketio.is_connected()) socketio.close();
+        
+    // announce
+    this->display("Disconnected.");
+    this->display_lcd("Disconnected.");
+    this->turnRGBLEDBlue();
+    
+    // reset any status
+    this->m_status = "OK";
+    socketio.resetMessageCounter();
+}
+
+// external function in main() to check for the CTRL-C key press to exit the application gracefully
+extern void checkForExit();
+
+// main loop
+void Thermostat::mainLoop() {
+    // initialize our location
+    this->initLocation(); 
+    
+    // begin the main loop
+    while(true) {
+        // sleep for a bit
+        checkForExit();
+        wait(DEFAULT_MAIN_LOOP_WAIT);
+        
+        // announce our position
+        this->updateCoordinates();
+                
+        // check and react to the joystick button press
+        if (joystick_pressed) {
+            if (this->m_rgbLEDColor > 1) {
+                this->turnRGBLEDRed();
+                this->m_status = "FAIL";
+            }
+            else {
+                this->turnRGBLEDGreen();
+                this->m_status = "OK";
+            }
+        }
+        else if (socketio.is_connected() && this->m_rgbLEDColor > 121) {
+            this->turnRGBLEDGreen();
+        }
+        
+        // check the status of the joystick
+        if (joystick) {
+            if (socketio.is_connected()) {
+                // announce 
+                this->display("Disconnecting...");
+                this->display_lcd("Disconnecting...");
+                
+                // disconnect
+                this->gracefullyDisconnect();
+            }
+            else if (!socketio.is_connected()){
+                // announce
+                this->display("Re-connecting...");
+                this->display_lcd("Re-connecting...");
+                
+                // re-connect
+                if (this->connectWebSocketService()) {
+                    // announce
+                    this->display("Reconnect success");
+                    this->display_lcd("Reconnect: SUCCESS");
+                    this->turnRGBLEDGreen();
+                    this->resetAllLEDs();
+                }
+                else {
+                    // announce
+                    this->display("Reconnect failure");
+                    this->display_lcd("Reconnect: FAILED");
+                    this->gracefullyDisconnect();
+                    this->turnRGBLEDRed();
+                }
+            }
+        }
+        
+        // if we are connected, send our status
+        if (socketio.is_connected()) {
+            // send status
+            this->sendStatus();
+            checkForExit();
+        }
+        
+        // if we are connected, read any control we may receive
+        if (socketio.is_connected()) {
+            // process control messages
+            this->processControlMessage();
+            checkForExit();
+        }
+    }
+}
+
+// Run the Demo
+void Thermostat::runDemo() {
+    // Announce
+    this->display("Thermostat Hands-On Demo v1.0");
+    this->display_lcd("Thermostat Hands-On\r\nDemo v1.0");
+            
+    // init the RGB LED
+    this->display("Initializing LEDs...");
+    this->turnRGBLEDBlue();
+    
+    // Log
+    this->display("Connecting...");
+    this->display_lcd("Connecting...");
+    
+    // connect and send the initial status
+    if (this->connectEthernet() == true && this->connectWebSocketService() == true) {
+        this->sendStatus();
+        this->mainLoop();
+    }
+    else {
+        this->display("Connection failure. Application exiting...");
+        this->display_lcd("Connect: FAILURE.\r\nApplication Exiting");
+    }
+        
+    // exit the application if we get here
+    exit(1);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Thermostat.h	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,104 @@
+/* Thermostat.h */
+/* Copyright (C) 2013 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+ 
+#ifndef THERMOSTAT_H_
+#define THERMOSTAT_H_
+
+// platform support
+#include "mbed.h"
+
+// Support for std args
+#include <stdarg.h>
+
+// maximum size of a displayed message
+#define MAX_MESSAGE_LENGTH  100
+
+class Thermostat {
+    public:
+        // Default Constructor
+        Thermostat();
+        
+        // Destructor
+        ~Thermostat();
+        
+        // invoke the demo
+        void runDemo();
+              
+    private: 
+        int getErrorState();
+        char *createDeregisterJSON(char *buffer);
+        char *createJSON(char *buffer, float temp, float latitude, float longitude, float bat);
+       
+        float getTemperature();
+        float getBatteryLevel();
+        
+        void resetDeviceStatus();
+        int translateLEDStatus(const char *status, int current);
+        void parseAndActOnControlMessage(char *json);
+        void processControlMessage();
+        void sendDeregisterMessage();
+        void sendStatus();
+        void sendStatus(float temp, int battery);
+        void sendStatus(float temp, float latitude, float longitude, float bat);
+        
+        char *receiveFromWSService(char *buffer);
+         
+        void parseSessionKey(char *response, char *sessionkey);
+        char *performSocketIOHandshake(char *sessionkey);
+        bool connectWebSocketService();
+        bool connectEthernet();
+        
+        void gracefullyDisconnect();
+        void mainLoop();
+        
+        // Thermostat-LEDUtils.cpp
+        void setAllLEDs(int state);
+        void resetAllLEDs();
+        void blinkAllLEDs();
+        void updateRGBLED(float H,float S, float V);
+        void setRGBLED(double color, double bright);       
+        void turnRGBLEDRed();
+        void turnRGBLEDGreen();
+        void turnRGBLEDBlue();
+        void blinkLED(DigitalOut led);
+        void blinkTransportTxLED();
+        void blinkTransportRxLED();
+        
+        // Thermostat-BaseUtils.cpp
+        void logMessage(bool do_lcd);
+        void display(const char *format, ...);
+        void display_lcd(const char *format, ...);
+        
+        // Stubs
+        void updateCoordinates();
+        void initLocation();
+        
+        // private members
+        float  m_latitude;
+        float  m_longitude;
+        float  m_temperature;
+        float  m_battery;
+        char  *m_status;
+        bool   m_error_state;
+        double m_rgbLEDColor;
+        double m_rgbLEDBright;
+        char   m_display_message[MAX_MESSAGE_LENGTH+1];
+};
+
+#endif /* THERMOSTAT_H_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ThermostatSocketIO.cpp	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,89 @@
+#include "ThermostatSocketIO.h"
+
+// Default SocketIO URL
+#define DEFAULT_URL     "mc-control-1.herokuapp.com"
+
+// message counter
+int counter = 1;
+
+// constructor
+ThermostatSocketIO::ThermostatSocketIO(char *devname) : SocketIO(DEFAULT_URL) {
+    this->device_name = devname;
+}
+
+// constructor
+ThermostatSocketIO::ThermostatSocketIO(char * myurl, char *devname) : SocketIO(myurl) {
+    this->device_name = devname;
+}
+
+// reset the message counter
+void ThermostatSocketIO::resetMessageCounter() {
+    counter = 1;
+}
+
+// emit a message (broadcast) to the SocketIO server
+int ThermostatSocketIO::emit(float temp, float latitude, float longitude, float bat, int errorState, char *t_status) {
+    // create json string with acc/tmp data
+    char send[256];
+    char *json = this->createJSON(send,temp,latitude,longitude,bat,errorState,t_status);
+    
+    // handle the message name
+    char message_name[32];
+    if (counter == 1) 
+        // we need to register the device
+        sprintf(message_name,"register-device");
+    else
+        // we are simply issuing readings...
+        sprintf(message_name,"readings");
+        
+    // increment our counter
+    ++counter;
+  
+    // emit this json
+    return ((SocketIO *)this)->emit(message_name,json);
+}
+
+// Close the thermostat socket.io
+bool ThermostatSocketIO::close() {
+    char buf[256];
+    char message_name[32];
+    
+    // we need to register the device
+    sprintf(message_name,"disconnect");
+
+    // create the deregister JSON message
+    char *json = this->createDeregisterJSON(buf);
+    
+    // now send...
+    int sent = ((SocketIO *)this)->emit(message_name,json);
+    
+    // now close
+    return ((SocketIO *)this)->close();
+} 
+
+// create the JSON to deregister the device
+char *ThermostatSocketIO::createDeregisterJSON(char *buffer) {
+    // create the JSON to just register the device
+    sprintf(buffer,"[{ \"device_id\": \"%s\" } }]",this->device_name);
+        
+    // return the JSON
+    return buffer;
+}
+
+// Create the JSON that is consumable by the demo webservice
+char *ThermostatSocketIO::createJSON(char *buffer, float temp, float latitude, float longitude, float bat, int errorState, char *t_status) {
+   // create the message name
+   if (counter == 1) {
+        // create the JSON to just register the device
+        sprintf(buffer,"[\"%s\",{\"battery\": %d, \"city\": \"Austin\", \"country\": \"US\", \"device_id\": \"%s\", \"lat\": %4.6f, \"long\": %4.6f, \"status\": \"%s\", \"temp\": %4.1f, \"switch\": %d}]", 
+               device_name, (int)bat, this->device_name, latitude, longitude, t_status, temp, errorState);
+   }
+   else {
+        // create the JSON
+        sprintf(buffer,"[{\"battery\": %d, \"city\": \"Austin\", \"country\": \"US\", \"device_id\": \"%s\", \"lat\": %4.6f, \"long\": %4.6f, \"status\": \"%s\", \"temp\": %4.1f, \"switch\": %d}]",
+          (int)bat, this->device_name, latitude, longitude, t_status, temp, errorState);
+   }
+   
+   // return the JSON
+   return buffer;        
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ThermostatSocketIO.h	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,94 @@
+/**
+* @author Doug Anson
+*
+* @section LICENSE
+*
+* Copyright (c) 2013 mbed
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*
+* @section DESCRIPTION
+*    SocketIO derivation client library for the Thermostat Demo
+*
+*/
+
+#ifndef THERMOSTATSOCKETIO_H
+#define THERMOSTATSOCKETIO_H
+
+#include "SocketIO.h"
+
+/** 
+ * ThermostatSocketIO client class.
+ * Derived class from SocketIO library specifically for the ThermostatDemo app
+ */
+
+class ThermostatSocketIO : public SocketIO
+{
+    public:
+        /**
+        * Constructor
+        *
+        * @param devname The device's devname for display in the console
+        */
+        ThermostatSocketIO(char *devname);
+        
+        /**
+        * Constructor
+        *
+        * @param url The SocketIO url in the form "www.example.com:[port]" (by default: port = 80) - i.e. just the endpoint name
+        * @param devname The device's devname for display in the console
+        */
+        ThermostatSocketIO(char * url, char *devname);
+        
+        /**
+        * Emit (Broadcast) a socket.io message to the SocketIO server - specific to the ThermostatDemo app
+        *
+        * @param temp - temperature
+        * @param latitude - the device latitude
+        * @param longitude - the device longitude
+        * @param bat - the battery level
+        * @param errorState - the devices current error state
+        * @param t_status - the devices current error state (string - either OK or FAIL)
+        *
+        * @returns the number of bytes sent
+        */
+        int emit(float temp, float latitude, float longitude, float bat, int errorState, char *t_status);
+        
+        /**
+        * Reset the message counter
+        */
+        void resetMessageCounter();
+        
+        /**
+        * Close the SocketIO connection
+        *
+        * @return true if the connection has been closed, false otherwise
+        */
+        bool close();
+        
+   private:
+        // variables
+        char *device_name;
+        
+        // methods
+        char *createDeregisterJSON(char *buffer);
+        char *createJSON(char *buffer, float temp, float latitude, float longitude, float bat, int errorState, char *t_status);
+};
+
+#endif // THERMOSTATSOCKETIO_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebSocketClient.lib	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/ansond/code/WebSocketClient-ThermostatDemo/#8ee61b912743
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,24 @@
+#include "mbed.h"
+
+#include "Thermostat.h"
+
+Serial pc(USBTX, USBRX);
+Thermostat *thermostat = NULL;
+
+// check for exit
+void checkForExit() {
+    if (pc.readable()) {
+        char c = pc.getc();
+        if (c == 0x03) {    // CTRL-C ASCII
+            pc.printf("ctrl-c: closing down thermostat...\r\n");
+            if (thermostat != NULL) delete thermostat;
+            pc.printf("app exiting...\r\n");
+            exit(1);
+        }
+    }
+}
+
+int main() {
+    thermostat = new Thermostat();
+    if (thermostat != NULL) thermostat->runDemo();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#ee87e782d34f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/a9913a65894f
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/picojson.lib	Tue Nov 05 21:31:01 2013 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/mimil/code/picojson/#2bb500b021e2