Skip to content

Instantly share code, notes, and snippets.

@paruljain
Last active February 12, 2018 19:29
Show Gist options
  • Save paruljain/e2f2e0ce0d88f4bd52e75a337ba07ce8 to your computer and use it in GitHub Desktop.
Save paruljain/e2f2e0ce0d88f4bd52e75a337ba07ce8 to your computer and use it in GitHub Desktop.
// 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