# API Reference Complete reference for the Tasmota Berry Animation Framework API. ## Core Classes ### AnimationEngine The central controller for all animations. ```berry var engine = animation.create_engine(strip) ``` #### Methods **`add_animation(animation)`** - Adds an animation to the engine - Auto-starts the animation if engine is running - Returns: `self` (for method chaining) **`remove_animation(animation)`** - Removes an animation from the engine - Returns: `self` **`clear()`** - Removes all animations - Returns: `self` **`start()`** - Starts the engine and all animations - Integrates with Tasmota's `fast_loop` - Returns: `self` **`stop()`** - Stops the engine and all animations - Returns: `self` **`size()`** - Returns: Number of active animations **`is_active()`** - Returns: `true` if engine is running #### Example ```berry var strip = Leds(30) var engine = animation.create_engine(strip) var pulse = animation.pulse(animation.solid(0xFFFF0000), 2000, 50, 255) engine.add_animation(pulse).start() ``` ### Pattern (Base Class) Base class for all visual elements. #### Properties - **`priority`** (int) - Rendering priority (higher = on top) - **`opacity`** (int) - Opacity 0-255 for blending - **`name`** (string) - Pattern identification - **`is_running`** (bool) - Whether pattern is active #### Methods **`start()`** / **`stop()`** - Control pattern lifecycle - Returns: `self` **`set_priority(priority)`** - Set rendering priority - Returns: `self` **`set_opacity(opacity)`** - Set opacity (0-255) - Returns: `self` ### Animation (Extends Pattern) Adds temporal behavior to patterns. #### Additional Properties - **`duration`** (int) - Animation duration in ms (0 = infinite) - **`loop`** (bool) - Whether to loop when complete - **`start_time`** (int) - When animation started - **`current_time`** (int) - Current animation time #### Additional Methods **`set_duration(duration_ms)`** - Set animation duration - Returns: `self` **`set_loop(loop)`** - Enable/disable looping - Returns: `self` **`get_progress()`** - Returns: Animation progress (0-255) ## Animation Functions ### Basic Animations **`animation.solid(color, priority=0, duration=0, loop=false, opacity=255, name="")`** - Creates solid color animation - **color**: ARGB color value (0xAARRGGBB) or ValueProvider instance - Returns: `PatternAnimation` instance ```berry var red = animation.solid(0xFFFF0000) var blue = animation.solid(0xFF0000FF, 10, 5000, true, 200, "blue_anim") var dynamic = animation.solid(animation.smooth(0xFF000000, 0xFFFFFFFF, 3000)) ``` **`animation.pulse(pattern, period_ms, min_brightness=0, max_brightness=255, priority=0, duration=0, loop=false, opacity=255, name="")`** - Creates pulsing animation - **pattern**: Base pattern to pulse - **period_ms**: Pulse period in milliseconds - **min_brightness**: Minimum brightness (0-255) - **max_brightness**: Maximum brightness (0-255) - Returns: `PulseAnimation` instance ```berry var pulse_red = animation.pulse(animation.solid(0xFFFF0000), 2000, 50, 255) ``` **`animation.breathe(color, period_ms, priority=0, duration=0, loop=false, opacity=255, name="")`** - Creates smooth breathing effect - **color**: ARGB color value or ValueProvider instance - **period_ms**: Breathing period in milliseconds - Returns: `BreatheAnimation` instance ```berry var breathe_blue = animation.breathe(0xFF0000FF, 4000) var dynamic_breathe = animation.breathe(animation.color_cycle_color_provider([0xFFFF0000, 0xFF00FF00], 2000), 4000) ``` ### Palette-Based Animations **`animation.rich_palette_animation(palette, period_ms, transition_type=1, brightness=255, priority=0, duration=0, loop=false, opacity=255, name="")`** - Creates palette-based color cycling animation - **palette**: Palette in VRGB bytes format or palette name - **period_ms**: Cycle period in milliseconds - **transition_type**: 0=linear, 1=smooth (sine) - **brightness**: Overall brightness (0-255) - Returns: `FilledAnimation` instance ```berry var rainbow = animation.rich_palette_animation(animation.PALETTE_RAINBOW, 5000, 1, 255) ``` ### Position-Based Animations **`animation.pulse_position_animation(color, pos, pulse_size, slew_size=0, priority=0, duration=0, loop=false, opacity=255, name="")`** - Creates pulse at specific position - **color**: ARGB color value or ValueProvider instance - **pos**: Pixel position (0-based) or ValueProvider instance - **pulse_size**: Width of pulse in pixels or ValueProvider instance - **slew_size**: Fade region size in pixels or ValueProvider instance - Returns: `PulsePositionAnimation` instance ```berry var center_pulse = animation.pulse_position_animation(0xFFFFFFFF, 15, 3, 2) var moving_pulse = animation.pulse_position_animation(0xFFFF0000, animation.smooth(0, 29, 3000), 3, 2) ``` **`animation.comet_animation(color, tail_length, speed_ms, priority=0, duration=0, loop=false, opacity=255, name="")`** - Creates moving comet effect - **color**: ARGB color value or ValueProvider instance - **tail_length**: Length of comet tail in pixels - **speed_ms**: Movement speed in milliseconds per pixel - Returns: `CometAnimation` instance ```berry var comet = animation.comet_animation(0xFF00FFFF, 8, 100) var rainbow_comet = animation.comet_animation(animation.rich_palette_color_provider(animation.PALETTE_RAINBOW, 3000), 8, 100) ``` **`animation.twinkle_animation(color, density, speed_ms, priority=0, duration=0, loop=false, opacity=255, name="")`** - Creates twinkling stars effect - **color**: ARGB color value or ValueProvider instance - **density**: Number of twinkling pixels - **speed_ms**: Twinkle speed in milliseconds - Returns: `TwinkleAnimation` instance ```berry var stars = animation.twinkle_animation(0xFFFFFFFF, 5, 500) var color_changing_stars = animation.twinkle_animation(animation.color_cycle_color_provider([0xFFFF0000, 0xFF00FF00, 0xFF0000FF], 4000), 5, 500) ``` ### Fire and Natural Effects **`animation.fire_animation(color=nil, intensity=200, speed_ms=100, priority=0, duration=0, loop=false, opacity=255, name="")`** - Creates realistic fire simulation - **color**: ARGB color value, ValueProvider instance, or nil for default fire palette - **intensity**: Fire intensity (0-255) - **speed_ms**: Animation speed in milliseconds - Returns: `FireAnimation` instance ```berry var fire = animation.fire_animation(nil, 180, 150) # Default fire palette var blue_fire = animation.fire_animation(0xFF0066FF, 180, 150) # Blue fire ``` ### Advanced Pattern Animations **`animation.noise_rainbow(scale, speed, strip_length, priority)`** - Creates rainbow noise pattern with fractal complexity - **scale**: Noise frequency/detail (0-255, higher = more detail) - **speed**: Animation speed (0-255, 0 = static) - **strip_length**: LED strip length - **priority**: Rendering priority - Returns: `NoiseAnimation` instance **`animation.noise_single_color(color, scale, speed, strip_length, priority)`** - Creates single-color noise pattern - **color**: ARGB color value or ValueProvider instance - Returns: `NoiseAnimation` instance **`animation.noise_fractal(color, scale, speed, octaves, strip_length, priority)`** - Creates multi-octave fractal noise - **color**: ARGB color value, ValueProvider instance, or nil for rainbow - **octaves**: Number of noise octaves (1-4) - Returns: `NoiseAnimation` instance ```berry var rainbow_noise = animation.noise_rainbow(60, 40, 30, 10) var blue_noise = animation.noise_single_color(0xFF0066FF, 120, 60, 30, 10) var fractal = animation.noise_fractal(nil, 40, 50, 3, 30, 10) ``` **`animation.plasma_rainbow(time_speed, strip_length, priority)`** - Creates rainbow plasma effect using sine wave interference - **time_speed**: Animation speed (0-255) - Returns: `PlasmaAnimation` instance **`animation.plasma_single_color(color, time_speed, strip_length, priority)`** - Creates single-color plasma effect - **color**: ARGB color value or ValueProvider instance - Returns: `PlasmaAnimation` instance ```berry var plasma = animation.plasma_rainbow(80, 30, 10) var purple_plasma = animation.plasma_single_color(0xFF8800FF, 60, 30, 10) ``` **`animation.sparkle_white(density, fade_speed, strip_length, priority)`** - Creates white twinkling sparkles - **density**: Sparkle creation probability (0-255) - **fade_speed**: Fade-out speed (0-255) - Returns: `SparkleAnimation` instance **`animation.sparkle_colored(color, density, fade_speed, strip_length, priority)`** - Creates colored sparkles - **color**: ARGB color value or ValueProvider instance - Returns: `SparkleAnimation` instance **`animation.sparkle_rainbow(density, fade_speed, strip_length, priority)`** - Creates rainbow sparkles - Returns: `SparkleAnimation` instance ```berry var white_sparkles = animation.sparkle_white(80, 60, 30, 10) var red_sparkles = animation.sparkle_colored(0xFFFF0000, 100, 50, 30, 10) var rainbow_sparkles = animation.sparkle_rainbow(60, 40, 30, 10) ``` **`animation.wave_rainbow_sine(amplitude, wave_speed, strip_length, priority)`** - Creates rainbow sine wave pattern - **amplitude**: Wave amplitude/intensity (0-255) - **wave_speed**: Wave movement speed (0-255) - Returns: `WaveAnimation` instance **`animation.wave_single_sine(color, amplitude, wave_speed, strip_length, priority)`** - Creates single-color sine wave - **color**: ARGB color value or ValueProvider instance - Returns: `WaveAnimation` instance **`animation.wave_custom(color, wave_type, amplitude, frequency, strip_length, priority)`** - Creates custom wave with specified type - **color**: ARGB color value, ValueProvider instance, or nil for rainbow - **wave_type**: 0=sine, 1=triangle, 2=square, 3=sawtooth - **frequency**: Wave frequency/density (0-255) - Returns: `WaveAnimation` instance ```berry var sine_wave = animation.wave_rainbow_sine(40, 80, 30, 10) var green_wave = animation.wave_single_sine(0xFF00FF00, 60, 40, 30, 10) var triangle_wave = animation.wave_custom(nil, 1, 50, 70, 30, 10) ``` ### Motion Effect Animations Motion effects transform existing animations by applying movement, scaling, and distortion effects. **`animation.shift_scroll_right(source, speed, strip_length, priority)`** - Scrolls animation to the right with wrapping - **source**: Source animation to transform - **speed**: Scroll speed (0-255) - Returns: `ShiftAnimation` instance **`animation.shift_scroll_left(source, speed, strip_length, priority)`** - Scrolls animation to the left with wrapping - Returns: `ShiftAnimation` instance **`animation.shift_bounce_horizontal(source, speed, strip_length, priority)`** - Bounces animation horizontally at strip edges - Returns: `ShiftAnimation` instance ```berry var base = animation.pulse_animation(0xFF0066FF, 80, 180, 3000, 5, 0, true, "base") var scrolling = animation.shift_scroll_right(base, 100, 30, 10) ``` **`animation.bounce_gravity(source, speed, gravity, strip_length, priority)`** - Physics-based bouncing with gravity simulation - **source**: Source animation to transform - **speed**: Initial bounce speed (0-255) - **gravity**: Gravity strength (0-255) - Returns: `BounceAnimation` instance **`animation.bounce_basic(source, speed, damping, strip_length, priority)`** - Basic bouncing without gravity - **damping**: Damping factor (0-255, 255=no damping) - Returns: `BounceAnimation` instance ```berry var sparkles = animation.sparkle_white(80, 50, 30, 5) var bouncing = animation.bounce_gravity(sparkles, 150, 80, 30, 10) var elastic = animation.bounce_basic(sparkles, 120, 240, 30, 10) ``` **`animation.scale_static(source, scale_factor, strip_length, priority)`** - Static scaling of animation - **source**: Source animation to transform - **scale_factor**: Scale factor (128=1.0x, 64=0.5x, 255=2.0x) - Returns: `ScaleAnimation` instance **`animation.scale_oscillate(source, speed, strip_length, priority)`** - Oscillating scale (breathing effect) - **speed**: Oscillation speed (0-255) - Returns: `ScaleAnimation` instance **`animation.scale_grow(source, speed, strip_length, priority)`** - Growing scale effect - Returns: `ScaleAnimation` instance ```berry var pattern = animation.gradient_rainbow_linear(0, 30, 5) var breathing = animation.scale_oscillate(pattern, 60, 30, 10) var zoomed = animation.scale_static(pattern, 180, 30, 10) # 1.4x scale ``` **`animation.jitter_position(source, intensity, frequency, strip_length, priority)`** - Random position shake effects - **source**: Source animation to transform - **intensity**: Jitter intensity (0-255) - **frequency**: Jitter frequency (0-255, maps to 0-30 Hz) - Returns: `JitterAnimation` instance **`animation.jitter_color(source, intensity, frequency, strip_length, priority)`** - Random color variations - Returns: `JitterAnimation` instance **`animation.jitter_brightness(source, intensity, frequency, strip_length, priority)`** - Random brightness changes - Returns: `JitterAnimation` instance **`animation.jitter_all(source, intensity, frequency, strip_length, priority)`** - Combination of position, color, and brightness jitter - Returns: `JitterAnimation` instance ```berry var base = animation.gradient_rainbow_linear(0, 30, 5) var glitch = animation.jitter_all(base, 120, 100, 30, 15) var shake = animation.jitter_position(base, 60, 40, 30, 10) ``` ### Chaining Motion Effects Motion effects can be chained together for complex transformations: ```berry # Base animation var base = animation.pulse_animation(0xFF0066FF, 80, 180, 3000, 5, 0, true, "base") # Apply multiple transformations var scaled = animation.scale_static(base, 150, 30, 8) # 1.2x scale var shifted = animation.shift_scroll_left(scaled, 60, 30, 12) # Scroll left var jittered = animation.jitter_color(shifted, 40, 30, 30, 15) # Add color jitter # Result: A scaled, scrolling, color-jittered pulse ``` ## Color System ### Color Formats **ARGB Format**: `0xAARRGGBB` - **AA**: Alpha channel (opacity) - usually `FF` for opaque - **RR**: Red component (00-FF) - **GG**: Green component (00-FF) - **BB**: Blue component (00-FF) ```berry var red = 0xFFFF0000 # Opaque red var semi_blue = 0x800000FF # Semi-transparent blue var white = 0xFFFFFFFF # Opaque white var black = 0xFF000000 # Opaque black ``` ### Predefined Colors ```berry # Available as constants animation.COLOR_RED # 0xFFFF0000 animation.COLOR_GREEN # 0xFF00FF00 animation.COLOR_BLUE # 0xFF0000FF animation.COLOR_WHITE # 0xFFFFFFFF animation.COLOR_BLACK # 0xFF000000 ``` ### Palette System **Creating Palettes** ```berry # VRGB format: Value(position), Red, Green, Blue var fire_palette = bytes("00000000" "80FF0000" "FFFFFF00") # ^pos=0 ^pos=128 ^pos=255 # black red yellow ``` **Predefined Palettes** ```berry animation.PALETTE_RAINBOW # Standard rainbow colors animation.PALETTE_FIRE # Fire effect colors animation.PALETTE_OCEAN # Ocean wave colors ``` ## Value Providers Dynamic parameters that change over time. ### Static Values ```berry # Regular values are automatically wrapped var static_color = 0xFFFF0000 var static_position = 15 ``` ### Oscillator Providers **`animation.smooth(start, end, period_ms)`** - Smooth cosine wave oscillation - Returns: `OscillatorValueProvider` **`animation.linear(start, end, period_ms)`** - Triangle wave oscillation (goes from start to end, then back to start) - Returns: `OscillatorValueProvider` **`animation.triangle(start, end, period_ms)`** - Alias for `linear()` - triangle wave oscillation - Returns: `OscillatorValueProvider` **`animation.ramp(start, end, period_ms)`** - Sawtooth wave oscillation (linear progression from start to end) - Returns: `OscillatorValueProvider` **`animation.sawtooth(start, end, period_ms)`** - Alias for `ramp()` - sawtooth wave oscillation - Returns: `OscillatorValueProvider` **`animation.square(start, end, period_ms, duty_cycle=50)`** - Square wave oscillation - **duty_cycle**: Percentage of time at high value - Returns: `OscillatorValueProvider` ```berry # Dynamic position that moves back and forth var moving_pos = animation.smooth(0, 29, 3000) # Dynamic color that cycles brightness var breathing_color = animation.smooth(50, 255, 2000) # Use with animations var dynamic_pulse = animation.pulse_position_animation( 0xFFFF0000, # Static red color moving_pos, # Dynamic position 3, # Static pulse size 1 # Static slew size ) ``` ## Event System ### Event Registration **`animation.register_event_handler(event_name, callback, priority=0, condition=nil, metadata=nil)`** - Registers an event handler - **event_name**: Name of event to handle - **callback**: Function to call when event occurs - **priority**: Handler priority (higher = executed first) - **condition**: Optional condition function - **metadata**: Optional metadata map - Returns: `EventHandler` instance ```berry def flash_white(event_data) var flash = animation.solid(0xFFFFFFFF) engine.add_animation(flash) end var handler = animation.register_event_handler("button_press", flash_white, 10) ``` ### Event Triggering **`animation.trigger_event(event_name, event_data={})`** - Triggers an event - **event_name**: Name of event to trigger - **event_data**: Data to pass to handlers ```berry animation.trigger_event("button_press", {"button": "main"}) ``` ## DSL System ### DSL Runtime **`animation.DSLRuntime(engine, debug_mode=false)`** - Creates DSL runtime instance - **engine**: AnimationEngine instance - **debug_mode**: Enable debug output - Returns: `DSLRuntime` instance #### Methods **`load_dsl(source_code)`** - Compiles and executes DSL source code - **source_code**: DSL source as string - Returns: `true` on success, `false` on error **`load_dsl_file(filename)`** - Loads and executes DSL from file - **filename**: Path to .anim file - Returns: `true` on success, `false` on error ```berry var runtime = animation.DSLRuntime(engine, true) # Debug mode on var dsl_code = ''' color red = #FF0000 animation pulse_red = pulse(solid(red), 2s, 50%, 100%) run pulse_red ''' if runtime.load_dsl(dsl_code) print("Animation loaded successfully") else print("Failed to load animation") end ``` ### DSL Compilation **`animation.compile_dsl(source_code)`** - Compiles DSL to Berry code - **source_code**: DSL source as string - Returns: Berry code string or raises exception - Raises: `"dsl_compilation_error"` on compilation failure ```berry try var berry_code = animation.compile_dsl(dsl_source) print("Generated code:", berry_code) var compiled_func = compile(berry_code) compiled_func() except "dsl_compilation_error" as e, msg print("Compilation error:", msg) end ``` ## User Functions ### Function Registration **`animation.register_user_function(name, func)`** - Registers Berry function for DSL use - **name**: Function name for DSL - **func**: Berry function to register **`animation.is_user_function(name)`** - Checks if function is registered - Returns: `true` if registered **`animation.get_user_function(name)`** - Gets registered function - Returns: Function or `nil` **`animation.list_user_functions()`** - Lists all registered function names - Returns: Array of function names ```berry def custom_breathing(color, period) return animation.pulse(animation.solid(color), period, 50, 255) end animation.register_user_function("breathing", custom_breathing) # Now available in DSL: # animation my_effect = breathing(red, 3s) ``` ## Version Information The framework uses a numeric version system for efficient comparison: ```berry # Primary version (0xAABBCCDD format: AA=major, BB=minor, CC=patch, DD=build) print(f"0x{animation.VERSION:08X}") # 0x00010000 # Convert to string format (drops build number) print(animation.version_string()) # "0.1.0" # Convert any version number to string print(animation.version_string(0x01020304)) # "1.2.3" # Extract components manually var major = (animation.VERSION >> 24) & 0xFF # 0 var minor = (animation.VERSION >> 16) & 0xFF # 1 var patch = (animation.VERSION >> 8) & 0xFF # 0 var build = animation.VERSION & 0xFF # 0 # Version comparison var is_new_enough = animation.VERSION >= 0x00010000 # v0.1.0+ ``` ## Utility Functions ### Global Variable Access **`animation.global(name)`** - Safely accesses global variables - **name**: Variable name - Returns: Variable value - Raises: `"syntax_error"` if variable doesn't exist ```berry # Set global variable global.my_color = 0xFFFF0000 # Access safely var color = animation.global("my_color") # Returns 0xFFFF0000 var missing = animation.global("missing") # Raises exception ``` ### Type Checking **`animation.is_value_provider(obj)`** - Checks if object is a ValueProvider - Returns: `true` if object implements ValueProvider interface **`animation.is_color_provider(obj)`** - Checks if object is a ColorProvider - Returns: `true` if object implements ColorProvider interface ```berry var static_val = 42 var dynamic_val = animation.smooth(0, 100, 2000) print(animation.is_value_provider(static_val)) # false print(animation.is_value_provider(dynamic_val)) # true ``` ## Error Handling ### Common Exceptions - **`"dsl_compilation_error"`** - DSL compilation failed - **`"syntax_error"`** - Variable not found or syntax error - **`"type_error"`** - Invalid parameter type - **`"runtime_error"`** - General runtime error ### Best Practices ```berry # Always use try/catch for DSL operations try runtime.load_dsl(dsl_code) except "dsl_compilation_error" as e, msg print("DSL Error:", msg) except .. as e, msg print("Unexpected error:", msg) end # Check engine state before operations if engine.is_active() engine.add_animation(new_animation) else print("Engine not running") end # Validate parameters if type(color) == "int" && color >= 0 var anim = animation.solid(color) else print("Invalid color value") end ``` ## Performance Tips ### Memory Management ```berry # Clear animations when switching effects engine.clear() engine.add_animation(new_animation) # Reuse animation objects when possible var pulse_red = animation.pulse(animation.solid(0xFFFF0000), 2000, 50, 255) # Use pulse_red multiple times instead of creating new instances ``` ### Timing Optimization ```berry # Use longer periods for smoother performance var smooth_pulse = animation.pulse(pattern, 3000, 50, 255) # 3 seconds var choppy_pulse = animation.pulse(pattern, 100, 50, 255) # 100ms - may be choppy # Limit simultaneous animations # Good: 1-3 animations # Avoid: 10+ animations running simultaneously ``` ### Value Provider Efficiency ```berry # Efficient: Reuse providers var breathing = animation.smooth(50, 255, 2000) var anim1 = animation.pulse(pattern1, breathing) var anim2 = animation.pulse(pattern2, breathing) # Reuse same provider # Inefficient: Create new providers var anim1 = animation.pulse(pattern1, animation.smooth(50, 255, 2000)) var anim2 = animation.pulse(pattern2, animation.smooth(50, 255, 2000)) # Duplicate ``` This API reference covers the essential classes and functions. For more advanced usage, see the [Examples](EXAMPLES.md) and [User Functions](.kiro/specs/berry-animation-framework/USER_FUNCTIONS.md) documentation.