commit 1ac1ce1be1ec9cb3cede1b154368204330ac6401 Author: sqozz Date: Thu Jul 12 21:19:16 2018 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1effebc --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*__pycache__* +secrets.h +.*.swp +.*.swo +build.py diff --git a/multi-esp.ino b/multi-esp.ino new file mode 100644 index 0000000..9182ff4 --- /dev/null +++ b/multi-esp.ino @@ -0,0 +1,224 @@ +#include +#include +#include +#include +#include "secrets.h" + +#define MQTT_VERSION MQTT_VERSION_3_1_1 + +RCSwitch mySwitch = RCSwitch(); + +typedef struct { + char* channel; + char* id; + String name; + bool powered; + uint8_t type; // 0=DIP, 1=Learned + int on_code; + int off_code; +} PowerSocket; + +// see struct for description of fields +PowerSocket sockets[] = { + (PowerSocket) {"00000", "10000", "A", false, 0, -1, -1}, + (PowerSocket) {"00000", "01000", "B", false, 0, -1, -1}, + (PowerSocket) {"00000", "00100", "C", false, 0, -1, -1}, + (PowerSocket) {"00000", "00010", "D", false, 0, -1, -1}, + (PowerSocket) {"", "", "E", false, 1, 530800, 713872}, + (PowerSocket) {"", "", "F", false, 1, 172340, 409380}, + (PowerSocket) {"", "", "G", false, 1, 842428, 409388}, + (PowerSocket) {"", "", "H", false, 1, 713874, 530802} +}; + +int numofsockets = sizeof(sockets)/sizeof(sockets[0]); + +// MQTT: ID, server IP, port, username and password +const PROGMEM char* MQTT_CLIENT_ID = "multi-esp"; +const PROGMEM char* MQTT_SERVER_IP = "10.42.0.3"; +const PROGMEM uint16_t MQTT_SERVER_PORT = 1883; +// TODO: check if needed? +//const PROGMEM char* MQTT_USER = "[Redacted]"; +//const PROGMEM char* MQTT_PASSWORD = "[Redacted]"; + + + +// MQTT: topics +const char* MQTT_LIGHT_STATE_TOPIC = "balcony/hanging_lamp/status"; +const char* MQTT_LIGHT_COMMAND_TOPIC = "balcony/hanging_lamp/switch"; + +const char* MQTT_RFSOCKET_STATE_BASE = "rfsockets/"; +const char* MQTT_RFSOCKET_STATE_TOPIC = "/status"; +const char* MQTT_RFSOCKET_COMMAND_TOPIC = "/switch"; + +// payloads by default (on/off) +const char* LIGHT_ON = "ON"; +const char* LIGHT_OFF = "OFF"; + +//const PROGMEM uint8_t LED_PIN = 5; +boolean m_light_state = false; // light is turned off by default + +WiFiClient wifiClient; +PubSubClient client(wifiClient); + +// function called to publish the state of the light (on/off) +void publishLightState() { + if (m_light_state) { + client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_ON, true); + } else { + client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true); + } +} + +// function called to turn on/off the light +void setLightState() { + byte socketIdx = 7; + if (m_light_state) { + setSocket(socketIdx, true); + Serial.println("INFO: Turn light on..."); + } else { + setSocket(socketIdx, false); + Serial.println("INFO: Turn light off..."); + } +} + +// function called when a MQTT message arrived +void callback(char* p_topic, byte* p_payload, unsigned int p_length) { + // concat the payload into a string + String payload; + for (uint8_t i = 0; i < p_length; i++) { + payload.concat((char)p_payload[i]); + } + + // handle message topic + if (String(MQTT_LIGHT_COMMAND_TOPIC).equals(p_topic)) { + // test if the payload is equal to "ON" or "OFF" + if (payload.equals(String(LIGHT_ON))) { + if (m_light_state != true) { + m_light_state = true; + setLightState(); + publishLightState(); + } + } else if (payload.equals(String(LIGHT_OFF))) { + if (m_light_state != false) { + m_light_state = false; + setLightState(); + publishLightState(); + } + } + } +} + +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)) { + Serial.println("INFO: connected"); + // Once connected, publish an announcement... + publishLightState(); + // ... and resubscribe + client.subscribe(MQTT_LIGHT_COMMAND_TOPIC); + } 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); + } + } +} + +bool setSocket(int socketIdx, bool newStatus) { + PowerSocket socket; + bool success = false; + + if (socketIdx >= 0) { + success = true; + socket = sockets[socketIdx]; + socket.powered = newStatus; + sockets[socketIdx] = socket; // write back to status array + if (newStatus == true) { + for (char i = 0; i <= 1; i++) { + if (socket.type == 0) { + Serial.println("id socket"); + mySwitch.setProtocol(1); + mySwitch.switchOn(socket.channel, socket.id); + } else if (socket.type == 1) { + Serial.println("learning socket"); + mySwitch.setProtocol(5); + mySwitch.send(socket.on_code, 24); + } + delay(250); + } + } else { + for (char i = 0; i <= 1; i++) { + if (socket.type == 0) { + Serial.println("id socket"); + mySwitch.setProtocol(1); + mySwitch.switchOff(socket.channel, socket.id); + } else if (socket.type == 1) { + Serial.println("learning socket"); + char* off_code = socket.id; + mySwitch.setProtocol(5); + mySwitch.send(socket.off_code, 24); + } + delay(250); + } + } + } + + return success; +} + +int findSocketIndex(String name) { + for (int socketIdx = 0; socketIdx < numofsockets; socketIdx++) { + PowerSocket canidateSocket = sockets[socketIdx]; + if (canidateSocket.name == name) { + return socketIdx; + } + } + + return -1; +} + +void setup() { + // setup serial + Serial.begin(115200); + Serial.println("Serial interface initialized"); + + WiFi.mode(WIFI_STA); + Serial.print("Connecting to wifi "); + Serial.println(WIFI_SSID); + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + + Serial.println("Enable transmission while waiting on wifi"); + mySwitch.enableTransmit(2); + delay(1000); + setLightState(); + Serial.print("Transmission enabled, waiting for wifi now."); + + // Wait for connection + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + + // serial output of connection details + Serial.println(""); + Serial.print("Wifi connected to "); + Serial.println(WIFI_SSID); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + // init the MQTT connection + client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT); + client.setCallback(callback); +} + +void loop() { + if (!client.connected()) { + reconnect(); + } + client.loop(); +}