Last active
February 12, 2018 19:29
-
-
Save paruljain/e2f2e0ce0d88f4bd52e75a337ba07ce8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Include the libraries we need | |
#include <OneWire.h> | |
#include <DallasTemperature.h> | |
#include <Ticker.h> | |
#include <ESP8266WiFi.h> | |
#include <EEPROM.h> | |
#include <PubSubClient.h> | |
#include <stdlib.h> | |
//Global variables | |
//WiFi settings | |
char ssid[] = "ParulNet-BGN"; | |
char pass[] = "**********"; | |
void callback(char* topic, byte* payload, unsigned int length); | |
WiFiClient espClient; | |
PubSubClient client("m10.cloudmqtt.com", 1111, callback, espClient); | |
//Thermostat contol globals | |
#define SYSTEM_MODE_OFF 0 | |
#define SYSTEM_MODE_HEAT 1 | |
#define SYSTEM_MODE_COOL 2 | |
#define FAN_MODE_AUTO 0 | |
#define FAN_MODE_ON 1 | |
#define OFF 0 | |
#define ON 1 | |
#define MAGIC 2455 | |
struct Config { | |
int magic; | |
int systemMode; | |
int fanMode; | |
float heatSetPoint; | |
float coolSetPoint; | |
} cfg; | |
struct State { | |
float temperature; | |
} state; | |
// Data wire is plugged into port 2 on the WEMOS D1 Mini | |
#define ONE_WIRE_BUS D2 | |
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) | |
OneWire oneWire(ONE_WIRE_BUS); | |
// Pass our oneWire reference to Dallas Temperature. | |
DallasTemperature sensors(&oneWire); | |
//Array to hold device address | |
DeviceAddress insideThermometer; | |
void setup(void) | |
{ | |
Serial.begin(9600); | |
//Read configuration | |
retrieveConfig(); | |
if (cfg.magic != MAGIC) { | |
//Config is bad or not initialized, so let us initialize it | |
Serial.print("Initializing configuration ... "); | |
cfg.magic = MAGIC; | |
cfg.systemMode = SYSTEM_MODE_OFF; | |
cfg.fanMode = FAN_MODE_AUTO; | |
cfg.heatSetPoint = 77.0; | |
cfg.coolSetPoint = 85.0; | |
storeConfig(); | |
Serial.println("done"); | |
} | |
//Set pin modes | |
pinMode(D1, OUTPUT); | |
// locate temperature sensor devices on the bus | |
Serial.print("Locating temperature sensor devices... "); | |
sensors.begin(); | |
Serial.print("found "); | |
Serial.print(sensors.getDeviceCount(), DEC); | |
Serial.println(" devices."); | |
if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); | |
// set the resolution | |
sensors.setResolution(insideThermometer, 12); | |
//Get current temperature | |
sensors.requestTemperatures(); | |
state.temperature = sensors.getTempF(insideThermometer); | |
//Start the furnace operator | |
Serial.println("Starting the furnace operator"); | |
furnaceOperator(); | |
//Connect to WiFi | |
WiFi.mode(WIFI_STA); | |
WiFi.begin(ssid, pass); | |
Serial.print("Connecting to WiFi ... "); | |
while (WiFi.status() != WL_CONNECTED) | |
{ | |
delay(500); | |
} | |
Serial.println("done"); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
} | |
long lastReconnectAttempt = 0; | |
boolean reconnect() { | |
if (client.connect("eagleschase", "*******", "*******")) { | |
client.subscribe("/eagleschase/thermostat/setHeatSetPoint"); | |
client.subscribe("/eagleschase/thermostat/setSystemMode"); | |
} | |
return client.connected(); | |
} | |
float prevTemp = 0.0; | |
int prevFurnaceState = 2; | |
void loop(void) | |
{ | |
sensors.requestTemperatures(); | |
state.temperature = sensors.getTempF(insideThermometer); | |
if (!client.connected()) { | |
long now = millis(); | |
if (now - lastReconnectAttempt > 5000) { | |
lastReconnectAttempt = now; | |
// Attempt to reconnect | |
if (reconnect()) { lastReconnectAttempt = 0; } | |
} | |
} else { | |
//We are online! | |
client.loop(); | |
if (prevTemp != state.temperature) { | |
char tempStr[10]; | |
dtostrf(state.temperature, 2, 3, tempStr); //2 is mininum width, 3 is precision | |
client.publish("/eagleschase/temperature", tempStr); | |
prevTemp = state.temperature; | |
} | |
int furnaceState = digitalRead(D1); | |
if (prevFurnaceState != furnaceState) { | |
if (furnaceState == LOW) {client.publish("/eagleschase/thermostat/furnace", "OFF");} | |
else {client.publish("/eagleschase/thermostat/furnace", "ON");} | |
prevFurnaceState = furnaceState; | |
} | |
} | |
delay(2000); | |
} | |
//Furnace Operator | |
Ticker furnaceTicker; | |
void furnaceOperator() { | |
furnaceTicker.detach(); | |
if (cfg.systemMode != SYSTEM_MODE_HEAT) { | |
digitalWrite(D1, LOW); | |
furnaceTicker.attach(5, furnaceOperator); | |
return; | |
} | |
if (digitalRead(D1) == HIGH){ | |
digitalWrite(D1, LOW); | |
furnaceTicker.attach(240, furnaceOperator); | |
return; | |
} | |
//Furnace is off, do we need to start it? | |
if (state.temperature >= cfg.heatSetPoint) { | |
furnaceTicker.attach(300, furnaceOperator); | |
return; | |
} | |
digitalWrite(D1, HIGH); | |
furnaceTicker.attach(45, furnaceOperator); | |
} | |
void setHeatSetPoint(float setPoint) { | |
if (setPoint == cfg.heatSetPoint) { return; } | |
cfg.heatSetPoint = setPoint; | |
storeConfig(); | |
Serial.print("Changed heat set point to "); | |
Serial.println(setPoint); | |
} | |
void setSystemMode(int mode) { | |
if (cfg.systemMode == mode) { return; } | |
cfg.systemMode = mode; | |
storeConfig(); | |
Serial.print("Changed system mode to "); | |
Serial.println(mode); | |
} | |
void storeConfig() { | |
EEPROM.begin(512); | |
EEPROM.put(0, cfg); | |
EEPROM.end(); | |
} | |
void retrieveConfig() { | |
EEPROM.begin(512); | |
EEPROM.get(0, cfg); | |
EEPROM.end(); | |
} | |
void callback(char* topic, byte* payload, unsigned int length) { | |
Serial.print("Message arrived ["); | |
Serial.print(topic); | |
Serial.print("] "); | |
char message[length + 1]; | |
for (int i=0;i<length;i++) { | |
message[i] = (char)payload[i]; | |
} | |
message[length] = '\0'; | |
if (strcmp(topic, "/eagleschase/thermostat/setHeatSetPoint") == 0) { | |
setHeatSetPoint(atof(message)); | |
} | |
else if (strcmp(topic, "/eagleschase/thermostat/setSystemMode") == 0) { | |
if (strcmp(message, "HEAT") == 0) { setSystemMode(SYSTEM_MODE_HEAT); } | |
else if (strcmp(message, "COOL") == 0) { setSystemMode(SYSTEM_MODE_COOL); } | |
else if (strcmp(message, "OFF") == 0) { setSystemMode(SYSTEM_MODE_OFF); } | |
} | |
Serial.println(message); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment