diff --git a/README.md b/README.md index b56fb79..7573034 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,6 @@ JBWopr is a helper library for the Arduino platform that allows you to easily interface with the Unexpected Maker W.O.P.R. board. -> Note - The Home Assistant support is still a work in progress. - -## Work in progress - - - Add support for state on/off for display/defcon - - Add support for discovery in Home Asssistant - ## Installation Install using the library manager in the Arduino IDE. diff --git a/library.properties b/library.properties index eecc029..330502c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=JBWopr -version=1.0.0-beta3 +version=1.0.0-beta4 author=Jonny Bergdahl maintainer=Jonny Bergdahl sentence=Support library for the Unexpected Maker W.O.P.R. boards diff --git a/src/effects/jbwopreffects.cpp b/src/effects/jbwopreffects.cpp index 48034c8..3f55e6b 100644 --- a/src/effects/jbwopreffects.cpp +++ b/src/effects/jbwopreffects.cpp @@ -263,18 +263,6 @@ void JBWoprTimeDisplayEffect::loop() { } JBWoprEffectBase::loop(); - if (_nextLedTick > millis()) { - return; - } - - auto leds = _woprDevice->getDefconLeds(); - _pixelHue += 256; - for (uint32_t i = 0; i < 5; i++) { - uint16_t pixelHue = _pixelHue + (i * 65536L / 5); - leds->setPixelColor(i, leds->gamma32(leds->ColorHSV(pixelHue))); - } - leds->show(); - _nextLedTick = millis() + 40; if (_nextTick > millis()) { return; @@ -319,11 +307,44 @@ std::string JBWoprTimeDisplayEffect::_getOddTimeFormat(const std::string &format return result; } +// ============================================ +// +// TimeDisplayEffect +// +JBWoprTimeDisplayRainbowEffect::JBWoprTimeDisplayRainbowEffect(JBWoprDevice *woprDevice, + std::string timeFormat, + uint32_t duration, + const std::string& name) : + JBWoprTimeDisplayEffect(woprDevice, timeFormat, duration, name) { +} + +void JBWoprTimeDisplayRainbowEffect::loop() { + char timeChars[12]; + tm timeinfo {}; + + if (!_isRunning) { + return; + } + + JBWoprTimeDisplayEffect::loop(); + if (_nextLedTick > millis()) { + return; + } + + auto leds = _woprDevice->getDefconLeds(); + _pixelHue += 256; + for (uint32_t i = 0; i < 5; i++) { + uint16_t pixelHue = _pixelHue + (i * 65536L / 5); + leds->setPixelColor(i, leds->gamma32(leds->ColorHSV(pixelHue))); + } + leds->show(); + _nextLedTick = millis() + 40; +} + // ============================================ // // DateDisplayEffect // -// Constructor JBWoprDateDisplayEffect::JBWoprDateDisplayEffect(JBWoprDevice *woprDevice, std::string dateFormat, uint32_t duration, @@ -347,16 +368,6 @@ void JBWoprDateDisplayEffect::loop() { } JBWoprEffectBase::loop(); - if (_nextLedTick < millis()) { - auto leds = _woprDevice->getDefconLeds(); - _pixelHue += 256; - for (uint32_t i = 0; i < 5; i++) { - uint16_t pixelHue = _pixelHue + (i * 65536L / 5); - leds->setPixelColor(i, leds->gamma32(leds->ColorHSV(pixelHue))); - } - leds->show(); - _nextLedTick = millis() + 40; - } if (_nextTick > millis()) { return; @@ -384,6 +395,38 @@ void JBWoprDateDisplayEffect::setDateFormat(const std::string& dateFormat) { _dateFormat = format; } +// ============================================ +// +// JBWoprDateDisplayRainbowEffect +// +JBWoprDateDisplayRainbowEffect::JBWoprDateDisplayRainbowEffect(JBWoprDevice *woprDevice, + std::string dateFormat, + uint32_t duration, + const std::string& name) : + JBWoprDateDisplayEffect(woprDevice, dateFormat, duration, name) { +} + +void JBWoprDateDisplayRainbowEffect::loop() { + char text[12]; + tm timeinfo{}; + + if (!_isRunning) { + return; + } + + JBWoprDateDisplayEffect::loop(); + if (_nextLedTick < millis()) { + auto leds = _woprDevice->getDefconLeds(); + _pixelHue += 256; + for (uint32_t i = 0; i < 5; i++) { + uint16_t pixelHue = _pixelHue + (i * 65536L / 5); + leds->setPixelColor(i, leds->gamma32(leds->ColorHSV(pixelHue))); + } + leds->show(); + _nextLedTick = millis() + 40; + } +} + // ============================================ // // DateTimeDisplayEffect @@ -414,18 +457,6 @@ void JBWoprDateTimeDisplayEffect::loop() { } JBWoprEffectBase::loop(); - if (_nextLedTick > millis()) { - return; - } - - auto leds = _woprDevice->getDefconLeds(); - _pixelHue += 256; - for (uint32_t i = 0; i < 5; i++) { - uint16_t pixelHue = _pixelHue + (i * 65536L / 5); - leds->setPixelColor(i, leds->gamma32(leds->ColorHSV(pixelHue))); - } - leds->show(); - _nextLedTick = millis() + 40; if (_nextTick > millis()) { return; @@ -480,7 +511,7 @@ void JBWoprDateTimeDisplayEffect::setDateFormat(const std::string& dateFormat) { } std::string JBWoprDateTimeDisplayEffect::_getOddTimeFormat(const std::string &format) { - std::string result = ""; + std::string result; for (char ch: format) { if (ch == '%' || std::isalpha(ch)) { result += ch; @@ -491,6 +522,42 @@ std::string JBWoprDateTimeDisplayEffect::_getOddTimeFormat(const std::string &fo return result; } +// ============================================ +// +// DateTimeDisplayEffect +// +JBWoprDateTimeDisplayRainbowEffect::JBWoprDateTimeDisplayRainbowEffect(JBWoprDevice *woprDevice, + std::string timeFormat, + std::string dateFormat, + uint32_t duration, + const std::string& name) : + JBWoprDateTimeDisplayEffect(woprDevice, timeFormat, dateFormat, duration, name) { +} + +void JBWoprDateTimeDisplayRainbowEffect::loop() { + char text[12]; + tm timeinfo{}; + + if (!_isRunning) { + return; + } + + JBWoprDateTimeDisplayEffect::loop(); + if (_nextLedTick > millis()) { + return; + } + + auto leds = _woprDevice->getDefconLeds(); + _pixelHue += 256; + for (uint32_t i = 0; i < 5; i++) { + uint16_t pixelHue = _pixelHue + (i * 65536L / 5); + leds->setPixelColor(i, leds->gamma32(leds->ColorHSV(pixelHue))); + } + leds->show(); + _nextLedTick = millis() + 40; +} + + // ============================================ // // XmasSecondsDisplayEffect diff --git a/src/effects/jbwopreffects.h b/src/effects/jbwopreffects.h index 79db468..e3cdb5a 100644 --- a/src/effects/jbwopreffects.h +++ b/src/effects/jbwopreffects.h @@ -21,8 +21,11 @@ class JBWoprDevice; #define JBWOPR_EFFECT_NAME_TEXT "Text" ///< Name of JBWoprDisplayTextEffect #define JBWOPR_EFFECT_NAME_SCROLLTEXT "Scroll text" ///< Name of JBWoprDisplayScrollTextEffect #define JBWOPR_EFFECT_NAME_TIME "Time" ///< Name of JBWoprDisplayTimeEffect +#define JBWOPR_EFFECT_NAME_TIME_RAINBOW "Time R" ///< Name of JBWoprDisplayTimeRainbowEffect #define JBWOPR_EFFECT_NAME_DATE "Date" ///< Name of JBWoprDisplayDateEffect +#define JBWOPR_EFFECT_NAME_DATETIME_RAINBOW "Date Time R" ///< Name of JBWoprDisplayDateTimeRainbowEffect #define JBWOPR_EFFECT_NAME_DATETIME "Date Time" ///< Name of JBWoprDisplayDateTimeEffect +#define JBWOPR_EFFECT_NAME_DATETIME_RAINBOW "Date Time R" ///< Name of JBWoprDisplayDateTimeRainbowEffect #define JBWOPR_EFFECT_NAME_XMAS_SECONDS "Xmas seconds" ///< Name of JBWoprDisplayXmasSecondsEffect #define JBWOPR_EFFECT_NAME_CODE_SOLVE "Code Solve" ///< Name of JBWoprWOPRMovieSolveEffect #define JBWOPR_EFFECT_NAME_DEFCON_RAINBOW "Rainbow" ///< Name of JBWoprDefconRainbowEffect @@ -217,6 +220,30 @@ class JBWoprTimeDisplayEffect : public JBWoprEffectBase { std::string _rawTimeFormat; ///< Raw time format std::string _timeFormatEven; ///< Time format for even std::string _timeFormatOdd; ///< Time format for odd + +private: + JBLogger _log {"time" }; ///< Logger instance +}; + +/// @brief Display effect for showing the current time +class JBWoprTimeDisplayRainbowEffect : public JBWoprTimeDisplayEffect { +public: + /// @brief Constructor + /// @ingroup EffectGroup + /// @param woprDevice JBWoprDevice instance + /// @param timeFormat (optional) Time format, default is fetched from config + /// @param duration (optional) Duration of effect in milliseconds, default is -1 (infinite) + /// @param name (optional) Name of effect + explicit JBWoprTimeDisplayRainbowEffect(JBWoprDevice *woprDevice, + std::string timeFormat = "", + uint32_t duration = -1, + const std::string& name=JBWOPR_EFFECT_NAME_TIME); + + /// @brief Run loop + /// @ingroup EffectGroup + void loop() override; + +protected: uint64_t _nextLedTick = 0; ///< Next LED tick uint16_t _pixelHue = 0; ///< Pixel hue @@ -257,6 +284,31 @@ class JBWoprDateDisplayEffect : public JBWoprEffectBase { std::string _timeFormatOdd; ///< Time format for odd std::string _rawDateFormat; ///< Raw date format std::string _dateFormat; ///< Date format + +private: + JBLogger _log {"date" }; ///< Logger instance +}; + +/// @brief Display effect for showing the current date, with rainbow colors +/// @ingroup EffectGroup +class JBWoprDateDisplayRainbowEffect : public JBWoprDateDisplayEffect { +public: + /// @brief Constructor + /// @ingroup EffectGroup + /// @param woprDevice JBWoprDevice instance + /// @param dateFormat (optional) Date format, default is fetched from config + /// @param duration (optional) Duration of effect in milliseconds, default is -1 (infinite) + /// @param name (optional) Name of effect + explicit JBWoprDateDisplayRainbowEffect(JBWoprDevice *woprDevice, + std::string dateFormat = "", + uint32_t duration = -1, + const std::string& name=JBWOPR_EFFECT_NAME_DATE); + + /// @brief Get name of effect + /// @ingroup EffectGroup + void loop() override; + +protected: uint64_t _nextLedTick = 0; ///< Next LED tick uint16_t _pixelHue = 0; ///< Pixel hue @@ -315,6 +367,32 @@ class JBWoprDateTimeDisplayEffect : public JBWoprEffectBase { virtual std::string _getOddTimeFormat(const std::string& format); }; +/// @brief Display effect for showing the current date and time, with rainbow colors +/// @ingroup EffectGroup +/// @details Shows date for 2 seconds, then time for 8 seconds +class JBWoprDateTimeDisplayRainbowEffect : public JBWoprDateTimeDisplayEffect { +public: + /// @brief Constructor + /// @ingroup EffectGroup + /// @param woprDevice JBWoprDevice instance + explicit JBWoprDateTimeDisplayRainbowEffect(JBWoprDevice *woprDevice, + std::string timeFormat = "", + std::string dateFormat = "", + uint32_t duration = -1, + const std::string& name=JBWOPR_EFFECT_NAME_DATETIME); + + /// @brief Get name of effect + /// @ingroup EffectGroup + void loop() override; + +protected: + uint64_t _nextLedTick = 0; ///< Next LED tick + uint16_t _pixelHue = 0; ///< Pixel hue + +private: + JBLogger _log {"datetime" }; ///< Logger instance +}; + /// @brief Display effect for showing seconds un til Xmas class JBWoprXmasSecondsDisplayEffect: public JBWoprScrollTextDisplayEffect { public: diff --git a/src/jbwopr.h b/src/jbwopr.h index 19b58d1..6c5c078 100644 --- a/src/jbwopr.h +++ b/src/jbwopr.h @@ -22,7 +22,7 @@ #include "effects/jbwopreffects.h" #include "jbwoprhelpers.h" -#define LIBRARY_VERSION "1.0.0-beta3"; +#define LIBRARY_VERSION "1.0.0-beta4"; /// @brief W.O.P.R. board version enum JBWoprBoardVariant { @@ -156,7 +156,7 @@ class JBWoprDevice { /// @param effect Effect to register void effectsRegisterEffect(JBWoprEffectBase* effect); - /// @brief Get list of registered effects + /// @brief Get a list of registered effects /// @ingroup EffectsGroup /// @return Default effects std::vector effectsGetRegisteredEffects(); diff --git a/src/jbwoprha.cpp b/src/jbwoprha.cpp index 819f601..aca44f4 100644 --- a/src/jbwoprha.cpp +++ b/src/jbwoprha.cpp @@ -360,6 +360,7 @@ bool JBWoprHADevice::_homeAssistantSendDiscovery() { jsonDoc["command_topic"] = "wopr/" + _getDeviceName() + "/defcon/state/set"; jsonDoc["brightness_state_topic"] = "wopr/" + _getDeviceName() + "/defcon/brightness"; jsonDoc["brightness_command_topic"] = "wopr/" + _getDeviceName() + "/defcon/brightness/set"; + jsonDoc["rgb_state_topic"] = "wopr/" + _getDeviceName() + "/defcon/color"; jsonDoc["rgb_command_topic"] = "wopr/" + _getDeviceName() + "/defcon/color/set"; jsonDoc["brightness_scale"] = 100; jsonDoc["icon"] = MDI_ICON_NUMERIC_5_BOX_OUTLINE;