Last active
January 28, 2017 13:50
-
-
Save arcao/12cce928645c6050383206265f1fae6b to your computer and use it in GitHub Desktop.
Improved biacz version (original: https://gist.github.com/biacz/5ad2f56b3d055a3fc7ac700c7bc7a294). Switching lights are postponed to perform together.
This file contains hidden or 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 <ESP8266WiFi.h> | |
#include <PubSubClient.h> | |
#include <DHT.h> | |
#include <ArduinoJson.h> | |
#include <RCSwitch.h> | |
#include <ESP8266HTTPClient.h> | |
#include <ESP8266httpUpdate.h> | |
#include <Ticker.h> | |
// WiFi config | |
#define WIFI_SSID "Drueck mich!" | |
#define WIFI_PASSWORD "Key01@BM" | |
// MQTT config | |
#define MQTT_CLIENT_ID "bedroom_dht11" | |
#define MQTT_SERVER_IP "" | |
#define MQTT_SERVER_PORT 1883 | |
#define MQTT_USER "" | |
#define MQTT_PASSWORD "" | |
// DHT sensor | |
#define DHT_PIN 13 | |
#define DHT_TYPE DHT11 | |
#define DHT_TOPIC "/house/livingroom/sensor_dht" | |
#define DHT_UPDATE_INTERVAL_IN_SEC 20 | |
// lights config | |
#define LIGHT_POSTPONE_DELAY_IN_MS 200 | |
struct LIGHT_SWITCH { | |
const char* name; | |
const char* status_topic; | |
const char* command_topic; | |
const char* socket_code; | |
bool state; | |
bool updateState; | |
}; | |
LIGHT_SWITCH lights[] = { | |
{ | |
"Steckdose Wohnzimmer Links", | |
"/house/livingroom/light_left/status", | |
"/house/livingroom/light_left/switch", | |
"00010", | |
false, | |
false | |
}, | |
{ | |
"Steckdose Wohnzimmer Rechts", | |
"/house/livingroom/light_right/status", | |
"/house/livingroom/light_right/switch", | |
"00001", | |
false, | |
false | |
}, | |
{ | |
"Steckdose Wohnzimmer Eingang", | |
"/house/livingroom/light_center/status", | |
"/house/livingroom/light_center/switch", | |
"10000", | |
false, | |
false | |
} | |
}; | |
#define LIGHT_COUNT 3 | |
#define LIGHT_ON "ON" | |
#define LIGHT_OFF "OFF" | |
// other config | |
#define HOUSE_CODE "11010" | |
#define JSON_CHAR_BUFFER_SIZE 200 | |
DHT dht(DHT_PIN, DHT_TYPE); | |
WiFiClient wifiClient; | |
PubSubClient client(wifiClient); | |
RCSwitch mySwitch = RCSwitch(); | |
Ticker postDhtTicker; | |
bool performPostDht = false; | |
Ticker applyLightsTicker; | |
bool applyLightsPlaned = false; | |
bool performApplyLights = false; | |
void applyLights() { | |
applyLightsPlaned = false; | |
for(int i=0; i < LIGHT_COUNT; i++) { | |
if (lights[i].updateState) { | |
lights[i].updateState = false; | |
if (lights[i].state) | |
mySwitch.switchOn(HOUSE_CODE, lights[i].socket_code); | |
if (!lights[i].state) | |
mySwitch.switchOff(HOUSE_CODE, lights[i].socket_code); | |
} | |
} | |
} | |
void callback(char* topic, byte* payload, unsigned int len) { | |
Serial.println(topic);// handle message topic | |
for(int i=0; i < LIGHT_COUNT; i++) { | |
if (strcmp(lights[i].command_topic, topic) == 0) { | |
// test if the payload is equal to "ON" or "OFF" | |
lights[i].state = strcmp(LIGHT_ON, (char*)payload) == 0; | |
lights[i].updateState = true; | |
Serial.print("INFO: Turn Light: "); | |
Serial.print(lights[i].name); | |
Serial.println((lights[i].state) ? " on!" : "off!"); | |
client.publish(lights[i].status_topic,(lights[i].state) ? LIGHT_ON : LIGHT_OFF, true); | |
if (!applyLightsPlaned) { | |
applyLightsPlaned = true; | |
applyLightsTicker.once_ms(LIGHT_POSTPONE_DELAY_IN_MS, []{ performApplyLights = true; }); | |
} | |
} | |
} | |
} | |
void reconnect() { | |
// Loop until we're reconnected | |
while (!client.connected()) { | |
Serial.println("INFO: Attempting MQTT connection..."); | |
// Attempt to connect | |
if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) { | |
Serial.println("INFO: connected"); | |
// subscribe and send state | |
for(int i=0; i < LIGHT_COUNT; i++) { | |
client.subscribe(lights[i].command_topic); | |
client.publish(lights[i].status_topic,(lights[i].state) ? LIGHT_ON : LIGHT_OFF, true); | |
} | |
} else { | |
Serial.print("ERROR: failed, rc="); | |
Serial.print(client.state()); | |
Serial.println("DEBUG: try again in 5 seconds"); | |
// Wait 5 seconds before retrying | |
delay(5000); | |
} | |
} | |
} | |
void setupLights() { | |
mySwitch.enableTransmit(2); | |
// turn off all lights | |
for(int i=0; i < LIGHT_COUNT; i++) { | |
mySwitch.switchOff(HOUSE_CODE, lights[i].socket_code); | |
lights[i].state = false; | |
lights[i].state = false; | |
} | |
} | |
void postDht() { | |
char buffer[JSON_CHAR_BUFFER_SIZE + 1]; | |
float h = dht.readHumidity(); | |
float t = dht.readTemperature(); | |
if (isnan(h) || isnan(t)) { | |
Serial.println("ERROR: Failed to read from DHT sensor!"); | |
return; | |
} else { | |
//Serial.println(h); | |
//Serial.println(t); | |
StaticJsonBuffer<200> jsonBuffer; | |
JsonObject& root = jsonBuffer.createObject(); | |
root["temperature"] = String(t); | |
root["humidity"] = String(h); | |
root.prettyPrintTo(Serial); | |
Serial.println(); | |
root.printTo(buffer, JSON_CHAR_BUFFER_SIZE); | |
client.publish(DHT_TOPIC, buffer, true); | |
} | |
} | |
void setupDht() { | |
dht.begin(); | |
applyLightsTicker.attach(DHT_UPDATE_INTERVAL_IN_SEC, []{ performPostDht = true; }); | |
} | |
void setup() { | |
// init the serial | |
Serial.begin(115200); | |
Serial.println(); | |
Serial.println(); | |
setupLights(); | |
setupDht(); | |
// init the WiFi connection | |
Serial.print("INFO: Connecting to "); | |
Serial.println(WIFI_SSID); | |
WiFi.mode(WIFI_STA); | |
WiFi.begin(WIFI_SSID, WIFI_PASSWORD); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(); | |
Serial.println("INFO: WiFi connected"); | |
Serial.println("INFO: IP address: "); | |
Serial.println(WiFi.localIP()); | |
t_httpUpdate_return ret = ESPhttpUpdate.update("http://beutler.nl/test.bin"); | |
switch(ret) { | |
case HTTP_UPDATE_FAILED: | |
Serial.print("HTTP_UPDATE_FAILD Error (%d): %s "); | |
Serial.println(ESPhttpUpdate.getLastErrorString().c_str()); | |
break; | |
case HTTP_UPDATE_NO_UPDATES: | |
Serial.println("HTTP_UPDATE_NO_UPDATES"); | |
break; | |
case HTTP_UPDATE_OK: | |
Serial.println("HTTP_UPDATE_OK"); | |
break; | |
} | |
// init the MQTT connection | |
client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT); | |
client.setCallback(callback); | |
} | |
void loop() { | |
if (!client.connected()) { | |
reconnect(); | |
} | |
client.loop(); | |
if (performPostDht) { | |
performPostDht = false; | |
postDht(); | |
} | |
if (performApplyLights) { | |
performApplyLights = false; | |
applyLights(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment