 String currentTempString = String(currentTemp); //String to store the sensor's temp so it can be exposed
 String currentHumidityString = String(currentHumidity); //String to store the sensor's humidity so it can be exposed
 
-//testing variables
+//TESTING_HACK
+// this allows me to system test the project
 bool testing = false;
 
+
+/*******************************************************************************
+ * Function Name  : setup
+ * Description    : this function runs once at system boot
+ *******************************************************************************/
 void setup() {
 
- //publish startup message with firmware version
- Particle.publish(APP_NAME, VERSION, 60, PRIVATE);
-
- //declare and init pins
- pinMode(fan, OUTPUT);
- pinMode(heat, OUTPUT);
- pinMode(cold, OUTPUT);
- myDigitalWrite(fan, LOW);
- myDigitalWrite(heat, LOW);
- myDigitalWrite(cold, LOW);
-
- //declare cloud variables
- //https://docs.particle.io/reference/firmware/photon/#particle-variable-
- //Currently, up to 10 cloud variables may be defined and each variable name is limited to a maximum of 12 characters
- if (Particle.variable("targetTemp", targetTempString)==false) {
-   Particle.publish(APP_NAME, "ERROR: Failed to register variable targetTemp", 60, PRIVATE);
- }
- if (Particle.variable("currentTemp", currentTempString)==false) {
-   Particle.publish(APP_NAME, "ERROR: Failed to register variable currentTemp", 60, PRIVATE);
- }
- if (Particle.variable("humidity", currentHumidityString)==false) {
-   Particle.publish(APP_NAME, "ERROR: Failed to register variable humidity", 60, PRIVATE);
- }
-
- //declare cloud functions
- //https://docs.particle.io/reference/firmware/photon/#particle-function-
- //Currently the application supports the creation of up to 4 different cloud functions.
- //The length of the funcKey is limited to a max of 12 characters.
- // If you declare a function name longer than 12 characters the function will not be registered.
- //user functions
- if (Particle.function("setTargetTmp", setTargetTemp)==false) {
-    Particle.publish(APP_NAME, "ERROR: Failed to register function setTargetTemp", 60, PRIVATE);
- }
- //testing functions
- if (Particle.function("setTesting", setTesting)==false) {
-    Particle.publish(APP_NAME, "ERROR: Failed to register function setTesting", 60, PRIVATE);
- }
- if (Particle.function("setCurrTmp", setCurrentTemp)==false) {
-    Particle.publish(APP_NAME, "ERROR: Failed to register function setCurrentTemp", 60, PRIVATE);
- }
- if (Particle.function("getOutputs", getOutputs)==false) {
-    Particle.publish(APP_NAME, "ERROR: Failed to register function getOutputs", 60, PRIVATE);
- }
+  //pulish startup message with firmware version
+  Particle.publish(APP_NAME, VERSION, 60, PRIVATE);
+
+  //declare and init pins
+  pinMode(fan, OUTPUT);
+  pinMode(heat, OUTPUT);
+  pinMode(cold, OUTPUT);
+  myDigitalWrite(fan, LOW);
+  myDigitalWrite(heat, LOW);
+  myDigitalWrite(cold, LOW);
+
+  //declare cloud variables
+  //https://docs.particle.io/reference/firmware/photon/#particle-variable-
+  //Currently, up to 10 cloud variables may be defined and each variable name is limited to a maximum of 12 characters
+  if (Particle.variable("targetTemp", targetTempString)==false) {
+    Particle.publish(APP_NAME, "ERROR: Failed to register variable targetTemp", 60, PRIVATE);
+  }
+  if (Particle.variable("currentTemp", currentTempString)==false) {
+    Particle.publish(APP_NAME, "ERROR: Failed to register variable currentTemp", 60, PRIVATE);
+  }
+  if (Particle.variable("humidity", currentHumidityString)==false) {
+    Particle.publish(APP_NAME, "ERROR: Failed to register variable humidity", 60, PRIVATE);
+  }
+
+  //declare cloud functions
+  //https://docs.particle.io/reference/firmware/photon/#particle-function-
+  //Currently the application supports the creation of up to 4 different cloud functions.
+  //The length of the funcKey is limited to a max of 12 characters.
+  // If you declare a function name longer than 12 characters the function will not be registered.
+  //user functions
+  if (Particle.function("setTargetTmp", setTargetTemp)==false) {
+     Particle.publish(APP_NAME, "ERROR: Failed to register function setTargetTemp", 60, PRIVATE);
+  }
+  //TESTING_HACK
+  if (Particle.function("setTesting", setTesting)==false) {
+     Particle.publish(APP_NAME, "ERROR: Failed to register function setTesting", 60, PRIVATE);
+  }
+  //TESTING_HACK
+  if (Particle.function("setCurrTmp", setCurrentTemp)==false) {
+     Particle.publish(APP_NAME, "ERROR: Failed to register function setCurrentTemp", 60, PRIVATE);
+  }
+  //TESTING_HACK
+  if (Particle.function("getOutputs", getOutputs)==false) {
+     Particle.publish(APP_NAME, "ERROR: Failed to register function getOutputs", 60, PRIVATE);
+  }
 
 }
 

//TODO:
// have a minimun time for each state to protect on-off on the fan and the heating element

//The MIT License (MIT)
//Copyright (c) 2016 Gustavo Gonnet
//

//initialize state machine, start in state: Idle
FSM thermostatStateMachine = FSM(initState);

//milliseconds for the init cycle, so temperature samples get stabilized
//this should be in the order of the 5 minutes: 5*60*1000==300000
#define INIT_TIMEOUT 30000
elapsedMillis initTimer;

//milliseconds to leave the fan on when the target temp has been reached
//this evacuates the heat or the cold air from vents
#define END_OF_CYCLE_TIMEOUT 15000
elapsedMillis endOfCycleTimer;

//minimum number of milliseconds to leave the heating element on
// to protect on-off on the fan and the heating element
#define MINIMUM_ON_TIMEOUT 5000
elapsedMillis minimumOnTimer;

/*******************************************************************************
 IO mapping
*******************************************************************************/
// D0 : relay: fan
// D1 : relay: heat
// D2 : relay: cold
// D4 : DHT22
// D3, D5~D7 : unused
// A0~A7 : unused
int fan = D0;
int heat = D1;
int cold = D2;
//TESTING_HACK
int fanTesting;
int heatTesting;
int coldTesting;

/*******************************************************************************
 DHT sensor
*******************************************************************************/
#define DHTTYPE  DHT22                // Sensor type DHT11/21/22/AM2301/AM2302
#define DHTPIN   4                    // Digital pin for communications
#define DHT_SAMPLE_INTERVAL   30000   // Sample room temperature every 30 seconds
