Skip to content

Instantly share code, notes, and snippets.

@biacz
Created February 27, 2017 17:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biacz/b6c79828701ffe3b6f47f8d0682abfde to your computer and use it in GitHub Desktop.
Save biacz/b6c79828701ffe3b6f47f8d0682abfde to your computer and use it in GitHub Desktop.
//include all libraries
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ESP8266httpUpdate.h>
#include <PubSubClient.h>
#include <RCSwitch.h>
#include <fauxmoESP.h>
//basic defines
#define MQTT_VERSION MQTT_VERSION_3_1_1
#define IRB 14
#define RCPIN 2
#define OTA_URL "rc_update.bin"
//wifi credentials
const char* WIFI_SSID = " mich!";
const char* WIFI_PASSWORD = "@BM";
//mqtt variables
const PROGMEM char* MQTT_CLIENT_ID = "livingroom_rc";
const PROGMEM char* MQTT_SERVER_IP = "";
const PROGMEM uint16_t MQTT_SERVER_PORT = 1883;
const PROGMEM char* MQTT_USER = "";
const PROGMEM char* MQTT_PASSWORD = "";
const PROGMEM char* MQTT_SENSOR_TOPIC = "/house/livingroom/sensor_dht";
const PROGMEM char* MQTT_LIGHT_STATE_TOPIC[] = { "/house/livingroom/light_left/status", "/house/livingroom/light_right/status", "/house/livingroom/light_center/status" };
const PROGMEM char* MQTT_LIGHT_COMMAND_TOPIC[] = { "/house/livingroom/light_left/switch", "/house/livingroom/light_right/switch", "/house/livingroom/light_center/switch" };
const PROGMEM char* MQTT_MOVEMENT_STATE_TOPIC = "/house/livingroom/movement/status";
boolean m_light_state[] = { false, false, false }; //variable to store light states
const char* LIGHT_ON = "ON";
const char* LIGHT_OFF = "OFF";
//variables for rc-switch functionality
const char* housecode = "11010"; //first 5 dip switches on rc switches
const char* socketcodes[] = { "00010", "00001", "10000" }; //last 5 dip switches on rc switches
const char* socketnames[] = { "Steckdose Wohnzimmer Links", "Steckdose Wohnzimmer Rechts", "Steckdose_Wohnzimmer_Eingang" }; //in case you like to name your rc switches, put them in here.
unsigned long wait = 30000;
unsigned long now = millis();
unsigned long last_millis = 0;
int lastState = LOW;
//initialize classes
WiFiClient wifiClient;
PubSubClient client(wifiClient);
RCSwitch mySwitch = RCSwitch();
fauxmoESP fauxmo;
void callback(char* p_topic, byte* p_payload, unsigned int p_length) { //handle mqtt callbacks
String payload;
for (uint8_t i = 0; i < p_length; i++) { //concatenate payload
payload.concat((char)p_payload[i]);
}
Serial.println(p_topic);
for (int i = 0; i < 3; i++) { //for loop to run though the MQTT_LIGHT_COMMAND_TOPIC array. if the topic equals, switch the corresponding RC
if (String(MQTT_LIGHT_COMMAND_TOPIC[i]).equals(p_topic)) { //if topic matches
if (payload.equals(String(LIGHT_ON))) {
m_light_state[i] = true; //set state for the corresponding light
mySwitch.switchOn(housecode, socketcodes[i]);
Serial.print("INFO: Turn Light: ");
Serial.print(MQTT_LIGHT_COMMAND_TOPIC[i]);
Serial.println(" on!");
client.publish(MQTT_LIGHT_STATE_TOPIC[i], LIGHT_ON, true); //publish the state to mqtt
}
else if (payload.equals(String(LIGHT_OFF))) {
m_light_state[i] = false;
mySwitch.switchOff(housecode, socketcodes[i]);
Serial.print("INFO: Turn Light: ");
Serial.print(MQTT_LIGHT_COMMAND_TOPIC[i]);
Serial.println(" off!");
client.publish(MQTT_LIGHT_STATE_TOPIC[i], LIGHT_OFF, true); //publish state to mqtt
}
}
}
}
void reconnect() {
while (!client.connected()) { //loop until we're reconnected
Serial.println("INFO: Attempting MQTT connection...");
if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) {
Serial.println("INFO: connected");
for (int i = 0; i < 3; i++) {
client.subscribe(MQTT_LIGHT_COMMAND_TOPIC[i]); //subscribe to all light topics
}
} else {
Serial.print("ERROR: failed, rc=");
Serial.print(client.state());
Serial.println("DEBUG: try again in 5 seconds");
delay(5000); //wait 5 seconds before retrying
}
}
}
void initOTA() {
t_httpUpdate_return ret = ESPhttpUpdate.update(OTA_URL);
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;
}
}
void setupWifi() {
Serial.print("INFO: Connecting to ");
WiFi.mode(WIFI_STA);
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD); //connect to wifi
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println(WiFi.status());
}
Serial.println("");
Serial.println("INFO: WiFi connected");
Serial.println("INFO: IP address: ");
Serial.println(WiFi.localIP());
}
void setupFauxmo() {
fauxmo.addDevice("Licht eins");
fauxmo.addDevice("Licht zwei");
fauxmo.addDevice("Licht drei");
fauxmo.onMessage([](unsigned char device_id, const char * device_name, bool state) {
Serial.printf("[MAIN] Device #%d (%s) state: %s\n", device_id, device_name, state ? "ON" : "OFF");
client.publish(MQTT_LIGHT_COMMAND_TOPIC[device_id], state ? "ON" : "OFF", true);
});
}
void movement() {
unsigned long now = millis();
if(digitalRead(IRB) == HIGH && lastState == LOW) {
if(now - last_millis >= wait) {
last_millis = now;
client.publish(MQTT_MOVEMENT_STATE_TOPIC, "ON", true); //publish the state to mqtt
Serial.println("INFO: Movement detected!");
lastState = HIGH;
}
}
if(digitalRead(IRB) == LOW && lastState == HIGH) {
if(now - last_millis >= wait) {
last_millis = now;
client.publish(MQTT_MOVEMENT_STATE_TOPIC, "OFF", true); //publish the state to mqtt
Serial.println("INFO: No more movement detected!");
lastState = LOW;
}
}
}
void setup() {
Serial.begin(115200); //init the serial
mySwitch.enableTransmit(RCPIN); //enable transmit on RCPIN
setupWifi();
initOTA();
setupFauxmo();
client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
fauxmo.handle();
movement();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment