From 627bea30edce65044f34f49dd650853f7a436aa4 Mon Sep 17 00:00:00 2001 From: devilpro1 <92226222+DevilPro1@users.noreply.github.com> Date: Sun, 26 May 2024 12:46:34 +0200 Subject: [PATCH 1/4] Delete usermods/smartnest directory --- usermods/smartnest/readme.md | 61 --------- usermods/smartnest/usermod_smartnest.h | 171 ------------------------- 2 files changed, 232 deletions(-) delete mode 100644 usermods/smartnest/readme.md delete mode 100644 usermods/smartnest/usermod_smartnest.h diff --git a/usermods/smartnest/readme.md b/usermods/smartnest/readme.md deleted file mode 100644 index 5c3ef8072e..0000000000 --- a/usermods/smartnest/readme.md +++ /dev/null @@ -1,61 +0,0 @@ -# Smartnest - -Enables integration with `smartnest.cz` service which provides MQTT integration with voice assistants. -In order to setup Smartnest follow the [documentation](https://www.docu.smartnest.cz/). - -## MQTT API - -The API is described in the Smartnest [Github repo](https://github.com/aososam/Smartnest/blob/master/Devices/lightRgb/lightRgb.ino). - - -## Usermod installation - -1. Register the usermod by adding `#include "../usermods/smartnest/usermod_smartnest.h"` at the top and `usermods.add(new Smartnest());` at the bottom of `usermods_list.cpp`. -or -2. Use `#define USERMOD_SMARTNEST` in wled.h or `-D USERMOD_SMARTNEST` in your platformio.ini - - -Example **usermods_list.cpp**: - -```cpp -#include "wled.h" -/* - * Register your v2 usermods here! - * (for v1 usermods using just usermod.cpp, you can ignore this file) - */ - -/* - * Add/uncomment your usermod filename here (and once more below) - * || || || - * \/ \/ \/ - */ -//#include "usermod_v2_example.h" -//#include "usermod_temperature.h" -#include "../usermods/usermod_smartnest.h" - -void registerUsermods() -{ - /* - * Add your usermod class name here - * || || || - * \/ \/ \/ - */ - //usermods.add(new MyExampleUsermod()); - //usermods.add(new UsermodTemperature()); - usermods.add(new Smartnest()); - -} -``` - -## Configuration - -Usermod has no configuration, but it relies on the MQTT configuration.\ -Under Config > Sync Interfaces > MQTT: -* Enable MQTT check box -* Set the `Broker` field to: `smartnest.cz` -* The `Username` and `Password` fields are the login information from the `smartnest.cz` website. -* `Client ID` field is obtained from the device configuration panel in `smartnest.cz`. - -## Change log -2022-09 -* First implementation. diff --git a/usermods/smartnest/usermod_smartnest.h b/usermods/smartnest/usermod_smartnest.h deleted file mode 100644 index 8d2b04ff96..0000000000 --- a/usermods/smartnest/usermod_smartnest.h +++ /dev/null @@ -1,171 +0,0 @@ -#ifndef WLED_ENABLE_MQTT -#error "This user mod requires MQTT to be enabled." -#endif - -#pragma once - -#include "wled.h" - -class Smartnest : public Usermod -{ -private: - void sendToBroker(const char *const topic, const char *const message) - { - if (!WLED_MQTT_CONNECTED) - { - return; - } - - String topic_ = String(mqttClientID) + "/" + String(topic); - mqtt->publish(topic_.c_str(), 0, true, message); - } - - void turnOff() - { - setBrightness(0); - turnOnAtBoot = false; - offMode = true; - sendToBroker("report/powerState", "OFF"); - } - - void turnOn() - { - setBrightness(briLast); - turnOnAtBoot = true; - offMode = false; - sendToBroker("report/powerState", "ON"); - } - - void setBrightness(int value) - { - if (value == 0 && bri > 0) briLast = bri; - bri = value; - stateUpdated(CALL_MODE_DIRECT_CHANGE); - } - - void setColor(int r, int g, int b) - { - strip.setColor(0, r, g, b); - stateUpdated(CALL_MODE_DIRECT_CHANGE); - char msg[18] {}; - sprintf(msg, "rgb(%d,%d,%d)", r, g, b); - sendToBroker("report/color", msg); - } - - int splitColor(const char *const color, int * const rgb) - { - char *color_ = NULL; - const char delim[] = ","; - char *cxt = NULL; - char *token = NULL; - int position = 0; - - // We need to copy the string in order to keep it read only as strtok_r function requires mutable string - color_ = (char *)malloc(strlen(color)); - if (NULL == color_) { - return -1; - } - - strcpy(color_, color); - token = strtok_r(color_, delim, &cxt); - - while (token != NULL) - { - rgb[position++] = (int)strtoul(token, NULL, 10); - token = strtok_r(NULL, delim, &cxt); - } - free(color_); - - return position; - } - -public: - // Functions called by WLED - - /** - * handling of MQTT message - * topic should look like: /// - */ - bool onMqttMessage(char *topic, char *message) - { - String topic_{topic}; - String topic_prefix{mqttClientID + String("/directive/")}; - - if (!topic_.startsWith(topic_prefix)) - { - return false; - } - - String subtopic = topic_.substring(topic_prefix.length()); - String message_(message); - - if (subtopic == "powerState") - { - if (strcmp(message, "ON") == 0) - { - turnOn(); - } - else if (strcmp(message, "OFF") == 0) - { - turnOff(); - } - return true; - } - - if (subtopic == "percentage") - { - int val = (int)strtoul(message, NULL, 10); - if (val >= 0 && val <= 100) - { - setBrightness(map(val, 0, 100, 0, 255)); - } - return true; - } - - if (subtopic == "color") - { - // Parse the message which is in the format "rgb(<0-255>,<0-255>,<0-255>)" - int rgb[3] = {}; - String colors = message_.substring(String("rgb(").length(), message_.lastIndexOf(')')); - if (3 != splitColor(colors.c_str(), rgb)) - { - return false; - } - setColor(rgb[0], rgb[1], rgb[2]); - return true; - } - - return false; - } - - /** - * subscribe to MQTT topic and send publish current status. - */ - void onMqttConnect(bool sessionPresent) - { - String topic = String(mqttClientID) + "/#"; - - mqtt->subscribe(topic.c_str(), 0); - sendToBroker("report/online", (bri ? "true" : "false")); // Reports that the device is online - delay(100); - sendToBroker("report/firmware", versionString); // Reports the firmware version - delay(100); - sendToBroker("report/ip", (char *)WiFi.localIP().toString().c_str()); // Reports the ip - delay(100); - sendToBroker("report/network", (char *)WiFi.SSID().c_str()); // Reports the network name - delay(100); - - String signal(WiFi.RSSI(), 10); - sendToBroker("report/signal", signal.c_str()); // Reports the signal strength - delay(100); - } - - /** - * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). - * This could be used in the future for the system to determine whether your usermod is installed. - */ - uint16_t getId() - { - return USERMOD_ID_SMARTNEST; - } -}; From 08f6d5a6834fa7116b3223c6962d0e7936435b9d Mon Sep 17 00:00:00 2001 From: devilpro1 <92226222+DevilPro1@users.noreply.github.com> Date: Sun, 26 May 2024 12:46:45 +0200 Subject: [PATCH 2/4] Add files via upload --- usermods/smartnest/readme.md | 74 +++++++++ usermods/smartnest/usermod_smartnest.h | 210 +++++++++++++++++++++++++ 2 files changed, 284 insertions(+) create mode 100644 usermods/smartnest/readme.md create mode 100644 usermods/smartnest/usermod_smartnest.h diff --git a/usermods/smartnest/readme.md b/usermods/smartnest/readme.md new file mode 100644 index 0000000000..85e7667c7b --- /dev/null +++ b/usermods/smartnest/readme.md @@ -0,0 +1,74 @@ +# Smartnest + +Enables integration with `smartnest.cz` service which provides MQTT integration with voice assistants, for example Google Home, Alexa, Siri, Home Assistant and more! + +In order to setup Smartnest follow the [documentation](https://www.docu.smartnest.cz/). + - You can create up to 5 different devices + - To add the project to Google Home you can find the information [here](https://www.docu.smartnest.cz/google-home-integration) + - To add the project to Alexa you can find the information [here](https://www.docu.smartnest.cz/alexa-integration) + +## MQTT API + +The API is described in the Smartnest [Github repo](https://github.com/aososam/Smartnest/blob/master/Devices/lightRgb/lightRgb.ino). + +## Usermod installation + +1. Use `#define USERMOD_SMARTNEST` in wled.h or `-D USERMOD_SMARTNEST` in your platformio.ini (recommended). + +## It is not necessary since the main branch of WLED brings it with it + +2. Register the usermod by adding `#include "../usermods/smartnest/usermod_smartnest.h"` at the top and `usermods.add(new Smartnest());` at the bottom of `usermods_list.cpp`. +or + +Example **usermods_list.cpp**: + +```cpp +#include "wled.h" +/* + * Register your v2 usermods here! + * (for v1 usermods using just usermod.cpp, you can ignore this file) + */ + +/* + * Add/uncomment your usermod filename here (and once more below) + * || || || + * \/ \/ \/ + */ +//#include "usermod_v2_example.h" +//#include "usermod_temperature.h" +#include "../usermods/usermod_smartnest.h" + +void registerUsermods() +{ + /* + * Add your usermod class name here + * || || || + * \/ \/ \/ + */ + //usermods.add(new MyExampleUsermod()); + //usermods.add(new UsermodTemperature()); + usermods.add(new Smartnest()); + +} +``` + +## Configuration + +Usermod has no configuration, but it relies on the MQTT configuration.\ +Under Config > Sync Interfaces > MQTT: + +* Enable `MQTT` check box. +* Set the `Broker` field to: `smartnest.cz` or `3.122.209.170`(both work). +* Set the `Port` field to: `1883` +* The `Username` and `Password` fields are the login information from the `smartnest.cz` website (It is located above in the 3 points). +* `Client ID` field is obtained from the device configuration panel in `smartnest.cz`. +* `Device Topic` is obtained by entering the ClientID/report , remember to replace ClientId with your real information (Because they can ban your device). +* `Group Topic` keep the same Group Topic. + +Wait `1 minute` after turning it on, as it usually takes a while. + +## Change log + 2024-05 +* Solved code. +* Updated documentation. +* Second implementation. diff --git a/usermods/smartnest/usermod_smartnest.h b/usermods/smartnest/usermod_smartnest.h new file mode 100644 index 0000000000..38026d9223 --- /dev/null +++ b/usermods/smartnest/usermod_smartnest.h @@ -0,0 +1,210 @@ +#ifndef WLED_ENABLE_MQTT +#error "This user mod requires MQTT to be enabled." +#endif + +#pragma once + +#include "wled.h" + +class Smartnest : public Usermod +{ +private: + bool initialized = false; + unsigned long lastMqttReport = 0; + unsigned long mqttReportInterval = 60000; // Report every minute + + void sendToBroker(const char *const topic, const char *const message) + { + if (!WLED_MQTT_CONNECTED) + { + return; + } + + String topic_ = String(mqttClientID) + "/" + String(topic); + mqtt->publish(topic_.c_str(), 0, true, message); + } + + void turnOff() + { + setBrightness(0); + turnOnAtBoot = false; + offMode = true; + sendToBroker("report/powerState", "OFF"); + } + + void turnOn() + { + setBrightness(briLast); + turnOnAtBoot = true; + offMode = false; + sendToBroker("report/powerState", "ON"); + } + + void setBrightness(int value) + { + if (value == 0 && bri > 0) briLast = bri; + bri = value; + stateUpdated(CALL_MODE_DIRECT_CHANGE); + } + + void setColor(int r, int g, int b) + { + strip.setColor(0, r, g, b); + stateUpdated(CALL_MODE_DIRECT_CHANGE); + char msg[18] {}; + sprintf(msg, "rgb(%d,%d,%d)", r, g, b); + sendToBroker("report/color", msg); + } + + int splitColor(const char *const color, int * const rgb) + { + char *color_ = NULL; + const char delim[] = ","; + char *cxt = NULL; + char *token = NULL; + int position = 0; + + // We need to copy the string in order to keep it read only as strtok_r function requires mutable string + color_ = (char *)malloc(strlen(color) + 1); + if (NULL == color_) { + return -1; + } + + strcpy(color_, color); + token = strtok_r(color_, delim, &cxt); + + while (token != NULL) + { + rgb[position++] = (int)strtoul(token, NULL, 10); + token = strtok_r(NULL, delim, &cxt); + } + free(color_); + + return position; + } + +public: + // Functions called by WLED + + /** + * handling of MQTT message + * topic should look like: /// + */ + bool onMqttMessage(char *topic, char *message) + { + String topic_{topic}; + String topic_prefix{mqttClientID + String("/directive/")}; + + if (!topic_.startsWith(topic_prefix)) + { + return false; + } + + String subtopic = topic_.substring(topic_prefix.length()); + String message_(message); + + if (subtopic == "powerState") + { + if (strcmp(message, "ON") == 0) + { + turnOn(); + } + else if (strcmp(message, "OFF") == 0) + { + turnOff(); + } + return true; + } + + if (subtopic == "percentage") + { + int val = (int)strtoul(message, NULL, 10); + if (val >= 0 && val <= 100) + { + setBrightness(map(val, 0, 100, 0, 255)); + } + return true; + } + + if (subtopic == "color") + { + // Parse the message which is in the format "rgb(<0-255>,<0-255>,<0-255>)" + int rgb[3] = {}; + String colors = message_.substring(String("rgb(").length(), message_.lastIndexOf(')')); + if (3 != splitColor(colors.c_str(), rgb)) + { + return false; + } + setColor(rgb[0], rgb[1], rgb[2]); + return true; + } + + return false; + } + + /** + * subscribe to MQTT topic and send publish current status. + */ + void onMqttConnect(bool sessionPresent) + { + String topic = String(mqttClientID) + "/#"; + + mqtt->subscribe(topic.c_str(), 0); + sendToBroker("report/online", (bri ? "true" : "false")); // Reports that the device is online + delay(100); + sendToBroker("report/firmware", versionString); // Reports the firmware version + delay(100); + sendToBroker("report/ip", (char *)WiFi.localIP().toString().c_str()); // Reports the IP + delay(100); + sendToBroker("report/network", (char *)WiFi.SSID().c_str()); // Reports the network name + delay(100); + + String signal(WiFi.RSSI(), 10); + sendToBroker("report/signal", signal.c_str()); // Reports the signal strength + delay(100); + } + + /** + * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). + * This could be used in the future for the system to determine whether your usermod is installed. + */ + uint16_t getId() + { + return USERMOD_ID_SMARTNEST; + } + + /** + * setup() is called once at startup to initialize the usermod. + */ + void setup() { + // Initialization code here + if (!initialized) { + DEBUG_PRINTF("Smartnest usermod setup initializing..."); + + // Publish initial status + sendToBroker("report/status", "Smartnest usermod initialized"); + + initialized = true; + } + } + + /** + * loop() is called continuously to keep the usermod running. + */ + void loop() { + // Periodically report status to MQTT broker + unsigned long currentMillis = millis(); + if (currentMillis - lastMqttReport >= mqttReportInterval) { + lastMqttReport = currentMillis; + + // Report current brightness + char brightnessMsg[6]; + sprintf(brightnessMsg, "%u", bri); + sendToBroker("report/brightness", brightnessMsg); + + // Report current signal strength + String signal(WiFi.RSSI(), 10); + sendToBroker("report/signal", signal.c_str()); + } + } +}; From e47932c9aa98d70833afa75e2bc8353fa4a7780d Mon Sep 17 00:00:00 2001 From: devilpro1 <92226222+DevilPro1@users.noreply.github.com> Date: Wed, 29 May 2024 20:13:37 +0200 Subject: [PATCH 3/4] Update usermod_smartnest.h --- usermods/smartnest/usermod_smartnest.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/usermods/smartnest/usermod_smartnest.h b/usermods/smartnest/usermod_smartnest.h index 38026d9223..92d524c88a 100644 --- a/usermods/smartnest/usermod_smartnest.h +++ b/usermods/smartnest/usermod_smartnest.h @@ -177,15 +177,10 @@ class Smartnest : public Usermod * setup() is called once at startup to initialize the usermod. */ void setup() { - // Initialization code here - if (!initialized) { DEBUG_PRINTF("Smartnest usermod setup initializing..."); // Publish initial status sendToBroker("report/status", "Smartnest usermod initialized"); - - initialized = true; - } } /** @@ -198,7 +193,7 @@ class Smartnest : public Usermod lastMqttReport = currentMillis; // Report current brightness - char brightnessMsg[6]; + char brightnessMsg[11]; sprintf(brightnessMsg, "%u", bri); sendToBroker("report/brightness", brightnessMsg); From f1cce8ef46508b45f01561b7a2b5c8f1fdb76198 Mon Sep 17 00:00:00 2001 From: devilpro1 <92226222+DevilPro1@users.noreply.github.com> Date: Wed, 29 May 2024 20:14:12 +0200 Subject: [PATCH 4/4] Update readme.md --- usermods/smartnest/readme.md | 49 ++++++------------------------------ 1 file changed, 8 insertions(+), 41 deletions(-) diff --git a/usermods/smartnest/readme.md b/usermods/smartnest/readme.md index 85e7667c7b..62bfcdada4 100644 --- a/usermods/smartnest/readme.md +++ b/usermods/smartnest/readme.md @@ -14,43 +14,6 @@ The API is described in the Smartnest [Github repo](https://github.com/aososam/S ## Usermod installation 1. Use `#define USERMOD_SMARTNEST` in wled.h or `-D USERMOD_SMARTNEST` in your platformio.ini (recommended). - -## It is not necessary since the main branch of WLED brings it with it - -2. Register the usermod by adding `#include "../usermods/smartnest/usermod_smartnest.h"` at the top and `usermods.add(new Smartnest());` at the bottom of `usermods_list.cpp`. -or - -Example **usermods_list.cpp**: - -```cpp -#include "wled.h" -/* - * Register your v2 usermods here! - * (for v1 usermods using just usermod.cpp, you can ignore this file) - */ - -/* - * Add/uncomment your usermod filename here (and once more below) - * || || || - * \/ \/ \/ - */ -//#include "usermod_v2_example.h" -//#include "usermod_temperature.h" -#include "../usermods/usermod_smartnest.h" - -void registerUsermods() -{ - /* - * Add your usermod class name here - * || || || - * \/ \/ \/ - */ - //usermods.add(new MyExampleUsermod()); - //usermods.add(new UsermodTemperature()); - usermods.add(new Smartnest()); - -} -``` ## Configuration @@ -68,7 +31,11 @@ Under Config > Sync Interfaces > MQTT: Wait `1 minute` after turning it on, as it usually takes a while. ## Change log - 2024-05 -* Solved code. -* Updated documentation. -* Second implementation. + +2022-09 + * First implementation. + +2024-05 + * Solved code. + * Updated documentation. + * Second implementation.