From bda0c4d8f4162fbd8c5f4f0918503a9ccf5b84b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Tue, 20 Dec 2016 16:26:45 +0100 Subject: [PATCH 1/4] Manage LED status from MQTT --- code/src/config/general.h | 9 +++ code/src/config/hardware.h | 52 +++++++++--------- code/src/led.ino | 110 +++++++++++++++++++++++++++++++++---- code/src/main.ino | 1 + 4 files changed, 135 insertions(+), 37 deletions(-) diff --git a/code/src/config/general.h b/code/src/config/general.h index f971ebb9..5e2e4c77 100644 --- a/code/src/config/general.h +++ b/code/src/config/general.h @@ -27,6 +27,15 @@ // 0 means ANY, 1 zero or one and 2 one and only one #define RELAY_SYNC RELAY_SYNC_ANY +//-------------------------------------------------------------------------------- +// LED +//-------------------------------------------------------------------------------- + +// All defined LEDs in the board can be managed through MQTT +// except the first one when LED_AUTO is set to 1. +// If LED_AUTO is set to 1 the board will use first defined LED to show wifi status. +#define LED_AUTO 1 + // ----------------------------------------------------------------------------- // WIFI & WEB // ----------------------------------------------------------------------------- diff --git a/code/src/config/hardware.h b/code/src/config/hardware.h index 9dc6ac9d..3b164872 100644 --- a/code/src/config/hardware.h +++ b/code/src/config/hardware.h @@ -26,8 +26,8 @@ #define DEVICE "LOLIN" #define BUTTON1_PIN 0 #define RELAY1_PIN 12 - #define LED_PIN 2 - #define LED_PIN_INVERSE 0 + #define LED1_PIN 2 + #define LED1_PIN_INVERSE 0 // ----------------------------------------------------------------------------- // Itead Studio boards @@ -39,8 +39,8 @@ #define DEVICE "SONOFF" #define BUTTON1_PIN 0 #define RELAY1_PIN 12 - #define LED_PIN 13 - #define LED_PIN_INVERSE 0 + #define LED1_PIN 13 + #define LED1_PIN_INVERSE 0 #elif defined(SONOFF_TH) @@ -48,8 +48,8 @@ #define DEVICE "SONOFF_TH" #define BUTTON1_PIN 0 #define RELAY1_PIN 12 - #define LED_PIN 13 - #define LED_PIN_INVERSE 0 + #define LED1_PIN 13 + #define LED1_PIN_INVERSE 0 #elif defined(SONOFF_TOUCH) @@ -57,8 +57,8 @@ #define DEVICE "SONOFF_TOUCH" #define BUTTON1_PIN 0 #define RELAY1_PIN 12 - #define LED_PIN 13 - #define LED_PIN_INVERSE 1 + #define LED1_PIN 13 + #define LED1_PIN_INVERSE 1 #elif defined(SONOFF_POW) @@ -66,8 +66,8 @@ #define DEVICE "SONOFF_POW" #define BUTTON1_PIN 0 #define RELAY1_PIN 12 - #define LED_PIN 15 - #define LED_PIN_INVERSE 1 + #define LED1_PIN 15 + #define LED1_PIN_INVERSE 1 #define ENABLE_POW 1 #elif defined(SONOFF_DUAL) @@ -75,8 +75,8 @@ #define MANUFACTURER "ITEAD" #define DEVICE "SONOFF_DUAL" #define BUTTON1_PIN 0 - #define LED_PIN 13 - #define LED_PIN_INVERSE 0 + #define LED1_PIN 13 + #define LED1_PIN_INVERSE 0 #undef SERIAL_BAUDRATE #define SERIAL_BAUDRATE 19230 @@ -92,8 +92,8 @@ #define RELAY2_PIN 5 #define RELAY3_PIN 4 #define RELAY4_PIN 15 - #define LED_PIN 13 - #define LED_PIN_INVERSE 1 + #define LED1_PIN 13 + #define LED1_PIN_INVERSE 1 #elif defined(SONOFF_SV) @@ -101,8 +101,8 @@ #define DEVICE "SONOFF_SV" #define BUTTON1_PIN 0 #define RELAY1_PIN 12 - #define LED_PIN 13 - #define LED_PIN_INVERSE 1 + #define LED1_PIN 13 + #define LED1_PIN_INVERSE 1 #elif defined(SLAMPHER) @@ -110,8 +110,8 @@ #define DEVICE "SLAMPHER" #define BUTTON1_PIN 0 #define RELAY1_PIN 12 - #define LED_PIN 13 - #define LED_PIN_INVERSE 0 + #define LED1_PIN 13 + #define LED1_PIN_INVERSE 0 #elif defined(S20) @@ -119,8 +119,8 @@ #define DEVICE "S20" #define BUTTON1_PIN 0 #define RELAY1_PIN 12 - #define LED_PIN 13 - #define LED_PIN_INVERSE 0 + #define LED1_PIN 13 + #define LED1_PIN_INVERSE 0 // ----------------------------------------------------------------------------- // Electrodragon boards @@ -134,8 +134,8 @@ #define BUTTON2_PIN 2 #define RELAY1_PIN 12 #define RELAY2_PIN 13 - #define LED_PIN 16 - #define LED_PIN_INVERSE 1 + #define LED1_PIN 16 + #define LED1_PIN_INVERSE 1 // ----------------------------------------------------------------------------- // WorkChoice ecoPlug @@ -147,8 +147,8 @@ #define DEVICE "ECOPLUG" #define BUTTON1_PIN 13 #define RELAY_PIN 15 - #define LED_PIN 2 - #define LED_PIN_INVERSE 1 + #define LED1_PIN 2 + #define LED1_PIN_INVERSE 1 // ----------------------------------------------------------------------------- // ESPurna board (still beta) @@ -160,8 +160,8 @@ #define DEVICE "ESPURNA" #define BUTTON1_PIN 0 #define RELAY1_PIN 12 - #define LED_PIN 13 - #define LED_PIN_INVERSE 0 + #define LED1_PIN 13 + #define LED1_PIN_INVERSE 0 // ----------------------------------------------------------------------------- // Unknown hardware diff --git a/code/src/led.ino b/code/src/led.ino index cd8c1346..f973e2d4 100644 --- a/code/src/led.ino +++ b/code/src/led.ino @@ -11,36 +11,124 @@ Copyright (C) 2016 by Xose PĂ©rez // LED // ----------------------------------------------------------------------------- -#ifdef LED_PIN +#ifdef LED1_PIN -void blink(unsigned long delayOff, unsigned long delayOn) { +typedef struct { + unsigned char pin; + bool reverse; +} led_t; + +std::vector _leds; +bool ledAuto; + +bool ledStatus(unsigned char id) { + bool status = digitalRead(_leds[id].pin); + return _leds[id].reverse ? !status : status; +} + +bool ledStatus(unsigned char id, bool status) { + bool s = _leds[id].reverse ? !status : status; + digitalWrite(_leds[id].pin, _leds[id].reverse ? !status : status); + return status; +} + +bool ledToggle(unsigned char id) { + return ledStatus(id, !ledStatus(id)); +} + +void ledBlink(unsigned char id, unsigned long delayOff, unsigned long delayOn) { static unsigned long next = millis(); - static bool status = HIGH; if (next < millis()) { - status = !status; - digitalWrite(LED_PIN, LED_PIN_INVERSE ? !status : status); - next += ((status) ? delayOff : delayOn); + next += (ledToggle(id) ? delayOn : delayOff); } } void showStatus() { if (wifiConnected()) { if (WiFi.getMode() == WIFI_AP) { - blink(2000, 2000); + ledBlink(0, 2000, 2000); } else { - blink(5000, 500); + ledBlink(0, 5000, 500); } } else { - blink(500, 500); + ledBlink(0, 500, 500); + } +} + +void ledMQTTCallback(unsigned int type, const char * topic, const char * payload) { + + static bool isFirstMessage = true; + + if (type == MQTT_CONNECT_EVENT) { + mqttSubscribe("/led/#"); + } + + if (type == MQTT_MESSAGE_EVENT) { + + // Match topic + if (memcmp("/led/", topic, 5) != 0) return; + + // Get led ID + unsigned int ledID = topic[strlen(topic)-1] - '0'; + if (ledID >= relayCount()) ledID = 0; + + // get value + unsigned int value = (char)payload[0] - '0'; + bool bitAuto = (value & 0x02) > 0; + bool bitState = (value & 0x01) > 0; + + // Check ledAuto + if (ledID == 0) { + if (bitAuto) { + ledAuto = bitState; + setSetting("ledAuto", String() + (ledAuto ? "1" : "0")); + return; + } else if (ledAuto) { + return; + } + } + + // Action to perform + ledStatus(ledID, bitState); + } + +} + +void ledConfigure() { + ledAuto = getSetting("ledAuto", String() + LED_AUTO).toInt() == 1; } void ledSetup() { - pinMode(LED_PIN, OUTPUT); + + #ifdef LED1_PIN + _leds.push_back((led_t) { LED1_PIN, LED1_PIN_INVERSE }); + #endif + #ifdef LED2_PIN + _leds.push_back((led_t) { LED2_PIN, LED2_PIN_INVERSE }); + #endif + #ifdef LED3_PIN + _leds.push_back((led_t) { LED3_PIN, LED3_PIN_INVERSE }); + #endif + #ifdef LED4_PIN + _leds.push_back((led_t) { LED4_PIN, LED4_PIN_INVERSE }); + #endif + + for (unsigned int i=0; i < _leds.size(); i++) { + pinMode(_leds[i].pin, OUTPUT); + ledStatus(i, false); + } + + ledConfigure(); + + mqttRegister(ledMQTTCallback); + + DEBUG_MSG("[LED] Number of leds: %d\n", _leds.size()); + } void ledLoop() { - showStatus(); + if (ledAuto) showStatus(); } #else diff --git a/code/src/main.ino b/code/src/main.ino index b72f3b0d..2f1d0365 100644 --- a/code/src/main.ino +++ b/code/src/main.ino @@ -31,6 +31,7 @@ along with this program. If not, see . #include "FS.h" String getSetting(const String& key, String defaultValue = ""); bool relayStatus(unsigned char id, bool status, bool report = true); +void mqttRegister(void (*callback)(unsigned int, const char *, const char *)); // ----------------------------------------------------------------------------- // METHODS From f94d5ef927f1753951b9ccc2775a52a911822496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Tue, 20 Dec 2016 16:55:58 +0100 Subject: [PATCH 2/4] Fix LED logic in hardware configuration --- code/src/config/hardware.h | 20 ++++++++++---------- code/src/led.ino | 6 +++++- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/code/src/config/hardware.h b/code/src/config/hardware.h index 3b164872..f14e9e77 100644 --- a/code/src/config/hardware.h +++ b/code/src/config/hardware.h @@ -26,8 +26,8 @@ #define DEVICE "LOLIN" #define BUTTON1_PIN 0 #define RELAY1_PIN 12 - #define LED1_PIN 2 - #define LED1_PIN_INVERSE 0 + #define LED1_PIN 2 + #define LED1_PIN_INVERSE 1 // ----------------------------------------------------------------------------- // Itead Studio boards @@ -40,7 +40,7 @@ #define BUTTON1_PIN 0 #define RELAY1_PIN 12 #define LED1_PIN 13 - #define LED1_PIN_INVERSE 0 + #define LED1_PIN_INVERSE 1 #elif defined(SONOFF_TH) @@ -49,7 +49,7 @@ #define BUTTON1_PIN 0 #define RELAY1_PIN 12 #define LED1_PIN 13 - #define LED1_PIN_INVERSE 0 + #define LED1_PIN_INVERSE 1 #elif defined(SONOFF_TOUCH) @@ -67,7 +67,7 @@ #define BUTTON1_PIN 0 #define RELAY1_PIN 12 #define LED1_PIN 15 - #define LED1_PIN_INVERSE 1 + #define LED1_PIN_INVERSE 0 #define ENABLE_POW 1 #elif defined(SONOFF_DUAL) @@ -76,7 +76,7 @@ #define DEVICE "SONOFF_DUAL" #define BUTTON1_PIN 0 #define LED1_PIN 13 - #define LED1_PIN_INVERSE 0 + #define LED1_PIN_INVERSE 1 #undef SERIAL_BAUDRATE #define SERIAL_BAUDRATE 19230 @@ -111,7 +111,7 @@ #define BUTTON1_PIN 0 #define RELAY1_PIN 12 #define LED1_PIN 13 - #define LED1_PIN_INVERSE 0 + #define LED1_PIN_INVERSE 1 #elif defined(S20) @@ -120,7 +120,7 @@ #define BUTTON1_PIN 0 #define RELAY1_PIN 12 #define LED1_PIN 13 - #define LED1_PIN_INVERSE 0 + #define LED1_PIN_INVERSE 1 // ----------------------------------------------------------------------------- // Electrodragon boards @@ -135,7 +135,7 @@ #define RELAY1_PIN 12 #define RELAY2_PIN 13 #define LED1_PIN 16 - #define LED1_PIN_INVERSE 1 + #define LED1_PIN_INVERSE 0 // ----------------------------------------------------------------------------- // WorkChoice ecoPlug @@ -148,7 +148,7 @@ #define BUTTON1_PIN 13 #define RELAY_PIN 15 #define LED1_PIN 2 - #define LED1_PIN_INVERSE 1 + #define LED1_PIN_INVERSE 0 // ----------------------------------------------------------------------------- // ESPurna board (still beta) diff --git a/code/src/led.ino b/code/src/led.ino index f973e2d4..14af752e 100644 --- a/code/src/led.ino +++ b/code/src/led.ino @@ -70,7 +70,7 @@ void ledMQTTCallback(unsigned int type, const char * topic, const char * payload // Get led ID unsigned int ledID = topic[strlen(topic)-1] - '0'; - if (ledID >= relayCount()) ledID = 0; + if (ledID >= ledCount()) ledID = 0; // get value unsigned int value = (char)payload[0] - '0'; @@ -95,6 +95,10 @@ void ledMQTTCallback(unsigned int type, const char * topic, const char * payload } +unsigned char ledCount() { + return _leds.size(); +} + void ledConfigure() { ledAuto = getSetting("ledAuto", String() + LED_AUTO).toInt() == 1; } From caf58e0eaba24b89570eb79ebafc7b3eb4f5179c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Wed, 21 Dec 2016 18:23:24 +0100 Subject: [PATCH 3/4] Automatically disable ledAuto when an MQTT message is received --- code/src/led.ino | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/code/src/led.ino b/code/src/led.ino index 14af752e..3e8de022 100644 --- a/code/src/led.ino +++ b/code/src/led.ino @@ -79,13 +79,9 @@ void ledMQTTCallback(unsigned int type, const char * topic, const char * payload // Check ledAuto if (ledID == 0) { - if (bitAuto) { - ledAuto = bitState; - setSetting("ledAuto", String() + (ledAuto ? "1" : "0")); - return; - } else if (ledAuto) { - return; - } + ledAuto = bitAuto ? bitState : false; + setSetting("ledAuto", String() + (ledAuto ? "1" : "0")); + if (bitAuto) return; } // Action to perform From 8cf10eee9089e2644a62b568c80507acbd8c769c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Fri, 23 Dec 2016 18:17:27 +0100 Subject: [PATCH 4/4] Added support for MQTT_USE_SETTER in leds module --- code/src/config/general.h | 1 + code/src/led.ino | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/code/src/config/general.h b/code/src/config/general.h index 2124af7c..c40a00c4 100644 --- a/code/src/config/general.h +++ b/code/src/config/general.h @@ -68,6 +68,7 @@ #define MQTT_KEEPALIVE 30 #define MQTT_RECONNECT_DELAY 10000 #define MQTT_RELAY_TOPIC "/relay" +#define MQTT_LED_TOPIC "/led" #define MQTT_IP_TOPIC "/ip" #define MQTT_VERSION_TOPIC "/version" #define MQTT_FSVERSION_TOPIC "/fsversion" diff --git a/code/src/led.ino b/code/src/led.ino index 3e8de022..e2cb3bbe 100644 --- a/code/src/led.ino +++ b/code/src/led.ino @@ -59,17 +59,23 @@ void ledMQTTCallback(unsigned int type, const char * topic, const char * payload static bool isFirstMessage = true; + String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER); + if (type == MQTT_CONNECT_EVENT) { - mqttSubscribe("/led/#"); + char buffer[strlen(MQTT_LED_TOPIC) + mqttSetter.length() + 3]; + sprintf(buffer, "%s/+%s", MQTT_LED_TOPIC, mqttSetter.c_str()); + mqttSubscribe(buffer); } if (type == MQTT_MESSAGE_EVENT) { // Match topic - if (memcmp("/led/", topic, 5) != 0) return; + String t = String(topic); + if (!t.startsWith(MQTT_LED_TOPIC)) return; + if (!t.endsWith(mqttSetter)) return; // Get led ID - unsigned int ledID = topic[strlen(topic)-1] - '0'; + unsigned int ledID = topic[strlen(MQTT_LED_TOPIC)+1] - '0'; if (ledID >= ledCount()) ledID = 0; // get value