DreamForce 2013 Hands-On Demo

Dependencies:   C12832_lcd EthernetInterface-ansond-patched HTTPClient-thermostat-remotes LM75B MMA7660 SocketIO WebSocketClient-ThermostatDemo mbed-rtos mbed picojson

Fork of ThermostatHandsOn by Doug Anson

Committer:
ansond
Date:
Mon Nov 11 20:35:13 2013 +0000
Revision:
7:57681d46485d
Parent:
6:510193bc7f26
updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:6b56785dd2b6 1 /* Thermostat.cpp */
ansond 0:6b56785dd2b6 2 /* Copyright (C) 2013 mbed.org, MIT License
ansond 0:6b56785dd2b6 3 *
ansond 0:6b56785dd2b6 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
ansond 0:6b56785dd2b6 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
ansond 0:6b56785dd2b6 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
ansond 0:6b56785dd2b6 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
ansond 0:6b56785dd2b6 8 * furnished to do so, subject to the following conditions:
ansond 0:6b56785dd2b6 9 *
ansond 0:6b56785dd2b6 10 * The above copyright notice and this permission notice shall be included in all copies or
ansond 0:6b56785dd2b6 11 * substantial portions of the Software.
ansond 0:6b56785dd2b6 12 *
ansond 0:6b56785dd2b6 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
ansond 0:6b56785dd2b6 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
ansond 0:6b56785dd2b6 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
ansond 0:6b56785dd2b6 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ansond 0:6b56785dd2b6 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ansond 0:6b56785dd2b6 18 */
ansond 0:6b56785dd2b6 19
ansond 0:6b56785dd2b6 20 /*
ansond 0:6b56785dd2b6 21 * Operation: with the MBED appboard - the following is available:
ansond 0:6b56785dd2b6 22 * 1. connect/disconnect: push and hold the joystick forward (towards potentiometer) until a connect/disconnect message is seen
ansond 0:6b56785dd2b6 23 * 2. control messages
ansond 0:6b56785dd2b6 24 * "led1" --> "on" or "off" (led1 is also used as the TX status...)
ansond 0:6b56785dd2b6 25 * "led2" --> "on" or "off" (led2 is also used as the RX status...)
ansond 0:6b56785dd2b6 26 * "led3" --> "on" or "off"
ansond 0:6b56785dd2b6 27 * "led4" --> "on" or "off"
ansond 0:6b56785dd2b6 28 * "blink" --> <dont care> should blink all 4 LEDs a few times
ansond 0:6b56785dd2b6 29 * "reset" --> <dont care> will reset the simulated error state for the device
ansond 0:6b56785dd2b6 30 * 3. simulated error state: depress and hold the joystick until the RGB LED turns red
ansond 0:6b56785dd2b6 31 * 4. rotate the potentiometer closest to the LCD panel to manipulate the battery level (0 - 100%)
ansond 0:6b56785dd2b6 32 * 5. rotate the potentiometer nearest the RGB LED to add/subtract 10 degrees from the current ambient temperature
ansond 0:6b56785dd2b6 33 */
ansond 0:6b56785dd2b6 34
ansond 0:6b56785dd2b6 35 // Primary include
ansond 0:6b56785dd2b6 36 #include "Thermostat.h"
ansond 0:6b56785dd2b6 37
ansond 4:048550d178c5 38 // DreamForce 2013 Tunables START
ansond 4:048550d178c5 39
ansond 0:6b56785dd2b6 40 //
ansond 0:6b56785dd2b6 41 // Our default Latitude and Longitude
ansond 0:6b56785dd2b6 42 //
ansond 3:6afb87443041 43 #define DEFAULT_LATITUDE 37.7842
ansond 3:6afb87443041 44 #define DEFAULT_LONGITUDE -122.4016
ansond 0:6b56785dd2b6 45
ansond 0:6b56785dd2b6 46 //
ansond 0:6b56785dd2b6 47 // Name our endpoint something unique
ansond 0:6b56785dd2b6 48 //
ansond 3:6afb87443041 49 #define DEFAULT_ENDPOINT_NAME "DreamForce Thermostat"
ansond 0:6b56785dd2b6 50
ansond 4:048550d178c5 51 // DreamForce 2013 Tunables END
ansond 4:048550d178c5 52
ansond 0:6b56785dd2b6 53 // Wait Loop default sleep per iteration
ansond 0:6b56785dd2b6 54 #define DEFAULT_MAIN_LOOP_WAIT 2.0 // 2 seconds
ansond 0:6b56785dd2b6 55
ansond 0:6b56785dd2b6 56 // JSON parsing support
ansond 0:6b56785dd2b6 57 #include "picojson.h"
ansond 0:6b56785dd2b6 58
ansond 0:6b56785dd2b6 59 //
ansond 0:6b56785dd2b6 60 // Accelerometer Support
ansond 0:6b56785dd2b6 61 //
ansond 0:6b56785dd2b6 62 #include "MMA7660.h"
ansond 0:6b56785dd2b6 63 MMA7660 acc(p28, p27);
ansond 0:6b56785dd2b6 64
ansond 0:6b56785dd2b6 65 //
ansond 0:6b56785dd2b6 66 // Temperature Sensor Support
ansond 0:6b56785dd2b6 67 //
ansond 0:6b56785dd2b6 68 #include "LM75B.h"
ansond 0:6b56785dd2b6 69 LM75B temp_sensor(p28,p27);
ansond 0:6b56785dd2b6 70
ansond 0:6b56785dd2b6 71 //
ansond 0:6b56785dd2b6 72 // Ethernet support
ansond 0:6b56785dd2b6 73 //
ansond 0:6b56785dd2b6 74 #include "EthernetInterface.h"
ansond 0:6b56785dd2b6 75 EthernetInterface ethernet;
ansond 0:6b56785dd2b6 76
ansond 0:6b56785dd2b6 77 //
ansond 0:6b56785dd2b6 78 // Thermostat SocketIO Support
ansond 0:6b56785dd2b6 79 //
ansond 0:6b56785dd2b6 80 #include "ThermostatSocketIO.h"
ansond 0:6b56785dd2b6 81 ThermostatSocketIO socketio(DEFAULT_ENDPOINT_NAME);
ansond 0:6b56785dd2b6 82
ansond 0:6b56785dd2b6 83 // Include LED Utils
ansond 0:6b56785dd2b6 84 #include "Thermostat-LEDUtils.h"
ansond 0:6b56785dd2b6 85
ansond 0:6b56785dd2b6 86 // Include Base Utils
ansond 0:6b56785dd2b6 87 #include "Thermostat-BaseUtils.h"
ansond 0:6b56785dd2b6 88
ansond 1:dfd24f608038 89 // Include Location Stubs
ansond 1:dfd24f608038 90 #include "Thermostat-Location.h"
ansond 1:dfd24f608038 91
ansond 0:6b56785dd2b6 92 // Default constructor
ansond 0:6b56785dd2b6 93 Thermostat::Thermostat() {
ansond 0:6b56785dd2b6 94 this->m_temperature = 0.0;
ansond 0:6b56785dd2b6 95 this->m_battery = 50.0;
ansond 0:6b56785dd2b6 96 this->m_status = "OK";
ansond 0:6b56785dd2b6 97 }
ansond 0:6b56785dd2b6 98
ansond 0:6b56785dd2b6 99 // Destructor
ansond 0:6b56785dd2b6 100 Thermostat::~Thermostat() {
ansond 0:6b56785dd2b6 101 // close down connections
ansond 0:6b56785dd2b6 102 socketio.close();
ansond 0:6b56785dd2b6 103 ethernet.disconnect();
ansond 0:6b56785dd2b6 104 this->turnRGBLEDBlue();
ansond 0:6b56785dd2b6 105 }
ansond 0:6b56785dd2b6 106
ansond 0:6b56785dd2b6 107 // get the temp
ansond 0:6b56785dd2b6 108 float Thermostat::getTemperature() {
ansond 0:6b56785dd2b6 109 // get Pot 2 an additive/subtractive value to the ambient temp
ansond 0:6b56785dd2b6 110 float scale = Pot2.read();
ansond 0:6b56785dd2b6 111 scale = scale * 20.0; // scale to 0 - 20
ansond 0:6b56785dd2b6 112 scale = scale - 10.0; // scale -10 to +10
ansond 0:6b56785dd2b6 113
ansond 0:6b56785dd2b6 114 // Get the Temperature (in C)
ansond 0:6b56785dd2b6 115 float c = temp_sensor.read();
ansond 0:6b56785dd2b6 116 float f = ((9/5) * c ) + 32;
ansond 0:6b56785dd2b6 117
ansond 0:6b56785dd2b6 118 // now get the ambient temp and scale it
ansond 0:6b56785dd2b6 119 this->m_temperature = c + scale;
ansond 0:6b56785dd2b6 120 this->display("Temp %.1f C (%.1f F)",this->m_temperature,f);
ansond 0:6b56785dd2b6 121 this->display_lcd("Temp: %.1f C (%.1f F)",this->m_temperature,f);
ansond 0:6b56785dd2b6 122
ansond 0:6b56785dd2b6 123 // return the temperature
ansond 0:6b56785dd2b6 124 return this->m_temperature;
ansond 0:6b56785dd2b6 125 }
ansond 0:6b56785dd2b6 126
ansond 0:6b56785dd2b6 127 // get the current battery level
ansond 0:6b56785dd2b6 128 float Thermostat::getBatteryLevel() {
ansond 0:6b56785dd2b6 129 // get Pot 1 an additive/subtractive value to simulate battery level
ansond 0:6b56785dd2b6 130 this->m_battery = Pot1.read();
ansond 0:6b56785dd2b6 131 this->m_battery = this->m_battery * 100.0; // scale to 0 - 100;
ansond 0:6b56785dd2b6 132
ansond 0:6b56785dd2b6 133 // return the battery level
ansond 0:6b56785dd2b6 134 return this->m_battery;
ansond 0:6b56785dd2b6 135 }
ansond 0:6b56785dd2b6 136
ansond 0:6b56785dd2b6 137 // receive from the heroku SocketIO web service
ansond 0:6b56785dd2b6 138 char *Thermostat::receiveFromWSService(char *buffer) {
ansond 0:6b56785dd2b6 139 bool success = socketio.read(buffer);
ansond 0:6b56785dd2b6 140 if (success == true)
ansond 0:6b56785dd2b6 141 this->display("SocketIO: Read success");
ansond 0:6b56785dd2b6 142 else
ansond 0:6b56785dd2b6 143 this->display("SocketIO: Read failure");
ansond 0:6b56785dd2b6 144
ansond 0:6b56785dd2b6 145 return buffer;
ansond 0:6b56785dd2b6 146 }
ansond 0:6b56785dd2b6 147
ansond 0:6b56785dd2b6 148 // translate the LED status
ansond 0:6b56785dd2b6 149 int Thermostat::translateLEDStatus(const char *status, int current) {
ansond 0:6b56785dd2b6 150 int i_status = current;
ansond 0:6b56785dd2b6 151
ansond 0:6b56785dd2b6 152 if (status != NULL && strlen(status) > 0) {
ansond 0:6b56785dd2b6 153 if (strcmp(status,"on") == 0 || strcmp(status,"ON") == 0 || strcmp(status,"On") == 0 || strcmp(status,"1") == 0 || strcmp(status,"oN") == 0)
ansond 0:6b56785dd2b6 154 i_status = 1;
ansond 0:6b56785dd2b6 155 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)
ansond 0:6b56785dd2b6 156 i_status = 0;
ansond 0:6b56785dd2b6 157 }
ansond 0:6b56785dd2b6 158
ansond 0:6b56785dd2b6 159 // return the status
ansond 0:6b56785dd2b6 160 return i_status;
ansond 0:6b56785dd2b6 161 }
ansond 0:6b56785dd2b6 162
ansond 0:6b56785dd2b6 163 // reset the device status to OK
ansond 0:6b56785dd2b6 164 void Thermostat::resetDeviceStatus() {
ansond 0:6b56785dd2b6 165 this->turnRGBLEDGreen();
ansond 0:6b56785dd2b6 166 this->m_status = "OK";
ansond 0:6b56785dd2b6 167 socketio.resetMessageCounter();
ansond 0:6b56785dd2b6 168 this->resetAllLEDs();
ansond 0:6b56785dd2b6 169 }
ansond 0:6b56785dd2b6 170
ansond 0:6b56785dd2b6 171 // basic parsing and processing of the control message
ansond 0:6b56785dd2b6 172 //
ansond 0:6b56785dd2b6 173 // Control Message Format: 5:::{"name":"control-device","args":[{"hello":"world"}]}
ansond 0:6b56785dd2b6 174 //
ansond 0:6b56785dd2b6 175 void Thermostat::parseAndActOnControlMessage(char *json) {
ansond 0:6b56785dd2b6 176 picojson::value v;
ansond 0:6b56785dd2b6 177
ansond 0:6b56785dd2b6 178 if (json != NULL && strlen(json) > 0 && strstr(json,"{") != NULL) {
ansond 0:6b56785dd2b6 179 // move past the socket.io header
ansond 0:6b56785dd2b6 180 char *json_proper = strstr(json,"{");
ansond 0:6b56785dd2b6 181
ansond 0:6b56785dd2b6 182 // parse the packet
ansond 0:6b56785dd2b6 183 string err = picojson::parse(v, json_proper, json_proper + strlen(json_proper));
ansond 0:6b56785dd2b6 184
ansond 0:6b56785dd2b6 185 // the args value is an array of json values
ansond 0:6b56785dd2b6 186 picojson::array list = v.get("args").get<picojson::array>();
ansond 0:6b56785dd2b6 187
ansond 0:6b56785dd2b6 188 // loop through the array and parse/process each element
ansond 0:6b56785dd2b6 189 for (picojson::array::iterator iter = list.begin(); iter != list.end(); ++iter) {
ansond 0:6b56785dd2b6 190 // Toggle LEDs
ansond 0:6b56785dd2b6 191 if ((*iter).get("led1") != NULL) led1.write(this->translateLEDStatus((*iter).get("led1").get<string>().c_str(),(int)led1));
ansond 0:6b56785dd2b6 192 if ((*iter).get("led2") != NULL) led2.write(this->translateLEDStatus((*iter).get("led2").get<string>().c_str(),(int)led2));
ansond 0:6b56785dd2b6 193 if ((*iter).get("led3") != NULL) led3.write(this->translateLEDStatus((*iter).get("led3").get<string>().c_str(),(int)led3));
ansond 0:6b56785dd2b6 194 if ((*iter).get("led4") != NULL) led4.write(this->translateLEDStatus((*iter).get("led4").get<string>().c_str(),(int)led4));
ansond 0:6b56785dd2b6 195 if ((*iter).get("reset") != NULL) this->resetDeviceStatus();
ansond 0:6b56785dd2b6 196 if ((*iter).get("blink") != NULL) this->blinkAllLEDs();
ansond 0:6b56785dd2b6 197 }
ansond 0:6b56785dd2b6 198 }
ansond 0:6b56785dd2b6 199 }
ansond 0:6b56785dd2b6 200
ansond 0:6b56785dd2b6 201 // recv and process a control message
ansond 0:6b56785dd2b6 202 void Thermostat::processControlMessage() {
ansond 0:6b56785dd2b6 203
ansond 0:6b56785dd2b6 204 if (socketio.is_connected()) {
ansond 0:6b56785dd2b6 205 char message[SOCKETIO_MESSAGE_LENGTH];
ansond 0:6b56785dd2b6 206 if (socketio.read(message)) {
ansond 0:6b56785dd2b6 207 // log the message
ansond 0:6b56785dd2b6 208 this->display("Received control message: %s",message);
ansond 0:6b56785dd2b6 209
ansond 0:6b56785dd2b6 210 // process the message
ansond 0:6b56785dd2b6 211 this->parseAndActOnControlMessage(message);
ansond 0:6b56785dd2b6 212
ansond 0:6b56785dd2b6 213 // blink the RX led
ansond 0:6b56785dd2b6 214 this->blinkTransportRxLED();
ansond 0:6b56785dd2b6 215 }
ansond 0:6b56785dd2b6 216 else {
ansond 0:6b56785dd2b6 217 // no messages received - log
ansond 0:6b56785dd2b6 218 this->display("No control message received. OK");
ansond 0:6b56785dd2b6 219 }
ansond 0:6b56785dd2b6 220 }
ansond 0:6b56785dd2b6 221 }
ansond 0:6b56785dd2b6 222
ansond 0:6b56785dd2b6 223 // send status (no params) to the service
ansond 0:6b56785dd2b6 224 void Thermostat::sendStatus() {
ansond 0:6b56785dd2b6 225 // send the status
ansond 0:6b56785dd2b6 226 this->sendStatus(this->getTemperature(),this->getBatteryLevel());
ansond 0:6b56785dd2b6 227 }
ansond 0:6b56785dd2b6 228
ansond 0:6b56785dd2b6 229 // send status (temp & battery) to the service
ansond 0:6b56785dd2b6 230 void Thermostat::sendStatus(float temp, int bat) {
ansond 0:6b56785dd2b6 231 // incorporate location coordinates
ansond 0:6b56785dd2b6 232 this->sendStatus(temp,this->m_latitude,this->m_longitude,bat);
ansond 0:6b56785dd2b6 233 }
ansond 0:6b56785dd2b6 234
ansond 0:6b56785dd2b6 235 // send status (temp, lat/long, battery) to the service
ansond 0:6b56785dd2b6 236 void Thermostat::sendStatus(float temp, float latitude, float longitude, float bat) {
ansond 0:6b56785dd2b6 237 // Announce
ansond 0:6b56785dd2b6 238 this->display("Send: status...");
ansond 0:6b56785dd2b6 239 this->display_lcd("Sending status...");
ansond 0:6b56785dd2b6 240
ansond 0:6b56785dd2b6 241 // now send...
ansond 0:6b56785dd2b6 242 int sent = socketio.emit(temp,latitude,longitude,bat,this->getErrorState(),this->m_status);
ansond 0:6b56785dd2b6 243
ansond 0:6b56785dd2b6 244 // Log
ansond 0:6b56785dd2b6 245 if (sent > 0) {
ansond 0:6b56785dd2b6 246 this->display("Send success. Ready...");
ansond 0:6b56785dd2b6 247 this->display_lcd("Send status: OK.\r\nSleeping...");
ansond 0:6b56785dd2b6 248 }
ansond 0:6b56785dd2b6 249 else {
ansond 0:6b56785dd2b6 250 this->display("Send Failed: sent=%d",sent);
ansond 0:6b56785dd2b6 251 this->display_lcd("Send status: FAILED.\r\nSleeping...");
ansond 0:6b56785dd2b6 252 }
ansond 0:6b56785dd2b6 253
ansond 0:6b56785dd2b6 254 // blink the TX led
ansond 0:6b56785dd2b6 255 this->blinkTransportTxLED();
ansond 0:6b56785dd2b6 256 }
ansond 0:6b56785dd2b6 257
ansond 0:6b56785dd2b6 258 // connect to the heroku WebService
ansond 0:6b56785dd2b6 259 bool Thermostat::connectWebSocketService() {
ansond 0:6b56785dd2b6 260 // Log
ansond 0:6b56785dd2b6 261 this->display("Connecting to SocketIO...");
ansond 0:6b56785dd2b6 262 this->display_lcd("SocketIO connecting...");
ansond 0:6b56785dd2b6 263
ansond 0:6b56785dd2b6 264 // only connect if we are not already so
ansond 0:6b56785dd2b6 265 if (!socketio.is_connected()) socketio.connect();
ansond 0:6b56785dd2b6 266
ansond 0:6b56785dd2b6 267 // check connection status
ansond 0:6b56785dd2b6 268 bool connected = socketio.is_connected();
ansond 0:6b56785dd2b6 269
ansond 0:6b56785dd2b6 270 // log
ansond 0:6b56785dd2b6 271 if (connected == true) {
ansond 0:6b56785dd2b6 272 this->display("SocketIO: Connected!");
ansond 0:6b56785dd2b6 273 this->display_lcd("SocketIO: Connected.");
ansond 0:6b56785dd2b6 274 }
ansond 0:6b56785dd2b6 275 else {
ansond 0:6b56785dd2b6 276 this->display("SocketIO: Not connected!");
ansond 0:6b56785dd2b6 277 this->display_lcd("SocketIO: Connect FAILED.");
ansond 0:6b56785dd2b6 278 }
ansond 0:6b56785dd2b6 279
ansond 0:6b56785dd2b6 280 // return the status
ansond 0:6b56785dd2b6 281 return connected;
ansond 0:6b56785dd2b6 282 }
ansond 0:6b56785dd2b6 283
ansond 0:6b56785dd2b6 284 // Connect up Ethernet
ansond 0:6b56785dd2b6 285 bool Thermostat::connectEthernet() {
ansond 0:6b56785dd2b6 286 bool connected = false;
ansond 0:6b56785dd2b6 287 char *ipAddr = NULL;
ansond 0:6b56785dd2b6 288
ansond 0:6b56785dd2b6 289 // Use DHCP
ansond 0:6b56785dd2b6 290 this->display("Initializing Ethernet...");
ansond 0:6b56785dd2b6 291 this->display_lcd("Ethernet: Initializing...");
ansond 0:6b56785dd2b6 292 ethernet.init();
ansond 0:6b56785dd2b6 293
ansond 0:6b56785dd2b6 294 // attempt connection
ansond 0:6b56785dd2b6 295 this->display("Connecting Ethernet...");
ansond 0:6b56785dd2b6 296 this->display_lcd("Ethernet: Connecting...");
ansond 0:6b56785dd2b6 297 if (ethernet.connect() == 0) connected = true;
ansond 0:6b56785dd2b6 298
ansond 0:6b56785dd2b6 299 // check connection status
ansond 0:6b56785dd2b6 300 if (connected) {
ansond 0:6b56785dd2b6 301 ipAddr = ethernet.getIPAddress();
ansond 0:6b56785dd2b6 302 if (ipAddr != NULL && strlen(ipAddr) > 0)
ansond 0:6b56785dd2b6 303 connected = true;
ansond 0:6b56785dd2b6 304 }
ansond 0:6b56785dd2b6 305
ansond 0:6b56785dd2b6 306 // log
ansond 0:6b56785dd2b6 307 if (connected == true) {
ansond 0:6b56785dd2b6 308 this->display("Ethernet: Connected.\r\nIP: %s", ipAddr);
ansond 0:6b56785dd2b6 309 this->display_lcd("Ethernet: Connected\r\nIP: %s",ipAddr);
ansond 0:6b56785dd2b6 310 }
ansond 0:6b56785dd2b6 311 else {
ansond 0:6b56785dd2b6 312 this->display("Ethernet: Not connected");
ansond 0:6b56785dd2b6 313 this->display_lcd("Ethernet: Connect FAILED.");
ansond 0:6b56785dd2b6 314 }
ansond 0:6b56785dd2b6 315
ansond 0:6b56785dd2b6 316 // return the status
ansond 0:6b56785dd2b6 317 return connected;
ansond 0:6b56785dd2b6 318 }
ansond 0:6b56785dd2b6 319
ansond 0:6b56785dd2b6 320 // gracefully de-register and close down the WS connection
ansond 0:6b56785dd2b6 321 void Thermostat::gracefullyDisconnect() {
ansond 0:6b56785dd2b6 322 // disconnect
ansond 0:6b56785dd2b6 323 if (socketio.is_connected()) socketio.close();
ansond 0:6b56785dd2b6 324
ansond 0:6b56785dd2b6 325 // announce
ansond 0:6b56785dd2b6 326 this->display("Disconnected.");
ansond 0:6b56785dd2b6 327 this->display_lcd("Disconnected.");
ansond 0:6b56785dd2b6 328 this->turnRGBLEDBlue();
ansond 0:6b56785dd2b6 329
ansond 0:6b56785dd2b6 330 // reset any status
ansond 0:6b56785dd2b6 331 this->m_status = "OK";
ansond 0:6b56785dd2b6 332 socketio.resetMessageCounter();
ansond 0:6b56785dd2b6 333 }
ansond 0:6b56785dd2b6 334
ansond 0:6b56785dd2b6 335 // external function in main() to check for the CTRL-C key press to exit the application gracefully
ansond 0:6b56785dd2b6 336 extern void checkForExit();
ansond 0:6b56785dd2b6 337
ansond 0:6b56785dd2b6 338 // main loop
ansond 0:6b56785dd2b6 339 void Thermostat::mainLoop() {
ansond 1:dfd24f608038 340 // initialize our location
ansond 1:dfd24f608038 341 this->initLocation();
ansond 1:dfd24f608038 342
ansond 1:dfd24f608038 343 // begin the main loop
ansond 0:6b56785dd2b6 344 while(true) {
ansond 0:6b56785dd2b6 345 // sleep for a bit
ansond 0:6b56785dd2b6 346 checkForExit();
ansond 0:6b56785dd2b6 347 wait(DEFAULT_MAIN_LOOP_WAIT);
ansond 0:6b56785dd2b6 348
ansond 0:6b56785dd2b6 349 // announce our position
ansond 1:dfd24f608038 350 this->updateCoordinates();
ansond 6:510193bc7f26 351
ansond 6:510193bc7f26 352 // if not connected... reconnect
ansond 6:510193bc7f26 353 if (!socketio.is_connected()){
ansond 6:510193bc7f26 354 // announce
ansond 6:510193bc7f26 355 this->display("Re-connecting...");
ansond 6:510193bc7f26 356 this->display_lcd("Re-connecting...");
ansond 6:510193bc7f26 357
ansond 6:510193bc7f26 358 // re-connect
ansond 6:510193bc7f26 359 if (this->connectWebSocketService()) {
ansond 6:510193bc7f26 360 // announce
ansond 6:510193bc7f26 361 this->display("Reconnect success");
ansond 6:510193bc7f26 362 this->display_lcd("Reconnect: SUCCESS");
ansond 6:510193bc7f26 363 this->turnRGBLEDGreen();
ansond 6:510193bc7f26 364 this->resetAllLEDs();
ansond 6:510193bc7f26 365 }
ansond 6:510193bc7f26 366 else {
ansond 6:510193bc7f26 367 // announce
ansond 6:510193bc7f26 368 this->display("Reconnect failure");
ansond 6:510193bc7f26 369 this->display_lcd("Reconnect: FAILED");
ansond 6:510193bc7f26 370 this->gracefullyDisconnect();
ansond 6:510193bc7f26 371 this->turnRGBLEDRed();
ansond 6:510193bc7f26 372 }
ansond 6:510193bc7f26 373 }
ansond 0:6b56785dd2b6 374
ansond 0:6b56785dd2b6 375 // check and react to the joystick button press
ansond 0:6b56785dd2b6 376 if (joystick_pressed) {
ansond 0:6b56785dd2b6 377 if (this->m_rgbLEDColor > 1) {
ansond 0:6b56785dd2b6 378 this->turnRGBLEDRed();
ansond 0:6b56785dd2b6 379 this->m_status = "FAIL";
ansond 0:6b56785dd2b6 380 }
ansond 0:6b56785dd2b6 381 else {
ansond 0:6b56785dd2b6 382 this->turnRGBLEDGreen();
ansond 0:6b56785dd2b6 383 this->m_status = "OK";
ansond 0:6b56785dd2b6 384 }
ansond 0:6b56785dd2b6 385 }
ansond 0:6b56785dd2b6 386 else if (socketio.is_connected() && this->m_rgbLEDColor > 121) {
ansond 0:6b56785dd2b6 387 this->turnRGBLEDGreen();
ansond 0:6b56785dd2b6 388 }
ansond 0:6b56785dd2b6 389
ansond 0:6b56785dd2b6 390 // check the status of the joystick
ansond 0:6b56785dd2b6 391 if (joystick) {
ansond 0:6b56785dd2b6 392 if (socketio.is_connected()) {
ansond 0:6b56785dd2b6 393 // announce
ansond 0:6b56785dd2b6 394 this->display("Disconnecting...");
ansond 0:6b56785dd2b6 395 this->display_lcd("Disconnecting...");
ansond 0:6b56785dd2b6 396
ansond 0:6b56785dd2b6 397 // disconnect
ansond 0:6b56785dd2b6 398 this->gracefullyDisconnect();
ansond 0:6b56785dd2b6 399 }
ansond 0:6b56785dd2b6 400 else if (!socketio.is_connected()){
ansond 0:6b56785dd2b6 401 // announce
ansond 0:6b56785dd2b6 402 this->display("Re-connecting...");
ansond 0:6b56785dd2b6 403 this->display_lcd("Re-connecting...");
ansond 0:6b56785dd2b6 404
ansond 0:6b56785dd2b6 405 // re-connect
ansond 0:6b56785dd2b6 406 if (this->connectWebSocketService()) {
ansond 0:6b56785dd2b6 407 // announce
ansond 0:6b56785dd2b6 408 this->display("Reconnect success");
ansond 0:6b56785dd2b6 409 this->display_lcd("Reconnect: SUCCESS");
ansond 0:6b56785dd2b6 410 this->turnRGBLEDGreen();
ansond 0:6b56785dd2b6 411 this->resetAllLEDs();
ansond 0:6b56785dd2b6 412 }
ansond 0:6b56785dd2b6 413 else {
ansond 0:6b56785dd2b6 414 // announce
ansond 0:6b56785dd2b6 415 this->display("Reconnect failure");
ansond 0:6b56785dd2b6 416 this->display_lcd("Reconnect: FAILED");
ansond 0:6b56785dd2b6 417 this->gracefullyDisconnect();
ansond 0:6b56785dd2b6 418 this->turnRGBLEDRed();
ansond 0:6b56785dd2b6 419 }
ansond 0:6b56785dd2b6 420 }
ansond 0:6b56785dd2b6 421 }
ansond 0:6b56785dd2b6 422
ansond 0:6b56785dd2b6 423 // if we are connected, send our status
ansond 0:6b56785dd2b6 424 if (socketio.is_connected()) {
ansond 0:6b56785dd2b6 425 // send status
ansond 0:6b56785dd2b6 426 this->sendStatus();
ansond 0:6b56785dd2b6 427 checkForExit();
ansond 0:6b56785dd2b6 428 }
ansond 0:6b56785dd2b6 429
ansond 0:6b56785dd2b6 430 // if we are connected, read any control we may receive
ansond 0:6b56785dd2b6 431 if (socketio.is_connected()) {
ansond 0:6b56785dd2b6 432 // process control messages
ansond 0:6b56785dd2b6 433 this->processControlMessage();
ansond 0:6b56785dd2b6 434 checkForExit();
ansond 0:6b56785dd2b6 435 }
ansond 0:6b56785dd2b6 436 }
ansond 0:6b56785dd2b6 437 }
ansond 0:6b56785dd2b6 438
ansond 0:6b56785dd2b6 439 // Run the Demo
ansond 0:6b56785dd2b6 440 void Thermostat::runDemo() {
ansond 0:6b56785dd2b6 441 // Announce
ansond 0:6b56785dd2b6 442 this->display("Thermostat Hands-On Demo v1.0");
ansond 0:6b56785dd2b6 443 this->display_lcd("Thermostat Hands-On\r\nDemo v1.0");
ansond 0:6b56785dd2b6 444
ansond 0:6b56785dd2b6 445 // init the RGB LED
ansond 0:6b56785dd2b6 446 this->display("Initializing LEDs...");
ansond 0:6b56785dd2b6 447 this->turnRGBLEDBlue();
ansond 0:6b56785dd2b6 448
ansond 0:6b56785dd2b6 449 // Log
ansond 0:6b56785dd2b6 450 this->display("Connecting...");
ansond 0:6b56785dd2b6 451 this->display_lcd("Connecting...");
ansond 0:6b56785dd2b6 452
ansond 0:6b56785dd2b6 453 // connect and send the initial status
ansond 0:6b56785dd2b6 454 if (this->connectEthernet() == true && this->connectWebSocketService() == true) {
ansond 0:6b56785dd2b6 455 this->sendStatus();
ansond 0:6b56785dd2b6 456 this->mainLoop();
ansond 0:6b56785dd2b6 457 }
ansond 0:6b56785dd2b6 458 else {
ansond 0:6b56785dd2b6 459 this->display("Connection failure. Application exiting...");
ansond 0:6b56785dd2b6 460 this->display_lcd("Connect: FAILURE.\r\nApplication Exiting");
ansond 0:6b56785dd2b6 461 }
ansond 0:6b56785dd2b6 462
ansond 0:6b56785dd2b6 463 // exit the application if we get here
ansond 0:6b56785dd2b6 464 exit(1);
ansond 0:6b56785dd2b6 465 }