diff --git a/examples/EspalexaColor/EspalexaColor.ino b/examples/EspalexaColor/EspalexaColor.ino new file mode 100644 index 0000000..2b89726 --- /dev/null +++ b/examples/EspalexaColor/EspalexaColor.ino @@ -0,0 +1,96 @@ +/* + * This is a basic example on how to use Espalexa with RGB color devices. + */ +#ifdef ARDUINO_ARCH_ESP32 +#include +#else +#include +#endif +#define ESPALEXA_ASYNC +#include + +// prototypes +boolean connectWifi(); + +//callback function prototype +void colorLightChanged(uint8_t brightness, uint32_t rgb); + +// Change this!! +const char* ssid = "..."; +const char* password = "wifipassword"; + +boolean wifiConnected = false; + +Espalexa espalexa; + +void setup() +{ + Serial.begin(115200); + // Initialise wifi connection + wifiConnected = connectWifi(); + + if(wifiConnected){ + espalexa.addDevice("Color Light", colorLightChanged); + + espalexa.begin(); + + } else + { + while (1) { + Serial.println("Cannot connect to WiFi. Please check data and reset the ESP."); + delay(2500); + } + } +} + +void loop() +{ + espalexa.loop(); + delay(1); +} + +//the color device callback function has two parameters +void colorLightChanged(uint8_t brightness, uint32_t rgb) { + //do what you need to do here, for example control RGB LED strip + Serial.print("Brightness: "); + Serial.print(brightness); + Serial.print(", Red: "); + Serial.print((rgb >> 16) & 0xFF); //get red component + Serial.print(", Green: "); + Serial.print((rgb >> 8) & 0xFF); //get green + Serial.print(", Blue: "); + Serial.println(rgb & 0xFF); //get blue +} + +// connect to wifi – returns true if successful or false if not +boolean connectWifi(){ + boolean state = true; + int i = 0; + + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + Serial.println(""); + Serial.println("Connecting to WiFi"); + + // Wait for connection + Serial.print("Connecting..."); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + if (i > 40){ + state = false; break; + } + i++; + } + Serial.println(""); + if (state){ + Serial.print("Connected to "); + Serial.println(ssid); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + } + else { + Serial.println("Connection failed."); + } + return state; +} diff --git a/library.properties b/library.properties index b6cd76a..519365b 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Espalexa -version=2.4.0 +version=2.4.1 author=Christian Schwinne maintainer=Christian Schwinne sentence=Library to control an ESP module with the Alexa voice assistant diff --git a/readme.md b/readme.md index fbc641c..499f172 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,7 @@ Now compatible with both ESP8266 and ESP32! #### What does this do similar projects don't already? -It allows you to set a ranged value (e.g. Brightness, Temperature) additionally to standard on/off control. +It allows you to set a ranged value (e.g. Brightness, Temperature) and optionally a color, additionally to standard on/off control. For example, you can say "Alexa, turn the light to 75% / 21 degrees". Alexa now finally supports colors with the local API! You can see how to add color devices in the EspalexaColor example. Then, you can say "Alexa, turn the light to Blue". Color temperature (white shades) is also supported. diff --git a/src/Espalexa.h b/src/Espalexa.h index b55f3b2..a246541 100644 --- a/src/Espalexa.h +++ b/src/Espalexa.h @@ -10,7 +10,7 @@ */ /* * @title Espalexa library - * @version 2.4.0 + * @version 2.4.1 * @author Christian Schwinne * @license MIT * @contributors d-999 @@ -49,7 +49,7 @@ #include #ifdef ESPALEXA_DEBUG - #pragma message "Espalexa 2.4.0 debug mode" + #pragma message "Espalexa 2.4.1 debug mode" #define EA_DEBUG(x) Serial.print (x) #define EA_DEBUGLN(x) Serial.println (x) #else @@ -174,7 +174,7 @@ class Espalexa { } res += "\r\nFree Heap: " + (String)ESP.getFreeHeap(); res += "\r\nUptime: " + (String)millis(); - res += "\r\n\r\nEspalexa library v2.4.0 by Christian Schwinne 2019"; + res += "\r\n\r\nEspalexa library v2.4.1 by Christian Schwinne 2019"; server->send(200, "text/plain", res); } #endif @@ -386,7 +386,7 @@ class Espalexa { return true; } - //deprecated brightness-only callback + //brightness-only callback bool addDevice(String deviceName, BrightnessCallbackFunction callback, uint8_t initialValue = 0) { EA_DEBUG("Constructing device "); @@ -395,6 +395,17 @@ class Espalexa { EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue); return addDevice(d); } + + //brightness-only callback + bool addDevice(String deviceName, ColorCallbackFunction callback, uint8_t initialValue = 0) + { + EA_DEBUG("Constructing device "); + EA_DEBUGLN((currentDeviceCount+1)); + if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false; + EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue); + return addDevice(d); + } + bool addDevice(String deviceName, DeviceCallbackFunction callback, EspalexaDeviceType t = EspalexaDeviceType::dimmable, uint8_t initialValue = 0) { diff --git a/src/EspalexaDevice.cpp b/src/EspalexaDevice.cpp index f440b80..da4aa69 100644 --- a/src/EspalexaDevice.cpp +++ b/src/EspalexaDevice.cpp @@ -4,7 +4,7 @@ EspalexaDevice::EspalexaDevice(){} -EspalexaDevice::EspalexaDevice(String deviceName, BrightnessCallbackFunction gnCallback, uint8_t initialValue) { //constructor +EspalexaDevice::EspalexaDevice(String deviceName, BrightnessCallbackFunction gnCallback, uint8_t initialValue) { //constructor for dimmable device _deviceName = deviceName; _callback = gnCallback; @@ -13,11 +13,19 @@ EspalexaDevice::EspalexaDevice(String deviceName, BrightnessCallbackFunction gnC _type = EspalexaDeviceType::dimmable; } -EspalexaDevice::EspalexaDevice(String deviceName, DeviceCallbackFunction gnCallback, EspalexaDeviceType t, uint8_t initialValue) { //constructor for color device +EspalexaDevice::EspalexaDevice(String deviceName, ColorCallbackFunction gnCallback, uint8_t initialValue) { //constructor for color device + + _deviceName = deviceName; + _callbackCol = gnCallback; + _val = initialValue; + _val_last = _val; + _type = EspalexaDeviceType::extendedcolor; +} + +EspalexaDevice::EspalexaDevice(String deviceName, DeviceCallbackFunction gnCallback, EspalexaDeviceType t, uint8_t initialValue) { //constructor for general device _deviceName = deviceName; _callbackDev = gnCallback; - _callback = nullptr; _type = t; _val = initialValue; _val_last = _val; @@ -305,5 +313,7 @@ void EspalexaDevice::setColor(uint8_t r, uint8_t g, uint8_t b) void EspalexaDevice::doCallback() { - (_callback != nullptr) ? _callback(_val) : _callbackDev(this); + if (_callback != nullptr) {_callback(_val); return;} + if (_callbackDev != nullptr) {_callbackDev(this); return;} + if (_callbackCol != nullptr) _callbackCol(_val, getRGB()); } \ No newline at end of file diff --git a/src/EspalexaDevice.h b/src/EspalexaDevice.h index 07708d0..8d7be87 100644 --- a/src/EspalexaDevice.h +++ b/src/EspalexaDevice.h @@ -7,6 +7,7 @@ typedef class EspalexaDevice; typedef void (*BrightnessCallbackFunction) (uint8_t b); typedef void (*DeviceCallbackFunction) (EspalexaDevice* d); +typedef void (*ColorCallbackFunction) (uint8_t br, uint32_t col); enum class EspalexaColorMode : uint8_t { none = 0, ct = 1, hs = 2, xy = 3 }; enum class EspalexaDeviceType : uint8_t { onoff = 0, dimmable = 1, whitespectrum = 2, color = 3, extendedcolor = 4 }; @@ -15,22 +16,24 @@ enum class EspalexaDeviceProperty : uint8_t { none = 0, on = 1, off = 2, bri = 3 class EspalexaDevice { private: String _deviceName; - BrightnessCallbackFunction _callback; - DeviceCallbackFunction _callbackDev; + BrightnessCallbackFunction _callback = nullptr; + DeviceCallbackFunction _callbackDev = nullptr; + ColorCallbackFunction _callbackCol = nullptr; uint8_t _val, _val_last, _sat = 0; uint16_t _hue = 0, _ct = 0; - float _x = 0, _y = 0; + float _x = 0.5, _y = 0.5; uint32_t _rgb = 0; uint8_t _id = 0; EspalexaDeviceType _type; EspalexaDeviceProperty _changed = EspalexaDeviceProperty::none; - EspalexaColorMode _mode; + EspalexaColorMode _mode = EspalexaColorMode::xy; public: EspalexaDevice(); ~EspalexaDevice(); EspalexaDevice(String deviceName, BrightnessCallbackFunction bcb, uint8_t initialValue =0); EspalexaDevice(String deviceName, DeviceCallbackFunction dcb, EspalexaDeviceType t =EspalexaDeviceType::dimmable, uint8_t initialValue =0); + EspalexaDevice(String deviceName, ColorCallbackFunction ccb, uint8_t initialValue =0); String getName(); uint8_t getId();