diff --git a/espmusicmouse/host_driver/host_driver.py b/espmusicmouse/host_driver/host_driver.py index 97830a0..fa03354 100644 --- a/espmusicmouse/host_driver/host_driver.py +++ b/espmusicmouse/host_driver/host_driver.py @@ -45,6 +45,7 @@ shelve_led_effect_to_message_id = { EffectRandomTwoColorInterpolationConfig: 17, EffectSwipeAndChange: 18, EffectReverseSwipe: 19, + EffectStaticDetailedConfig: 20, } mouse_leds_index_ranges = { @@ -54,8 +55,8 @@ mouse_leds_index_ranges = { TouchButton.RIGHT_EAR: (6 + 6 + 16, 6 + 6 + 16 + 17), } -PREV_BUTTON_LED_MSG = 20 -NEXT_BUTTON_LED_MSG = 21 +PREV_BUTTON_LED_MSG = 21 +NEXT_BUTTON_LED_MSG = 22 class RfidTokenRead: diff --git a/espmusicmouse/host_driver/led_cmds.py b/espmusicmouse/host_driver/led_cmds.py index f2ed170..2bf7daf 100644 --- a/espmusicmouse/host_driver/led_cmds.py +++ b/espmusicmouse/host_driver/led_cmds.py @@ -76,6 +76,20 @@ class EffectStaticConfig: return self.color.as_bytes() + struct.pack(" bytes: + return self.color.as_bytes() + struct.pack(" 0: + eff = EffectStaticDetailedConfig(ColorRGBW(0,0,0,0), transition_tim_in_ms=transition) + else: + eff = EffectStaticConfig(ColorRGBW(0, 0, 0, 0)) elif s['effect'] == 'static': - eff = EffectStaticConfig(current_color) + if transition > 0: + eff = EffectStaticDetailedConfig(current_color, transition_time_in_ms=transition) + else: + eff = EffectStaticConfig(current_color) elif s['effect'] == 'circular': eff = EffectCircularConfig(speed=180, width=90, color=current_color) elif s['effect'] == 'wipeup': @@ -92,6 +100,14 @@ class ShelveLightMqtt: eff.hue1_random = True eff.hue2_random = True eff.start_with_existing = True + elif s['effect'] == "side_0.2": + eff = EffectStaticDetailedConfig(current_color, begin=0.9, end=0.1, increment=1, transition_time_in_ms=transition) + elif s['effect'] == "side_0.2_inc4": + eff = EffectStaticDetailedConfig(current_color, begin=0.9, end=0.1, increment=4, transition_time_in_ms=transition) + elif s['effect'] == "side_0.5": + eff = EffectStaticDetailedConfig(current_color, begin=0.75, end=0.25, increment=1, transition_time_in_ms=transition) + elif s['effect'] == "side_0.5_inc4": + eff = EffectStaticDetailedConfig(current_color, begin=0.75, end=0.25, increment=4, transition_time_in_ms=transition) else: print(f"Unknown effect {s['effect']}") eff = EffectStaticConfig(ColorRGBW(0, 0, 0, 0)) @@ -115,7 +131,8 @@ class ShelveLightMqtt: # 'model': "SK6812 LED strip", #}, 'effect': True, - 'effect_list': ['static', 'circular', 'wipeup', 'twocolor', 'twocolorrandom'], + 'effect_list': ['static', 'circular', 'wipeup', 'twocolor', 'twocolorrandom', + "side_0.2", "side_0.5", "side_0.2_inc4", "side_0.5_inc4", "top_0.2"], 'supported_color_modes': ['rgbw'], } diff --git a/espmusicmouse/lib/ledtl/effects/Common.h b/espmusicmouse/lib/ledtl/effects/Common.h index a294101..34050de 100644 --- a/espmusicmouse/lib/ledtl/effects/Common.h +++ b/espmusicmouse/lib/ledtl/effects/Common.h @@ -8,6 +8,7 @@ enum class EffectId RANDOM_TWO_COLOR_INTERPOLATION, SWIPE_AND_CHANGE, // combination of ALEXA_SWIPE and RANDOM_TWO_COLOR_INTERPOLATION REVERSE_SWIPE, + STATIC_DETAILED, }; template diff --git a/espmusicmouse/lib/ledtl/effects/Static.h b/espmusicmouse/lib/ledtl/effects/Static.h index 59b6186..24c0a2d 100644 --- a/espmusicmouse/lib/ledtl/effects/Static.h +++ b/espmusicmouse/lib/ledtl/effects/Static.h @@ -3,6 +3,7 @@ #include "effects/Common.h" #include "helpers/ColorRGBW.h" +#pragma pack(push, 1) struct EffectStaticConfig { EffectStaticConfig(const ColorRGBW &c = ColorRGBW{0, 0, 0, 0}, uint16_t beg = 0, uint16_t en = 0) @@ -12,6 +13,7 @@ struct EffectStaticConfig uint16_t begin = 0; uint16_t end = 0; }; +#pragma pack(pop) template class EffectStatic diff --git a/espmusicmouse/lib/ledtl/effects/StaticDetailed.h b/espmusicmouse/lib/ledtl/effects/StaticDetailed.h new file mode 100644 index 0000000..d745440 --- /dev/null +++ b/espmusicmouse/lib/ledtl/effects/StaticDetailed.h @@ -0,0 +1,97 @@ +#pragma once + +#include "effects/Common.h" +#include "helpers/ColorRGBW.h" +#include "helpers/ColorConversions.h" + + +#pragma pack(push, 1) +struct EffectStaticDetailedConfig +{ + EffectStaticDetailedConfig(const ColorRGBW &c = ColorRGBW{0, 0, 0, 0}, uint16_t beg = 0, uint16_t en = 0) + : color(c), begin(beg), end(en) {} + + ColorRGBW color; + uint16_t increment = 1; + float begin = 0.0f; + float end = 0.0f; + float transition_time_in_ms = 0.0f; +}; +#pragma pack(pop) + +template +class EffectStaticDetailed +{ +public: + static constexpr auto NUM_LEDS = numLeds(); + static constexpr int DELAY_MS = 10; + using ConfigType = EffectStaticDetailedConfig; + + EffectStaticDetailed(const EffectStaticDetailedConfig &cfg, TLedStrip &ledStrip) + : config_(cfg), + ledStrip_(ledStrip) + { + for (int i = 0; i < NUM_LEDS; ++i) + state_[i] = getLedRGBW(ledStrip_, i); + + beginIdx_ = constrain(static_cast(cfg.begin * NUM_LEDS + 0.5f), 0, NUM_LEDS - 1); + endIdx_ = constrain(static_cast(cfg.end * NUM_LEDS + 0.5f), 0, NUM_LEDS - 1); + } + + bool finished() const { return finished_; } + + int operator()() + { + if (finished_) + return 1000000; + + const float progress = static_cast(DELAY_MS * calls_) / config_.transition_time_in_ms; + + // Finished case + if(progress > 1.0) { + finished_ = true; + return 10000000; + } + + // In-progress case + clear(ledStrip_); + for(int i = beginIdx_; i != endIdx_; i += config_.increment) { + ColorRGBW newColor = hsv2rgb(interpolate(rgb2hsv(state_[i]), rgb2hsv(config_.color), progress)); + newColor.w = config_.color.w * progress + state_[i].w * (1 - progress); + setLedRGBW(ledStrip_, i, newColor); + if(i >= NUM_LEDS) + i = 0; + } + + ++calls_; + return DELAY_MS; + } + +private: + EffectStaticDetailedConfig config_; + TLedStrip &ledStrip_; + ColorRGBW state_[NUM_LEDS]; + int beginIdx_; + int endIdx_; + int calls_ = 0; + bool finished_ = false; +}; + +// Traits +template <> +struct EffectIdToConfig +{ + using type = EffectStaticDetailedConfig; +}; + +template <> +struct EffectConfigToId +{ + static constexpr auto id = EffectId::STATIC_DETAILED; +}; + +template +struct EffectIdToClass +{ + using type = EffectStaticDetailed; +}; \ No newline at end of file diff --git a/espmusicmouse/src/Messages.h b/espmusicmouse/src/Messages.h index a93a0b3..169a07c 100644 --- a/espmusicmouse/src/Messages.h +++ b/espmusicmouse/src/Messages.h @@ -116,9 +116,10 @@ enum class MessageHostToFw : uint8_t SHELF_LED_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 17, SHELF_LED_EFFECT_SWIPE_AND_CHANGE = 18, SHELF_LED_EFFECT_REVERSE_SWIPE = 19, + SHELF_LED_EFFECT_STATIC_DETAILED = 20, - PREV_BUTTON_LED = 20, - NEXT_BUTTON_LED = 21, + PREV_BUTTON_LED = 21, + NEXT_BUTTON_LED = 22, }; template <> @@ -227,6 +228,7 @@ inline void handleIncomingMessagesFromHost(LedTask1 *ledTaskCircle, LedTask2 *le else if (handleLedEffect(ledTaskShelf, MessageHostToFw::SHELF_LED_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION, msgType, msgBuffer)) {} else if (handleLedEffect(ledTaskShelf, MessageHostToFw::SHELF_LED_EFFECT_SWIPE_AND_CHANGE, msgType, msgBuffer)) {} else if (handleLedEffect(ledTaskShelf, MessageHostToFw::SHELF_LED_EFFECT_REVERSE_SWIPE, msgType, msgBuffer)) {} + else if (handleLedEffect(ledTaskShelf, MessageHostToFw::SHELF_LED_EFFECT_STATIC_DETAILED, msgType, msgBuffer)) {} // clang-format on else if (msgType == MessageHostToFw::PREV_BUTTON_LED) diff --git a/espmusicmouse/src/TaskLed.h b/espmusicmouse/src/TaskLed.h index 9fd455c..2511c73 100644 --- a/espmusicmouse/src/TaskLed.h +++ b/espmusicmouse/src/TaskLed.h @@ -77,6 +77,7 @@ void _led_task_func(void *params) // clang-format off if (dispatchEffectId(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {} else if (dispatchEffectId(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {} + else if (dispatchEffectId(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {} else if (dispatchEffectId(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {} else if (dispatchEffectId(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {} else if (dispatchEffectId(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {} diff --git a/espmusicmouse/src/main.cpp b/espmusicmouse/src/main.cpp index e60de98..91c7144 100644 --- a/espmusicmouse/src/main.cpp +++ b/espmusicmouse/src/main.cpp @@ -8,6 +8,7 @@ #include "drivers/Esp32DriverRGBW.h" #include "effects/Circular.h" #include "effects/Static.h" +#include "effects/StaticDetailed.h" #include "effects/AlexaSwipe.h" #include "effects/RandomTwoColorInterpolation.h"