diff --git a/multi-esp.ino b/multi-esp.ino index 9182ff4..a8d2d0c 100644 --- a/multi-esp.ino +++ b/multi-esp.ino @@ -11,7 +11,7 @@ RCSwitch mySwitch = RCSwitch(); typedef struct { char* channel; char* id; - String name; + char name[255]; bool powered; uint8_t type; // 0=DIP, 1=Learned int on_code; @@ -42,11 +42,11 @@ const PROGMEM uint16_t MQTT_SERVER_PORT = 1883; -// MQTT: topics -const char* MQTT_LIGHT_STATE_TOPIC = "balcony/hanging_lamp/status"; -const char* MQTT_LIGHT_COMMAND_TOPIC = "balcony/hanging_lamp/switch"; +//// 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_SUBSYSTEM = "rfsockets/"; const char* MQTT_RFSOCKET_STATE_TOPIC = "/status"; const char* MQTT_RFSOCKET_COMMAND_TOPIC = "/switch"; @@ -54,25 +54,27 @@ const char* MQTT_RFSOCKET_COMMAND_TOPIC = "/switch"; 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); +void publishLightState(int socketIdx) { + char *socket_name = sockets[socketIdx].name; + char topic[strlen(MQTT_RFSOCKET_SUBSYSTEM) + strlen(MQTT_RFSOCKET_STATE_TOPIC) + strlen(socket_name)]; + strcpy(topic, MQTT_RFSOCKET_SUBSYSTEM); + strcat(topic, socket_name); + strcat(topic, MQTT_RFSOCKET_STATE_TOPIC); + + if (sockets[socketIdx].powered) { + client.publish(topic, LIGHT_ON, true); } else { - client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true); + client.publish(topic, LIGHT_OFF, true); } } // function called to turn on/off the light -void setLightState() { - byte socketIdx = 7; - if (m_light_state) { +void setLightState(byte socketIdx) { + if (sockets[socketIdx].powered) { setSocket(socketIdx, true); Serial.println("INFO: Turn light on..."); } else { @@ -90,22 +92,54 @@ void callback(char* p_topic, byte* p_payload, unsigned int p_length) { } // 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(); - } - } - } + Serial.print("Got a message on topic: "); + Serial.println(p_topic); + + char *topic_ptr; + const char* delimiter = "/"; + topic_ptr = strtok(p_topic, delimiter); + if (topic_ptr != NULL) { + char *subsystem = topic_ptr; + Serial.print("Found subsystem: "); + Serial.println(subsystem); + topic_ptr = strtok(NULL, delimiter); + if (topic_ptr != NULL) { + char *name = topic_ptr; + Serial.print("Found socket name: "); + Serial.println(name); + int socketIdx = findSocketIndex(name); + Serial.print("Found socket index "); + Serial.println(socketIdx); + // We only listen on the command channel so no further splitting needed + if (payload.equals(String(LIGHT_ON))) { + if (sockets[socketIdx].powered != true) { + sockets[socketIdx].powered = true; + setLightState(socketIdx); + publishLightState(socketIdx); + } + } else if (payload.equals(String(LIGHT_OFF))) { + if (sockets[socketIdx].powered != false) { + sockets[socketIdx].powered = false; + setLightState(socketIdx); + publishLightState(socketIdx); + } + } else { + Serial.print("Unknown payload received: "); + Serial.println(payload); + Serial.println("Ignoring it…\n"); + } + } else { + Serial.print("Got topic without delimiter ("); + Serial.print(delimiter); + Serial.print("), topic was:"); + Serial.println(p_topic); + } + } else { + Serial.print("Got topic without delimiter ("); + Serial.print(delimiter); + Serial.print("), topic was:"); + Serial.println(p_topic); + } } void reconnect() { @@ -115,10 +149,21 @@ void reconnect() { // 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); + for (int i = 0; i < numofsockets; i++) { + publishLightState(i); + } + for (int i = 0; i < numofsockets; i++) { + char *socket_name = sockets[i].name; + char topic[strlen(MQTT_RFSOCKET_SUBSYSTEM) + strlen(MQTT_RFSOCKET_COMMAND_TOPIC) + strlen(socket_name)]; + strcpy(topic, MQTT_RFSOCKET_SUBSYSTEM); + strcat(topic, socket_name); + strcat(topic, MQTT_RFSOCKET_COMMAND_TOPIC); + + Serial.print("INFO: subscribing to topic \""); + Serial.print(topic); + Serial.println("\""); + client.subscribe(topic); + } } else { Serial.print("ERROR: failed, rc="); Serial.print(client.state()); @@ -171,10 +216,13 @@ bool setSocket(int socketIdx, bool newStatus) { return success; } -int findSocketIndex(String name) { +int findSocketIndex(char *name) { for (int socketIdx = 0; socketIdx < numofsockets; socketIdx++) { PowerSocket canidateSocket = sockets[socketIdx]; - if (canidateSocket.name == name) { + if (strcmp(canidateSocket.name, name) == 0) { + Serial.print(canidateSocket.name); + Serial.print(" equals "); + Serial.println(name); return socketIdx; } } @@ -195,7 +243,6 @@ void setup() { 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