mirror of
https://github.com/arendst/Tasmota.git
synced 2025-11-30 05:07:39 +00:00
Berry animation add strip_length provider (#23822)
This commit is contained in:
@@ -40,6 +40,7 @@ ParameterizedObject
|
||||
│ └── (other animation classes)
|
||||
└── ValueProvider
|
||||
├── StaticValueProvider
|
||||
├── StripLengthProvider
|
||||
├── OscillatorValueProvider
|
||||
└── ColorProvider
|
||||
├── StaticColorProvider
|
||||
@@ -103,6 +104,18 @@ Wraps static values to provide ValueProvider interface. Inherits from `ValueProv
|
||||
|
||||
**Factory**: `animation.static_value(engine)`
|
||||
|
||||
### StripLengthProvider
|
||||
|
||||
Provides access to the LED strip length as a dynamic value. Inherits from `ValueProvider`.
|
||||
|
||||
| Parameter | Type | Default | Constraints | Description |
|
||||
|-----------|------|---------|-------------|-------------|
|
||||
| *(none)* | - | - | - | No parameters - strip length obtained from engine |
|
||||
|
||||
**Usage**: Returns the 1D length of the LED strip in pixels. Useful for animations that need to know the strip dimensions for positioning, scaling, or boundary calculations.
|
||||
|
||||
**Factory**: `animation.strip_length(engine)`
|
||||
|
||||
### OscillatorValueProvider
|
||||
|
||||
Generates oscillating values using various waveforms. Inherits from `ValueProvider`.
|
||||
|
||||
@@ -496,6 +496,7 @@ Value providers create dynamic values that change over time:
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `static_value` | Returns a constant value |
|
||||
| `strip_length` | Returns the LED strip length in pixels |
|
||||
| `oscillator_value` | Oscillates between min/max values with various waveforms |
|
||||
|
||||
**Oscillator Aliases:**
|
||||
@@ -530,6 +531,7 @@ bounce(min_value=0, max_value=255, period=2s) # Bouncing ball effect
|
||||
set brightness_oscillator = smooth(min_value=50, max_value=255, period=3s)
|
||||
set position_sweep = triangle(min_value=0, max_value=29, period=5s)
|
||||
set elastic_movement = elastic(min_value=0, max_value=30, period=4s)
|
||||
set strip_len = strip_length() # Get the current strip length
|
||||
```
|
||||
|
||||
### Color Providers
|
||||
|
||||
@@ -93,6 +93,8 @@ import "providers/static_value_provider.be" as static_value_provider
|
||||
register_to_animation(static_value_provider)
|
||||
import "providers/oscillator_value_provider.be" as oscillator_value_provider
|
||||
register_to_animation(oscillator_value_provider)
|
||||
import "providers/strip_length_provider.be" as strip_length_provider
|
||||
register_to_animation(strip_length_provider)
|
||||
|
||||
# Import color providers
|
||||
import "providers/color_provider.be" as color_provider
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# StripLengthProvider for Berry Animation Framework
|
||||
#
|
||||
# This value provider returns the length of the LED strip from the animation engine.
|
||||
# It provides access to the strip length as a dynamic value that can be used by
|
||||
# animations that need to know the strip dimensions.
|
||||
#
|
||||
# The strip length is obtained from the engine's width property, which is cached
|
||||
# from the strip.length() method for performance.
|
||||
#
|
||||
# Follows the parameterized class specification:
|
||||
# - Constructor takes only 'engine' parameter
|
||||
# - No additional parameters needed since strip length is obtained from engine
|
||||
|
||||
#@ solidify:StripLengthProvider,weak
|
||||
class StripLengthProvider : animation.value_provider
|
||||
# Produce the strip length value
|
||||
#
|
||||
# @param name: string - Parameter name being requested (ignored)
|
||||
# @param time_ms: int - Current time in milliseconds (ignored)
|
||||
# @return int - The strip length in pixels
|
||||
def produce_value(name, time_ms)
|
||||
if self.engine == nil
|
||||
return 0
|
||||
end
|
||||
return self.engine.width
|
||||
end
|
||||
|
||||
# String representation of the provider
|
||||
def tostring()
|
||||
try
|
||||
var length = self.engine != nil ? self.engine.width : 0
|
||||
return f"StripLengthProvider(length={length})"
|
||||
except ..
|
||||
return "StripLengthProvider(length=unknown)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return {'strip_length': StripLengthProvider}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,158 @@
|
||||
# Test file for StripLengthProvider class
|
||||
#
|
||||
# This file contains tests for the StripLengthProvider class which provides
|
||||
# access to the LED strip length as a dynamic value provider.
|
||||
#
|
||||
# Command to run test is:
|
||||
# ./berry -s -g -m lib/libesp32/berry_animation/src -e "import tasmota" lib/libesp32/berry_animation/src/tests/strip_length_provider_test.be
|
||||
|
||||
import animation
|
||||
|
||||
print("Testing StripLengthProvider...")
|
||||
|
||||
# Create a mock LED strip for testing
|
||||
class MockStrip
|
||||
var _length
|
||||
|
||||
def init(length)
|
||||
self._length = length
|
||||
end
|
||||
|
||||
def length()
|
||||
return self._length
|
||||
end
|
||||
|
||||
def set_pixel_color(index, color)
|
||||
# Mock implementation - do nothing
|
||||
end
|
||||
|
||||
def show()
|
||||
# Mock implementation - do nothing
|
||||
end
|
||||
|
||||
def clear()
|
||||
# Mock implementation - do nothing
|
||||
end
|
||||
|
||||
def can_show()
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
# Test basic functionality
|
||||
def test_basic_functionality()
|
||||
print(" Testing basic functionality...")
|
||||
|
||||
# Test with different strip lengths
|
||||
var test_lengths = [10, 30, 60, 144]
|
||||
|
||||
for length : test_lengths
|
||||
# Create mock strip and engine
|
||||
var strip = MockStrip(length)
|
||||
var engine = animation.animation_engine(strip)
|
||||
|
||||
# Create StripLengthProvider
|
||||
var provider = animation.strip_length(engine)
|
||||
|
||||
# Test the provider
|
||||
var result = provider.produce_value("length", 1000)
|
||||
assert(result == length, f"Expected {length}, got {result}")
|
||||
|
||||
# Test that parameter name doesn't matter
|
||||
var result2 = provider.produce_value("width", 2000)
|
||||
assert(result2 == length, f"Expected {length}, got {result2}")
|
||||
|
||||
# Test that time doesn't matter
|
||||
var result3 = provider.produce_value("size", nil)
|
||||
assert(result3 == length, f"Expected {length}, got {result3}")
|
||||
end
|
||||
|
||||
print(" ✓ Basic functionality tests passed")
|
||||
end
|
||||
|
||||
# Test string representation
|
||||
def test_string_representation()
|
||||
print(" Testing string representation...")
|
||||
|
||||
var strip = MockStrip(42)
|
||||
var engine = animation.animation_engine(strip)
|
||||
var provider = animation.strip_length(engine)
|
||||
|
||||
var str_repr = str(provider)
|
||||
assert(str_repr == "StripLengthProvider(length=42)", f"Unexpected string representation: {str_repr}")
|
||||
|
||||
print(" ✓ String representation test passed")
|
||||
end
|
||||
|
||||
# Test error handling
|
||||
def test_error_handling()
|
||||
print(" Testing error handling...")
|
||||
|
||||
# Test with nil engine (should raise error during construction)
|
||||
try
|
||||
var provider_nil = animation.strip_length(nil)
|
||||
assert(false, "Should have raised an error with nil engine")
|
||||
except "value_error"
|
||||
# Expected behavior
|
||||
except .. as e
|
||||
assert(false, f"Unexpected error: {e}")
|
||||
end
|
||||
|
||||
print(" ✓ Error handling test passed")
|
||||
end
|
||||
|
||||
# Test integration with animation system
|
||||
def test_integration()
|
||||
print(" Testing integration with animation system...")
|
||||
|
||||
var strip = MockStrip(20)
|
||||
var engine = animation.animation_engine(strip)
|
||||
var provider = animation.strip_length(engine)
|
||||
|
||||
# Test that it's recognized as a value provider
|
||||
assert(animation.is_value_provider(provider), "Should be recognized as a value provider")
|
||||
|
||||
# Test that it can be used as a parameter value
|
||||
var solid_anim = animation.solid(engine)
|
||||
solid_anim.color = 0xFF0000FF
|
||||
|
||||
# This should work without errors (though the animation won't use strip_length directly)
|
||||
var length_value = provider.produce_value("test", engine.time_ms)
|
||||
assert(length_value == 20, f"Expected 20, got {length_value}")
|
||||
|
||||
print(" ✓ Integration test passed")
|
||||
end
|
||||
|
||||
# Test consistency with engine properties
|
||||
def test_engine_consistency()
|
||||
print(" Testing consistency with engine properties...")
|
||||
|
||||
var strip = MockStrip(100)
|
||||
var engine = animation.animation_engine(strip)
|
||||
var provider = animation.strip_length(engine)
|
||||
|
||||
# Test that provider returns same value as engine properties
|
||||
var provider_length = provider.produce_value("length", 0)
|
||||
var engine_width = engine.width
|
||||
var engine_strip_length = engine.get_strip_length()
|
||||
|
||||
assert(provider_length == engine_width, f"Provider length {provider_length} != engine width {engine_width}")
|
||||
assert(provider_length == engine_strip_length, f"Provider length {provider_length} != engine strip length {engine_strip_length}")
|
||||
|
||||
print(" ✓ Engine consistency test passed")
|
||||
end
|
||||
|
||||
# Run all tests
|
||||
def run_all_tests()
|
||||
test_basic_functionality()
|
||||
test_string_representation()
|
||||
test_error_handling()
|
||||
test_integration()
|
||||
test_engine_consistency()
|
||||
|
||||
print("All StripLengthProvider tests passed!")
|
||||
return true
|
||||
end
|
||||
|
||||
# Execute tests
|
||||
run_all_tests()
|
||||
@@ -94,6 +94,7 @@ def run_all_tests()
|
||||
"lib/libesp32/berry_animation/src/tests/oscillator_value_provider_test.be",
|
||||
"lib/libesp32/berry_animation/src/tests/oscillator_ease_test.be",
|
||||
"lib/libesp32/berry_animation/src/tests/oscillator_elastic_bounce_test.be",
|
||||
"lib/libesp32/berry_animation/src/tests/strip_length_provider_test.be",
|
||||
"lib/libesp32/berry_animation/src/tests/breathe_color_provider_test.be",
|
||||
|
||||
# DSL tests
|
||||
|
||||
Reference in New Issue
Block a user