diff --git a/lib/libesp32/berry_animation/anim_examples/aurora_borealis.anim b/lib/libesp32/berry_animation/anim_examples/aurora_borealis.anim index 03ea8045c..32da7b29a 100644 --- a/lib/libesp32/berry_animation/anim_examples/aurora_borealis.anim +++ b/lib/libesp32/berry_animation/anim_examples/aurora_borealis.anim @@ -5,20 +5,20 @@ # Define aurora color palette palette aurora_colors = [ - (0, #000022), # Dark night sky - (64, #004400), # Dark green - (128, #00AA44), # Aurora green - (192, #44AA88), # Light green - (255, #88FFAA) # Bright aurora + (0, 0x000022), # Dark night sky + (64, 0x004400), # Dark green + (128, 0x00AA44), # Aurora green + (192, 0x44AA88), # Light green + (255, 0x88FFAA) # Bright aurora ] # Secondary purple palette palette aurora_purple = [ - (0, #220022), # Dark purple - (64, #440044), # Medium purple - (128, #8800AA), # Bright purple - (192, #AA44CC), # Light purple - (255, #CCAAFF) # Pale purple + (0, 0x220022), # Dark purple + (64, 0x440044), # Medium purple + (128, 0x8800AA), # Bright purple + (192, 0xAA44CC), # Light purple + (255, 0xCCAAFF) # Pale purple ] # Base aurora animation with slow flowing colors diff --git a/lib/libesp32/berry_animation/anim_examples/breathing_colors.anim b/lib/libesp32/berry_animation/anim_examples/breathing_colors.anim index cf2735e90..3f9d6142a 100644 --- a/lib/libesp32/berry_animation/anim_examples/breathing_colors.anim +++ b/lib/libesp32/berry_animation/anim_examples/breathing_colors.anim @@ -4,20 +4,20 @@ strip length 60 # Define breathing colors -color breathe_red = #FF0000 -color breathe_green = #00FF00 -color breathe_blue = #0000FF -color breathe_purple = #800080 -color breathe_orange = #FF8000 +color breathe_red = 0xFF0000 +color breathe_green = 0x00FF00 +color breathe_blue = 0x0000FF +color breathe_purple = 0x800080 +color breathe_orange = 0xFF8000 # Create breathing animation that cycles through colors palette breathe_palette = [ - (0, #FF0000), # Red - (51, #FF8000), # Orange - (102, #FFFF00), # Yellow - (153, #00FF00), # Green - (204, #0000FF), # Blue - (255, #800080) # Purple + (0, 0xFF0000), # Red + (51, 0xFF8000), # Orange + (102, 0xFFFF00), # Yellow + (153, 0x00FF00), # Green + (204, 0x0000FF), # Blue + (255, 0x800080) # Purple ] # Create a rich palette color provider diff --git a/lib/libesp32/berry_animation/anim_examples/candy_cane.anim b/lib/libesp32/berry_animation/anim_examples/candy_cane.anim index 5b1135224..02a21b45a 100644 --- a/lib/libesp32/berry_animation/anim_examples/candy_cane.anim +++ b/lib/libesp32/berry_animation/anim_examples/candy_cane.anim @@ -4,8 +4,8 @@ strip length 60 # Define stripe colors -color candy_red = #FF0000 -color candy_white = #FFFFFF +color candy_red = 0xFF0000 +color candy_white = 0xFFFFFF # Create alternating red and white pattern # Using multiple pulse positions to create stripes diff --git a/lib/libesp32/berry_animation/anim_examples/christmas_tree.anim b/lib/libesp32/berry_animation/anim_examples/christmas_tree.anim index 43542958c..a47ae5380 100644 --- a/lib/libesp32/berry_animation/anim_examples/christmas_tree.anim +++ b/lib/libesp32/berry_animation/anim_examples/christmas_tree.anim @@ -4,16 +4,16 @@ strip length 60 # Green tree base -color tree_green = #006600 +color tree_green = 0x006600 animation tree_base = solid(tree_green) # Define ornament colors palette ornament_colors = [ - (0, #FF0000), # Red - (64, #FFD700), # Gold - (128, #0000FF), # Blue - (192, #FFFFFF), # White - (255, #FF00FF) # Magenta + (0, 0xFF0000), # Red + (64, 0xFFD700), # Gold + (128, 0x0000FF), # Blue + (192, 0xFFFFFF), # White + (255, 0xFF00FF) # Magenta ] # Colorful ornaments as twinkling lights @@ -27,19 +27,19 @@ ornaments.priority = 10 # Star on top (bright yellow pulse) animation tree_star = pulse_position_animation( - #FFFF00, # Bright yellow - 58, # position (near the top) - 3, # star size - 1 # sharp edges + 0xFFFF00, # Bright yellow + 58, # position (near the top) + 3, # star size + 1 # sharp edges ) tree_star.priority = 20 tree_star.opacity = smooth(200, 255, 2s) # Gentle pulsing # Add some white sparkles for snow/magic animation snow_sparkles = twinkle_animation( - #FFFFFF, # White snow - 8, # density (sparkle count) - 400ms # twinkle speed (quick sparkles) + 0xFFFFFF, # White snow + 8, # density (sparkle count) + 400ms # twinkle speed (quick sparkles) ) snow_sparkles.priority = 15 diff --git a/lib/libesp32/berry_animation/anim_examples/comet_chase.anim b/lib/libesp32/berry_animation/anim_examples/comet_chase.anim index abf5bf4fb..081c63d15 100644 --- a/lib/libesp32/berry_animation/anim_examples/comet_chase.anim +++ b/lib/libesp32/berry_animation/anim_examples/comet_chase.anim @@ -4,31 +4,31 @@ strip length 60 # Dark blue background -color space_blue = #000066 # Note: opaque 0xFF alpha channel is implicitly added +color space_blue = 0x000066 # Note: opaque 0xFF alpha channel is implicitly added animation background = solid(space_blue) # Main comet with bright white head animation comet_main = comet_animation( - #FFFFFF, # White head - 10, # tail length - 2s # speed + 0xFFFFFF, # White head + 10, # tail length + 2s # speed ) comet_main.priority = 7 # Secondary comet in different color, opposite direction animation comet_secondary = comet_animation( - #FF4500, # Orange head - 8, # shorter tail - 3s, # slower speed - -1 # other direction + 0xFF4500, # Orange head + 8, # shorter tail + 3s, # slower speed + -1 # other direction ) comet_secondary.priority = 5 # Add sparkle trail behind comets but on top of blue background animation comet_sparkles = twinkle_animation( - #AAAAFF, # Light blue sparkles - 8, # density (moderate sparkles) - 400ms # twinkle speed (quick sparkle) + 0xAAAAFF, # Light blue sparkles + 8, # density (moderate sparkles) + 400ms # twinkle speed (quick sparkle) ) comet_sparkles.priority = 8 diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/COMPILATION_REPORT.md b/lib/libesp32/berry_animation/anim_examples/compiled/COMPILATION_REPORT.md index e0035b64f..ba9fbec2d 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/COMPILATION_REPORT.md +++ b/lib/libesp32/berry_animation/anim_examples/compiled/COMPILATION_REPORT.md @@ -1,6 +1,6 @@ # DSL Compilation Report -Generated: Ven 1 aoû 2025 16:04:44 CEST +Generated: Ven 1 aoû 2025 18:49:41 CEST ## Summary diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/aurora_borealis.be b/lib/libesp32/berry_animation/anim_examples/compiled/aurora_borealis.be index 5c8bdb28a..5dd20fe02 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/aurora_borealis.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/aurora_borealis.be @@ -13,20 +13,20 @@ # # # Define aurora color palette # palette aurora_colors = [ -# (0, #000022), # Dark night sky -# (64, #004400), # Dark green -# (128, #00AA44), # Aurora green -# (192, #44AA88), # Light green -# (255, #88FFAA) # Bright aurora +# (0, 0x000022), # Dark night sky +# (64, 0x004400), # Dark green +# (128, 0x00AA44), # Aurora green +# (192, 0x44AA88), # Light green +# (255, 0x88FFAA) # Bright aurora # ] # # # Secondary purple palette # palette aurora_purple = [ -# (0, #220022), # Dark purple -# (64, #440044), # Medium purple -# (128, #8800AA), # Bright purple -# (192, #AA44CC), # Light purple -# (255, #CCAAFF) # Pale purple +# (0, 0x220022), # Dark purple +# (64, 0x440044), # Medium purple +# (128, 0x8800AA), # Bright purple +# (192, 0xAA44CC), # Light purple +# (255, 0xCCAAFF) # Pale purple # ] # # # Base aurora animation with slow flowing colors diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/breathing_colors.be b/lib/libesp32/berry_animation/anim_examples/compiled/breathing_colors.be index c8825a4bc..5f1c7e46f 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/breathing_colors.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/breathing_colors.be @@ -12,20 +12,20 @@ # strip length 60 # # # Define breathing colors -# color breathe_red = #FF0000 -# color breathe_green = #00FF00 -# color breathe_blue = #0000FF -# color breathe_purple = #800080 -# color breathe_orange = #FF8000 +# color breathe_red = 0xFF0000 +# color breathe_green = 0x00FF00 +# color breathe_blue = 0x0000FF +# color breathe_purple = 0x800080 +# color breathe_orange = 0xFF8000 # # # Create breathing animation that cycles through colors # palette breathe_palette = [ -# (0, #FF0000), # Red -# (51, #FF8000), # Orange -# (102, #FFFF00), # Yellow -# (153, #00FF00), # Green -# (204, #0000FF), # Blue -# (255, #800080) # Purple +# (0, 0xFF0000), # Red +# (51, 0xFF8000), # Orange +# (102, 0xFFFF00), # Yellow +# (153, 0x00FF00), # Green +# (204, 0x0000FF), # Blue +# (255, 0x800080) # Purple # ] # # # Create a rich palette color provider diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/candy_cane.be b/lib/libesp32/berry_animation/anim_examples/compiled/candy_cane.be index 60fdbee0f..51ba6bdbf 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/candy_cane.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/candy_cane.be @@ -12,8 +12,8 @@ # strip length 60 # # # Define stripe colors -# color candy_red = #FF0000 -# color candy_white = #FFFFFF +# color candy_red = 0xFF0000 +# color candy_white = 0xFFFFFF # # # Create alternating red and white pattern # # Using multiple pulse positions to create stripes diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/christmas_tree.be b/lib/libesp32/berry_animation/anim_examples/compiled/christmas_tree.be index 17d882fb5..fc2915818 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/christmas_tree.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/christmas_tree.be @@ -12,16 +12,16 @@ # strip length 60 # # # Green tree base -# color tree_green = #006600 +# color tree_green = 0x006600 # animation tree_base = solid(tree_green) # # # Define ornament colors # palette ornament_colors = [ -# (0, #FF0000), # Red -# (64, #FFD700), # Gold -# (128, #0000FF), # Blue -# (192, #FFFFFF), # White -# (255, #FF00FF) # Magenta +# (0, 0xFF0000), # Red +# (64, 0xFFD700), # Gold +# (128, 0x0000FF), # Blue +# (192, 0xFFFFFF), # White +# (255, 0xFF00FF) # Magenta # ] # # # Colorful ornaments as twinkling lights @@ -35,19 +35,19 @@ # # # Star on top (bright yellow pulse) # animation tree_star = pulse_position_animation( -# #FFFF00, # Bright yellow -# 58, # position (near the top) -# 3, # star size -# 1 # sharp edges +# 0xFFFF00, # Bright yellow +# 58, # position (near the top) +# 3, # star size +# 1 # sharp edges # ) # tree_star.priority = 20 # tree_star.opacity = smooth(200, 255, 2s) # Gentle pulsing # # # Add some white sparkles for snow/magic # animation snow_sparkles = twinkle_animation( -# #FFFFFF, # White snow -# 8, # density (sparkle count) -# 400ms # twinkle speed (quick sparkles) +# 0xFFFFFF, # White snow +# 8, # density (sparkle count) +# 400ms # twinkle speed (quick sparkles) # ) # snow_sparkles.priority = 15 # diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/comet_chase.be b/lib/libesp32/berry_animation/anim_examples/compiled/comet_chase.be index a60e083a1..56d878b76 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/comet_chase.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/comet_chase.be @@ -12,31 +12,31 @@ # strip length 60 # # # Dark blue background -# color space_blue = #000066 # Note: opaque 0xFF alpha channel is implicitly added +# color space_blue = 0x000066 # Note: opaque 0xFF alpha channel is implicitly added # animation background = solid(space_blue) # # # Main comet with bright white head # animation comet_main = comet_animation( -# #FFFFFF, # White head -# 10, # tail length -# 2s # speed +# 0xFFFFFF, # White head +# 10, # tail length +# 2s # speed # ) # comet_main.priority = 7 # # # Secondary comet in different color, opposite direction # animation comet_secondary = comet_animation( -# #FF4500, # Orange head -# 8, # shorter tail -# 3s, # slower speed -# -1 # other direction +# 0xFF4500, # Orange head +# 8, # shorter tail +# 3s, # slower speed +# -1 # other direction # ) # comet_secondary.priority = 5 # # # Add sparkle trail behind comets but on top of blue background # animation comet_sparkles = twinkle_animation( -# #AAAAFF, # Light blue sparkles -# 8, # density (moderate sparkles) -# 400ms # twinkle speed (quick sparkle) +# 0xAAAAFF, # Light blue sparkles +# 8, # density (moderate sparkles) +# 400ms # twinkle speed (quick sparkle) # ) # comet_sparkles.priority = 8 # diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/disco_strobe.be b/lib/libesp32/berry_animation/anim_examples/compiled/disco_strobe.be index fb98ce7e6..02cf3e07e 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/disco_strobe.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/disco_strobe.be @@ -13,13 +13,13 @@ # # # Define disco color palette # palette disco_colors = [ -# (0, #FF0000), # Red -# (42, #FF8000), # Orange -# (85, #FFFF00), # Yellow -# (128, #00FF00), # Green -# (170, #0000FF), # Blue -# (213, #8000FF), # Purple -# (255, #FF00FF) # Magenta +# (0, 0xFF0000), # Red +# (42, 0xFF8000), # Orange +# (85, 0xFFFF00), # Yellow +# (128, 0x00FF00), # Green +# (170, 0x0000FF), # Blue +# (213, 0x8000FF), # Purple +# (255, 0xFF00FF) # Magenta # ] # # # Fast color cycling base @@ -29,7 +29,7 @@ # disco_base.opacity = square(0, 255, 100ms, 30) # Fast strobe # # # Add white flash overlay -# animation white_flash = solid(#FFFFFF) +# animation white_flash = solid(0xFFFFFF) # white_flash.opacity = square(0, 255, 50ms, 10) # Quick white flashes # white_flash.priority = 20 # diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/fire_flicker.be b/lib/libesp32/berry_animation/anim_examples/compiled/fire_flicker.be index 7234382ba..889357f33 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/fire_flicker.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/fire_flicker.be @@ -13,11 +13,11 @@ # # # Define fire palette from black to yellow # palette fire_colors = [ -# (0, #000000), # Black -# (64, #800000), # Dark red -# (128, #FF0000), # Red -# (192, #FF4500), # Orange red -# (255, #FFFF00) # Yellow +# (0, 0x000000), # Black +# (64, 0x800000), # Dark red +# (128, 0xFF0000), # Red +# (192, 0xFF4500), # Orange red +# (255, 0xFFFF00) # Yellow # ] # # # Create base fire animation with palette diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/heartbeat_pulse.be b/lib/libesp32/berry_animation/anim_examples/compiled/heartbeat_pulse.be index 97c31ce3d..61149a423 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/heartbeat_pulse.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/heartbeat_pulse.be @@ -12,32 +12,32 @@ # strip length 60 # # # Dark background -# color heart_bg = #110000 +# color heart_bg = 0x110000 # animation background = solid(heart_bg) # # # Define heartbeat timing - double pulse pattern # # First pulse (stronger) -# animation heartbeat1 = solid(#FF0000) # Bright red +# animation heartbeat1 = solid(0xFF0000) # Bright red # heartbeat1.opacity = square(0, 255, 150ms, 20) # Quick strong pulse # heartbeat1.priority = 10 # # # Second pulse (weaker, slightly delayed) -# animation heartbeat2 = solid(#CC0000) # Slightly dimmer red +# animation heartbeat2 = solid(0xCC0000) # Slightly dimmer red # # Delay the second pulse by adjusting the square wave phase # heartbeat2.opacity = square(0, 180, 150ms, 15) # Weaker pulse # heartbeat2.priority = 8 # # # Add subtle glow effect -# animation heart_glow = solid(#660000) # Dim red glow +# animation heart_glow = solid(0x660000) # Dim red glow # heart_glow.opacity = smooth(30, 100, 1s) # Gentle breathing glow # heart_glow.priority = 5 # # # Add center pulse for emphasis # animation center_pulse = pulse_position_animation( -# #FFFFFF, # White center -# 30, # center of strip -# 4, # small center -# 2 # soft edges +# 0xFFFFFF, # White center +# 30, # center of strip +# 4, # small center +# 2 # soft edges # ) # center_pulse.priority = 20 # center_pulse.opacity = square(0, 200, 100ms, 10) # Quick white flash diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/lava_lamp.be b/lib/libesp32/berry_animation/anim_examples/compiled/lava_lamp.be index 872480121..100b58089 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/lava_lamp.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/lava_lamp.be @@ -13,11 +13,11 @@ # # # Define lava colors (warm oranges and reds) # palette lava_colors = [ -# (0, #330000), # Dark red -# (64, #660000), # Medium red -# (128, #CC3300), # Bright red -# (192, #FF6600), # Orange -# (255, #FFAA00) # Yellow-orange +# (0, 0x330000), # Dark red +# (64, 0x660000), # Medium red +# (128, 0xCC3300), # Bright red +# (192, 0xFF6600), # Orange +# (255, 0xFFAA00) # Yellow-orange # ] # # # Base lava animation - very slow color changes diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/lightning_storm.be b/lib/libesp32/berry_animation/anim_examples/compiled/lightning_storm.be index afd6244e6..92f0e26d8 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/lightning_storm.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/lightning_storm.be @@ -13,38 +13,38 @@ # # # Dark stormy background with subtle purple/blue # palette storm_colors = [ -# (0, #000011), # Very dark blue -# (128, #110022), # Dark purple -# (255, #220033) # Slightly lighter purple +# (0, 0x000011), # Very dark blue +# (128, 0x110022), # Dark purple +# (255, 0x220033) # Slightly lighter purple # ] # # animation storm_bg = rich_palette_animation(storm_colors, 12s, smooth, 100) # # # Random lightning flashes - full strip -# animation lightning_main = solid(#FFFFFF) # Bright white +# animation lightning_main = solid(0xFFFFFF) # Bright white # lightning_main.opacity = square(0, 255, 80ms, 3) # Quick bright flashes # lightning_main.priority = 20 # # # Secondary lightning - partial strip # animation lightning_partial = pulse_position_animation( -# #FFFFAA, # Slightly yellow white -# 30, # center position -# 20, # covers part of strip -# 5 # soft edges +# 0xFFFFAA, # Slightly yellow white +# 30, # center position +# 20, # covers part of strip +# 5 # soft edges # ) # lightning_partial.priority = 15 # lightning_partial.opacity = square(0, 200, 120ms, 4) # Different timing # # # Add blue afterglow -# animation afterglow = solid(#4444FF) # Blue glow +# animation afterglow = solid(0x4444FF) # Blue glow # afterglow.opacity = square(0, 80, 200ms, 8) # Longer, dimmer glow # afterglow.priority = 10 # # # Distant thunder (dim flashes) # animation distant_flash = twinkle_animation( -# #666699, # Dim blue-white -# 4, # density (few flashes) -# 300ms # twinkle speed (medium duration) +# 0x666699, # Dim blue-white +# 4, # density (few flashes) +# 300ms # twinkle speed (medium duration) # ) # distant_flash.priority = 5 # diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/matrix_rain.be b/lib/libesp32/berry_animation/anim_examples/compiled/matrix_rain.be index a68ad0d41..645a3a27f 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/matrix_rain.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/matrix_rain.be @@ -12,16 +12,16 @@ # strip length 60 # # # Dark background -# color matrix_bg = #000000 +# color matrix_bg = 0x000000 # animation background = solid(matrix_bg) # # # Define matrix green palette # palette matrix_greens = [ -# (0, #000000), # Black -# (64, #003300), # Dark green -# (128, #006600), # Medium green -# (192, #00AA00), # Bright green -# (255, #00FF00) # Neon green +# (0, 0x000000), # Black +# (64, 0x003300), # Dark green +# (128, 0x006600), # Medium green +# (192, 0x00AA00), # Bright green +# (255, 0x00FF00) # Neon green # ] # # # Create multiple cascading streams @@ -51,9 +51,9 @@ # # # Add random bright flashes (like code highlights) # animation code_flash = twinkle_animation( -# #00FFAA, # Bright cyan-green -# 3, # density (few flashes) -# 150ms # twinkle speed (quick flash) +# 0x00FFAA, # Bright cyan-green +# 3, # density (few flashes) +# 150ms # twinkle speed (quick flash) # ) # code_flash.priority = 20 # diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/meteor_shower.be b/lib/libesp32/berry_animation/anim_examples/compiled/meteor_shower.be index f0500ca87..d30853873 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/meteor_shower.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/meteor_shower.be @@ -12,51 +12,51 @@ # strip length 60 # # # Dark space background -# color space_bg = #000011 +# color space_bg = 0x000011 # animation background = solid(space_bg) # # # Multiple meteors with different speeds and colors # animation meteor1 = comet_animation( -# #FFFFFF, # Bright white -# 12, # long trail -# 1.5s # fast speed +# 0xFFFFFF, # Bright white +# 12, # long trail +# 1.5s # fast speed # ) # meteor1.priority = 15 # # animation meteor2 = comet_animation( -# #FFAA00, # Orange -# 10, # medium trail -# 2s # medium speed +# 0xFFAA00, # Orange +# 10, # medium trail +# 2s # medium speed # ) # meteor2.priority = 12 # # animation meteor3 = comet_animation( -# #AAAAFF, # Blue-white -# 8, # shorter trail -# 1.8s # fast speed +# 0xAAAAFF, # Blue-white +# 8, # shorter trail +# 1.8s # fast speed # ) # meteor3.priority = 10 # # animation meteor4 = comet_animation( -# #FFAAAA, # Pink-white -# 14, # long trail -# 2.5s # slower speed +# 0xFFAAAA, # Pink-white +# 14, # long trail +# 2.5s # slower speed # ) # meteor4.priority = 8 # # # Add distant stars # animation stars = twinkle_animation( -# #CCCCCC, # Dim white -# 12, # density (many stars) -# 2s # twinkle speed (slow twinkle) +# 0xCCCCCC, # Dim white +# 12, # density (many stars) +# 2s # twinkle speed (slow twinkle) # ) # stars.priority = 5 # # # Add occasional bright flash (meteor explosion) # animation meteor_flash = twinkle_animation( -# #FFFFFF, # Bright white -# 1, # density (single flash) -# 100ms # twinkle speed (very quick) +# 0xFFFFFF, # Bright white +# 1, # density (single flash) +# 100ms # twinkle speed (very quick) # ) # meteor_flash.priority = 25 # diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/neon_glow.be b/lib/libesp32/berry_animation/anim_examples/compiled/neon_glow.be index 0a03b160c..fc4609c7d 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/neon_glow.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/neon_glow.be @@ -13,10 +13,10 @@ # # # Define neon colors # palette neon_colors = [ -# (0, #FF0080), # Hot pink -# (85, #00FF80), # Neon green -# (170, #8000FF), # Electric purple -# (255, #FF8000) # Neon orange +# (0, 0xFF0080), # Hot pink +# (85, 0x00FF80), # Neon green +# (170, 0x8000FF), # Electric purple +# (255, 0xFF8000) # Neon orange # ] # # # Main neon glow with color cycling @@ -26,7 +26,7 @@ # neon_main.opacity = smooth(220, 255, 200ms) # # # Add occasional electrical surge -# animation neon_surge = solid(#FFFFFF) # White surge +# animation neon_surge = solid(0xFFFFFF) # White surge # neon_surge.opacity = square(0, 255, 50ms, 2) # Quick bright surges # neon_surge.priority = 20 # @@ -58,9 +58,9 @@ # # # Add electrical arcing between segments # animation arc_sparkles = twinkle_animation( -# #AAAAFF, # Electric blue -# 4, # density (few arcs) -# 100ms # twinkle speed (quick arcs) +# 0xAAAAFF, # Electric blue +# 4, # density (few arcs) +# 100ms # twinkle speed (quick arcs) # ) # arc_sparkles.priority = 15 # diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/ocean_waves.be b/lib/libesp32/berry_animation/anim_examples/compiled/ocean_waves.be index 6d5f99b4e..10401add4 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/ocean_waves.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/ocean_waves.be @@ -13,11 +13,11 @@ # # # Define ocean color palette # palette ocean_colors = [ -# (0, #000080), # Deep blue -# (64, #0040C0), # Ocean blue -# (128, #0080FF), # Light blue -# (192, #40C0FF), # Cyan -# (255, #80FFFF) # Light cyan +# (0, 0x000080), # Deep blue +# (64, 0x0040C0), # Ocean blue +# (128, 0x0080FF), # Light blue +# (192, 0x40C0FF), # Cyan +# (255, 0x80FFFF) # Light cyan # ] # # # Base ocean animation with slow color cycling @@ -46,9 +46,9 @@ # # # Add foam sparkles # animation foam = twinkle_animation( -# #FFFFFF, # White foam -# 6, # density (sparkle count) -# 300ms # twinkle speed (quick sparkles) +# 0xFFFFFF, # White foam +# 6, # density (sparkle count) +# 300ms # twinkle speed (quick sparkles) # ) # foam.priority = 15 # diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/palette_demo.be b/lib/libesp32/berry_animation/anim_examples/compiled/palette_demo.be index 0f2311357..930c0e59f 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/palette_demo.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/palette_demo.be @@ -13,20 +13,20 @@ # # # Define a fire palette # palette fire_colors = [ -# (0, #000000), # Black -# (64, #800000), # Dark red -# (128, #FF0000), # Red -# (192, #FF8000), # Orange -# (255, #FFFF00) # Yellow +# (0, 0x000000), # Black +# (64, 0x800000), # Dark red +# (128, 0xFF0000), # Red +# (192, 0xFF8000), # Orange +# (255, 0xFFFF00) # Yellow # ] # # # Define an ocean palette # palette ocean_colors = [ -# (0, #000080), # Navy blue -# (64, #0000FF), # Blue -# (128, #00FFFF), # Cyan -# (192, #00FF80), # Spring green -# (255, #008000) # Green +# (0, 0x000080), # Navy blue +# (64, 0x0000FF), # Blue +# (128, 0x00FFFF), # Cyan +# (192, 0x00FF80), # Spring green +# (255, 0x008000) # Green # ] # # # Create animations using the palettes diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/palette_showcase.be b/lib/libesp32/berry_animation/anim_examples/compiled/palette_showcase.be index 5aae976a7..446a14d09 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/palette_showcase.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/palette_showcase.be @@ -13,15 +13,15 @@ # # # Example 1: Fire palette with hex colors # palette fire_gradient = [ -# (0, #000000), # Black (no fire) -# (32, #330000), # Very dark red -# (64, #660000), # Dark red -# (96, #CC0000), # Red -# (128, #FF3300), # Red-orange -# (160, #FF6600), # Orange -# (192, #FF9900), # Light orange -# (224, #FFCC00), # Yellow-orange -# (255, #FFFF00) # Bright yellow +# (0, 0x000000), # Black (no fire) +# (32, 0x330000), # Very dark red +# (64, 0x660000), # Dark red +# (96, 0xCC0000), # Red +# (128, 0xFF3300), # Red-orange +# (160, 0xFF6600), # Orange +# (192, 0xFF9900), # Light orange +# (224, 0xFFCC00), # Yellow-orange +# (255, 0xFFFF00) # Bright yellow # ] # # # Example 2: Ocean palette with named colors @@ -35,20 +35,20 @@ # # # Example 3: Aurora palette (from the original example) # palette aurora_borealis = [ -# (0, #000022), # Dark night sky -# (64, #004400), # Dark green -# (128, #00AA44), # Aurora green -# (192, #44AA88), # Light green -# (255, #88FFAA) # Bright aurora +# (0, 0x000022), # Dark night sky +# (64, 0x004400), # Dark green +# (128, 0x00AA44), # Aurora green +# (192, 0x44AA88), # Light green +# (255, 0x88FFAA) # Bright aurora # ] # # # Example 4: Sunset palette mixing hex and named colors # palette sunset_sky = [ -# (0, #191970), # Midnight blue -# (64, purple), # Purple twilight -# (128, #FF69B4), # Hot pink -# (192, orange), # Sunset orange -# (255, yellow) # Sun +# (0, 0x191970), # Midnight blue +# (64, purple), # Purple twilight +# (128, 0xFF69B4), # Hot pink +# (192, orange), # Sunset orange +# (255, yellow) # Sun # ] # # # Create animations using each palette diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/plasma_wave.be b/lib/libesp32/berry_animation/anim_examples/compiled/plasma_wave.be index 830b3188b..daa4df876 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/plasma_wave.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/plasma_wave.be @@ -13,12 +13,12 @@ # # # Define plasma color palette with smooth transitions # palette plasma_colors = [ -# (0, #FF0080), # Magenta -# (51, #FF8000), # Orange -# (102, #FFFF00), # Yellow -# (153, #80FF00), # Yellow-green -# (204, #00FF80), # Cyan-green -# (255, #0080FF) # Blue +# (0, 0xFF0080), # Magenta +# (51, 0xFF8000), # Orange +# (102, 0xFFFF00), # Yellow +# (153, 0x80FF00), # Yellow-green +# (204, 0x00FF80), # Cyan-green +# (255, 0x0080FF) # Blue # ] # # # Base plasma animation with medium speed diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/police_lights.be b/lib/libesp32/berry_animation/anim_examples/compiled/police_lights.be index e19765c06..d94c12434 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/police_lights.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/police_lights.be @@ -16,26 +16,26 @@ # # # Left side red flashing # animation left_red = pulse_position_animation( -# #FF0000, # Bright red -# 15, # center of left half -# 15, # half the strip -# 2 # sharp edges +# 0xFF0000, # Bright red +# 15, # center of left half +# 15, # half the strip +# 2 # sharp edges # ) # left_red.priority = 10 # left_red.opacity = square(0, 255, 400ms, 50) # 50% duty cycle # # # Right side blue flashing (opposite phase) # animation right_blue = pulse_position_animation( -# #0000FF, # Bright blue -# 45, # center of right half -# 15, # half the strip -# 2 # sharp edges +# 0x0000FF, # Bright blue +# 45, # center of right half +# 15, # half the strip +# 2 # sharp edges # ) # right_blue.priority = 10 # right_blue.opacity = square(255, 0, 400ms, 50) # Opposite phase # # # Add white strobe overlay occasionally -# animation white_strobe = solid(#FFFFFF) +# animation white_strobe = solid(0xFFFFFF) # white_strobe.opacity = square(0, 255, 100ms, 5) # Quick bright flashes # white_strobe.priority = 20 # diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/property_assignment_demo.be b/lib/libesp32/berry_animation/anim_examples/compiled/property_assignment_demo.be index 86c52d8a2..308a5e579 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/property_assignment_demo.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/property_assignment_demo.be @@ -12,9 +12,9 @@ # strip length 60 # # # Define colors -# color red_custom = #FF0000 -# color blue_custom = #0000FF -# color green_custom = #00FF00 +# color red_custom = 0xFF0000 +# color blue_custom = 0x0000FF +# color green_custom = 0x00FF00 # # # Create animations # animation left_pulse = pulse_position_animation(red_custom, 15, 15, 3) diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/rainbow_cycle.be b/lib/libesp32/berry_animation/anim_examples/compiled/rainbow_cycle.be index 6b1cb001e..326f68c14 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/rainbow_cycle.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/rainbow_cycle.be @@ -13,7 +13,7 @@ # # # Create smooth rainbow cycle animation # animation rainbow_cycle = color_cycle_animation( -# [#FF0000, #FF8000, #FFFF00, #00FF00, #0000FF, #8000FF, #FF00FF], # rainbow colors +# [0xFF0000, 0xFF8000, 0xFFFF00, 0x00FF00, 0x0000FF, 0x8000FF, 0xFF00FF], # rainbow colors # 5s # cycle period # ) # diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/scanner_larson.be b/lib/libesp32/berry_animation/anim_examples/compiled/scanner_larson.be index 02d7496b6..6d8491be9 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/scanner_larson.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/scanner_larson.be @@ -12,15 +12,15 @@ # strip length 60 # # # Dark background -# color scanner_bg = #110000 +# color scanner_bg = 0x110000 # animation background = solid(scanner_bg) # # # Main scanner pulse that bounces # animation scanner = pulse_position_animation( -# #FF0000, # Bright red -# 2, # initial position -# 3, # pulse width -# 2 # fade region +# 0xFF0000, # Bright red +# 2, # initial position +# 3, # pulse width +# 2 # fade region # ) # scanner.priority = 10 # @@ -29,10 +29,10 @@ # # # Add trailing glow effect # animation scanner_trail = pulse_position_animation( -# #660000, # Dim red trail -# 2, # initial position -# 6, # wider trail -# 4 # more fade +# 0x660000, # Dim red trail +# 2, # initial position +# 6, # wider trail +# 4 # more fade # ) # scanner_trail.priority = 5 # scanner_trail.pos = triangle(2, 57, 2s) diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/sunrise_sunset.be b/lib/libesp32/berry_animation/anim_examples/compiled/sunrise_sunset.be index 227b25463..ec82a1bde 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/sunrise_sunset.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/sunrise_sunset.be @@ -13,15 +13,15 @@ # # # Define time-of-day color palette # palette daylight_colors = [ -# (0, #000011), # Night - dark blue -# (32, #001133), # Pre-dawn -# (64, #FF4400), # Sunrise orange -# (96, #FFAA00), # Morning yellow -# (128, #FFFF88), # Midday bright -# (160, #FFAA44), # Afternoon -# (192, #FF6600), # Sunset orange -# (224, #AA2200), # Dusk red -# (255, #220011) # Night - dark red +# (0, 0x000011), # Night - dark blue +# (32, 0x001133), # Pre-dawn +# (64, 0xFF4400), # Sunrise orange +# (96, 0xFFAA00), # Morning yellow +# (128, 0xFFFF88), # Midday bright +# (160, 0xFFAA44), # Afternoon +# (192, 0xFF6600), # Sunset orange +# (224, 0xAA2200), # Dusk red +# (255, 0x220011) # Night - dark red # ] # # # Main daylight cycle - very slow transition @@ -29,10 +29,10 @@ # # # Add sun position effect - bright spot that moves # animation sun_position = pulse_position_animation( -# #FFFFAA, # Bright yellow sun -# 5, # initial position -# 8, # sun size -# 4 # soft glow +# 0xFFFFAA, # Bright yellow sun +# 5, # initial position +# 8, # sun size +# 4 # soft glow # ) # sun_position.priority = 10 # sun_position.pos = smooth(5, 55, 30s) # Sun arc across sky @@ -40,10 +40,10 @@ # # # Add atmospheric glow around sun # animation sun_glow = pulse_position_animation( -# #FFCC88, # Warm glow -# 5, # initial position -# 16, # larger glow -# 8 # very soft +# 0xFFCC88, # Warm glow +# 5, # initial position +# 16, # larger glow +# 8 # very soft # ) # sun_glow.priority = 5 # sun_glow.pos = smooth(5, 55, 30s) # Follow sun @@ -51,9 +51,9 @@ # # # Add twinkling stars during night phases # animation stars = twinkle_animation( -# #FFFFFF, # White stars -# 6, # density (star count) -# 1s # twinkle speed (slow twinkle) +# 0xFFFFFF, # White stars +# 6, # density (star count) +# 1s # twinkle speed (slow twinkle) # ) # stars.priority = 15 # stars.opacity = smooth(255, 0, 30s) # Fade out during day diff --git a/lib/libesp32/berry_animation/anim_examples/compiled/twinkle_stars.be b/lib/libesp32/berry_animation/anim_examples/compiled/twinkle_stars.be index f36d381cf..aa9fd8ef7 100644 --- a/lib/libesp32/berry_animation/anim_examples/compiled/twinkle_stars.be +++ b/lib/libesp32/berry_animation/anim_examples/compiled/twinkle_stars.be @@ -12,22 +12,22 @@ # strip length 60 # # # Dark blue background -# color night_sky = #000033 +# color night_sky = 0x000033 # animation background = solid(night_sky) # # # White twinkling stars # animation stars = twinkle_animation( -# #FFFFFF, # White stars -# 8, # density (number of stars) -# 500ms # twinkle speed (twinkle duration) +# 0xFFFFFF, # White stars +# 8, # density (number of stars) +# 500ms # twinkle speed (twinkle duration) # ) # stars.priority = 10 # # # Add occasional bright flash # animation bright_flash = twinkle_animation( -# #FFFFAA, # Bright yellow-white -# 2, # density (fewer bright flashes) -# 300ms # twinkle speed (quick flash) +# 0xFFFFAA, # Bright yellow-white +# 2, # density (fewer bright flashes) +# 300ms # twinkle speed (quick flash) # ) # bright_flash.priority = 15 # diff --git a/lib/libesp32/berry_animation/anim_examples/disco_strobe.anim b/lib/libesp32/berry_animation/anim_examples/disco_strobe.anim index 1332baaa3..7217a44af 100644 --- a/lib/libesp32/berry_animation/anim_examples/disco_strobe.anim +++ b/lib/libesp32/berry_animation/anim_examples/disco_strobe.anim @@ -5,13 +5,13 @@ strip length 60 # Define disco color palette palette disco_colors = [ - (0, #FF0000), # Red - (42, #FF8000), # Orange - (85, #FFFF00), # Yellow - (128, #00FF00), # Green - (170, #0000FF), # Blue - (213, #8000FF), # Purple - (255, #FF00FF) # Magenta + (0, 0xFF0000), # Red + (42, 0xFF8000), # Orange + (85, 0xFFFF00), # Yellow + (128, 0x00FF00), # Green + (170, 0x0000FF), # Blue + (213, 0x8000FF), # Purple + (255, 0xFF00FF) # Magenta ] # Fast color cycling base @@ -21,7 +21,7 @@ animation disco_base = rich_palette_animation(disco_colors, 1s, linear, 255) disco_base.opacity = square(0, 255, 100ms, 30) # Fast strobe # Add white flash overlay -animation white_flash = solid(#FFFFFF) +animation white_flash = solid(0xFFFFFF) white_flash.opacity = square(0, 255, 50ms, 10) # Quick white flashes white_flash.priority = 20 diff --git a/lib/libesp32/berry_animation/anim_examples/fire_flicker.anim b/lib/libesp32/berry_animation/anim_examples/fire_flicker.anim index 1520f7fe5..6199b30c3 100644 --- a/lib/libesp32/berry_animation/anim_examples/fire_flicker.anim +++ b/lib/libesp32/berry_animation/anim_examples/fire_flicker.anim @@ -5,11 +5,11 @@ strip length 60 # Define fire palette from black to yellow palette fire_colors = [ - (0, #000000), # Black - (64, #800000), # Dark red - (128, #FF0000), # Red - (192, #FF4500), # Orange red - (255, #FFFF00) # Yellow + (0, 0x000000), # Black + (64, 0x800000), # Dark red + (128, 0xFF0000), # Red + (192, 0xFF4500), # Orange red + (255, 0xFFFF00) # Yellow ] # Create base fire animation with palette diff --git a/lib/libesp32/berry_animation/anim_examples/heartbeat_pulse.anim b/lib/libesp32/berry_animation/anim_examples/heartbeat_pulse.anim index b0e9b4e54..1f036db8d 100644 --- a/lib/libesp32/berry_animation/anim_examples/heartbeat_pulse.anim +++ b/lib/libesp32/berry_animation/anim_examples/heartbeat_pulse.anim @@ -4,32 +4,32 @@ strip length 60 # Dark background -color heart_bg = #110000 +color heart_bg = 0x110000 animation background = solid(heart_bg) # Define heartbeat timing - double pulse pattern # First pulse (stronger) -animation heartbeat1 = solid(#FF0000) # Bright red +animation heartbeat1 = solid(0xFF0000) # Bright red heartbeat1.opacity = square(0, 255, 150ms, 20) # Quick strong pulse heartbeat1.priority = 10 # Second pulse (weaker, slightly delayed) -animation heartbeat2 = solid(#CC0000) # Slightly dimmer red +animation heartbeat2 = solid(0xCC0000) # Slightly dimmer red # Delay the second pulse by adjusting the square wave phase heartbeat2.opacity = square(0, 180, 150ms, 15) # Weaker pulse heartbeat2.priority = 8 # Add subtle glow effect -animation heart_glow = solid(#660000) # Dim red glow +animation heart_glow = solid(0x660000) # Dim red glow heart_glow.opacity = smooth(30, 100, 1s) # Gentle breathing glow heart_glow.priority = 5 # Add center pulse for emphasis animation center_pulse = pulse_position_animation( - #FFFFFF, # White center - 30, # center of strip - 4, # small center - 2 # soft edges + 0xFFFFFF, # White center + 30, # center of strip + 4, # small center + 2 # soft edges ) center_pulse.priority = 20 center_pulse.opacity = square(0, 200, 100ms, 10) # Quick white flash diff --git a/lib/libesp32/berry_animation/anim_examples/lava_lamp.anim b/lib/libesp32/berry_animation/anim_examples/lava_lamp.anim index 69266248c..cc5af3902 100644 --- a/lib/libesp32/berry_animation/anim_examples/lava_lamp.anim +++ b/lib/libesp32/berry_animation/anim_examples/lava_lamp.anim @@ -5,11 +5,11 @@ strip length 60 # Define lava colors (warm oranges and reds) palette lava_colors = [ - (0, #330000), # Dark red - (64, #660000), # Medium red - (128, #CC3300), # Bright red - (192, #FF6600), # Orange - (255, #FFAA00) # Yellow-orange + (0, 0x330000), # Dark red + (64, 0x660000), # Medium red + (128, 0xCC3300), # Bright red + (192, 0xFF6600), # Orange + (255, 0xFFAA00) # Yellow-orange ] # Base lava animation - very slow color changes diff --git a/lib/libesp32/berry_animation/anim_examples/lightning_storm.anim b/lib/libesp32/berry_animation/anim_examples/lightning_storm.anim index bb8bc227a..54f5a0797 100644 --- a/lib/libesp32/berry_animation/anim_examples/lightning_storm.anim +++ b/lib/libesp32/berry_animation/anim_examples/lightning_storm.anim @@ -5,38 +5,38 @@ strip length 60 # Dark stormy background with subtle purple/blue palette storm_colors = [ - (0, #000011), # Very dark blue - (128, #110022), # Dark purple - (255, #220033) # Slightly lighter purple + (0, 0x000011), # Very dark blue + (128, 0x110022), # Dark purple + (255, 0x220033) # Slightly lighter purple ] animation storm_bg = rich_palette_animation(storm_colors, 12s, smooth, 100) # Random lightning flashes - full strip -animation lightning_main = solid(#FFFFFF) # Bright white +animation lightning_main = solid(0xFFFFFF) # Bright white lightning_main.opacity = square(0, 255, 80ms, 3) # Quick bright flashes lightning_main.priority = 20 # Secondary lightning - partial strip animation lightning_partial = pulse_position_animation( - #FFFFAA, # Slightly yellow white - 30, # center position - 20, # covers part of strip - 5 # soft edges + 0xFFFFAA, # Slightly yellow white + 30, # center position + 20, # covers part of strip + 5 # soft edges ) lightning_partial.priority = 15 lightning_partial.opacity = square(0, 200, 120ms, 4) # Different timing # Add blue afterglow -animation afterglow = solid(#4444FF) # Blue glow +animation afterglow = solid(0x4444FF) # Blue glow afterglow.opacity = square(0, 80, 200ms, 8) # Longer, dimmer glow afterglow.priority = 10 # Distant thunder (dim flashes) animation distant_flash = twinkle_animation( - #666699, # Dim blue-white - 4, # density (few flashes) - 300ms # twinkle speed (medium duration) + 0x666699, # Dim blue-white + 4, # density (few flashes) + 300ms # twinkle speed (medium duration) ) distant_flash.priority = 5 diff --git a/lib/libesp32/berry_animation/anim_examples/matrix_rain.anim b/lib/libesp32/berry_animation/anim_examples/matrix_rain.anim index a9c22f777..017804058 100644 --- a/lib/libesp32/berry_animation/anim_examples/matrix_rain.anim +++ b/lib/libesp32/berry_animation/anim_examples/matrix_rain.anim @@ -4,16 +4,16 @@ strip length 60 # Dark background -color matrix_bg = #000000 +color matrix_bg = 0x000000 animation background = solid(matrix_bg) # Define matrix green palette palette matrix_greens = [ - (0, #000000), # Black - (64, #003300), # Dark green - (128, #006600), # Medium green - (192, #00AA00), # Bright green - (255, #00FF00) # Neon green + (0, 0x000000), # Black + (64, 0x003300), # Dark green + (128, 0x006600), # Medium green + (192, 0x00AA00), # Bright green + (255, 0x00FF00) # Neon green ] # Create multiple cascading streams @@ -43,9 +43,9 @@ stream3.priority = 6 # Add random bright flashes (like code highlights) animation code_flash = twinkle_animation( - #00FFAA, # Bright cyan-green - 3, # density (few flashes) - 150ms # twinkle speed (quick flash) + 0x00FFAA, # Bright cyan-green + 3, # density (few flashes) + 150ms # twinkle speed (quick flash) ) code_flash.priority = 20 diff --git a/lib/libesp32/berry_animation/anim_examples/meteor_shower.anim b/lib/libesp32/berry_animation/anim_examples/meteor_shower.anim index 06503208a..5ea8c047b 100644 --- a/lib/libesp32/berry_animation/anim_examples/meteor_shower.anim +++ b/lib/libesp32/berry_animation/anim_examples/meteor_shower.anim @@ -4,51 +4,51 @@ strip length 60 # Dark space background -color space_bg = #000011 +color space_bg = 0x000011 animation background = solid(space_bg) # Multiple meteors with different speeds and colors animation meteor1 = comet_animation( - #FFFFFF, # Bright white - 12, # long trail - 1.5s # fast speed + 0xFFFFFF, # Bright white + 12, # long trail + 1.5s # fast speed ) meteor1.priority = 15 animation meteor2 = comet_animation( - #FFAA00, # Orange - 10, # medium trail - 2s # medium speed + 0xFFAA00, # Orange + 10, # medium trail + 2s # medium speed ) meteor2.priority = 12 animation meteor3 = comet_animation( - #AAAAFF, # Blue-white - 8, # shorter trail - 1.8s # fast speed + 0xAAAAFF, # Blue-white + 8, # shorter trail + 1.8s # fast speed ) meteor3.priority = 10 animation meteor4 = comet_animation( - #FFAAAA, # Pink-white - 14, # long trail - 2.5s # slower speed + 0xFFAAAA, # Pink-white + 14, # long trail + 2.5s # slower speed ) meteor4.priority = 8 # Add distant stars animation stars = twinkle_animation( - #CCCCCC, # Dim white - 12, # density (many stars) - 2s # twinkle speed (slow twinkle) + 0xCCCCCC, # Dim white + 12, # density (many stars) + 2s # twinkle speed (slow twinkle) ) stars.priority = 5 # Add occasional bright flash (meteor explosion) animation meteor_flash = twinkle_animation( - #FFFFFF, # Bright white - 1, # density (single flash) - 100ms # twinkle speed (very quick) + 0xFFFFFF, # Bright white + 1, # density (single flash) + 100ms # twinkle speed (very quick) ) meteor_flash.priority = 25 diff --git a/lib/libesp32/berry_animation/anim_examples/neon_glow.anim b/lib/libesp32/berry_animation/anim_examples/neon_glow.anim index 97685658e..c5ef60346 100644 --- a/lib/libesp32/berry_animation/anim_examples/neon_glow.anim +++ b/lib/libesp32/berry_animation/anim_examples/neon_glow.anim @@ -5,10 +5,10 @@ strip length 60 # Define neon colors palette neon_colors = [ - (0, #FF0080), # Hot pink - (85, #00FF80), # Neon green - (170, #8000FF), # Electric purple - (255, #FF8000) # Neon orange + (0, 0xFF0080), # Hot pink + (85, 0x00FF80), # Neon green + (170, 0x8000FF), # Electric purple + (255, 0xFF8000) # Neon orange ] # Main neon glow with color cycling @@ -18,7 +18,7 @@ animation neon_main = rich_palette_animation(neon_colors, 4s, linear, 255) neon_main.opacity = smooth(220, 255, 200ms) # Add occasional electrical surge -animation neon_surge = solid(#FFFFFF) # White surge +animation neon_surge = solid(0xFFFFFF) # White surge neon_surge.opacity = square(0, 255, 50ms, 2) # Quick bright surges neon_surge.priority = 20 @@ -50,9 +50,9 @@ segment3.priority = 10 # Add electrical arcing between segments animation arc_sparkles = twinkle_animation( - #AAAAFF, # Electric blue - 4, # density (few arcs) - 100ms # twinkle speed (quick arcs) + 0xAAAAFF, # Electric blue + 4, # density (few arcs) + 100ms # twinkle speed (quick arcs) ) arc_sparkles.priority = 15 diff --git a/lib/libesp32/berry_animation/anim_examples/ocean_waves.anim b/lib/libesp32/berry_animation/anim_examples/ocean_waves.anim index a95d5bcf1..b7c3553ae 100644 --- a/lib/libesp32/berry_animation/anim_examples/ocean_waves.anim +++ b/lib/libesp32/berry_animation/anim_examples/ocean_waves.anim @@ -5,11 +5,11 @@ strip length 60 # Define ocean color palette palette ocean_colors = [ - (0, #000080), # Deep blue - (64, #0040C0), # Ocean blue - (128, #0080FF), # Light blue - (192, #40C0FF), # Cyan - (255, #80FFFF) # Light cyan + (0, 0x000080), # Deep blue + (64, 0x0040C0), # Ocean blue + (128, 0x0080FF), # Light blue + (192, 0x40C0FF), # Cyan + (255, 0x80FFFF) # Light cyan ] # Base ocean animation with slow color cycling @@ -38,9 +38,9 @@ wave2.pos = sawtooth(52, 8, 7s) # Opposite direction # Add foam sparkles animation foam = twinkle_animation( - #FFFFFF, # White foam - 6, # density (sparkle count) - 300ms # twinkle speed (quick sparkles) + 0xFFFFFF, # White foam + 6, # density (sparkle count) + 300ms # twinkle speed (quick sparkles) ) foam.priority = 15 diff --git a/lib/libesp32/berry_animation/anim_examples/palette_demo.anim b/lib/libesp32/berry_animation/anim_examples/palette_demo.anim index d29e3d3ff..619aac56d 100644 --- a/lib/libesp32/berry_animation/anim_examples/palette_demo.anim +++ b/lib/libesp32/berry_animation/anim_examples/palette_demo.anim @@ -5,20 +5,20 @@ strip length 30 # Define a fire palette palette fire_colors = [ - (0, #000000), # Black - (64, #800000), # Dark red - (128, #FF0000), # Red - (192, #FF8000), # Orange - (255, #FFFF00) # Yellow + (0, 0x000000), # Black + (64, 0x800000), # Dark red + (128, 0xFF0000), # Red + (192, 0xFF8000), # Orange + (255, 0xFFFF00) # Yellow ] # Define an ocean palette palette ocean_colors = [ - (0, #000080), # Navy blue - (64, #0000FF), # Blue - (128, #00FFFF), # Cyan - (192, #00FF80), # Spring green - (255, #008000) # Green + (0, 0x000080), # Navy blue + (64, 0x0000FF), # Blue + (128, 0x00FFFF), # Cyan + (192, 0x00FF80), # Spring green + (255, 0x008000) # Green ] # Create animations using the palettes diff --git a/lib/libesp32/berry_animation/anim_examples/palette_showcase.anim b/lib/libesp32/berry_animation/anim_examples/palette_showcase.anim index e4ddeb430..7678b394c 100644 --- a/lib/libesp32/berry_animation/anim_examples/palette_showcase.anim +++ b/lib/libesp32/berry_animation/anim_examples/palette_showcase.anim @@ -5,15 +5,15 @@ strip length 60 # Example 1: Fire palette with hex colors palette fire_gradient = [ - (0, #000000), # Black (no fire) - (32, #330000), # Very dark red - (64, #660000), # Dark red - (96, #CC0000), # Red - (128, #FF3300), # Red-orange - (160, #FF6600), # Orange - (192, #FF9900), # Light orange - (224, #FFCC00), # Yellow-orange - (255, #FFFF00) # Bright yellow + (0, 0x000000), # Black (no fire) + (32, 0x330000), # Very dark red + (64, 0x660000), # Dark red + (96, 0xCC0000), # Red + (128, 0xFF3300), # Red-orange + (160, 0xFF6600), # Orange + (192, 0xFF9900), # Light orange + (224, 0xFFCC00), # Yellow-orange + (255, 0xFFFF00) # Bright yellow ] # Example 2: Ocean palette with named colors @@ -27,20 +27,20 @@ palette ocean_depths = [ # Example 3: Aurora palette (from the original example) palette aurora_borealis = [ - (0, #000022), # Dark night sky - (64, #004400), # Dark green - (128, #00AA44), # Aurora green - (192, #44AA88), # Light green - (255, #88FFAA) # Bright aurora + (0, 0x000022), # Dark night sky + (64, 0x004400), # Dark green + (128, 0x00AA44), # Aurora green + (192, 0x44AA88), # Light green + (255, 0x88FFAA) # Bright aurora ] # Example 4: Sunset palette mixing hex and named colors palette sunset_sky = [ - (0, #191970), # Midnight blue - (64, purple), # Purple twilight - (128, #FF69B4), # Hot pink - (192, orange), # Sunset orange - (255, yellow) # Sun + (0, 0x191970), # Midnight blue + (64, purple), # Purple twilight + (128, 0xFF69B4), # Hot pink + (192, orange), # Sunset orange + (255, yellow) # Sun ] # Create animations using each palette diff --git a/lib/libesp32/berry_animation/anim_examples/plasma_wave.anim b/lib/libesp32/berry_animation/anim_examples/plasma_wave.anim index 6ee1ab9d2..6c1ec0c2b 100644 --- a/lib/libesp32/berry_animation/anim_examples/plasma_wave.anim +++ b/lib/libesp32/berry_animation/anim_examples/plasma_wave.anim @@ -5,12 +5,12 @@ strip length 60 # Define plasma color palette with smooth transitions palette plasma_colors = [ - (0, #FF0080), # Magenta - (51, #FF8000), # Orange - (102, #FFFF00), # Yellow - (153, #80FF00), # Yellow-green - (204, #00FF80), # Cyan-green - (255, #0080FF) # Blue + (0, 0xFF0080), # Magenta + (51, 0xFF8000), # Orange + (102, 0xFFFF00), # Yellow + (153, 0x80FF00), # Yellow-green + (204, 0x00FF80), # Cyan-green + (255, 0x0080FF) # Blue ] # Base plasma animation with medium speed diff --git a/lib/libesp32/berry_animation/anim_examples/police_lights.anim b/lib/libesp32/berry_animation/anim_examples/police_lights.anim index fd4075c97..806ada2c5 100644 --- a/lib/libesp32/berry_animation/anim_examples/police_lights.anim +++ b/lib/libesp32/berry_animation/anim_examples/police_lights.anim @@ -8,26 +8,26 @@ set half_length = 30 # Left side red flashing animation left_red = pulse_position_animation( - #FF0000, # Bright red - 15, # center of left half - 15, # half the strip - 2 # sharp edges + 0xFF0000, # Bright red + 15, # center of left half + 15, # half the strip + 2 # sharp edges ) left_red.priority = 10 left_red.opacity = square(0, 255, 400ms, 50) # 50% duty cycle # Right side blue flashing (opposite phase) animation right_blue = pulse_position_animation( - #0000FF, # Bright blue - 45, # center of right half - 15, # half the strip - 2 # sharp edges + 0x0000FF, # Bright blue + 45, # center of right half + 15, # half the strip + 2 # sharp edges ) right_blue.priority = 10 right_blue.opacity = square(255, 0, 400ms, 50) # Opposite phase # Add white strobe overlay occasionally -animation white_strobe = solid(#FFFFFF) +animation white_strobe = solid(0xFFFFFF) white_strobe.opacity = square(0, 255, 100ms, 5) # Quick bright flashes white_strobe.priority = 20 diff --git a/lib/libesp32/berry_animation/anim_examples/property_assignment_demo.anim b/lib/libesp32/berry_animation/anim_examples/property_assignment_demo.anim index 6c6740f19..45f7f590c 100644 --- a/lib/libesp32/berry_animation/anim_examples/property_assignment_demo.anim +++ b/lib/libesp32/berry_animation/anim_examples/property_assignment_demo.anim @@ -4,9 +4,9 @@ strip length 60 # Define colors -color red_custom = #FF0000 -color blue_custom = #0000FF -color green_custom = #00FF00 +color red_custom = 0xFF0000 +color blue_custom = 0x0000FF +color green_custom = 0x00FF00 # Create animations animation left_pulse = pulse_position_animation(red_custom, 15, 15, 3) diff --git a/lib/libesp32/berry_animation/anim_examples/rainbow_cycle.anim b/lib/libesp32/berry_animation/anim_examples/rainbow_cycle.anim index 49c7721f9..285e0f6c1 100644 --- a/lib/libesp32/berry_animation/anim_examples/rainbow_cycle.anim +++ b/lib/libesp32/berry_animation/anim_examples/rainbow_cycle.anim @@ -5,7 +5,7 @@ strip length 60 # Create smooth rainbow cycle animation animation rainbow_cycle = color_cycle_animation( - [#FF0000, #FF8000, #FFFF00, #00FF00, #0000FF, #8000FF, #FF00FF], # rainbow colors + [0xFF0000, 0xFF8000, 0xFFFF00, 0x00FF00, 0x0000FF, 0x8000FF, 0xFF00FF], # rainbow colors 5s # cycle period ) diff --git a/lib/libesp32/berry_animation/anim_examples/scanner_larson.anim b/lib/libesp32/berry_animation/anim_examples/scanner_larson.anim index f7f1f1a9e..37b50adb7 100644 --- a/lib/libesp32/berry_animation/anim_examples/scanner_larson.anim +++ b/lib/libesp32/berry_animation/anim_examples/scanner_larson.anim @@ -4,15 +4,15 @@ strip length 60 # Dark background -color scanner_bg = #110000 +color scanner_bg = 0x110000 animation background = solid(scanner_bg) # Main scanner pulse that bounces animation scanner = pulse_position_animation( - #FF0000, # Bright red - 2, # initial position - 3, # pulse width - 2 # fade region + 0xFF0000, # Bright red + 2, # initial position + 3, # pulse width + 2 # fade region ) scanner.priority = 10 @@ -21,10 +21,10 @@ scanner.pos = triangle(2, 57, 2s) # Add trailing glow effect animation scanner_trail = pulse_position_animation( - #660000, # Dim red trail - 2, # initial position - 6, # wider trail - 4 # more fade + 0x660000, # Dim red trail + 2, # initial position + 6, # wider trail + 4 # more fade ) scanner_trail.priority = 5 scanner_trail.pos = triangle(2, 57, 2s) diff --git a/lib/libesp32/berry_animation/anim_examples/sunrise_sunset.anim b/lib/libesp32/berry_animation/anim_examples/sunrise_sunset.anim index 0308f7d85..73a346c46 100644 --- a/lib/libesp32/berry_animation/anim_examples/sunrise_sunset.anim +++ b/lib/libesp32/berry_animation/anim_examples/sunrise_sunset.anim @@ -5,15 +5,15 @@ strip length 60 # Define time-of-day color palette palette daylight_colors = [ - (0, #000011), # Night - dark blue - (32, #001133), # Pre-dawn - (64, #FF4400), # Sunrise orange - (96, #FFAA00), # Morning yellow - (128, #FFFF88), # Midday bright - (160, #FFAA44), # Afternoon - (192, #FF6600), # Sunset orange - (224, #AA2200), # Dusk red - (255, #220011) # Night - dark red + (0, 0x000011), # Night - dark blue + (32, 0x001133), # Pre-dawn + (64, 0xFF4400), # Sunrise orange + (96, 0xFFAA00), # Morning yellow + (128, 0xFFFF88), # Midday bright + (160, 0xFFAA44), # Afternoon + (192, 0xFF6600), # Sunset orange + (224, 0xAA2200), # Dusk red + (255, 0x220011) # Night - dark red ] # Main daylight cycle - very slow transition @@ -21,10 +21,10 @@ animation daylight_cycle = rich_palette_animation(daylight_colors, 60s) # Add sun position effect - bright spot that moves animation sun_position = pulse_position_animation( - #FFFFAA, # Bright yellow sun - 5, # initial position - 8, # sun size - 4 # soft glow + 0xFFFFAA, # Bright yellow sun + 5, # initial position + 8, # sun size + 4 # soft glow ) sun_position.priority = 10 sun_position.pos = smooth(5, 55, 30s) # Sun arc across sky @@ -32,10 +32,10 @@ sun_position.opacity = smooth(0, 255, 30s) # Fade in and out # Add atmospheric glow around sun animation sun_glow = pulse_position_animation( - #FFCC88, # Warm glow - 5, # initial position - 16, # larger glow - 8 # very soft + 0xFFCC88, # Warm glow + 5, # initial position + 16, # larger glow + 8 # very soft ) sun_glow.priority = 5 sun_glow.pos = smooth(5, 55, 30s) # Follow sun @@ -43,9 +43,9 @@ sun_glow.opacity = smooth(0, 150, 30s) # Dimmer glow # Add twinkling stars during night phases animation stars = twinkle_animation( - #FFFFFF, # White stars - 6, # density (star count) - 1s # twinkle speed (slow twinkle) + 0xFFFFFF, # White stars + 6, # density (star count) + 1s # twinkle speed (slow twinkle) ) stars.priority = 15 stars.opacity = smooth(255, 0, 30s) # Fade out during day diff --git a/lib/libesp32/berry_animation/anim_examples/twinkle_stars.anim b/lib/libesp32/berry_animation/anim_examples/twinkle_stars.anim index 79d4ca161..a69ea5d41 100644 --- a/lib/libesp32/berry_animation/anim_examples/twinkle_stars.anim +++ b/lib/libesp32/berry_animation/anim_examples/twinkle_stars.anim @@ -4,22 +4,22 @@ strip length 60 # Dark blue background -color night_sky = #000033 +color night_sky = 0x000033 animation background = solid(night_sky) # White twinkling stars animation stars = twinkle_animation( - #FFFFFF, # White stars - 8, # density (number of stars) - 500ms # twinkle speed (twinkle duration) + 0xFFFFFF, # White stars + 8, # density (number of stars) + 500ms # twinkle speed (twinkle duration) ) stars.priority = 10 # Add occasional bright flash animation bright_flash = twinkle_animation( - #FFFFAA, # Bright yellow-white - 2, # density (fewer bright flashes) - 300ms # twinkle speed (quick flash) + 0xFFFFAA, # Bright yellow-white + 2, # density (fewer bright flashes) + 300ms # twinkle speed (quick flash) ) bright_flash.priority = 15 diff --git a/lib/libesp32/berry_animation/docs/API_REFERENCE.md b/lib/libesp32/berry_animation/docs/API_REFERENCE.md index 1bafb54e1..d377a130a 100644 --- a/lib/libesp32/berry_animation/docs/API_REFERENCE.md +++ b/lib/libesp32/berry_animation/docs/API_REFERENCE.md @@ -104,12 +104,13 @@ Adds temporal behavior to patterns. **`animation.solid(color, priority=0, duration=0, loop=false, opacity=255, name="")`** - Creates solid color animation -- **color**: ARGB color value (0xAARRGGBB) +- **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="")`** @@ -126,12 +127,13 @@ 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 +- **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 @@ -152,48 +154,53 @@ var rainbow = animation.rich_palette_animation(animation.PALETTE_RAINBOW, 5000, **`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 -- **pos**: Pixel position (0-based) -- **pulse_size**: Width of pulse in pixels -- **slew_size**: Fade region size in pixels +- **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 +- **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 +- **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(intensity=200, speed_ms=100, priority=0, duration=0, loop=false, opacity=255, name="")`** +**`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(180, 150) +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 @@ -208,11 +215,12 @@ var fire = animation.fire_animation(180, 150) **`animation.noise_single_color(color, scale, speed, strip_length, priority)`** - Creates single-color noise pattern -- **color**: ARGB color value +- **color**: ARGB color value or ValueProvider instance - Returns: `NoiseAnimation` instance -**`animation.noise_fractal(color_source, scale, speed, octaves, strip_length, priority)`** +**`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 @@ -229,7 +237,7 @@ var fractal = animation.noise_fractal(nil, 40, 50, 3, 30, 10) **`animation.plasma_single_color(color, time_speed, strip_length, priority)`** - Creates single-color plasma effect -- **color**: ARGB color value +- **color**: ARGB color value or ValueProvider instance - Returns: `PlasmaAnimation` instance ```berry @@ -245,7 +253,7 @@ var purple_plasma = animation.plasma_single_color(0xFF8800FF, 60, 30, 10) **`animation.sparkle_colored(color, density, fade_speed, strip_length, priority)`** - Creates colored sparkles -- **color**: ARGB color value +- **color**: ARGB color value or ValueProvider instance - Returns: `SparkleAnimation` instance **`animation.sparkle_rainbow(density, fade_speed, strip_length, priority)`** @@ -266,11 +274,12 @@ var rainbow_sparkles = animation.sparkle_rainbow(60, 40, 30, 10) **`animation.wave_single_sine(color, amplitude, wave_speed, strip_length, priority)`** - Creates single-color sine wave -- **color**: ARGB color value +- **color**: ARGB color value or ValueProvider instance - Returns: `WaveAnimation` instance -**`animation.wave_custom(color_source, wave_type, amplitude, frequency, strip_length, priority)`** +**`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 @@ -447,11 +456,19 @@ var static_position = 15 - Returns: `OscillatorValueProvider` **`animation.linear(start, end, period_ms)`** -- Triangle wave oscillation +- 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 +- 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)`** diff --git a/lib/libesp32/berry_animation/docs/PROJECT_STRUCTURE.md b/lib/libesp32/berry_animation/docs/PROJECT_STRUCTURE.md index b4bb24989..31d9a6b88 100644 --- a/lib/libesp32/berry_animation/docs/PROJECT_STRUCTURE.md +++ b/lib/libesp32/berry_animation/docs/PROJECT_STRUCTURE.md @@ -9,7 +9,7 @@ This document explains the organization of the Tasmota Berry Animation Framework ├── docs/ # User documentation ├── lib/libesp32/berry_animation/ # Framework source code ├── anim_examples/ # DSL animation examples (.anim files) -├── compiled/ # Compiled Berry code from DSL examples +├── anim_examples/compiled/ # Compiled Berry code from DSL examples ├── .kiro/ # Project specifications and design docs └── .docs_archive/ # Archived technical implementation docs ``` @@ -113,12 +113,12 @@ anim_examples/ └── simple_pulse.anim # Basic pulsing effect ``` -## Compiled Examples (`compiled/`) +## Compiled Examples (`anim_examples/compiled/`) Berry code generated from DSL examples (for reference): ``` -compiled/ +anim_examples/compiled/ ├── aurora_borealis.be # Compiled from aurora_borealis.anim ├── breathing_colors.be # Compiled from breathing_colors.anim └── ... (compiled versions of .anim files) @@ -200,7 +200,7 @@ Technical implementation documents moved from active documentation: ### DSL Files - **`*.anim`** - DSL animation files -- **`*.be`** (in compiled/) - Compiled Berry code from DSL +- **`*.be`** (in anim_examples/compiled/) - Compiled Berry code from DSL ## Navigation Tips diff --git a/lib/libesp32/berry_animation/src/dsl/lexer.be b/lib/libesp32/berry_animation/src/dsl/lexer.be index 58bbf6312..b027a3410 100644 --- a/lib/libesp32/berry_animation/src/dsl/lexer.be +++ b/lib/libesp32/berry_animation/src/dsl/lexer.be @@ -58,7 +58,9 @@ class DSLLexer self.column = 1 return elif ch == '#' - self.scan_comment_or_color() + self.scan_comment() + elif ch == '0' && self.peek() == 'x' + self.scan_hex_color_0x() elif self.is_alpha(ch) || ch == '_' self.scan_identifier_or_keyword() elif self.is_digit(ch) @@ -72,30 +74,27 @@ class DSLLexer end end - # Scan comment or hex color (both start with #) - def scan_comment_or_color() + # Scan comment (now unambiguous - only starts with #) + def scan_comment() var start_pos = self.position - 1 var start_column = self.column - 1 - # Look ahead to see if this is a hex color - if self.position < size(self.source) && self.is_hex_digit(self.source[self.position]) - # This is a hex color - self.scan_hex_color() - else - # This is a comment - consume until end of line - while !self.at_end() && self.peek() != '\n' - self.advance() - end - - var comment_text = self.source[start_pos..self.position-1] - self.add_token(37 #-animation.Token.COMMENT-#, comment_text, self.position - start_pos) + # This is a comment - consume until end of line + while !self.at_end() && self.peek() != '\n' + self.advance() end + + var comment_text = self.source[start_pos..self.position-1] + self.add_token(37 #-animation.Token.COMMENT-#, comment_text, self.position - start_pos) end - # Scan hex color (#RRGGBB, #RGB, #AARRGGBB, or #ARGB) - def scan_hex_color() - var start_pos = self.position - 1 # Include the # + # Scan hex color (0xRRGGBB, 0xAARRGGBB) + def scan_hex_color_0x() + var start_pos = self.position - 1 # Include the '0' var start_column = self.column - 1 + + # Advance past 'x' + self.advance() var hex_digits = 0 # Count hex digits @@ -106,11 +105,11 @@ class DSLLexer var color_value = self.source[start_pos..self.position-1] - # Validate hex color format - support alpha channel - if hex_digits == 3 || hex_digits == 4 || hex_digits == 6 || hex_digits == 8 + # Validate hex color format - support 6 (RGB) or 8 (ARGB) digits + if hex_digits == 6 || hex_digits == 8 self.add_token(4 #-animation.Token.COLOR-#, color_value, size(color_value)) else - self.add_error("Invalid hex color format: " + color_value) + self.add_error("Invalid hex color format: " + color_value + " (expected 0xRRGGBB or 0xAARRGGBB)") self.add_token(39 #-animation.Token.ERROR-#, color_value, size(color_value)) end end diff --git a/lib/libesp32/berry_animation/src/dsl/transpiler.be b/lib/libesp32/berry_animation/src/dsl/transpiler.be index bd6dca499..fd4171207 100644 --- a/lib/libesp32/berry_animation/src/dsl/transpiler.be +++ b/lib/libesp32/berry_animation/src/dsl/transpiler.be @@ -870,7 +870,16 @@ class SimpleDSLTranspiler # Conversion helpers def convert_color(color_str) import string - # Handle hex colors + # Handle 0x hex colors (new format) + if string.startswith(color_str, "0x") + if size(color_str) == 10 # 0xAARRGGBB (with alpha channel) + return color_str + elif size(color_str) == 8 # 0xRRGGBB (without alpha channel - add opaque alpha) + return f"0xFF{color_str[2..]}" + end + end + + # Handle legacy # hex colors (for backward compatibility during transition) if string.startswith(color_str, "#") if size(color_str) == 9 # #AARRGGBB (with alpha channel) return f"0x{color_str[1..]}" diff --git a/lib/libesp32/berry_animation/src/examples/PORTED_EXAMPLES_README.md b/lib/libesp32/berry_animation/src/examples/PORTED_EXAMPLES_README.md deleted file mode 100644 index ba138c03d..000000000 --- a/lib/libesp32/berry_animation/src/examples/PORTED_EXAMPLES_README.md +++ /dev/null @@ -1,170 +0,0 @@ -# Ported Examples - Legacy to Modern Animation Framework - -This directory contains examples that demonstrate the evolution from the legacy `animate` module to the modern Berry Animation Framework. Each example is provided in three versions to show different approaches and capabilities. - -## Overview - -The examples are organized into three categories: - -- **Option A: Direct 1:1 Ports** (`ported/`) - Exact functionality using new framework -- **Option B: Enhanced Modern Versions** (`enhanced/`) - Improved versions showcasing new capabilities -- **Option C: DSL-Based Ports** (`dsl/`) - Declarative syntax versions - -## Example Categories - -### 1. Breathing Effect Examples - -**Original**: `berry_animate_examples/animate_demo_breathe.be` -- Used old `animate.core()`, `animate.pulse()`, `animate.palette()`, `animate.oscillator()` -- Complex callback-based architecture -- ~25 lines of setup code - -**Ported Versions**: -- **A**: `ported/breathe_demo_ported.be` - Direct port using `BreatheAnimation` + `RichPaletteColorProvider` -- **B**: `enhanced/modern_breathe_showcase.be` - Multi-layer breathing with events and dynamic parameters -- **C**: `dsl/breathe_demo.anim` - Clean DSL syntax (~15 lines) - -### 2. Palette Background Examples - -**Original**: `berry_animate_examples/animate_demo_palette_background.be` -- Used old `animate.core()` with `add_background_animator()` -- Simple rainbow cycling background - -**Ported Versions**: -- **A**: `ported/palette_background_demo_ported.be` - Direct port using `FilledAnimation` + rainbow palette -- **B**: `enhanced/advanced_palette_demo.be` - Multiple palettes with layering and mode switching -- **C**: `dsl/palette_background_demo.anim` - Minimal DSL syntax - -### 3. Pulse Effect Examples - -**Original**: `berry_animate_examples/animate_demo_pulse.be` -- Used old `animate.core()`, `animate.pulse()`, `animate.oscillator()`, `animate.palette()` -- Moving pulse with oscillating position and cycling color - -**Ported Versions**: -- **A**: `ported/pulse_demo_ported.be` - Direct port using `PulsePositionAnimation` + `OscillatorValueProvider` -- **B**: `enhanced/dynamic_pulse_demo.be` - Multiple pulse types with interactive control -- **C**: `dsl/pulse_demo.anim` - Declarative pulse definition - -### 4. Blending Examples - -**Original**: `berry_animate_examples/leds_blend_demo.be` -- Used old `animate.frame()` with manual blending -- Low-level frame buffer operations - -**Ported Versions**: -- **A**: `ported/blend_demo_ported.be` - Direct port using new `FrameBuffer` blending -- **B**: `enhanced/comprehensive_blend_demo.be` - Advanced multi-layer blending with interactive control -- **C**: DSL blending is handled automatically by the animation engine - -## Key Improvements in New Framework - -### Code Simplicity -- **Legacy**: Complex callback chains and manual object management -- **Modern**: Clean object-oriented design with value providers -- **DSL**: Declarative syntax that's easy to read and modify - -### Performance -- **Legacy**: Multiple separate objects with manual coordination -- **Modern**: Unified engine with optimized rendering pipeline -- **DSL**: Compiled to optimized Berry code - -### Capabilities -- **Legacy**: Basic effects with manual parameter control -- **Modern**: Advanced layering, blending, dynamic parameters, event system -- **DSL**: Full framework capabilities with simple syntax - -### Maintainability -- **Legacy**: Tightly coupled code, hard to modify -- **Modern**: Modular design, easy to extend -- **DSL**: Configuration-based, non-programmers can create animations - -## Running the Examples - -### Direct Ports (Option A) -```berry -# Run individual ported examples -load("lib/libesp32/berry_animation/examples/ported/breathe_demo_ported.be") -load("lib/libesp32/berry_animation/examples/ported/palette_background_demo_ported.be") -load("lib/libesp32/berry_animation/examples/ported/pulse_demo_ported.be") -load("lib/libesp32/berry_animation/examples/ported/blend_demo_ported.be") -``` - -### Enhanced Versions (Option B) -```berry -# Run enhanced examples with advanced features -load("lib/libesp32/berry_animation/examples/enhanced/modern_breathe_showcase.be") -load("lib/libesp32/berry_animation/examples/enhanced/advanced_palette_demo.be") -load("lib/libesp32/berry_animation/examples/enhanced/dynamic_pulse_demo.be") -load("lib/libesp32/berry_animation/examples/enhanced/comprehensive_blend_demo.be") -``` - -### DSL Versions (Option C) -```berry -# Run DSL examples using the demo runner -load("lib/libesp32/berry_animation/examples/dsl/run_dsl_demo.be") -# Edit the demo_file variable in run_dsl_demo.be to try different DSL files -``` - -## Interactive Features - -Many enhanced examples include interactive event systems. You can trigger events from the Berry console: - -```berry -# Speed up animations -animation.trigger_event("speed_up", {}) - -# Toggle layers -animation.trigger_event("toggle_layer", {"layer": "rainbow_comet"}) - -# Switch modes -animation.trigger_event("mode_switch", {}) - -# Adjust opacity -animation.trigger_event("adjust_opacity", {"layer": "all", "opacity": 100}) -``` - -## Educational Value - -These examples demonstrate: - -1. **Migration Path**: How to convert legacy code to the new framework -2. **Architecture Evolution**: From callback-based to object-oriented to declarative -3. **Feature Progression**: Basic effects → Advanced layering → Simple DSL syntax -4. **Best Practices**: Modern Berry coding patterns and animation techniques -5. **Framework Capabilities**: Full range of new framework features - -## File Structure - -``` -examples/ -├── ported/ # Direct 1:1 ports (Option A) -│ ├── breathe_demo_ported.be -│ ├── palette_background_demo_ported.be -│ ├── pulse_demo_ported.be -│ └── blend_demo_ported.be -├── enhanced/ # Enhanced modern versions (Option B) -│ ├── modern_breathe_showcase.be -│ ├── advanced_palette_demo.be -│ ├── dynamic_pulse_demo.be -│ └── comprehensive_blend_demo.be -├── dsl/ # DSL-based ports (Option C) -│ ├── breathe_demo.anim -│ ├── palette_background_demo.anim -│ ├── pulse_demo.anim -│ ├── enhanced_breathe_showcase.anim -│ ├── advanced_palette_showcase.anim -│ ├── dynamic_pulse_showcase.anim -│ └── run_dsl_demo.be # DSL runner utility -└── PORTED_EXAMPLES_README.md # This file -``` - -## Next Steps - -1. Try running each version to see the visual differences -2. Compare the code complexity between versions -3. Experiment with the interactive features in enhanced versions -4. Create your own DSL animations using the examples as templates -5. Use the ported examples as a reference for migrating your own legacy animations - -The progression from legacy → modern → DSL demonstrates the evolution of the animation framework and provides multiple approaches for different use cases and skill levels. \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/all_easing_demo.be b/lib/libesp32/berry_animation/src/examples/all_easing_demo.be deleted file mode 100644 index c2f48fba2..000000000 --- a/lib/libesp32/berry_animation/src/examples/all_easing_demo.be +++ /dev/null @@ -1,123 +0,0 @@ -# Comprehensive demo of all easing types in OscillatorValueProvider -# -# This demo shows all available easing waveforms: -# EASE_IN, EASE_OUT, ELASTIC, and BOUNCE - -import global -import tasmota - -# Mock tasmota functions for testing -if !global.contains("tasmota") - tasmota = {} - tasmota.millis = def() return 1000 end - tasmota.scale_uint = def(value, from_min, from_max, to_min, to_max) - if from_max == from_min return to_min end - return to_min + ((value - from_min) * (to_max - to_min)) / (from_max - from_min) - end - tasmota.sine_int = def(angle) - import math - return int(4096 * math.sin(angle * math.pi / 16384)) - end -end - -# Load just the oscillator provider -import "providers/oscillator_value_provider.be" as osc_provider - -print("=== Complete Easing Types Demo ===") -print("Showing all available easing waveforms (0->100 over 1000ms)") - -# Create all easing types -var ease_in = osc_provider.ease_in(0, 100, 1000) -var ease_out = osc_provider.ease_out(0, 100, 1000) -var elastic = osc_provider.elastic(0, 100, 1000) -var bounce = osc_provider.bounce(0, 100, 1000) -var linear = osc_provider.linear(0, 100, 1000) # For comparison - -print("\nTime% Linear Ease-In Ease-Out Elastic Bounce") -print("---- ------ ------- -------- ------- ------") - -var start_time = 1000 -for i: [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000] - var percent = i / 10 # Convert to percentage - var linear_val = linear.get_value(start_time + i) - var ease_in_val = ease_in.get_value(start_time + i) - var ease_out_val = ease_out.get_value(start_time + i) - var elastic_val = elastic.get_value(start_time + i) - var bounce_val = bounce.get_value(start_time + i) - - print(f"{percent:3.0f}% {linear_val:6d} {ease_in_val:7d} {ease_out_val:8d} {elastic_val:7d} {bounce_val:6d}") -end - -print("\n=== Easing Type Characteristics ===") - -print("\n1. EASE_IN (Quadratic Acceleration)") -print(" • Starts slow, accelerates") -print(" • Formula: f(t) = t²") -print(" • Use: Smooth start-up animations") -print(" • Constructor: animation.ease_in(start, end, duration)") - -print("\n2. EASE_OUT (Quadratic Deceleration)") -print(" • Starts fast, decelerates") -print(" • Formula: f(t) = 1 - (1-t)²") -print(" • Use: Smooth stop animations") -print(" • Constructor: animation.ease_out(start, end, duration)") - -print("\n3. ELASTIC (Spring-like)") -print(" • Overshoots and oscillates like a spring") -print(" • Shows spring-back behavior") -print(" • Use: Playful, attention-grabbing effects") -print(" • Constructor: animation.elastic(start, end, duration)") - -print("\n4. BOUNCE (Ball-like)") -print(" • Bounces like a ball with decreasing amplitude") -print(" • Multiple bounces that settle") -print(" • Use: Drop animations, impact effects") -print(" • Constructor: animation.bounce(start, end, duration)") - -print("\n=== Usage Examples ===") - -print("\n# Smooth brightness fade-in") -print("var brightness = animation.ease_in(0, 255, 3000)") -print("var fade_anim = animation.filled(0xFF0000FF, brightness, 0, false, 'fade')") - -print("\n# Gentle position movement") -print("var position = animation.ease_out(0, 29, 2000)") -print("var move_anim = animation.pulse_position(0xFF00FF00, 5, position, 1, 10, 0, true, 'move')") - -print("\n# Playful spring effect") -print("var spring_size = animation.elastic(1, 10, 2500)") -print("var spring_anim = animation.pulse(0xFFFF0000, spring_size, 0, 0, true, 'spring')") - -print("\n# Bouncing comet") -print("var bounce_pos = animation.bounce(0, 29, 3000)") -print("var comet_anim = animation.comet(0xFF00FFFF, bounce_pos, 8, 200, true, 'bouncy')") - -print("\n# DSL Integration") -print("# animation smooth_pulse = pulse(red, ease_in(50, 255, 2s), 0, 0)") -print("# animation spring_move = comet(blue, elastic(0, 29, 3s), 5, 128)") -print("# animation bouncy_breathe = breathe(green, bounce(30, 255, 4s), 8000)") - -print("\n=== Advanced Features ===") - -print("\n• All easing types support phase shifts:") -var phased_elastic = osc_provider.elastic(0, 100, 2000) -phased_elastic.set_phase(25) -print(f" Elastic with 25% phase: {phased_elastic}") - -print("\n• Method chaining works with all types:") -var chained = osc_provider.bounce(10, 90, 3000).set_phase(10) -print(f" Chained bounce: {chained}") - -print("\n• All types work with any value range:") -print(" animation.elastic(-50, 150, 2000) # Negative to positive") -print(" animation.bounce(100, 105, 1000) # Small range") -print(" animation.ease_in(1000, 0, 3000) # Reverse direction") - -print("\n=== Performance Notes ===") -print("• All calculations use integer arithmetic") -print("• Uses tasmota.scale_uint for efficient scaling") -print("• Minimal memory overhead") -print("• Suitable for embedded systems") - -print("\n=== Demo Complete ===") -print("All easing types are now available in the Berry Animation Framework!") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/animation_engine_demo.be b/lib/libesp32/berry_animation/src/examples/animation_engine_demo.be deleted file mode 100644 index 9cdae994d..000000000 --- a/lib/libesp32/berry_animation/src/examples/animation_engine_demo.be +++ /dev/null @@ -1,311 +0,0 @@ -# Animation Engine Demo -# -# This example demonstrates how to use the unified AnimationEngine -# to manage animations for an LED strip. - -# Import the animation module -import animation -import math -import tasmota -import global - -# Create a mock WS2812 class for testing -class WS2812 - var length_value - var pixels - var show_called - var can_show_result - - def init(length) - self.length_value = length - self.pixels = {} - self.show_called = false - self.can_show_result = true - end - - def length() - return self.length_value - end - - def set_pixel_color(index, r, g, b) - self.pixels[index] = { - "r": r, - "g": g, - "b": b - } - end - - def show() - self.show_called = true - end - - def can_show() - return self.can_show_result - end -end - -# Create a simple animation that pulses a color -class PulseAnimation : animation.animation - var color - var min_brightness - var max_brightness - - def init(color, min_brightness, max_brightness, duration) - # Initialize with priority 1, specified duration, and looping enabled - super(self).init(1, duration, true, "pulse") - - # Store parameters - self.color = color - self.min_brightness = min_brightness - self.max_brightness = max_brightness - - # Register parameters with validation - self.register_param("color", {"default": 0xFF0000}) # Default to red - self.register_param("min_brightness", {"min": 0, "max": 100, "default": 10}) - self.register_param("max_brightness", {"min": 0, "max": 100, "default": 100}) - - # Set initial values - self.set_param("color", color) - self.set_param("min_brightness", min_brightness) - self.set_param("max_brightness", max_brightness) - end - - def render(frame) - if !self.is_running || frame == nil - return false - end - - # Calculate current brightness based on progress - var progress = self.get_progress() - - # Convert progress to 0.0-1.0 range and use sine wave for smooth pulsing (0 to 1 to 0) - var progress_float = progress / 255.0 - var brightness_factor = math.sin(progress_float * math.pi) - - # Scale brightness between min and max - var brightness_range = self.max_brightness - self.min_brightness - var brightness = self.min_brightness + (brightness_factor * brightness_range) - - # Extract color components - var r = self.color & 0xFF - var g = (self.color >> 8) & 0xFF - var b = (self.color >> 16) & 0xFF - - # Apply brightness - r = tasmota.scale_uint(r, 0, 255, 0, tasmota.scale_uint(brightness, 0, 100, 0, 255)) - g = tasmota.scale_uint(g, 0, 255, 0, tasmota.scale_uint(brightness, 0, 100, 0, 255)) - b = tasmota.scale_uint(b, 0, 255, 0, tasmota.scale_uint(brightness, 0, 100, 0, 255)) - - # Fill the frame with the color at the calculated brightness - frame.fill_pixels(animation.frame_buffer.to_color(r, g, b, 255)) - - return true - end - - def on_param_changed(name, value) - if name == "color" - self.color = value - elif name == "min_brightness" - self.min_brightness = value - elif name == "max_brightness" - self.max_brightness = value - end - end -end - -# Create a simple animation that moves a dot across the strip -class MovingDotAnimation : animation.animation - var color - var background_color - var dot_size - var direction - var position - - def init(color, background_color, dot_size, duration) - # Initialize with priority 2, specified duration, and looping enabled - super(self).init(2, duration, true, "moving_dot") - - # Store parameters - self.color = color - self.background_color = background_color - self.dot_size = dot_size - self.direction = 1 # 1 for right, -1 for left - self.position = 0 - - # Register parameters - self.register_param("color", {"default": 0xFFFFFF}) # Default to white - self.register_param("background_color", {"default": 0x000000}) # Default to black - self.register_param("dot_size", {"min": 1, "default": 3}) - self.register_param("direction", {"enum": [1, -1], "default": 1}) - - # Set initial values - self.set_param("color", color) - self.set_param("background_color", background_color) - self.set_param("dot_size", dot_size) - self.set_param("direction", self.direction) - end - - def render(frame) - if !self.is_running || frame == nil - return false - end - - # Calculate current position based on progress - var progress = self.get_progress() - var width = frame.width - - # Calculate position (0 to width-1) - convert progress from 0-255 to 0.0-1.0 range - var progress_float = progress / 255.0 - self.position = int(progress_float * width) - - # Fill background - frame.fill_pixels(animation.frame_buffer.to_color( - self.background_color & 0xFF, - (self.background_color >> 8) & 0xFF, - (self.background_color >> 16) & 0xFF, - 255 - )) - - # Draw dot - var half_size = self.dot_size / 2 - var start_pos = self.position - half_size - var end_pos = self.position + half_size - - # Ensure dot is within bounds - if start_pos < 0 - start_pos = 0 - end - if end_pos >= width - end_pos = width - 1 - end - - # Draw the dot - for i: start_pos..end_pos - frame.set_pixel_color(i, - animation.frame_buffer.to_color( - self.color & 0xFF, - (self.color >> 8) & 0xFF, - (self.color >> 16) & 0xFF - ) - ) - end - - return true - end - - def on_param_changed(name, value) - if name == "color" - self.color = value - elif name == "background_color" - self.background_color = value - elif name == "dot_size" - self.dot_size = value - elif name == "direction" - self.direction = value - end - end -end - -# Main demo function -def run_demo() - # Create a WS2812 LED strip (adjust parameters for your setup) - var strip_length = 30 - var strip = WS2812(strip_length) - - # Create the animation engine - var engine = animation.create_engine(strip) - - # Create animations - var pulse = PulseAnimation(0xFF0000, 10, 100, 2000) # Red pulse, 2 seconds duration - var dot = MovingDotAnimation(0x00FF00, 0x000000, 3, 5000) # Green dot, 5 seconds duration - - # Add animations to the engine - engine.add_animation(pulse) - engine.add_animation(dot) - - # Start the engine - engine.start() - - print("Animation engine demo started") - print("Press 'b+' to increase brightness") - print("Press 'b-' to decrease brightness") - print("Press 's' to stop animations") - print("Press 'r' to restart animations") - print("Press 'p' to pause animations (keeps fast_loop active)") - print("Press 'c' to resume animations") - print("Press 'i' to show controller info") - print("Press 'q' to quit") - - # Set up a simple command handler - def handle_command(cmd) - if cmd == "b+" - # Brightness is now handled by the strip object - var current_bri = strip.get_bri() - var new_bri = current_bri + 25 # Increase by ~10% (25/255) - if new_bri > 255 - new_bri = 255 - end - strip.set_bri(new_bri) - print(f"Brightness set to {tasmota.scale_uint(new_bri, 0, 255, 0, 100)}%") - elif cmd == "b-" - # Brightness is now handled by the strip object - var current_bri = strip.get_bri() - var new_bri = current_bri - 25 # Decrease by ~10% (25/255) - if new_bri < 0 - new_bri = 0 - end - strip.set_bri(new_bri) - print(f"Brightness set to {tasmota.scale_uint(new_bri, 0, 255, 0, 100)}%") - elif cmd == "s" - engine.stop() - print("Animations stopped") - elif cmd == "r" - engine.start() - print("Animations restarted") - elif cmd == "p" - # Pause individual animations - for anim : engine.get_animations() - anim.pause() - end - print("Animations paused (fast_loop still active)") - elif cmd == "c" - # Resume individual animations - for anim : engine.get_animations() - anim.resume() - end - print("Animations resumed") - elif cmd == "i" - print(engine) - print(f"Last update: {engine.last_update} ms") - print(f"Current time: {tasmota.millis()} ms") - elif cmd == "q" - engine.stop() - print("Demo ended") - return false - end - return true - end - - # In a real application, you would integrate with Tasmota's command system - # For this demo, we'll just return the engine and handler for manual testing - return { - "engine": engine, - "handler": handle_command - } -end - -# Run the demo if this file is executed directly -try - if tasmota != nil - # When running in Tasmota - var demo = run_demo() - return demo - end -except .. as e - # When running in standalone Berry or if tasmota is not available - print("This demo is designed to run in Tasmota") - print("Running in simulation mode...") - var demo = run_demo() - print("Demo initialized successfully in simulation mode") - return demo -end \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/breathe_animation_demo.be b/lib/libesp32/berry_animation/src/examples/breathe_animation_demo.be deleted file mode 100644 index 0dd0db385..000000000 --- a/lib/libesp32/berry_animation/src/examples/breathe_animation_demo.be +++ /dev/null @@ -1,98 +0,0 @@ -# Breathe Animation Demo with LED Values -# -# This example demonstrates the Breathe animation effect -# which creates a smooth, natural breathing effect with customizable parameters. -# -# The demo creates a blue breathing effect with a 3-second period and shows actual LED values. -# -# Command to run demo: -# ./berry -s -g -m lib/libesp32/berry_animation lib/libesp32/berry_animation/examples/breathe_animation_demo.be - -import global -import tasmota -import animation - -def dump_rgb(strip) - var output = "LEDs: [" - for i:0..strip.length()-1 - var color = strip.get_pixel_color(i) - var r = (color >> 16) & 0xFF - var g = (color >> 8) & 0xFF - var b = color & 0xFF - - if i > 0 - output += ", " - end - output += format("R:%d,G:%d,B:%d", r, g, b) - end - output += "]" - print(output) -end - -def dump(strip) - var output = "[" - for i:0..strip.length()-1 - if i > 0 - output += ", " - end - output += format("0x%06X", strip.get_pixel_color(i) & 0xFFFFFF) - end - output += "]" - print(output) -end - -print("Starting Breathe animation demo with LED values...") - -# Create a mock LED strip with 5 pixels (reduced for readability) -var strip = global.Leds(5) - -# Create an animation controller for the strip -var controller = animation.animation_controller(strip) - -# Create a breathe animation with blue color -# Parameters: -# - Color: 0xFF0000FF (blue) -# - Min brightness: 10 -# - Max brightness: 200 -# - Breathe period: 3000ms (3 seconds) -# - Curve factor: 3 (medium-high curve for more natural breathing) -# - Priority: 1 -# - Duration: 0 (infinite) -# - Loop: true -var breathe_anim = animation.breathe_animation(0xFF0000FF, 10, 200, 3000, 3, 1, 255, 0, true) - -# Add the animation to the controller and start it -controller.add_animation(breathe_anim) -breathe_anim.start() - -# Start the controller -controller.start() - -# Simulate the fast_loop for a full breathing cycle -print("Simulating animation updates for one full breathing cycle...") - -var start_time = tasmota.millis() -var end_time = start_time + 3500 # Run for slightly more than one cycle -var update_interval = 300 # Update every 300ms for demonstration - -# Simulate updates -var current_time = start_time -while current_time < end_time - # Update the controller with the current time - controller.on_tick(current_time) - - # Show the current state with detailed LED values - print(f"Time: {current_time - start_time}ms, Brightness: {breathe_anim.current_brightness}") - dump_rgb(strip) # Show RGB components - dump(strip) # Show hex values for reference - - # Increment time - current_time += update_interval -end - -print("Breathe animation demo completed") - -# Stop the animation -controller.stop() - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/clean_api_demo.be b/lib/libesp32/berry_animation/src/examples/clean_api_demo.be deleted file mode 100644 index 9d3ed4a4f..000000000 --- a/lib/libesp32/berry_animation/src/examples/clean_api_demo.be +++ /dev/null @@ -1,147 +0,0 @@ -# Clean API Demo -# Demonstrates the simplified, unified animation API - -import animation -import tasmota - -print("=== Clean Animation API Demo ===") - -# Mock LED strip for demonstration -class MockStrip - var length_val - var pixels - - def init(length) - self.length_val = length - self.pixels = [] - for i : 0..length-1 - self.pixels.push(0x00000000) - end - end - - def length() - return self.length_val - end - - def set_pixel_color(index, color) - if index >= 0 && index < self.length_val - self.pixels[index] = color - end - end - - def show() - print(f"✓ Strip updated with {self.length_val} pixels") - end - - def can_show() - return true - end -end - -print("\n--- Simple Setup ---") - -# Create LED strip -var strip = MockStrip(30) -print(f"Created strip with {strip.length()} pixels") - -# Create animation engine - ONE LINE SETUP! -var engine = animation.create_engine(strip) -print(f"Created engine: {engine}") - -print("\n--- Add Animations ---") - -# Create some animations -var red_fill = animation.solid(0xFFFF0000, 10) # Solid red, priority 10 -var blue_pulse = animation.pulse_animation(0xFF0000FF, 2000, 5) # Blue pulse, 2s, priority 5 -var rainbow = animation.rich_palette_animation(animation.PALETTE_RAINBOW, 5000, 1, 255, 15) # Rainbow, priority 15 - -print("Created animations:") -print(f" Red fill: priority {red_fill.priority}") -print(f" Blue pulse: priority {blue_pulse.priority}") -print(f" Rainbow: priority {rainbow.priority}") - -# Add animations to engine -engine.add_animation(red_fill) -engine.add_animation(blue_pulse) -engine.add_animation(rainbow) - -print(f"Engine now managing {engine.size()} animations") - -print("\n--- Start Animation System ---") - -# Start the engine -engine.start() -print(f"Engine started: {engine.is_active()}") - -print("\n--- Simulate Animation Loop ---") - -# Simulate some animation frames -var current_time = tasmota.millis() -for i : 0..5 - print(f"\nFrame {i+1}:") - engine.on_tick(current_time + (i * 50)) # 50ms intervals - - var active_animations = engine.get_animations() - print(f" Active animations: {size(active_animations)}") - for anim : active_animations - if anim.is_running - print(f" ✓ {anim.name} (priority: {anim.priority})") - end - end -end - -print("\n--- Sequence Management ---") - -# Create and run a sequence -var seq_manager = animation.SequenceManager(engine) -var steps = [] - -# Build sequence: red for 1s, wait 0.5s, rainbow for 2s -steps.push(animation.create_play_step(red_fill, 1000)) -steps.push(animation.create_wait_step(500)) -steps.push(animation.create_play_step(rainbow, 2000)) - -print(f"Created sequence with {size(steps)} steps") - -# Add sequence to engine and start -engine.add_sequence_manager(seq_manager) -seq_manager.start_sequence(steps) - -print("Sequence started - simulating execution...") - -# Simulate sequence execution -for i : 0..8 - print(f"Sequence frame {i+1}:") - engine.on_tick(current_time + 1000 + (i * 250)) # 250ms intervals - - if seq_manager.is_sequence_running() - var step_info = seq_manager.get_current_step_info() - print(f" Current step: {step_info}") - else - print(" ✓ Sequence completed") - break - end -end - -print("\n--- Cleanup ---") - -# Stop the engine -engine.stop() -print(f"Engine stopped: {engine.is_active()}") - -# Clear all animations -engine.clear() -print(f"Animations cleared: {engine.size()} remaining") - -print("\n=== API Summary ===") -print("The unified animation API provides:") -print("✓ Single object creation: animation.create_engine(strip)") -print("✓ Simple animation management: engine.add_animation()") -print("✓ Easy lifecycle control: engine.start() / engine.stop()") -print("✓ Integrated sequence support: engine.add_sequence_manager()") -print("✓ Clean, intuitive interface with no deprecated components") -print("✓ High performance through unified architecture") - -print("\n=== Demo Complete ===") -print("This demonstrates the clean, simplified animation framework") -print("that replaces the previous complex multi-object architecture") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/color_ambiguity_demo.be b/lib/libesp32/berry_animation/src/examples/color_ambiguity_demo.be deleted file mode 100644 index 0b50074a4..000000000 --- a/lib/libesp32/berry_animation/src/examples/color_ambiguity_demo.be +++ /dev/null @@ -1,186 +0,0 @@ -# Color Ambiguity Resolution Demo -# Demonstrates how the DSL handles color name conflicts between predefined and user-defined colors -# -# Command to run demo: -# ./berry -s -g -m lib/libesp32/berry_animation lib/libesp32/berry_animation/examples/color_ambiguity_demo.be - -import tasmota -import animation - -print("=== Color Ambiguity Resolution Demo ===") -print("This demo shows how the DSL resolves conflicts between predefined and user-defined colors.") -print("") - -# Test Case 1: Using predefined colors without redefinition -print("--- Test Case 1: Predefined Colors (No Conflicts) ---") -var test1_dsl = "strip length 30\n" + - "color primary = red\n" + # 'red' is predefined - "color secondary = blue\n" + # 'blue' is predefined - "pattern red_pattern = solid(red)\n" + # Should use predefined red - "pattern blue_pattern = solid(blue)\n" # Should use predefined blue - -print("DSL Input:") -print(test1_dsl) -print("") - -var test1_berry = animation.compile_dsl(test1_dsl) -if test1_berry != nil - print("Generated Berry Code:") - print(test1_berry) - print("✅ Test 1 PASSED: Predefined colors used correctly") -else - print("❌ Test 1 FAILED: Compilation error") -end -print("") - -# Test Case 2: User redefining predefined color names -print("--- Test Case 2: User Redefining Predefined Colors ---") -var test2_dsl = "strip length 30\n" + - "color red = #0000FF\n" + # User redefines 'red' as blue! - "color blue = #FF0000\n" + # User redefines 'blue' as red! - "pattern red_pattern = solid(red)\n" + # Should use user's red (blue) - "pattern blue_pattern = solid(blue)\n" # Should use user's blue (red) - -print("DSL Input:") -print(test2_dsl) -print("") - -var test2_berry = animation.compile_dsl(test2_dsl) -if test2_berry != nil - print("Generated Berry Code:") - print(test2_berry) - print("✅ Test 2 PASSED: User-defined colors take precedence") -else - print("❌ Test 2 FAILED: Compilation error") -end -print("") - -# Test Case 3: Mixed usage - some predefined, some user-defined -print("--- Test Case 3: Mixed Predefined and User-Defined Colors ---") -var test3_dsl = "strip length 30\n" + - "color red = #FF8000\n" + # User redefines 'red' as orange - "# 'blue' is not redefined, so it remains predefined\n" + - "color custom = #00FF80\n" + # User defines a new color - "pattern red_pattern = solid(red)\n" + # Should use user's red (orange) - "pattern blue_pattern = solid(blue)\n" + # Should use predefined blue - "pattern custom_pattern = solid(custom)\n" # Should use user's custom color - -print("DSL Input:") -print(test3_dsl) -print("") - -var test3_berry = animation.compile_dsl(test3_dsl) -if test3_berry != nil - print("Generated Berry Code:") - print(test3_berry) - print("✅ Test 3 PASSED: Mixed color resolution works correctly") -else - print("❌ Test 3 FAILED: Compilation error") -end -print("") - -# Test Case 4: Forward references with redefined colors -print("--- Test Case 4: Forward References with Color Redefinition ---") -var test4_dsl = "strip length 30\n" + - "pattern early_pattern = solid(red)\n" + # Forward reference to 'red' - "color red = #FFFF00\n" + # User redefines 'red' as yellow (after reference) - "pattern late_pattern = solid(red)\n" # Direct reference to user's red - -print("DSL Input:") -print(test4_dsl) -print("") - -var test4_berry = animation.compile_dsl(test4_dsl) -if test4_berry != nil - print("Generated Berry Code:") - print(test4_berry) - print("✅ Test 4 PASSED: Forward references with redefinition work") -else - print("❌ Test 4 FAILED: Compilation error") -end -print("") - -# Test Case 5: Complex scenario with multiple redefinitions -print("--- Test Case 5: Complex Color Redefinition Scenario ---") -var test5_dsl = "strip length 60\n" + - "# Swap the meanings of red and blue\n" + - "color red = #0000FF\n" + # red is now blue - "color blue = #FF0000\n" + # blue is now red - "color green = #FFFF00\n" + # green is now yellow - "# white and black remain predefined\n" + - "\n" + - "# Create patterns using the redefined colors\n" + - "pattern fire_pattern = solid(red)\n" + # This will be blue! - "pattern water_pattern = solid(blue)\n" + # This will be red! - "pattern earth_pattern = solid(green)\n" + # This will be yellow! - "pattern air_pattern = solid(white)\n" + # This remains white (predefined) - "\n" + - "# Create animations\n" + - "animation fire_anim = fire_pattern\n" + - "animation water_anim = water_pattern\n" + - "\n" + - "# Create a sequence\n" + - "sequence color_swap_demo {\n" + - " play fire_anim for 2s\n" + - " play water_anim for 2s\n" + - "}\n" + - "\n" + - "run color_swap_demo\n" - -print("DSL Input:") -print(test5_dsl) -print("") - -var test5_berry = animation.compile_dsl(test5_dsl) -if test5_berry != nil - print("Generated Berry Code:") - print(test5_berry) - print("✅ Test 5 PASSED: Complex color redefinition scenario works") -else - print("❌ Test 5 FAILED: Compilation error") -end -print("") - -# Test Case 6: Error case - undefined color -print("--- Test Case 6: Error Handling for Undefined Colors ---") -var test6_dsl = "strip length 30\n" + - "pattern mystery_pattern = solid(undefined_color)\n" # This should cause an error - -print("DSL Input:") -print(test6_dsl) -print("") - -var test6_berry = animation.compile_dsl(test6_dsl) -if test6_berry != nil - print("Generated Berry Code:") - print(test6_berry) - print("⚠️ Test 6: Code generated despite undefined color (will be caught at runtime)") -else - print("✅ Test 6 PASSED: Undefined color properly detected as error") -end -print("") - -print("=== Color Resolution Summary ===") -print("The DSL color resolution system works as follows:") -print("") -print("1. SCOPED RESOLUTION: User-defined colors always take precedence over predefined ones") -print(" - If user defines 'color red = #0000FF', then 'red' means blue in that DSL scope") -print(" - Predefined colors are only used if the user hasn't redefined them") -print("") -print("2. FORWARD REFERENCE SUPPORT: Colors can be referenced before they are defined") -print(" - The transpiler scans ahead to detect user color definitions") -print(" - This ensures consistent behavior regardless of definition order") -print("") -print("3. CLEAR PRECEDENCE RULES:") -print(" - User-defined colors (highest precedence)") -print(" - Predefined color names (medium precedence)") -print(" - Undefined colors (error - lowest precedence)") -print("") -print("4. BENEFITS:") -print(" - No ambiguity: clear, predictable color resolution") -print(" - User control: users can redefine any color name") -print(" - Backward compatibility: existing DSL code continues to work") -print(" - Forward compatibility: new predefined colors won't break user code") -print("") -print("This approach solves the color ambiguity problem while maintaining") -print("intuitive behavior and full user control over color definitions.") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/color_cycle_animation_demo.be b/lib/libesp32/berry_animation/src/examples/color_cycle_animation_demo.be deleted file mode 100644 index 3d7d4d476..000000000 --- a/lib/libesp32/berry_animation/src/examples/color_cycle_animation_demo.be +++ /dev/null @@ -1,48 +0,0 @@ -# ColorCycle Animation Demo -# -# This example demonstrates the Filled animation with a color cycle provider -# which smoothly transitions between colors in a palette. - -# Import the animation module -import global -import tasmota -import animation - -# Create an animation controller for a strip of 30 LEDs -var strip = global.Leds(30, 1) # Assuming global.Leds class is available in Tasmota -var controller = animation.animation_controller(strip) - -# Create a color cycle animation with a custom palette -var palette = [ - 0xFFFF0000, # Red - 0xFFFF7F00, # Orange - 0xFFFFFF00, # Yellow - 0xFF00FF00, # Green - 0xFF0000FF, # Blue - 0xFF4B0082, # Indigo - 0xFF8F00FF # Violet -] - -# Create the animation with a 5-second cycle period and sine transition -# Using the factory method for color_cycle -var rainbow_cycle = animation.color_cycle_animation(palette, 5000, 1, 0, 255) - -# Add the animation to the controller -controller.add_animation(rainbow_cycle) - -# Start the animation -controller.start() - -print("Running ColorCycle animation demo") -print("Press Ctrl+C to stop") - -# In a real application, the animation would continue running -# Here we'll just wait for a while to demonstrate -tasmota.delay(30000) # Run for 30 seconds - -# Stop the animation -controller.stop() - -print("ColorCycle animation demo completed") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/color_provider_demo.be b/lib/libesp32/berry_animation/src/examples/color_provider_demo.be deleted file mode 100644 index 1a2e8bd73..000000000 --- a/lib/libesp32/berry_animation/src/examples/color_provider_demo.be +++ /dev/null @@ -1,133 +0,0 @@ -# Color Provider Demo for Berry Animation Framework -# -# This example demonstrates the use of color providers to generate colors -# for different purposes, including filling frames and creating patterns. - -import tasmota -import animation - -# Create a frame buffer for testing -var frame_width = 30 -var frame = animation.frame_buffer(frame_width, 1) - -# Create a rich palette color provider -print("Creating a rich palette color provider...") -var palette_provider = animation.rich_palette_color_provider( - animation.PALETTE_RAINBOW, # Use the rainbow palette - 5000, # 5 second cycle period - 1, # Sine transition - 255 # Full brightness -) - -# Create a color cycle color provider -print("Creating a color cycle color provider...") -var cycle_provider = animation.color_cycle_color_provider( - [0xFF0000FF, 0xFF00FF00, 0xFFFF0000], # RGB colors - 3000, # 3 second cycle period - 1 # Sine transition -) - -# Create a solid color provider -print("Creating a solid color provider...") -var solid_provider = animation.solid_color_provider(0xFFFF0000) # Red - -# Create a composite color provider that combines the palette and cycle providers -print("Creating a composite color provider...") -var composite_provider = animation.composite_color_provider( - [palette_provider, cycle_provider], # List of providers to combine - 0 # Overlay blend mode -) - -# Demonstrate getting colors from providers -print("Demonstrating color providers...") - -# Get colors at different times -var time_ms = tasmota.millis() -print(f"Current time: {time_ms} ms") - -print("Colors at current time:") -print(f" Palette provider: 0x{palette_provider.get_color(time_ms):08X}") -print(f" Cycle provider: 0x{cycle_provider.get_color(time_ms):08X}") -print(f" Solid provider: 0x{solid_provider.get_color(time_ms):08X}") -print(f" Composite provider: 0x{composite_provider.get_color(time_ms):08X}") - -# Get colors for different values -print("Colors for value 50:") -print(f" Palette provider: 0x{palette_provider.get_color_for_value(50, time_ms):08X}") -print(f" Cycle provider: 0x{cycle_provider.get_color_for_value(50, time_ms):08X}") -print(f" Solid provider: 0x{solid_provider.get_color_for_value(50, time_ms):08X}") -print(f" Composite provider: 0x{composite_provider.get_color_for_value(50, time_ms):08X}") - -# Create a pattern function that generates a wave pattern -def wave_pattern(pixel_index, time_ms, animation) - var wave_period = 2000 # 2 second period - var wave_length = 30 # 30 pixel wavelength - - # Calculate the wave position - var position = (time_ms % wave_period) / wave_period - var offset = int(position * wave_length) - - # Calculate the wave value (0-100) - var pos_in_wave = (pixel_index + offset) % wave_length - var angle = tasmota.scale_uint(pos_in_wave, 0, wave_length, 0, 32767) # 0 to 2π in fixed-point - var sine_value = tasmota.sine_int(angle) # -4096 to 4096 - - # Map sine value from -4096..4096 to 0..100 - var value = tasmota.scale_int(sine_value, -4096, 4096, 0, 100) - - return value -end - -# Fill the frame with colors from different providers -print("Filling frame with colors from different providers...") - -# Fill with palette provider -frame.clear() -for i:0..frame_width-1 - var value = wave_pattern(i, time_ms, nil) - var color = palette_provider.get_color_for_value(value, time_ms) - frame.set_pixel_color(i, color) -end -print("Frame filled with palette provider colors") - -# Fill with cycle provider -frame.clear() -for i:0..frame_width-1 - var value = wave_pattern(i, time_ms, nil) - var color = cycle_provider.get_color_for_value(value, time_ms) - frame.set_pixel_color(i, color) -end -print("Frame filled with cycle provider colors") - -# Fill with composite provider -frame.clear() -for i:0..frame_width-1 - var value = wave_pattern(i, time_ms, nil) - var color = composite_provider.get_color_for_value(value, time_ms) - frame.set_pixel_color(i, color) -end -print("Frame filled with composite provider colors") - -# Create a PalettePatternAnimation that uses a color provider -print("Creating a PalettePatternAnimation with a color provider...") -var pattern_animation = animation.palette_pattern( - palette_provider, # Use the palette provider as the color source - wave_pattern, # Use the wave pattern function - frame_width, # Frame width - 10, # Priority - 0, # Duration (0 = infinite) - true, # Loop - "wave_pattern" # Name -) - -# Start the animation -pattern_animation.start() - -# Update and render the animation -print("Updating and rendering the animation...") -pattern_animation.update(time_ms) -frame.clear() -pattern_animation.render(frame, time_ms) -print("Animation rendered to frame") - -print("Color Provider Demo completed successfully!") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/comet_animation_demo.be b/lib/libesp32/berry_animation/src/examples/comet_animation_demo.be deleted file mode 100644 index 5358fd9cf..000000000 --- a/lib/libesp32/berry_animation/src/examples/comet_animation_demo.be +++ /dev/null @@ -1,98 +0,0 @@ -# Comet Animation Demo -# Demonstrates the comet animation effect with different configurations - -import tasmota -import animation - -print("=== Comet Animation Demo ===") - -# Test 1: Basic solid color comet -print("\n--- Test 1: Basic Solid Color Comet ---") -var comet1 = animation.comet.solid(0xFFFF0000, 5, 2560, 30, 10) # Red comet, 5-pixel tail, 10 pixels/sec, 30-pixel strip -print("Created:", comet1) - -# Test the parameter system -print("Setting tail length to 8...") -comet1.set_tail_length(8) -print("Tail length:", comet1.get_param("tail_length")) - -print("Setting speed to 15.0...") -comet1.set_speed(3840) -print("Speed:", comet1.get_param("speed")) - -# Test 2: Color cycling comet -print("\n--- Test 2: Color Cycling Comet ---") -var rainbow_colors = [0xFFFF0000, 0xFFFF8000, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFF8000FF] -var comet2 = animation.comet.color_cycle(rainbow_colors, 3000, 7, 2048, 30, 15) -print("Created:", comet2) - -# Test 3: Rich palette comet -print("\n--- Test 3: Rich Palette Comet ---") -var comet3 = animation.comet.rich_palette(animation.PALETTE_FIRE, 4000, 6, 3072, 30, 20) -print("Created:", comet3) - -# Test 4: Custom configuration -print("\n--- Test 4: Custom Configuration ---") -var comet4 = animation.comet( - 0xFF00FFFF, # Cyan color - 10, # 10-pixel tail - 1280, # 5 pixels/sec (5 * 256) - -1, # Backward direction - false, # No wrap around (bounce) - 204, # Slower fade (80% = 204/255) - 25, # 25-pixel strip - 25, # Priority 25 - 0, # Infinite duration - true, # Loop - "custom_comet" -) -print("Created:", comet4) - -# Test parameter validation -print("\n--- Test 5: Parameter Validation ---") -print("Testing invalid tail length...") -var result = comet1.set_param("tail_length", -1) -print("Set tail_length to -1:", result ? "SUCCESS" : "FAILED (expected)") - -print("Testing invalid speed...") -result = comet1.set_param("speed", 0) -print("Set speed to 0:", result ? "SUCCESS" : "FAILED (expected)") - -print("Testing invalid direction...") -result = comet1.set_param("direction", 2) -print("Set direction to 2:", result ? "SUCCESS" : "FAILED (expected)") - -print("Testing valid direction...") -result = comet1.set_param("direction", -1) -print("Set direction to -1:", result ? "SUCCESS (expected)" : "FAILED") - -# Test 6: Animation lifecycle -print("\n--- Test 6: Animation Lifecycle ---") -print("Starting comet1...") -comet1.start() -print("Is running:", comet1.is_running) - -print("Stopping comet1...") -comet1.stop() -print("Is running:", comet1.is_running) - -# Test 7: Frame buffer rendering -print("\n--- Test 7: Frame Buffer Rendering ---") -var frame = animation.frame_buffer(30) -print("Created frame buffer:", frame) - -# Start the animation and simulate a few updates -comet1.start() -var start_time = tasmota.millis() - -print("Simulating animation updates...") -var i = 0 -while i < 5 - var current_time = start_time + (i * 100) # 100ms intervals - comet1.update(current_time) - comet1.render(frame, current_time) - print(f"Frame {i}: head_pos={comet1.head_position:.2f}") - i += 1 -end - -print("\n=== Comet Animation Demo Complete ===") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/crenel_color_demo.be b/lib/libesp32/berry_animation/src/examples/crenel_color_demo.be deleted file mode 100644 index 8b9f0a27c..000000000 --- a/lib/libesp32/berry_animation/src/examples/crenel_color_demo.be +++ /dev/null @@ -1,153 +0,0 @@ -# CrenelPositionAnimation Color Demo -# -# This example demonstrates the fixed CrenelPositionAnimation that can handle -# both integer colors and ColorProvider instances. - -import animation - -print("=== CrenelPositionAnimation Color Demo ===") - -# Create a frame buffer for testing -var frame_width = 20 -var frame = animation.frame_buffer(frame_width) - -# Create an animation engine -var strip = global.Leds(frame_width, 1) -var engine = animation.create_engine(strip) - -print("1. Creating CrenelPositionAnimation with integer color...") - -# Create a crenel animation with a static red color -var red_crenel = animation.crenel_position_animation( - 0xFFFF0000, # Red color (integer) - 0, # pos - 3, # pulse_size - 2, # low_size - 4, # nb_pulse - 10, # priority - 0, # duration (infinite) - true, # loop - "red_crenel" -) - -# Add to engine and render -engine.add_animation(red_crenel) -engine.start() - -# Simulate a frame update -engine.on_tick(tasmota.millis()) -print("✓ Red crenel animation created and rendered successfully") - -print("2. Creating CrenelPositionAnimation with SolidColorProvider...") - -# Create a solid color provider for blue -var blue_provider = animation.solid_color_provider(0xFF0000FF) # Blue - -# Create a crenel animation with the color provider -var blue_crenel = animation.crenel_position_animation( - blue_provider, # Blue ColorProvider - 5, # pos - 2, # pulse_size - 3, # low_size - 3, # nb_pulse - 15, # priority (higher than red) - 0, # duration (infinite) - true, # loop - "blue_crenel" -) - -# Add to engine -engine.add_animation(blue_crenel) - -# Simulate another frame update -engine.on_tick(tasmota.millis()) -print("✓ Blue crenel animation with ColorProvider created and rendered successfully") - -print("3. Creating CrenelPositionAnimation with dynamic RichPaletteColorProvider...") - -# Create a dynamic color provider that cycles through rainbow colors -var rainbow_provider = animation.rich_palette_color_provider( - animation.PALETTE_RAINBOW, # Rainbow palette - 3000, # 3 second cycle - 1, # Sine transition - 255 # Full brightness -) - -# Create a crenel animation with the dynamic color provider -var rainbow_crenel = animation.crenel_position_animation( - rainbow_provider, # Dynamic rainbow ColorProvider - 10, # pos - 4, # pulse_size - 1, # low_size - 2, # nb_pulse - 20, # priority (highest) - 0, # duration (infinite) - true, # loop - "rainbow_crenel" -) - -# Add to engine -engine.add_animation(rainbow_crenel) - -# Simulate frame updates at different times to show color changes -for time_offset : [0, 1000, 2000, 3000] - engine.on_tick(tasmota.millis() + time_offset) - print(f"✓ Rainbow crenel rendered at time offset {time_offset}ms") -end - -print("4. Testing set_color method with both types...") - -# Test changing from integer to ColorProvider -var test_crenel = animation.crenel_position_animation( - 0xFF00FF00, # Start with green integer - 15, 2, 1, 1, 5, 0, true, "test_crenel" -) - -engine.add_animation(test_crenel) -engine.on_tick(tasmota.millis()) -print("✓ Test crenel created with integer color") - -# Change to a ColorProvider -var yellow_provider = animation.solid_color_provider(0xFFFFFF00) # Yellow -test_crenel.set_color(yellow_provider) -engine.on_tick(tasmota.millis()) -print("✓ Test crenel color changed to ColorProvider") - -# Change back to integer color -test_crenel.set_color(0xFFFF00FF) # Magenta -engine.on_tick(tasmota.millis()) -print("✓ Test crenel color changed back to integer") - -print("5. Displaying string representations...") - -print(f"Red crenel: {red_crenel}") -print(f"Blue crenel: {blue_crenel}") -print(f"Rainbow crenel: {rainbow_crenel}") -print(f"Test crenel: {test_crenel}") - -print("6. Testing with generic ValueProvider (not ColorProvider)...") - -# Create a static value provider with a color value -var static_provider = animation.static_value_provider(0xFFFFFF00) # Yellow -var static_crenel = animation.crenel_position_animation( - static_provider, # Generic ValueProvider - 0, 1, 4, 1, 5, 0, true, "static_provider_crenel" -) - -engine.add_animation(static_crenel) -engine.on_tick(tasmota.millis()) -print("✓ Generic ValueProvider crenel created and rendered successfully") - -print("=== CrenelPositionAnimation Color Demo completed successfully! ===") -print("") -print("Summary of the enhanced fix:") -print("- CrenelPositionAnimation now correctly handles integer colors and ANY ValueProvider subclass") -print("- The parameter system accepts ValueProvider instances for integer parameters") -print("- ColorProvider instances use get_color(time_ms) for optimal color handling") -print("- Generic ValueProvider instances use get_value(time_ms) for flexibility") -print("- Range validation is bypassed for ValueProviders (since they provide dynamic values)") -print("- The set_color() method accepts integers, ColorProviders, and any ValueProvider") -print("- String representation handles all types appropriately") -print("- All existing functionality with integer colors remains unchanged") -print("- The type system is now extensible for future ValueProvider subclasses") -print("- Clean, single method call: var color = self.get_param_value('color', tasmota.millis())") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/crenel_position_animation_demo.be b/lib/libesp32/berry_animation/src/examples/crenel_position_animation_demo.be deleted file mode 100644 index 85276cd5a..000000000 --- a/lib/libesp32/berry_animation/src/examples/crenel_position_animation_demo.be +++ /dev/null @@ -1,155 +0,0 @@ -# Crenel Position Animation Demo with LED Values -# -# This example demonstrates the Crenel Position animation effect -# which creates repeating rectangular pulses (square wave pattern) on the LED strip. -# -# The demo creates a green crenel pattern with customizable parameters and shows actual LED values. -# -# Command to run demo: -# ./berry -s -g -m lib/libesp32/berry_animation lib/libesp32/berry_animation/examples/crenel_position_animation_demo.be - -import global -import tasmota -import animation - -def dump_rgb(strip) - var output = "LEDs: [" - for i:0..strip.length()-1 - var color = strip.get_pixel_color(i) - var r = (color >> 16) & 0xFF - var g = (color >> 8) & 0xFF - var b = color & 0xFF - - if i > 0 - output += ", " - end - output += format("R:%d,G:%d,B:%d", r, g, b) - end - output += "]" - print(output) -end - -def dump(strip) - var output = "[" - for i:0..strip.length()-1 - if i > 0 - output += ", " - end - output += format("0x%06X", strip.get_pixel_color(i) & 0xFFFFFF) - end - output += "]" - print(output) -end - -print("Starting Crenel Position animation demo with LED values...") - -# Create a mock LED strip with 12 pixels for better pattern visibility -var strip = global.Leds(12) - -# Create an animation engine for the strip -var engine = animation.create_engine(strip) - -print("=== Demo 1: Basic crenel pattern ===") -# Create a crenel animation with green color -# Parameters: -# - Color: 0xFF00FF00 (green) -# - Pulse size: 2 pixels -# - Low size: 3 pixels (spacing between pulses) -# - Number of pulses: -1 (infinite) -# - Priority: 1 -# - Duration: 0 (infinite) -# - Loop: true -var crenel_anim = animation.crenel_position(0xFF00FF00, 2, 3, -1, 1, 0, true, "demo_crenel") - -# Add the animation to the engine and start it -engine.add_animation(crenel_anim) -crenel_anim.start() - -# Start the engine -engine.start() - -# Show the static pattern -engine.on_tick(tasmota.millis()) -print("Basic crenel pattern (2 pixels on, 3 pixels off, infinite):") -dump_rgb(strip) -dump(strip) - -print() -print("=== Demo 2: Crenel with background color ===") -# Set a dark blue background -crenel_anim.set_back_color(0xFF000080) -engine.on_tick(tasmota.millis() + 10) # Force update with new time -print("Crenel with dark blue background:") -dump_rgb(strip) -dump(strip) - -print() -print("=== Demo 3: Different pulse and spacing sizes ===") -# Change to 3 pixels on, 2 pixels off -crenel_anim.set_back_color(0xFF000000) # Back to transparent -crenel_anim.set_pulse_size(3) -crenel_anim.set_low_size(2) -engine.on_tick(tasmota.millis() + 20) # Force update with new time -print("Modified pattern (3 pixels on, 2 pixels off):") -dump_rgb(strip) -dump(strip) - -print() -print("=== Demo 4: Limited number of pulses ===") -# Show only 2 pulses -crenel_anim.set_nb_pulse(2) -crenel_anim.set_pos(1) # Start at position 1 -engine.on_tick(tasmota.millis() + 30) # Force update with new time -print("Limited to 2 pulses starting at position 1:") -dump_rgb(strip) -dump(strip) - -print() -print("=== Demo 5: Single pixel pulses ===") -# Reset to infinite and show single pixel pulses -crenel_anim.set_nb_pulse(-1) -crenel_anim.set_pos(0) -crenel_anim.set_pulse_size(1) -crenel_anim.set_low_size(2) -crenel_anim.set_color(0xFFFF0000) # Change to red -engine.on_tick(tasmota.millis() + 40) # Force update with new time -print("Single pixel red pulses (1 pixel on, 2 pixels off):") -dump_rgb(strip) -dump(strip) - -print() -print("=== Demo 6: Edge case - zero pulse size ===") -# Test with zero pulse size (should show nothing) -crenel_anim.set_pulse_size(0) -engine.on_tick(tasmota.millis() + 50) # Force update with new time -print("Zero pulse size (should be empty):") -dump_rgb(strip) -dump(strip) - -print() -print("=== Demo 7: Position offset ===") -# Reset pulse size and test position offset -crenel_anim.set_pulse_size(2) -crenel_anim.set_low_size(3) -crenel_anim.set_pos(2) # Start at position 2 -crenel_anim.set_color(0xFF0000FF) # Change to blue -engine.on_tick(tasmota.millis() + 60) # Force update with new time -print("Pattern starting at position 2 (blue):") -dump_rgb(strip) -dump(strip) - -print() -print("=== Demo 8: Negative position (wrapping) ===") -# Test negative position -crenel_anim.set_pos(-1) -engine.on_tick(tasmota.millis() + 70) # Force update with new time -print("Pattern with negative position -1:") -dump_rgb(strip) -dump(strip) - -print("Crenel Position animation demo completed") - -# Stop the animation -engine.stop() - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dsl/advanced_palette_showcase.anim b/lib/libesp32/berry_animation/src/examples/dsl/advanced_palette_showcase.anim deleted file mode 100644 index 41c44cada..000000000 --- a/lib/libesp32/berry_animation/src/examples/dsl/advanced_palette_showcase.anim +++ /dev/null @@ -1,121 +0,0 @@ -# Advanced DSL palette demonstration -# Showcases: Multiple palettes, layering, dynamic switching -# Demonstrates: Complex palette compositions, event-driven control -# -# This creates a sophisticated multi-palette display with interactive control - -strip length 60 - -# Define multiple custom palettes -palette sunset = [ - (0, #FF4500), # Orange red - (64, #FF8C00), # Dark orange - (128, #FFD700), # Gold - (192, #FF69B4), # Hot pink - (255, #800080) # Purple -] - -palette ocean = [ - (0, #000080), # Navy blue - (64, #0000FF), # Blue - (128, #00FFFF), # Cyan - (192, #00FF80), # Spring green - (255, #008000) # Green -] - -palette fire = [ - (0, #000000), # Black - (64, #800000), # Dark red - (128, #FF0000), # Red - (192, #FF8000), # Orange - (255, #FFFF00) # Yellow -] - -# Create base palette animations with different speeds -animation sunset_base = filled( - rich_palette(sunset, 8s, smooth, 200), - loop -) -sunset_base.opacity = smooth(100, 255, 15s) -sunset_base.priority = 0 - -animation ocean_layer = filled( - rich_palette(ocean, 12s, smooth, 180), - loop -) -ocean_layer.opacity = linear(50, 200, 10s) -ocean_layer.priority = 5 - -animation fire_overlay = filled( - rich_palette(fire, 4s, linear, 220), - loop -) -fire_overlay.opacity = square(0, 180, 6s, 30) # Strobe effect -fire_overlay.priority = 10 - -# Create moving effects using composite colors -animation palette_comet = comet( - composite([ - rich_palette(sunset, 8s, smooth, 255), - rich_palette(ocean, 12s, smooth, 255), - rich_palette(fire, 4s, linear, 255) - ], overlay), - 8, # length - 3, # trail - 2s, # speed - loop -) -palette_comet.priority = 20 - -animation palette_sparkles = twinkle( - composite([ - rich_palette(sunset, 8s, smooth, 255), - rich_palette(ocean, 12s, smooth, 255) - ], overlay), - 8, # count - 300ms, # duration - loop -) -palette_sparkles.priority = 25 - -# Event handlers for mode switching -variable current_mode = 0 - -on mode_switch: - current_mode = (current_mode + 1) % 5 - - # Clear all current animations - stop all - - # Switch to different display modes - if current_mode == 0: - # All layers mode - run sunset_base - run ocean_layer - run fire_overlay - run palette_comet - run palette_sparkles - elif current_mode == 1: - # Sunset only - run sunset_base - elif current_mode == 2: - # Ocean only - run ocean_layer - elif current_mode == 3: - # Fire only - run fire_overlay - elif current_mode == 4: - # Effects only - run palette_comet - run palette_sparkles - -# Auto-mode switching every 20 seconds -on timer(20s): - trigger mode_switch - -# Start with all layers -run sunset_base -run ocean_layer -run fire_overlay -run palette_comet -run palette_sparkles \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dsl/breathe_demo.anim b/lib/libesp32/berry_animation/src/examples/dsl/breathe_demo.anim deleted file mode 100644 index 523d1aa0a..000000000 --- a/lib/libesp32/berry_animation/src/examples/dsl/breathe_demo.anim +++ /dev/null @@ -1,31 +0,0 @@ -# DSL version of the breathing effect -# Original: Complex Berry code with multiple objects and callbacks -# DSL: Simple declarative syntax that's easy to read and modify -# -# This recreates the same visual effect as animate_demo_breathe.be -# but with much cleaner, more readable syntax - -strip length 25 - -# Define the same palette as original (black to red to orange) -palette fire_palette = [ - (0, #000000), # black - (136, #880000), # red - (255, #FF5500) # orange -] - -# Create breathing effect with palette colors -# This replaces the complex animate.pulse + animate.palette + animate.oscillator setup -animation breathing = breathe( - rich_palette(fire_palette, 3s, smooth, 255), - 150, # base opacity - 3s, # duration matches original - loop -) - -# Add brightness oscillation like original (50-255 range, cosine curve) -# This replaces the animate.oscillator(50, 255, duration, animate.COSINE) callback -breathing.opacity = smooth(50, 255, 3s) - -# Start the animation -run breathing \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dsl/dynamic_pulse_showcase.anim b/lib/libesp32/berry_animation/src/examples/dsl/dynamic_pulse_showcase.anim deleted file mode 100644 index 9adba6bab..000000000 --- a/lib/libesp32/berry_animation/src/examples/dsl/dynamic_pulse_showcase.anim +++ /dev/null @@ -1,120 +0,0 @@ -# Dynamic pulse DSL demonstration -# Showcases: Multiple pulse types, dynamic parameters, interactive control -# Demonstrates: Advanced DSL features, value providers, event system -# -# This creates multiple pulse types with different characteristics - -strip length 50 - -# Define background with subtle color cycling -palette bg_colors = [ - (0, #001122), - (85, #002211), - (170, #112200), - (255, #220011) -] - -animation cycling_bg = filled( - color_cycle(bg_colors, 30s, smooth), - loop -) - -# Create multiple pulse types with different characteristics - -# 1. Breathing pulse with oscillating size -animation breathe_pulse = pulse_position( - #FF0000, # red - 5, # initial size - 1, # slew - 10, # priority - loop -) -breathe_pulse.pulse_size = smooth(2, 12, 4s) -breathe_pulse.pos = linear(5, 35, 8s) # 50-15 = 35 - -# 2. Strobe pulse with square wave intensity -animation strobe_pulse = pulse_position( - #00FF00, # green - 3, # size - 1, # slew - 15, # priority - loop -) -strobe_pulse.opacity = square(50, 255, 800ms, 25) # Fast strobe, 25% duty -strobe_pulse.pos = linear(40, 5, 6s) # Opposite direction - -# 3. Rainbow pulse with dynamic color -animation rainbow_pulse = pulse_position( - #0000FF, # blue (will be overridden) - 8, # size - 2, # slew - 20, # priority - loop -) -rainbow_pulse.color = rainbow(5s, smooth, 255) -rainbow_pulse.pos = smooth(12, 37, 10s) # 50/4 to 3*50/4 - -# 4. Fire pulse with fire palette -palette fire_colors = [ - (0, #000000), # Black - (64, #800000), # Dark red - (128, #FF0000), # Red - (192, #FF8000), # Orange - (255, #FFFF00) # Yellow -] - -animation fire_pulse = pulse_position( - #FF4400, # orange (will be overridden) - 6, # size - 3, # slew - 25, # priority - loop -) -fire_pulse.color = rich_palette(fire_colors, 3s, linear, 255) -fire_pulse.pulse_size = linear(4, 15, 7s) -fire_pulse.pos = 25 # Fixed center position - -# Interactive event handlers for dynamic control -on speed_up: - # Double all animation speeds by halving durations - breathe_pulse.pulse_size.duration = 2s - breathe_pulse.pos.duration = 4s - strobe_pulse.opacity.duration = 400ms - strobe_pulse.pos.duration = 3s - rainbow_pulse.color.duration = 2.5s - rainbow_pulse.pos.duration = 5s - fire_pulse.color.duration = 1.5s - fire_pulse.pulse_size.duration = 3.5s - -on slow_down: - # Halve all animation speeds by doubling durations - breathe_pulse.pulse_size.duration = 8s - breathe_pulse.pos.duration = 16s - strobe_pulse.opacity.duration = 1600ms - strobe_pulse.pos.duration = 12s - rainbow_pulse.color.duration = 10s - rainbow_pulse.pos.duration = 20s - fire_pulse.color.duration = 6s - fire_pulse.pulse_size.duration = 14s - -on randomize_positions: - # Set random positions for all pulses - breathe_pulse.pos = random(5, 35) - strobe_pulse.pos = random(5, 35) - rainbow_pulse.pos = random(12, 37) - # fire_pulse keeps center position - -on toggle_pulse: - # Toggle individual pulses (would need pulse name in event data) - # This is a simplified version - real implementation would check event data - if breathe_pulse.running: - stop breathe_pulse - else: - run breathe_pulse - -# Start all animations -run cycling_bg -run breathe_pulse -run strobe_pulse -run rainbow_pulse -run fire_pulse \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dsl/enhanced_breathe_showcase.anim b/lib/libesp32/berry_animation/src/examples/dsl/enhanced_breathe_showcase.anim deleted file mode 100644 index 59969af54..000000000 --- a/lib/libesp32/berry_animation/src/examples/dsl/enhanced_breathe_showcase.anim +++ /dev/null @@ -1,68 +0,0 @@ -# Enhanced DSL version with multiple breathing layers -# Showcases: Multiple colors, layering, dynamic parameters -# Demonstrates: Advanced DSL features, event system integration -# -# This creates a more sophisticated breathing effect with multiple layers - -strip length 30 - -# Define multiple colors for layered breathing -color red = #FF0000 -color green = #00FF00 -color blue = #0000FF -color yellow = #FFFF00 -color magenta = #FF00FF - -# Create background rainbow that slowly cycles -animation rainbow_bg = filled( - rainbow(20s, smooth, 50), # Slow, dim rainbow - loop -) - -# Create multiple breathing layers with different phases and speeds -animation breathe_red = breathe(red, 150, 3s, loop) -breathe_red.opacity = smooth(30, 200, 3s) -breathe_red.priority = 2 - -animation breathe_green = breathe(green, 150, 4s, loop) -breathe_green.opacity = smooth(30, 200, 4s) -breathe_green.opacity.phase = 20 # 20% phase offset -breathe_green.priority = 4 - -animation breathe_blue = breathe(blue, 150, 5s, loop) -breathe_blue.opacity = smooth(30, 200, 5s) -breathe_blue.opacity.phase = 40 # 40% phase offset -breathe_blue.priority = 6 - -animation breathe_yellow = breathe(yellow, 150, 3.5s, loop) -breathe_yellow.opacity = smooth(30, 200, 3.5s) -breathe_yellow.opacity.phase = 60 # 60% phase offset -breathe_yellow.priority = 8 - -animation breathe_magenta = breathe(magenta, 150, 4.5s, loop) -breathe_magenta.opacity = smooth(30, 200, 4.5s) -breathe_magenta.opacity.phase = 80 # 80% phase offset -breathe_magenta.priority = 10 - -# Event handlers for interactive control -on button_press: - # Speed up all breathing animations - breathe_red.duration = 1.5s - breathe_green.duration = 2s - breathe_blue.duration = 2.5s - breathe_yellow.duration = 1.75s - breathe_magenta.duration = 2.25s - -on timer(10s): - # Add temporary sparkle overlay every 10 seconds - animation sparkles = twinkle(#FFFFFF, 5, 500ms, 2s, once) - sparkles.priority = 100 - run sparkles - -# Start all animations -run rainbow_bg -run breathe_red -run breathe_green -run breathe_blue -run breathe_yellow -run breathe_magenta \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dsl/palette_background_demo.anim b/lib/libesp32/berry_animation/src/examples/dsl/palette_background_demo.anim deleted file mode 100644 index 87d53c618..000000000 --- a/lib/libesp32/berry_animation/src/examples/dsl/palette_background_demo.anim +++ /dev/null @@ -1,18 +0,0 @@ -# DSL version of the palette background effect -# Original: animate_demo_palette_background.be -# DSL: Clean declarative syntax for rainbow background -# -# This recreates the cycling rainbow background effect -# but with much simpler syntax - -strip length 25 - -# Create rainbow background that cycles over 10 seconds -# This replaces animate.core() + add_background_animator() + animate.palette() -animation rainbow_bg = filled( - rainbow(10s, smooth, 255), # Built-in rainbow palette - loop -) - -# Start the animation -run rainbow_bg \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dsl/palette_dsl_demo.be b/lib/libesp32/berry_animation/src/examples/dsl/palette_dsl_demo.be deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/libesp32/berry_animation/src/examples/dsl/pulse_demo.anim b/lib/libesp32/berry_animation/src/examples/dsl/pulse_demo.anim deleted file mode 100644 index 9519a5168..000000000 --- a/lib/libesp32/berry_animation/src/examples/dsl/pulse_demo.anim +++ /dev/null @@ -1,45 +0,0 @@ -# DSL version of the moving pulse effect -# Original: animate_demo_pulse.be with complex oscillator and palette setup -# DSL: Clean declarative syntax for moving pulse with color cycling -# -# This recreates the moving pulse with oscillating position and cycling color - -strip length 25 - -# Define background color (matches original anim.set_back_color(0x2222AA)) -color background_blue = #2222AA - -# Create background animation -animation background = solid(background_blue, loop) - -# Define color palette for the pulse (matches PALETTE_STANDARD_VAL) -palette standard_colors = [ - (0, #FF0000), # Red - (64, #FFFF00), # Yellow - (128, #00FF00), # Green - (192, #00FFFF), # Cyan - (255, #0000FF) # Blue -] - -# Create moving pulse with dynamic properties -# This replaces animate.pulse(0xFF4444, 2, 1) + oscillator callbacks -animation moving_pulse = pulse_position( - #FF4444, # base color (will be overridden by palette) - 2, # pulse size - 1, # slew (fade region) - 10, # priority (higher than background) - loop -) - -# Set dynamic position (matches animate.oscillator(-3, 26, 5000, animate.COSINE)) -moving_pulse.pos = smooth(-3, 26, 5s) - -# Set cycling color (matches animate.palette(animate.PALETTE_STANDARD_VAL, 30000)) -moving_pulse.color = rich_palette(standard_colors, 30s, smooth, 255) - -# Set brightness to 60% (matches original anim.set_bri(60)) -moving_pulse.opacity = 153 # 60% of 255 - -# Run both animations -run background -run moving_pulse \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dsl/run_dsl_demo.be b/lib/libesp32/berry_animation/src/examples/dsl/run_dsl_demo.be deleted file mode 100644 index d2c731cb0..000000000 --- a/lib/libesp32/berry_animation/src/examples/dsl/run_dsl_demo.be +++ /dev/null @@ -1,48 +0,0 @@ -# -# DSL Demo Runner -# Loads and runs DSL animation files (.anim extension) -# Usage: Modify the 'demo_file' variable to run different DSL demos -# - -import animation - -# Configuration - change this to run different DSL demos -var demo_file = "breathe_demo.anim" # Options: - # - breathe_demo.anim - # - palette_background_demo.anim - # - pulse_demo.anim - # - enhanced_breathe_showcase.anim - # - advanced_palette_showcase.anim - # - dynamic_pulse_showcase.anim - -var leds = 30 # Adjust based on your LED strip - -# Create LED strip -var strip = global.Leds(leds, gpio.pin(gpio.WS2812, 0)) - -# Create DSL runtime -var runtime = animation.create_dsl_runtime(strip) - -# Load and run the DSL file -print("Loading DSL demo:", demo_file) -print("=" * 50) - -var success = runtime.load_dsl_file("lib/libesp32/berry_animation/examples/dsl/" + demo_file) - -if success - print("DSL demo loaded and running successfully!") - print("Visual effect should now be visible on your LED strip") - print("\nTo try different demos, edit the 'demo_file' variable above") - print("Available DSL demos:") - print("- breathe_demo.anim (simple breathing effect)") - print("- palette_background_demo.anim (rainbow background)") - print("- pulse_demo.anim (moving pulse with color cycling)") - print("- enhanced_breathe_showcase.anim (multi-layer breathing)") - print("- advanced_palette_showcase.anim (complex palette effects)") - print("- dynamic_pulse_showcase.anim (multiple pulse types)") -else - print("Failed to load DSL demo!") - print("Check that the file exists and the DSL syntax is correct") -end - -print("\nPress Ctrl+C to stop") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dsl_core_features_demo.be b/lib/libesp32/berry_animation/src/examples/dsl_core_features_demo.be deleted file mode 100644 index c13372852..000000000 --- a/lib/libesp32/berry_animation/src/examples/dsl_core_features_demo.be +++ /dev/null @@ -1,149 +0,0 @@ -# DSL Core Features Demo -# Demonstrates all implemented core processing methods in the DSL transpiler -# -# This example shows: -# - Color definitions (hex, named colors) -# - Pattern definitions (solid, gradient) -# - Animation definitions (pulse, breathe, simple references) -# - Variable assignments (numbers, percentages, times) -# - Sequence definitions with control flow -# - Play statements with duration -# - With statements for parallel animations -# - Repeat statements (forever, N times, range) -# - If/else statements -# - Wait statements -# - Loop statements -# - Run statements - -import animation - -# Comprehensive DSL example showcasing all core features -var comprehensive_dsl = "# LED Strip Animation DSL - Core Features Demo\n" + - "\n" + - "# Strip Configuration\n" + - "strip length 60\n" + - "\n" + - "# Color Definitions\n" + - "color red = #FF0000\n" + - "color blue = #0000FF\n" + - "color green = #00FF00\n" + - "color white = white\n" + - "color warm_orange = #FF8000\n" + - "\n" + - "# Variable Assignments\n" + - "set brightness_level = 80%\n" + - "set cycle_duration = 5s\n" + - "set repeat_count = 3\n" + - "set fade_time = 2s\n" + - "\n" + - "# Pattern Definitions\n" + - "pattern solid_red = solid(red)\n" + - "pattern solid_blue = solid(blue)\n" + - "pattern fire_gradient = gradient(red, warm_orange)\n" + - "\n" + - "# Animation Definitions\n" + - "animation red_pulse = pulse(solid_red, 2s, 20%, 100%)\n" + - "animation blue_breathe = breathe(solid_blue, 4s)\n" + - "animation simple_red = solid_red\n" + - "animation fade_effect = fade(red, blue, 3s)\n" + - "\n" + - "# Main Sequence with All Control Flow Features\n" + - "sequence comprehensive_demo {\n" + - " # Basic play statement\n" + - " play red_pulse for 3s\n" + - " \n" + - " # Wait statement\n" + - " wait 1s\n" + - " \n" + - " # Repeat N times\n" + - " repeat 2 times:\n" + - " play blue_breathe for 2s\n" + - " wait 500ms\n" + - " \n" + - " # Conditional statement\n" + - " if brightness_level > 50:\n" + - " play red_pulse for 4s\n" + - " else:\n" + - " play blue_breathe for 4s\n" + - " \n" + - " # Parallel animation with modifiers\n" + - " with simple_red for 6s opacity 60%\n" + - " \n" + - " # Wait before final effect\n" + - " wait 2s\n" + - " \n" + - " # Final play\n" + - " play fade_effect for 5s\n" + - "}\n" + - "\n" + - "# Simple sequence for comparison\n" + - "sequence simple_demo {\n" + - " play red_pulse for 10s\n" + - "}\n" + - "\n" + - "# Run the comprehensive demo\n" + - "run comprehensive_demo" - -print("=== DSL Core Features Demo ===") -print() -print("This demo showcases all implemented core processing methods:") -print("✓ Color definitions (hex colors, named colors)") -print("✓ Pattern definitions (solid, gradient)") -print("✓ Animation definitions (pulse, breathe, references)") -print("✓ Variable assignments (percentages, times, numbers)") -print("✓ Sequence definitions with control flow") -print("✓ Play statements with duration") -print("✓ With statements for parallel animations") -print("✓ Repeat statements (N times)") -print("✓ If/else conditional statements") -print("✓ Wait statements for delays") -print("✓ Run statements for execution") -print() - -print("Compiling comprehensive DSL...") -var berry_code = animation.compile_dsl(comprehensive_dsl) - -if berry_code != nil - print("✅ Compilation successful!") - print() - print("Generated Berry Code:") - print("============================================================") - print(berry_code) - print("============================================================") - print() - print("🎉 All core processing methods are working correctly!") - print() - print("Key features demonstrated:") - print("- Forward reference resolution (animations using patterns)") - print("- Deferred code generation for complex expressions") - print("- Proper symbol table management") - print("- Control flow statement generation") - print("- Expression parsing and code generation") - print("- Error handling and recovery") -else - print("❌ Compilation failed") - - # Detailed error analysis - var lexer = animation.DSLLexer(comprehensive_dsl) - var tokens = lexer.tokenize() - - if lexer.has_errors() - print() - print("Lexical errors:") - print(lexer.get_error_report()) - else - print("✓ Lexical analysis passed") - - var transpiler = animation.SinglePassDSLTranspiler(tokens) - var result = transpiler.transpile() - - if transpiler.has_errors() - print() - print("Transpilation errors:") - print(transpiler.get_error_report()) - end - end -end - -print() -print("=== Demo Complete ===") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dsl_runtime_demo.be b/lib/libesp32/berry_animation/src/examples/dsl_runtime_demo.be deleted file mode 100644 index ea1bb57c0..000000000 --- a/lib/libesp32/berry_animation/src/examples/dsl_runtime_demo.be +++ /dev/null @@ -1,266 +0,0 @@ -# DSL Runtime Integration Demo -# Demonstrates complete DSL execution lifecycle with practical examples - -import global -import tasmota -import animation - -def demo_basic_dsl_runtime() - print("=== Basic DSL Runtime Demo ===") - - # Create LED strip (30 pixels) - var strip = global.Leds(30, 1) - - # Create DSL runtime with debug mode - var runtime = animation.create_dsl_runtime(strip, true) - - # Define a simple animation DSL - var campfire_dsl = - "# Campfire animation DSL\n" + - "strip length 30\n" + - "\n" + - "# Define fire colors\n" + - "color red = #FF0000\n" + - "color orange = #FF8000\n" + - "\n" + - "# Create fire animation\n" + - "animation flames = solid(red)\n" + - "\n" + - "# Define the campfire sequence\n" + - "sequence campfire {\n" + - " play flames for 5s\n" + - "}\n" + - "\n" + - "# Start the campfire\n" + - "run campfire" - - print("Loading campfire DSL...") - print("Runtime created successfully") - print("```") - print(campfire_dsl) - print("```") - if runtime.load_dsl(campfire_dsl) - print("✓ Campfire DSL loaded successfully!") - - # Show generated Berry code (first 200 characters) - var generated_code = runtime.get_generated_code() - if generated_code != nil - print("Generated Berry code preview:") - # var preview = size(generated_code) > 200 ? generated_code[0..199] + "..." : generated_code - # print(generated_code) - print(generated_code) - end - - print("Campfire animation is now running!") - print("(In real usage, this would continue until stopped)") - - else - print("✗ Failed to load campfire DSL") - end -end - -def demo_dsl_hot_reloading() - print("\n=== DSL Hot Reloading Demo ===") - - var strip = global.Leds(20, 1) - var runtime = animation.create_dsl_runtime(strip, true) - - # Load initial animation - var initial_dsl = "strip length 20\n" + - "color blue = #0000FF\n" + - "animation blue_anim = solid(blue)\n" + - "sequence initial {\n" + - " play blue_anim for 3s\n" + - "}\n" + - "run initial" - - print("Loading initial blue animation...") - if runtime.load_dsl(initial_dsl) - print("✓ Initial animation loaded") - - # Simulate development workflow - modify and reload - var updated_dsl = "strip length 20\n" + - "color red = #FF0000\n" + - "animation red_anim = solid(red)\n" + - "sequence updated {\n" + - " play red_anim for 5s\n" + - "}\n" + - "run updated" - - print("Updating to red/white strobe animation...") - if runtime.load_dsl(updated_dsl) - print("✓ Animation updated successfully!") - - else - print("✗ Failed to update animation") - end - else - print("✗ Failed to load initial animation") - end -end - -def demo_dsl_error_handling() - print("\n=== DSL Error Handling Demo ===") - - var strip = global.Leds(15, 1) - var runtime = animation.create_dsl_runtime(strip, true) - - # Try to load DSL with various errors - var error_cases = [ - { - "name": "Syntax Error", - "dsl": "color red = \n" + - "pattern broken = solid(red)" - }, - { - "name": "Undefined Reference", - "dsl": "strip length 15\n" + - "pattern test = solid(undefined_color)\n" + - "sequence demo { play test for 1s }\n" + - "run demo" - }, - { - "name": "Invalid Color Format", - "dsl": "strip length 15\n" + - "color bad = #GGGGGG\n" + - "sequence demo { play solid(bad) for 1s }\n" + - "run demo" - } - ] - - for case : error_cases - print(f"\nTesting {case['name']}:") - if runtime.load_dsl(case["dsl"]) - print(f"✗ Expected {case['name']} to fail, but it succeeded") - else - print(f"✓ {case['name']} correctly rejected") - end - end - - # Show that runtime is still functional after errors - var valid_dsl = "strip length 15\n" + - "color green = #00FF00\n" + - "animation green_anim = solid(green)\n" + - "sequence recovery {\n" + - " play green_anim for 2s\n" + - "}\n" + - "run recovery" - - print("\nTesting recovery with valid DSL:") - if runtime.load_dsl(valid_dsl) - print("✓ Runtime recovered successfully after errors") - else - print("✗ Runtime failed to recover") - end -end - -def demo_dsl_caching_performance() - print("\n=== DSL Caching Performance Demo ===") - - var strip = global.Leds(25, 1) - var runtime = animation.create_dsl_runtime(strip, false) # Disable debug for cleaner output - - var test_dsl = "strip length 25\n" + - "color cyan = #00FFFF\n" + - "animation wave = solid(cyan)\n" + - "sequence performance_test {\n" + - " play wave for 5s\n" + - "}\n" + - "run performance_test" - - print("Testing compilation performance...") - - # First load (compilation) - var start_time = tasmota.millis() - var success1 = runtime.load_dsl(test_dsl) - var first_load_time = tasmota.millis() - start_time - - if success1 - print(f"✓ DSL compilation: {first_load_time}ms") - else - print("✗ Performance test failed") - end -end - -def demo_advanced_dsl_features() - print("\n=== Advanced DSL Features Demo ===") - - var strip = global.Leds(40, 1) - var runtime = animation.create_dsl_runtime(strip, true) - - # Complex DSL with multiple patterns and sequences - var advanced_dsl = "# Advanced LED Animation Demo\n" + - "strip length 40\n" + - "\n" + - "# Color palette\n" + - "color blue = #0000FF\n" + - "color white = #FFFFFF\n" + - "color gold = #FFD700\n" + - "\n" + - "# Multiple animations\n" + - "animation ocean_waves = solid(blue)\n" + - "animation sunset_glow = solid(gold)\n" + - "animation lighthouse = solid(white)\n" + - "\n" + - "# Complex sequence with multiple phases\n" + - "sequence coastal_scene {\n" + - " play ocean_waves for 3s\n" + - " play sunset_glow for 3s\n" + - " play lighthouse for 2s\n" + - "}\n" + - "\n" + - "run coastal_scene" - - print("Loading advanced coastal scene DSL...") - if runtime.load_dsl(advanced_dsl) - print("✓ Advanced DSL loaded successfully!") - print("Coastal scene animation with multiple phases is now running") - - # Show the complexity of generated code - var generated_code = runtime.get_generated_code() - if generated_code != nil - var lines = 0 - for i : 0..size(generated_code)-1 - if generated_code[i] == '\n' - lines += 1 - end - end - print(f"Generated {lines} lines of Berry code from DSL") - end - - else - print("✗ Failed to load advanced DSL") - end -end - -# Main demo function -def run_dsl_runtime_demos() - print("🌟 DSL Runtime Integration Demos 🌟") - print("Demonstrating complete DSL execution lifecycle\n") - - demo_basic_dsl_runtime() - demo_dsl_hot_reloading() - demo_dsl_error_handling() - demo_dsl_caching_performance() - demo_advanced_dsl_features() - - print("\n🎉 DSL Runtime demos completed!") - print("The DSL Runtime provides:") - print(" • Complete DSL-to-animation execution") - print(" • Intelligent compilation caching") - print(" • Hot reloading for development") - print(" • Robust error handling") - print(" • File-based DSL loading") - print(" • Performance optimization") -end - -run_dsl_runtime_demos() - -return { - "run_dsl_runtime_demos": run_dsl_runtime_demos, - "demo_basic_dsl_runtime": demo_basic_dsl_runtime, - "demo_dsl_hot_reloading": demo_dsl_hot_reloading, - "demo_dsl_error_handling": demo_dsl_error_handling, - "demo_dsl_caching_performance": demo_dsl_caching_performance, - "demo_advanced_dsl_features": demo_advanced_dsl_features -} \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dsl_transpiler_demo.be b/lib/libesp32/berry_animation/src/examples/dsl_transpiler_demo.be deleted file mode 100644 index db90f4857..000000000 --- a/lib/libesp32/berry_animation/src/examples/dsl_transpiler_demo.be +++ /dev/null @@ -1,220 +0,0 @@ -# DSL Transpiler Demo -# Demonstrates the single-pass DSL transpiler functionality -# -# Command to run demo is: -# ./berry -s -g -m lib/libesp32/berry_animation lib/libesp32/berry_animation/examples/dsl_transpiler_demo.be - -import tasmota -import animation - -print("=== Animation DSL Transpiler Demo ===") - -# Example 1: Simple color and strip configuration -print("\n--- Example 1: Basic Configuration ---") -var basic_dsl = "strip length 30\n" + - "color red = #FF0000\n" + - "color blue = #0000FF\n" - -print("DSL Input:") -print(basic_dsl) - -var basic_berry = animation.compile_dsl(basic_dsl) -if basic_berry != nil - print("\nGenerated Berry Code:") - print(basic_berry) -else - print("❌ Compilation failed") -end - -# Example 2: Pattern and animation definitions -print("\n--- Example 2: Patterns and Animations ---") -var pattern_dsl = "color green = #00FF00\n" + - "pattern solid_green = solid(green)\n" - -print("DSL Input:") -print(pattern_dsl) - -var pattern_berry = animation.compile_dsl(pattern_dsl) -if pattern_berry != nil - print("\nGenerated Berry Code:") - print(pattern_berry) -else - print("❌ Compilation failed") -end - -# Example 3: Complete sequence with execution -print("\n--- Example 3: Complete Animation Sequence ---") -var sequence_dsl = "# LED Strip Setup\n" + - "strip length 60\n" + - "\n" + - "# Colors\n" + - "color red = #FF0000\n" + - "color white = white\n" + - "\n" + - "# Patterns\n" + - "pattern red_solid = solid(red)\n" + - "\n" + - "# Variables\n" + - "set duration = 3s\n" + - "\n" + - "# Sequence\n" + - "sequence blink {\n" + - " play red_solid for 2s\n" + - "}\n" + - "\n" + - "# Run the sequence\n" + - "run blink\n" - -print("DSL Input:") -print(sequence_dsl) - -var sequence_berry = animation.compile_dsl(sequence_dsl) -if sequence_berry != nil - print("\nGenerated Berry Code:") - print(sequence_berry) -else - print("❌ Compilation failed") -end - -# Example 4: Variable assignments and time conversions -print("\n--- Example 4: Variables and Time Conversions ---") -var variables_dsl = "set strip_length = 60\n" + - "set brightness = 75%\n" + - "set short_time = 500ms\n" + - "set long_time = 2s\n" + - "set very_long = 1m\n" - -print("DSL Input:") -print(variables_dsl) - -var variables_berry = animation.compile_dsl(variables_dsl) -if variables_berry != nil - print("\nGenerated Berry Code:") - print(variables_berry) -else - print("❌ Compilation failed") -end - -# Example 5: Error handling demonstration -print("\n--- Example 5: Error Handling ---") -var error_dsl = "# This should produce errors\n" + - "invalid_keyword test = value\n" + - "color incomplete = \n" + - "strip length\n" - -print("DSL Input (with intentional errors):") -print(error_dsl) - -var lexer = animation.DSLLexer(error_dsl) -var tokens = lexer.tokenize() - -if lexer.has_errors() - print("\nLexical Errors:") - print(lexer.get_error_report()) -end - -var transpiler = animation.SimpleDSLTranspiler(tokens) -var error_berry = transpiler.transpile() - -if transpiler.has_errors() - print("\nTranspilation Errors:") - print(transpiler.get_error_report()) -end - -if error_berry != nil - print("\nGenerated Berry Code (despite errors):") - print(error_berry) -else - print("❌ Compilation failed due to errors") -end - -# Example 6: Demonstrate deferred resolution (forward references) -print("\n--- Example 6: Forward References ---") -var forward_ref_dsl = "# This pattern references colors defined later\n" + - "animation test_anim = red_pattern\n" + - "pattern red_pattern = solid(red)\n" + - "color red = #FF0000\n" - -print("DSL Input (with forward references):") -print(forward_ref_dsl) - -var forward_berry = animation.compile_dsl(forward_ref_dsl) -if forward_berry != nil - print("\nGenerated Berry Code:") - print(forward_berry) -else - print("❌ Forward reference resolution not yet fully implemented") - - # Show what the transpiler attempted - var lexer2 = animation.DSLLexer(forward_ref_dsl) - var tokens2 = lexer2.tokenize() - var transpiler2 = animation.SimpleDSLTranspiler(tokens2) - var result = transpiler2.transpile() - - if transpiler2.has_errors() - print("\nTranspilation Errors:") - print(transpiler2.get_error_report()) - end -end - -# Example 7: Practical LED animation -print("\n--- Example 7: Practical LED Animation ---") -var practical_dsl = "# Campfire effect setup\n" + - "strip length 60\n" + - "\n" + - "# Fire colors\n" + - "color deep_red = #8B0000\n" + - "color red = #FF0000\n" + - "color orange = #FF4500\n" + - "color yellow = #FFD700\n" + - "\n" + - "# Simple solid patterns for now\n" + - "pattern fire_base = solid(red)\n" + - "\n" + - "# Animation\n" + - "animation campfire = fire_base\n" + - "\n" + - "# Show the fire\n" + - "sequence fire_show {\n" + - " play campfire for 10s\n" + - "}\n" + - "\n" + - "run fire_show\n" - -print("DSL Input:") -print(practical_dsl) - -var practical_berry = animation.compile_dsl(practical_dsl) -if practical_berry != nil - print("\nGenerated Berry Code:") - print(practical_berry) - - print("\n--- Compilation Summary ---") - print("✅ DSL successfully compiled to Berry code") - print("✅ Strip configuration generated") - print("✅ Color definitions converted") - print("✅ Pattern definitions created") - print("✅ Animation definitions prepared") - print("✅ Sequence function generated") - print("✅ Execution code added") -else - print("❌ Compilation failed") -end - -print("\n=== Demo Complete ===") -print("The DSL transpiler can now handle:") -print("• Strip configuration (length)") -print("• Color definitions (hex colors and named colors)") -print("• Simple pattern definitions (solid patterns)") -print("• Variable assignments with type conversion") -print("• Sequence definitions with play statements") -print("• Run statements for execution") -print("• Basic error detection and reporting") -print("") -print("Next steps for full DSL implementation:") -print("• Complex pattern functions (gradient, sparkle, etc.)") -print("• Advanced animation functions (shift, pulse, etc.)") -print("• Control flow statements (repeat, if, etc.)") -print("• Function definitions and calls") -print("• Event handlers") -print("• Full forward reference resolution") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dynamic_crenel_demo.be b/lib/libesp32/berry_animation/src/examples/dynamic_crenel_demo.be deleted file mode 100644 index b6ff727c8..000000000 --- a/lib/libesp32/berry_animation/src/examples/dynamic_crenel_demo.be +++ /dev/null @@ -1,83 +0,0 @@ -# Demonstration of fully dynamic crenel_position animation -# -# This example shows how all parameters of the crenel_position animation -# can now be made dynamic using value providers. - -import global -import tasmota -import animation - -print("=== Dynamic Crenel Position Animation Demo ===") - -print("\n1. Creating dynamic value providers for all parameters:") - -# Create dynamic providers for all parameters -var dynamic_color = animation.solid_color_provider(0xFF00FF00) # Green color -var dynamic_back_color = animation.static_value_provider(0xFF000000) # Transparent background -var dynamic_pos = animation.static_value_provider(1) # Position 1 -var dynamic_pulse_size = animation.static_value_provider(3) # 3 pixels wide -var dynamic_low_size = animation.static_value_provider(2) # 2 pixels gap -var dynamic_nb_pulse = animation.static_value_provider(5) # 5 pulses - -print(" ✓ Dynamic color provider: " + str(dynamic_color)) -print(" ✓ Dynamic background color provider: " + str(dynamic_back_color)) -print(" ✓ Dynamic position provider: " + str(dynamic_pos)) -print(" ✓ Dynamic pulse size provider: " + str(dynamic_pulse_size)) -print(" ✓ Dynamic low size provider: " + str(dynamic_low_size)) -print(" ✓ Dynamic nb_pulse provider: " + str(dynamic_nb_pulse)) - -print("\n2. Creating crenel animation with all dynamic parameters:") - -# Create a crenel animation where ALL parameters are dynamic -var fully_dynamic_crenel = animation.crenel_position_animation( - dynamic_color, # Dynamic color - dynamic_pos, # Dynamic position - dynamic_pulse_size, # Dynamic pulse size - dynamic_low_size, # Dynamic low size - dynamic_nb_pulse, # Dynamic number of pulses - 10, # Static priority - 0, # Infinite duration - false, # No loop - "fully_dynamic_crenel" -) - -print(" ✓ Fully dynamic crenel created: " + str(fully_dynamic_crenel)) - -print("\n3. Testing parameter resolution:") - -# Test that resolve_value works for all parameters -var test_time = tasmota.millis() - -print(" Testing resolve_value() on all parameters:") -var resolved_color = fully_dynamic_crenel.resolve_value(dynamic_color, "color", test_time) -var resolved_pos = fully_dynamic_crenel.resolve_value(dynamic_pos, "pos", test_time) -var resolved_pulse_size = fully_dynamic_crenel.resolve_value(dynamic_pulse_size, "pulse_size", test_time) -var resolved_low_size = fully_dynamic_crenel.resolve_value(dynamic_low_size, "low_size", test_time) -var resolved_nb_pulse = fully_dynamic_crenel.resolve_value(dynamic_nb_pulse, "nb_pulse", test_time) - -print(" ✓ Color resolved to: 0x" + format("%08x", resolved_color)) -print(" ✓ Position resolved to: " + str(resolved_pos)) -print(" ✓ Pulse size resolved to: " + str(resolved_pulse_size)) -print(" ✓ Low size resolved to: " + str(resolved_low_size)) -print(" ✓ Number of pulses resolved to: " + str(resolved_nb_pulse)) -print(" ✓ All parameters resolved successfully!") - -print("\n4. Benefits of fully dynamic parameters:") -print(" ✓ Color can change over time (e.g., rainbow effects)") -print(" ✓ Position can animate (moving pulses)") -print(" ✓ Pulse size can vary (breathing effect)") -print(" ✓ Gap size can change (rhythm variations)") -print(" ✓ Number of pulses can be time-based") -print(" ✓ Background color can fade or cycle") - -print("\n5. Example use cases:") -print(" • Animated progress bars with changing colors") -print(" • Breathing effects with variable pulse sizes") -print(" • Moving patterns with position animation") -print(" • Rhythm-based lighting with variable gaps") -print(" • Dynamic backgrounds that fade in/out") - -print("\n=== Demo Complete ===") -print("All parameters in crenel_position can now be dynamic!") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/dynamic_pulse_demo.be b/lib/libesp32/berry_animation/src/examples/dynamic_pulse_demo.be deleted file mode 100644 index 3b1e8480f..000000000 --- a/lib/libesp32/berry_animation/src/examples/dynamic_pulse_demo.be +++ /dev/null @@ -1,77 +0,0 @@ -# Demonstration of fully dynamic pulse_position animation -# -# This example shows how all parameters of the pulse_position animation -# can now be made dynamic using value providers. - -import global -import tasmota -import animation - -print("=== Dynamic Pulse Position Animation Demo ===") - -print("\n1. Creating dynamic value providers for all parameters:") - -# Create dynamic providers for all parameters -var dynamic_color = animation.solid_color_provider(0xFF0000FF) # Blue color -var dynamic_back_color = animation.static_value_provider(0xFF000000) # Transparent background -var dynamic_pos = animation.static_value_provider(2) # Position 2 -var dynamic_pulse_size = animation.static_value_provider(4) # 4 pixels wide -var dynamic_slew_size = animation.static_value_provider(1) # 1 pixel fade - -print(" ✓ Dynamic color provider: " + str(dynamic_color)) -print(" ✓ Dynamic background color provider: " + str(dynamic_back_color)) -print(" ✓ Dynamic position provider: " + str(dynamic_pos)) -print(" ✓ Dynamic pulse size provider: " + str(dynamic_pulse_size)) -print(" ✓ Dynamic slew size provider: " + str(dynamic_slew_size)) - -print("\n2. Creating pulse animation with all dynamic parameters:") - -# Create a pulse animation where ALL parameters are dynamic -var fully_dynamic_pulse = animation.pulse_position_animation( - dynamic_color, # Dynamic color - dynamic_pos, # Dynamic position - dynamic_pulse_size, # Dynamic pulse size - dynamic_slew_size, # Dynamic slew size - 10, # Static priority - 0, # Infinite duration - false, # No loop - "fully_dynamic_pulse" -) - -print(" ✓ Fully dynamic pulse created: " + str(fully_dynamic_pulse)) - -print("\n3. Testing parameter resolution:") - -# Test that resolve_value works for all parameters -var test_time = tasmota.millis() - -print(" Testing resolve_value() on all parameters:") -var resolved_color = fully_dynamic_pulse.resolve_value(dynamic_color, "color", test_time) -var resolved_pos = fully_dynamic_pulse.resolve_value(dynamic_pos, "pos", test_time) -var resolved_pulse_size = fully_dynamic_pulse.resolve_value(dynamic_pulse_size, "pulse_size", test_time) -var resolved_slew_size = fully_dynamic_pulse.resolve_value(dynamic_slew_size, "slew_size", test_time) - -print(" ✓ Color resolved to: 0x" + format("%08x", resolved_color)) -print(" ✓ Position resolved to: " + str(resolved_pos)) -print(" ✓ Pulse size resolved to: " + str(resolved_pulse_size)) -print(" ✓ Slew size resolved to: " + str(resolved_slew_size)) -print(" ✓ All parameters resolved successfully!") - -print("\n4. Benefits of fully dynamic parameters:") -print(" ✓ Color can change over time (e.g., rainbow effects)") -print(" ✓ Position can animate (moving pulses)") -print(" ✓ Pulse size can vary (breathing effect)") -print(" ✓ Slew size can change (fade intensity variations)") -print(" ✓ Background color can fade or cycle") - -print("\n5. Example use cases:") -print(" • Moving spotlight effects with animated positions") -print(" • Breathing effects with variable pulse sizes and fade") -print(" • Color-changing indicators with dynamic backgrounds") -print(" • Animated progress indicators with smooth edges") -print(" • Dynamic lighting that responds to music or sensors") - -print("\n=== Demo Complete ===") -print("All parameters in pulse_position can now be dynamic!") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/ease_demo.be b/lib/libesp32/berry_animation/src/examples/ease_demo.be deleted file mode 100644 index 562a12d45..000000000 --- a/lib/libesp32/berry_animation/src/examples/ease_demo.be +++ /dev/null @@ -1,85 +0,0 @@ -# Demo of ease_in and ease_out functionality in OscillatorValueProvider -# -# This demo shows how to use the new EASE_IN and EASE_OUT waveforms -# for creating smooth acceleration and deceleration effects. - -import animation -import tasmota - -print("=== Ease In/Out Demo ===") - -# Create different easing providers -var ease_in_brightness = animation.ease_in(0, 255, 3000) # 3-second ease-in from 0 to 255 -var ease_out_brightness = animation.ease_out(255, 0, 2000) # 2-second ease-out from 255 to 0 -var ease_in_position = animation.ease_in(0, 30, 4000) # 4-second ease-in position -var ease_out_size = animation.ease_out(1, 10, 1500) # 1.5-second ease-out size - -print("Created easing providers:") -print(f" Ease-in brightness: {ease_in_brightness}") -print(f" Ease-out brightness: {ease_out_brightness}") -print(f" Ease-in position: {ease_in_position}") -print(f" Ease-out size: {ease_out_size}") - -# Simulate time progression and show values -print("\nEase-in brightness progression (0->255 over 3 seconds):") -var start_time = tasmota.millis() -for i: [0, 750, 1500, 2250, 3000] - var value = ease_in_brightness.get_value(start_time + i) - var percent = (i * 100) / 3000 - print(f" {percent:3.0f}% ({i:4d}ms): brightness = {value:3d}") -end - -print("\nEase-out brightness progression (255->0 over 2 seconds):") -start_time = tasmota.millis() -for i: [0, 500, 1000, 1500, 2000] - var value = ease_out_brightness.get_value(start_time + i) - var percent = (i * 100) / 2000 - print(f" {percent:3.0f}% ({i:4d}ms): brightness = {value:3d}") -end - -# Show comparison with linear interpolation -print("\nComparison: Ease-in vs Linear vs Ease-out (0->100 over 2 seconds):") -var linear_provider = animation.linear(0, 100, 2000) -var ease_in_demo = animation.ease_in(0, 100, 2000) -var ease_out_demo = animation.ease_out(0, 100, 2000) - -start_time = tasmota.millis() -print("Time% Linear Ease-In Ease-Out") -print("---- ------ ------- --------") -for i: [0, 500, 1000, 1500, 2000] - var percent = (i * 100) / 2000 - var linear_val = linear_provider.get_value(start_time + i) - var ease_in_val = ease_in_demo.get_value(start_time + i) - var ease_out_val = ease_out_demo.get_value(start_time + i) - print(f"{percent:3.0f}% {linear_val:6d} {ease_in_val:7d} {ease_out_val:8d}") -end - -# Show how to use with phase shifts -print("\nEase-in with 25% phase shift:") -var phased_ease = animation.ease_in(0, 100, 2000) -phased_ease.set_phase(25) - -start_time = tasmota.millis() -for i: [0, 500, 1000, 1500, 2000] - var value = phased_ease.get_value(start_time + i) - var percent = (i * 100) / 2000 - print(f" {percent:3.0f}% ({i:4d}ms): value = {value:3d}") -end - -# Example usage in animation context -print("\nExample: Using ease providers in animations") -print("# Create a breathing effect with ease-in/out") -print("var breathing_brightness = animation.ease_in(50, 255, 2000)") -print("var pulse_anim = animation.pulse(0xFF0000FF, breathing_brightness, 0, 0, true, 'breathing')") -print("") -print("# Create a smooth position animation") -print("var smooth_position = animation.ease_out(0, 29, 3000)") -print("var comet_anim = animation.comet(0xFF00FF00, smooth_position, 5, 128, true, 'smooth_comet')") - -print("\n=== Demo Complete ===") -print("The new ease_in and ease_out functions provide:") -print("• EASE_IN: Quadratic acceleration (starts slow, speeds up)") -print("• EASE_OUT: Quadratic deceleration (starts fast, slows down)") -print("• Both work with all existing OscillatorValueProvider features") -print("• Phase shifts, duty cycles, and method chaining all supported") -print("• Use animation.ease_in(start, end, duration_ms) and animation.ease_out(start, end, duration_ms)") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/enhanced/advanced_palette_demo.be b/lib/libesp32/berry_animation/src/examples/enhanced/advanced_palette_demo.be deleted file mode 100644 index 0071587af..000000000 --- a/lib/libesp32/berry_animation/src/examples/enhanced/advanced_palette_demo.be +++ /dev/null @@ -1,136 +0,0 @@ -# -# Advanced palette demonstration with multiple palettes and layering -# Showcases: Multiple palettes, composite providers, dynamic switching -# Demonstrates: Rich palette system, blending modes, palette transitions -# - -import animation - -var leds = 60 # More LEDs for better palette display - -# Create LED strip -var strip = global.Leds(leds, gpio.pin(gpio.WS2812, 0)) -var engine = animation.create_engine(strip) - -# Define multiple custom palettes -var sunset_palette = bytes( - "00FF4500" # Orange red - "40FF8C00" # Dark orange - "80FFD700" # Gold - "C0FF69B4" # Hot pink - "FF800080" # Purple -) - -var ocean_palette = bytes( - "00000080" # Navy blue - "400000FF" # Blue - "8000FFFF" # Cyan - "C000FF80" # Spring green - "FF008000" # Green -) - -var fire_palette = bytes( - "00000000" # Black - "40800000" # Dark red - "80FF0000" # Red - "C0FF8000" # Orange - "FFFFFF00" # Yellow -) - -# Create palette providers with different speeds and transitions -var sunset_provider = animation.rich_palette_color_provider(sunset_palette, 8000, 1, 200) -var ocean_provider = animation.rich_palette_color_provider(ocean_palette, 12000, 1, 180) -var fire_provider = animation.rich_palette_color_provider(fire_palette, 4000, 0, 220) # Linear transition - -# Create base palette animations -var sunset_anim = animation.filled_animation(sunset_provider, 0, 0, true, "sunset_base") -var ocean_anim = animation.filled_animation(ocean_provider, 5, 0, true, "ocean_layer") -var fire_anim = animation.filled_animation(fire_provider, 10, 0, true, "fire_overlay") - -# Add opacity oscillators for dynamic blending -var sunset_opacity = animation.smooth(100, 255, 15000) -var ocean_opacity = animation.linear(50, 200, 10000) -var fire_opacity = animation.square(0, 180, 6000, 30) # Strobe effect - -sunset_anim.set_param_value("opacity", sunset_opacity) -ocean_anim.set_param_value("opacity", ocean_opacity) -fire_anim.set_param_value("opacity", fire_opacity) - -# Add all palette layers -engine.add_animation(sunset_anim) -engine.add_animation(ocean_anim) -engine.add_animation(fire_anim) - -# Create a composite color provider that blends multiple palettes -var composite_provider = animation.composite_color_provider([ - sunset_provider, - ocean_provider, - fire_provider -], 0) # Overlay blend mode - -# Add moving effects using the composite provider -var comet_anim = animation.comet(composite_provider, 8, 3, 2000, true, true, "palette_comet") -comet_anim.priority = 20 -engine.add_animation(comet_anim) - -# Add sparkle effects with palette colors -var sparkle_anim = animation.twinkle_animation(composite_provider, 8, 300, 0, true, "palette_sparkles") -sparkle_anim.priority = 25 -engine.add_animation(sparkle_anim) - -# Event handlers for palette switching -var current_mode = 0 -var modes = ["all_layers", "sunset_only", "ocean_only", "fire_only", "composite_only"] - -animation.register_event_handler("mode_switch", - def(event_data) - current_mode = (current_mode + 1) % 5 - var mode = modes[current_mode] - - print("Switching to mode:", mode) - - # Clear current animations - engine.clear() - - if mode == "all_layers" - engine.add_animation(sunset_anim) - engine.add_animation(ocean_anim) - engine.add_animation(fire_anim) - engine.add_animation(comet_anim) - engine.add_animation(sparkle_anim) - elif mode == "sunset_only" - engine.add_animation(sunset_anim) - elif mode == "ocean_only" - engine.add_animation(ocean_anim) - elif mode == "fire_only" - engine.add_animation(fire_anim) - elif mode == "composite_only" - engine.add_animation(comet_anim) - engine.add_animation(sparkle_anim) - end - end, - 10, nil, {"description": "Switch between palette display modes"} -) - -# Auto-mode switching every 20 seconds -animation.register_event_handler("auto_switch", - def(event_data) - animation.trigger_event("mode_switch", {}) - end, - 5, nil, {"description": "Automatic mode switching"} -) - -engine.start() - -print("Advanced Palette Demo - Multiple palettes with layering and effects") -print("Features:") -print("- 3 custom palettes (sunset, ocean, fire)") -print("- Dynamic opacity blending") -print("- Composite color provider") -print("- Moving comet with palette colors") -print("- Sparkle effects") -print("- Mode switching system") -print("\nModes:", modes) -print("\nTrigger mode switch:") -print("- animation.trigger_event('mode_switch', {})") -print("\nPress Ctrl+C to stop") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/enhanced/comprehensive_blend_demo.be b/lib/libesp32/berry_animation/src/examples/enhanced/comprehensive_blend_demo.be deleted file mode 100644 index 544bd619d..000000000 --- a/lib/libesp32/berry_animation/src/examples/enhanced/comprehensive_blend_demo.be +++ /dev/null @@ -1,210 +0,0 @@ -# -# Comprehensive blending demonstration with multiple animations -# Showcases: Advanced blending, multiple layers, dynamic composition -# Demonstrates: Frame buffer blending, animation layering, blend modes -# - -import animation - -var leds = 40 # Good size for blending demonstration - -# Create LED strip -var strip = global.Leds(leds, gpio.pin(gpio.WS2812, 0)) -var engine = animation.create_engine(strip) - -# Layer 1: Base gradient background -var gradient_colors = [0x440000, 0x004400, 0x000044, 0x444400] -var gradient_provider = animation.color_cycle_color_provider(gradient_colors, 20000, 1) -var gradient_bg = animation.filled_animation(gradient_provider, 0, 0, true, "gradient_background") -gradient_bg.set_param_value("opacity", 120) # Semi-transparent base -engine.add_animation(gradient_bg) - -# Layer 2: Moving comet with trail -var comet_color = animation.rich_palette_color_provider.rainbow(8000, 1, 255) -var comet = animation.comet(comet_color, 12, 6, 4000, true, true, "rainbow_comet") -comet.priority = 10 -comet.set_param_value("opacity", 200) -engine.add_animation(comet) - -# Layer 3: Breathing pulse overlay -var pulse_color = animation.color_cycle_color_provider([ - 0xFFFFFF, 0xFF8080, 0x80FF80, 0x8080FF -], 6000, 1) -var breathe = animation.breathe_animation(pulse_color, 180, 3000, true, "color_breathe") -breathe.priority = 20 -var breathe_opacity = animation.smooth(80, 220, 5000) -breathe.set_param_value("opacity", breathe_opacity) -engine.add_animation(breathe) - -# Layer 4: Sparkle effects -var sparkle = animation.twinkle_animation(0xFFFFFF, 6, 200, 0, true, "white_sparkles") -sparkle.priority = 30 -sparkle.set_param_value("opacity", 150) -engine.add_animation(sparkle) - -# Layer 5: Position-based pulse that moves -var moving_pulse = animation.pulse_position(0xFF00FF, 8, 2, 35, 0, true, "moving_pulse") -var pulse_pos = animation.linear(2, leds-10, 7000) -var pulse_size = animation.smooth(4, 16, 4500) -moving_pulse.set_param_value("pos", pulse_pos) -moving_pulse.set_param_value("pulse_size", pulse_size) -moving_pulse.priority = 25 -moving_pulse.set_param_value("opacity", 180) -engine.add_animation(moving_pulse) - -# Demonstration of manual frame buffer blending -def demonstrate_manual_blending() - print("\n--- Manual Frame Buffer Blending Demo ---") - - # Create separate frame buffers - var frame1 = animation.frame_buffer(leds) - var frame2 = animation.frame_buffer(leds) - var frame3 = animation.frame_buffer(leds) - - # Fill frame1 with red gradient - for i: 0..leds-1 - var intensity = int(tasmota.scale_uint(i, 0, leds-1, 50, 255)) - frame1.set_pixel(i, intensity, 0, 0, 200) - end - - # Fill frame2 with green wave pattern - import math - for i: 0..leds-1 - var wave = int((math.sin(i * 0.3) + 1) * 127) - frame2.set_pixel(i, 0, wave, 0, 150) - end - - # Fill frame3 with blue sparkles - for i: 0..leds-1 - if (i % 7) == 0 # Every 7th pixel - frame3.set_pixel(i, 0, 0, 255, 180) - end - end - - # Blend all frames together - frame1.blend(frame2, 255) # Blend green wave onto red gradient - frame1.blend(frame3, 255) # Blend blue sparkles on top - - print("Manual blending result:") - print("Frame1 (red gradient):", frame1.pixels[0..20].tohex()) - print("Combined result shows additive blending of RGB channels") - - return frame1 -end - -# Event handlers for blending control -animation.register_event_handler("toggle_layer", - def(event_data) - var layer_name = event_data.find("layer", "rainbow_comet") - print("Toggling layer:", layer_name) - - var found = false - for anim: engine.get_animations() - if anim.name == layer_name - engine.remove_animation(anim) - found = true - break - end - end - - if !found - # Re-add the animation based on name - if layer_name == "rainbow_comet" - engine.add_animation(comet) - elif layer_name == "color_breathe" - engine.add_animation(breathe) - elif layer_name == "white_sparkles" - engine.add_animation(sparkle) - elif layer_name == "moving_pulse" - engine.add_animation(moving_pulse) - end - end - end, - 10, nil, {"description": "Toggle individual layers"} -) - -animation.register_event_handler("adjust_opacity", - def(event_data) - var layer = event_data.find("layer", "all") - var opacity = event_data.find("opacity", 128) - - print("Adjusting opacity for", layer, "to", opacity) - - if layer == "all" - for anim: engine.get_animations() - if anim.name != "gradient_background" - anim.set_param_value("opacity", opacity) - end - end - else - for anim: engine.get_animations() - if anim.name == layer - anim.set_param_value("opacity", opacity) - break - end - end - end - end, - 8, nil, {"description": "Adjust layer opacity"} -) - -animation.register_event_handler("demo_manual_blend", - def(event_data) - demonstrate_manual_blending() - end, - 5, nil, {"description": "Demonstrate manual frame buffer blending"} -) - -animation.register_event_handler("blend_mode_info", - def(event_data) - print("\n--- Blending Information ---") - print("Current layers (bottom to top):") - var anims = engine.get_animations() - # Sort by priority for display - for i: 0..anims.size()-1 - for j: i+1..anims.size()-1 - if anims[i].priority > anims[j].priority - var temp = anims[i] - anims[i] = anims[j] - anims[j] = temp - end - end - end - - for anim: anims - var opacity = anim.get_param("opacity", 255) - print("- " + anim.name + " (priority: " + str(anim.priority) + ", opacity: " + str(opacity) + ")") - end - - print("\nBlending occurs in priority order (low to high)") - print("Each layer blends with the accumulated result below it") - print("Alpha values control transparency and blending intensity") - end, - 1, nil, {"description": "Show current blending configuration"} -) - -# Start the engine -engine.start() - -# Show initial manual blending demo -demonstrate_manual_blending() - -print("Comprehensive Blend Demo - Advanced layering and blending") -print("Features:") -print("- 5 animation layers with different priorities") -print("- Dynamic opacity control using value providers") -print("- Multiple blend types (gradient, comet, breathe, sparkle, pulse)") -print("- Manual frame buffer blending demonstration") -print("- Interactive layer control") -print("\nLayers (priority order):") -print("0. Gradient background (priority 0)") -print("1. Rainbow comet (priority 10)") -print("2. Color breathe (priority 20)") -print("3. Moving pulse (priority 25)") -print("4. White sparkles (priority 30)") -print("\nInteractive events:") -print("- animation.trigger_event('toggle_layer', {'layer': 'rainbow_comet'})") -print("- animation.trigger_event('adjust_opacity', {'layer': 'all', 'opacity': 100})") -print("- animation.trigger_event('demo_manual_blend', {})") -print("- animation.trigger_event('blend_mode_info', {})") -print("\nPress Ctrl+C to stop") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/enhanced/dynamic_pulse_demo.be b/lib/libesp32/berry_animation/src/examples/enhanced/dynamic_pulse_demo.be deleted file mode 100644 index f66d136bb..000000000 --- a/lib/libesp32/berry_animation/src/examples/enhanced/dynamic_pulse_demo.be +++ /dev/null @@ -1,166 +0,0 @@ -# -# Dynamic pulse demonstration with value providers and events -# Showcases: Multiple pulse types, dynamic parameters, interactive control -# Demonstrates: Value provider system, event-driven parameter changes -# - -import animation - -var leds = 50 # More LEDs for better pulse effects - -# Create LED strip -var strip = global.Leds(leds, gpio.pin(gpio.WS2812, 0)) -var engine = animation.create_engine(strip) - -# Create background with subtle color cycling -var bg_provider = animation.color_cycle_color_provider([ - 0x001122, 0x002211, 0x112200, 0x220011 -], 30000, 1) -var background = animation.filled_animation(bg_provider, 0, 0, true, "cycling_background") -engine.add_animation(background) - -# Create multiple pulse types with different characteristics - -# 1. Breathing pulse with oscillating size -var breathe_pulse = animation.pulse_position(0xFF0000, 5, 1, 10, 0, true, "breathe_pulse") -var size_osc = animation.smooth(2, 12, 4000) -var pos_osc = animation.linear(5, leds-15, 8000) -breathe_pulse.set_param_value("pulse_size", size_osc) -breathe_pulse.set_param_value("pos", pos_osc) -breathe_pulse.priority = 10 -engine.add_animation(breathe_pulse) - -# 2. Strobe pulse with square wave intensity -var strobe_pulse = animation.pulse_position(0x00FF00, 3, 1, 15, 0, true, "strobe_pulse") -var strobe_intensity = animation.square(50, 255, 800, 25) # Fast strobe, 25% duty cycle -var strobe_pos = animation.linear(leds-10, 5, 6000) # Opposite direction -strobe_pulse.set_param_value("opacity", strobe_intensity) -strobe_pulse.set_param_value("pos", strobe_pos) -strobe_pulse.priority = 15 -engine.add_animation(strobe_pulse) - -# 3. Color-cycling pulse with dynamic color -var rainbow_pulse = animation.pulse_position(0x0000FF, 8, 2, 20, 0, true, "rainbow_pulse") -var rainbow_color = animation.rich_palette_color_provider.rainbow(5000, 1, 255) -var center_pos = animation.smooth(leds/4, 3*leds/4, 10000) -rainbow_pulse.set_param_value("color", rainbow_color) -rainbow_pulse.set_param_value("pos", center_pos) -rainbow_pulse.priority = 20 -engine.add_animation(rainbow_pulse) - -# 4. Fire pulse with fire palette -var fire_palette = animation.PALETTE_FIRE -var fire_color = animation.rich_palette_color_provider(fire_palette, 3000, 0, 255) -var fire_pulse = animation.pulse_position(0xFF4400, 6, 3, 25, 0, true, "fire_pulse") -var fire_size = animation.linear(4, 15, 7000) -fire_pulse.set_param_value("color", fire_color) -fire_pulse.set_param_value("pulse_size", fire_size) -fire_pulse.set_param_value("pos", leds/2) # Fixed center position -fire_pulse.priority = 25 -engine.add_animation(fire_pulse) - -# Interactive event handlers for dynamic control -animation.register_event_handler("speed_up", - def(event_data) - print("Speed up event - doubling all animation speeds") - for anim: engine.get_animations() - if anim.name != "cycling_background" - # Speed up oscillators by halving their duration - for param_name: ["pulse_size", "pos", "opacity", "color"] - var param_value = anim.get_param(param_name, nil) - if animation.is_value_provider(param_value) - if param_value.find("duration_ms") != nil - param_value.duration_ms = param_value.duration_ms / 2 - end - end - end - end - end - end, - 10, nil, {"description": "Double animation speeds"} -) - -animation.register_event_handler("slow_down", - def(event_data) - print("Slow down event - halving all animation speeds") - for anim: engine.get_animations() - if anim.name != "cycling_background" - # Slow down oscillators by doubling their duration - for param_name: ["pulse_size", "pos", "opacity", "color"] - var param_value = anim.get_param(param_name, nil) - if animation.is_value_provider(param_value) - if param_value.find("duration_ms") != nil - param_value.duration_ms = param_value.duration_ms * 2 - end - end - end - end - end - end, - 10, nil, {"description": "Halve animation speeds"} -) - -animation.register_event_handler("randomize_positions", - def(event_data) - print("Randomize positions event - setting random pulse positions") - import math - for anim: engine.get_animations() - if anim.name[0..4] == "pulse" || anim.name[-5..-1] == "pulse" - var random_pos = int(math.rand() % (leds - 10)) + 5 - anim.set_param_value("pos", random_pos) - end - end - end, - 5, nil, {"description": "Randomize pulse positions"} -) - -animation.register_event_handler("toggle_pulse", - def(event_data) - var pulse_name = event_data.find("pulse_name", "breathe_pulse") - print("Toggle pulse event - toggling", pulse_name) - - var found = false - for anim: engine.get_animations() - if anim.name == pulse_name - engine.remove_animation(anim) - found = true - break - end - end - - if !found - # Re-add the pulse based on name - if pulse_name == "breathe_pulse" - engine.add_animation(breathe_pulse) - elif pulse_name == "strobe_pulse" - engine.add_animation(strobe_pulse) - elif pulse_name == "rainbow_pulse" - engine.add_animation(rainbow_pulse) - elif pulse_name == "fire_pulse" - engine.add_animation(fire_pulse) - end - end - end, - 8, nil, {"description": "Toggle individual pulses on/off"} -) - -engine.start() - -print("Dynamic Pulse Demo - Multiple pulse types with interactive control") -print("Features:") -print("- 4 different pulse types with unique characteristics") -print("- Dynamic parameters using value providers") -print("- Interactive event system for real-time control") -print("- Background color cycling") -print("- Layered composition with priorities") -print("\nPulse types:") -print("- Breathe: Red pulse with oscillating size and position") -print("- Strobe: Green pulse with square wave intensity") -print("- Rainbow: Color-cycling pulse with smooth movement") -print("- Fire: Fire-colored pulse with growing size") -print("\nInteractive events:") -print("- animation.trigger_event('speed_up', {})") -print("- animation.trigger_event('slow_down', {})") -print("- animation.trigger_event('randomize_positions', {})") -print("- animation.trigger_event('toggle_pulse', {'pulse_name': 'breathe_pulse'})") -print("\nPress Ctrl+C to stop") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/enhanced/modern_breathe_showcase.be b/lib/libesp32/berry_animation/src/examples/enhanced/modern_breathe_showcase.be deleted file mode 100644 index 2e03af174..000000000 --- a/lib/libesp32/berry_animation/src/examples/enhanced/modern_breathe_showcase.be +++ /dev/null @@ -1,90 +0,0 @@ -# -# Enhanced modern version of the breathing effect -# Showcases: Multiple colors, layering, value providers, events -# Demonstrates: Advanced color providers, dynamic parameters, event system -# - -import animation - -var leds = 30 # More LEDs for better effect - -# Create LED strip -var strip = global.Leds(leds, gpio.pin(gpio.WS2812, 0)) -var engine = animation.create_engine(strip) - -# Create multiple breathing layers with different colors and speeds -var colors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF] -var durations = [3000, 4000, 5000, 3500, 4500] - -# Create breathing animations with different phases -for i: 0..4 - var color = colors[i] - var duration = durations[i] - - # Create oscillator with phase offset to create wave effect - var phase_offset = int(tasmota.scale_uint(i, 0, 4, 0, 100)) - var brightness_osc = animation.smooth(30, 200, duration) - brightness_osc.set_phase(phase_offset) - - # Create position oscillator for moving breathe effect - var pos_osc = animation.linear(0, leds-5, duration * 2) - pos_osc.set_phase(phase_offset) - - # Create breathe animation - var breathe_anim = animation.breathe_animation(color, 150, duration, true, "breathe_" + str(i)) - breathe_anim.set_param_value("opacity", brightness_osc) - - # Add slight priority differences for layering - breathe_anim.priority = i * 2 - engine.add_animation(breathe_anim) -end - -# Add a background rainbow that slowly cycles -var rainbow_bg = animation.filled_animation( - animation.rich_palette_color_provider.rainbow(20000, 1, 50), # Slow, dim rainbow - 0, 0, true, "rainbow_background" -) -engine.add_animation(rainbow_bg) - -# Register event handlers for interactive control -animation.register_event_handler("button_press", - def(event_data) - print("Button pressed - changing breathing speed") - # Speed up all animations - for anim: engine.get_animations() - if anim.name[0..7] == "breathe_" - # Double the breathing speed - var current_duration = anim.get_param("duration", 3000) - anim.set_param("duration", current_duration / 2) - end - end - end, - 10, nil, {"description": "Speed up breathing on button press"} -) - -animation.register_event_handler("timer", - def(event_data) - if event_data.find("interval") == 10000 # Every 10 seconds - print("Timer event - adding sparkle effect") - # Add temporary sparkle overlay - var sparkle = animation.twinkle_animation(0xFFFFFF, 5, 500, 2000, false, "sparkle_overlay") - sparkle.priority = 100 # High priority overlay - engine.add_animation(sparkle) - end - end, - 5, nil, {"description": "Add sparkles every 10 seconds"} -) - -engine.start() - -print("Modern Breathe Showcase - Enhanced breathing with multiple layers") -print("Features:") -print("- 5 breathing layers with different colors and phases") -print("- Background rainbow effect") -print("- Event system for interactive control") -print("- Dynamic parameter updates") -print("- Layered composition") -print("\nTrigger events:") -print("- animation.trigger_event('button_press', {})") -print("- animation.trigger_event('timer', {'interval': 10000})") -print("\nPress Ctrl+C to stop") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/event_system_demo.be b/lib/libesp32/berry_animation/src/examples/event_system_demo.be deleted file mode 100644 index 1f6f844eb..000000000 --- a/lib/libesp32/berry_animation/src/examples/event_system_demo.be +++ /dev/null @@ -1,242 +0,0 @@ -# Event System Demo -# Demonstrates the event handling capabilities of the Berry Animation Framework - -import string - -# Import animation module -var animation = global.animation - -print("=== Event System Demo ===") -print() - -# Create a mock LED strip for demonstration -var mock_strip = { - "length": def() return 30 end, - "show": def() end, - "can_show": def() return true end, - "set_pixel": def(i, color) end -} - -# Create animation engine -var engine = animation.create_engine(mock_strip) - -print("1. Basic Event Handler Registration") -print("-----------------------------------") - -# Register a simple event handler -var button_handler = animation.register_event_handler( - "button_press", - def(event_data) - print(f"Button pressed! Data: {event_data}") - # Add a flash animation - var flash_anim = animation.solid(0xFFFFFFFF) # White flash - engine.add_animation(flash_anim) - end, - 10, # High priority - nil, # No condition - {} # No metadata -) - -print("✓ Registered button_press event handler") - -# Trigger the event -print("Triggering button_press event...") -animation.trigger_event("button_press", {"button": "main", "timestamp": tasmota.millis()}) -print() - -print("2. Event Handler with Conditions") -print("--------------------------------") - -# Register a conditional event handler -var brightness_handler = animation.register_event_handler( - "brightness_change", - def(event_data) - var brightness = event_data["brightness"] - if brightness > 80 - print("High brightness detected - switching to day mode") - else - print("Low brightness detected - switching to night mode") - end - end, - 5, # Medium priority - def(event_data) return event_data.contains("brightness") end, # Condition - {"type": "brightness_monitor"} # Metadata -) - -print("✓ Registered brightness_change event handler with condition") - -# Trigger with valid data -print("Triggering brightness_change with brightness=90...") -animation.trigger_event("brightness_change", {"brightness": 90}) - -# Trigger with invalid data (should be ignored due to condition) -print("Triggering brightness_change without brightness data (should be ignored)...") -animation.trigger_event("brightness_change", {"other_data": "test"}) -print() - -print("3. Timer Event with Metadata") -print("----------------------------") - -# Register a timer event handler -var timer_handler = animation.register_event_handler( - "timer", - def(event_data) - print(f"Timer event triggered! Interval: {event_data['interval']}ms") - # Add a pulse animation - var pulse_anim = animation.pulse_animation(animation.solid(0xFF00FF00), 1000, 100, 255) # Green pulse - engine.add_animation(pulse_anim) - end, - 0, # Normal priority - nil, # No condition - {"interval": 5000, "repeat": true} # 5-second timer -) - -print("✓ Registered timer event handler") - -# Simulate timer trigger -print("Simulating timer trigger...") -animation.trigger_event("timer", {"interval": 5000}) -print() - -print("4. Global Event Handler") -print("-----------------------") - -# Register a global event handler that responds to all events -var global_handler = animation.register_event_handler( - "*", # Global event name - def(event_data) - var event_name = event_data["event_name"] - print(f"Global handler: Event '{event_name}' was triggered") - end, - 1, # Low priority (runs after specific handlers) - nil, # No condition - {"type": "global_monitor"} -) - -print("✓ Registered global event handler") - -# Trigger various events to show global handler -print("Triggering various events to demonstrate global handler...") -animation.trigger_event("test_event_1", {"data": "test1"}) -animation.trigger_event("test_event_2", {"data": "test2"}) -print() - -print("5. DSL Event Handler Compilation") -print("--------------------------------") - -# Demonstrate DSL event handler compilation -var dsl_code = - "strip length 30\n" - "color red = #FF0000\n" - "color blue = #0000FF\n" - "color white = #FFFFFF\n" - "\n" - "# Event handlers\n" - "on button_press: solid(red)\n" - "on timer(3s): solid(blue)\n" - "on startup: solid(white)\n" - "\n" - "# Main sequence\n" - "sequence main {\n" - " play solid(red) for 2s\n" - " play solid(blue) for 2s\n" - "}\n" - "\n" - "run main" - -print("Compiling DSL with event handlers...") -var compiled_code = animation.compile_dsl(dsl_code) - -if compiled_code != nil - print("✓ DSL compilation successful!") - print("Generated Berry code contains:") - if string.find(compiled_code, "register_event_handler") >= 0 - print(" - Event handler registrations") - end - if string.find(compiled_code, "button_press") >= 0 - print(" - Button press event") - end - if string.find(compiled_code, "timer") >= 0 - print(" - Timer event") - end - if string.find(compiled_code, "startup") >= 0 - print(" - Startup event") - end -else - print("✗ DSL compilation failed") -end -print() - -print("6. Event System Status") -print("---------------------") - -# Show registered events -var registered_events = animation.get_registered_events() -print(f"Registered events: {registered_events}") - -# Show handlers for a specific event -var button_handlers = animation.get_event_handlers("button_press") -print(f"Button press handlers: {size(button_handlers)}") - -for handler_info : button_handlers - print(f" - Priority: {handler_info['priority']}, Active: {handler_info['is_active']}") -end -print() - -print("7. Animation Engine Integration") -print("-------------------------------") - -# Demonstrate animation engine event integration -print("Testing animation engine interrupt methods...") - -# Add some test animations -engine.add_animation(animation.solid(0xFF00FF00)) # Green -engine.add_animation(animation.solid(0xFF0000FF)) # Blue - -print(f"Animations before interrupt: {engine.size()}") - -# Test interrupt current -engine.interrupt_current() -print("✓ interrupt_current() executed") - -# Add more animations -engine.add_animation(animation.solid(0xFFFF0000)) # Red -engine.add_animation(animation.solid(0xFFFFFF00)) # Yellow - -print(f"Animations after adding more: {engine.size()}") - -# Test interrupt all -engine.interrupt_all() -print("✓ interrupt_all() executed") -print(f"Animations after interrupt_all: {engine.size()}") - -print() - -print("8. Cleanup") -print("----------") - -# Clean up event handlers -animation.unregister_event_handler(button_handler) -animation.unregister_event_handler(brightness_handler) -animation.unregister_event_handler(timer_handler) -animation.unregister_event_handler(global_handler) - -print("✓ All event handlers unregistered") - -# Verify cleanup -var remaining_events = animation.get_registered_events() -print(f"Remaining registered events: {size(remaining_events)}") - -print() -print("=== Event System Demo Complete ===") -print("The event system is ready for use!") -print() -print("Key Features Demonstrated:") -print("- Basic event handler registration and triggering") -print("- Event priority ordering") -print("- Conditional event handlers") -print("- Global event handlers") -print("- Timer events with metadata") -print("- DSL event handler compilation") -print("- Animation engine integration") -print("- Event handler cleanup") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/fast_loop_demo.be b/lib/libesp32/berry_animation/src/examples/fast_loop_demo.be deleted file mode 100644 index 35e187ce7..000000000 --- a/lib/libesp32/berry_animation/src/examples/fast_loop_demo.be +++ /dev/null @@ -1,158 +0,0 @@ -# Fast Loop Integration Demo -# -# This example demonstrates how the AnimationController integrates -# with Tasmota's fast_loop system for efficient animation updates. - -# Import the animation module -import global -import tasmota -import animation - -# Create a mock WS2812 class for testing -class WS2812 - var length_value - var pixels - var show_called - var can_show_result - - def init(length) - self.length_value = length - self.pixels = {} - self.show_called = false - self.can_show_result = true - end - - def length() - return self.length_value - end - - def set_pixel_color(index, color) - self.pixels[index] = { - "r": color & 0xFF, - "g": (color >> 8) & 0xFF, - "b": (color >> 16) & 0xFF - } - end - - def show() - self.show_called = true - end - - def can_show() - return self.can_show_result - end -end - -# Create a simple animation that shows the fast_loop timing -class TimingAnimation : animation.animation - var color - var last_update - var update_count - - def init(color) - # Initialize with priority 1, 1 second duration, and looping enabled - super(self).init(1, 1000, true, "timing_animation") - - # Store parameters - self.color = color - self.last_update = 0 - self.update_count = 0 - end - - def update(time_ms) - # Track update timing - if self.last_update > 0 - var delta = time_ms - self.last_update - - # Print timing information every second - if self.update_count % 200 == 0 # Roughly every second at ~200 updates/sec - print(format("Animation update delta: %dms", delta)) - end - end - - self.last_update = time_ms - self.update_count += 1 - - return super(self).update(time_ms) - end - - def render(frame) - if !self.is_running || frame == nil - return false - end - - # Extract color components - var r = self.color & 0xFF - var g = (self.color >> 8) & 0xFF - var b = (self.color >> 16) & 0xFF - - # Fill the frame with the color - frame.fill_pixels(animation.frame_buffer.to_color(r, g, b, 255)) - - return true - end -end - -# Main demo function -def run_demo() - # Create a WS2812 LED strip (adjust parameters for your setup) - var strip_length = 30 - var strip = WS2812(strip_length) - - # Create the animation controller - var controller = animation.animation_controller(strip) - - # Create timing animation - var timing_anim = TimingAnimation(0x0000FF) # Blue color - - # Add animation to the controller - controller.add_animation(timing_anim) - - # Start the controller - controller.start() - - print("Fast loop integration demo started") - print("This demo shows the fast_loop integration with timing information") - print("Press 's' to stop animations") - print("Press 'r' to restart animations") - print("Press 'q' to quit") - - # Set up a simple command handler - def handle_command(cmd) - if cmd == "s" - controller.stop() - print("Animations stopped") - elif cmd == "r" - controller.start() - print("Animations restarted") - elif cmd == "q" - controller.stop() - print("Demo ended") - return false - end - return true - end - - # In a real application, you would integrate with Tasmota's command system - # For this demo, we'll just return the controller and handler for manual testing - return { - "controller": controller, - "handler": handle_command - } -end - -# Run the demo if this file is executed directly -try - if tasmota != nil - # When running in Tasmota - var demo = run_demo() - return demo - end -except .. as e - # When running in standalone Berry or if tasmota is not available - print("This demo is designed to run in Tasmota") - print("Running in simulation mode...") - var demo = run_demo() - print("Demo initialized successfully in simulation mode") - return demo -end \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/filled_animation_demo.be b/lib/libesp32/berry_animation/src/examples/filled_animation_demo.be deleted file mode 100644 index e73a0feb0..000000000 --- a/lib/libesp32/berry_animation/src/examples/filled_animation_demo.be +++ /dev/null @@ -1,113 +0,0 @@ -# Filled Animation Demo for Berry Animation Framework -# -# This example demonstrates the use of the animation.filled_animation class with different color providers. - -import animation - -# Create a strip and controller -var strip_width = 30 -var controller = animation.animation_controller(strip_width) - -print("animation.filled_animation Demo") -print("====================") - -# Example 1: Solid color -print("\n1. Creating a filled animation with a solid color...") -var solid_anim = animation.filled_animation(0xFF0000FF, 10, 255, 0, true, "red_fill") -controller.add_animation(solid_anim) -solid_anim.start() - -# Wait a moment to see the solid color -tasmota.delay(2000) -solid_anim.stop() -controller.remove_animation(solid_anim) - -# Example 2: Color cycle provider -print("\n2. Creating a filled animation with a color cycle provider...") -var cycle_anim = animation.color_cycle_animation( - [0xFF0000FF, 0xFF00FF00, 0xFFFF0000], # RGB colors - 3000, # 3 second cycle period - 1, # Sine transition - 10 # Priority -) -controller.add_animation(cycle_anim) -cycle_anim.start() - -# Let the color cycle run for a few seconds -tasmota.delay(5000) -cycle_anim.stop() -controller.remove_animation(cycle_anim) - -# Example 3: Rich palette provider -print("\n3. Creating a filled animation with a rich palette provider...") -var rainbow_anim = animation.rich_palette_animation( - animation.PALETTE_RAINBOW, # Use the rainbow palette - 5000, # 5 second cycle period - 1, # Sine transition - 255, # Full brightness - 10 # Priority -) -controller.add_animation(rainbow_anim) -rainbow_anim.start() - -# Let the rainbow animation run for a few seconds -tasmota.delay(5000) -rainbow_anim.stop() -controller.remove_animation(rainbow_anim) - -# Example 4: Composite provider -print("\n4. Creating a filled animation with a composite provider...") -var palette_provider = animation.rich_palette_color_provider( - animation.PALETTE_RAINBOW, # Use the rainbow palette - 5000, # 5 second cycle period - 1, # Sine transition - 255 # Full brightness -) - -var cycle_provider = animation.color_cycle_color_provider( - [0xFF0000FF, 0xFF00FF00, 0xFFFF0000], # RGB colors - 3000, # 3 second cycle period - 1 # Sine transition -) - -var composite_anim = animation.composite( - [palette_provider, cycle_provider], # List of providers to combine - 0, # Overlay blend mode - 10 # Priority -) -controller.add_animation(composite_anim) -composite_anim.start() - -# Let the composite animation run for a few seconds -tasmota.delay(5000) -composite_anim.stop() -controller.remove_animation(composite_anim) - -# Example 5: Changing color provider dynamically -print("\n5. Changing color provider dynamically...") -var dynamic_anim = animation.filled_animation(0xFF0000FF, 10, 255, 0, true, "dynamic") -controller.add_animation(dynamic_anim) -dynamic_anim.start() - -# Show solid color first -tasmota.delay(2000) - -# Change to color cycle provider -print(" Changing to color cycle provider...") -dynamic_anim.set_color_provider(cycle_provider) -tasmota.delay(3000) - -# Change to rich palette provider -print(" Changing to rich palette provider...") -dynamic_anim.set_color_provider(palette_provider) -tasmota.delay(3000) - -# Change back to solid color -print(" Changing back to solid color...") -dynamic_anim.set_color(0x00FF00FF) # Green -tasmota.delay(2000) - -dynamic_anim.stop() -controller.remove_animation(dynamic_anim) - -print("\nanimation.filled Demo completed!") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/fire_animation_demo.be b/lib/libesp32/berry_animation/src/examples/fire_animation_demo.be deleted file mode 100644 index c49549438..000000000 --- a/lib/libesp32/berry_animation/src/examples/fire_animation_demo.be +++ /dev/null @@ -1,186 +0,0 @@ -# Fire Animation Demo -# Demonstrates the FireAnimation class with various configurations - -import "animation" as animation - -print("=== Fire Animation Demo ===") - -# Demo configuration -var STRIP_LENGTH = 30 -var DEMO_DURATION = 10000 # 10 seconds per demo - -print(f"Strip length: {STRIP_LENGTH} pixels") -print(f"Demo duration: {DEMO_DURATION}ms per animation") - -# Demo 1: Classic Fire Effect -print("\n--- Demo 1: Classic Fire Effect ---") -var classic_fire = animation.fire_animation.classic(180, STRIP_LENGTH, 10) -print(f"Created classic fire: {classic_fire}") -print("This creates a realistic fire effect with warm colors") -print("- Base intensity: 180/255") -print("- Flicker speed: 8 Hz") -print("- Uses built-in fire palette (black -> dark red -> red -> orange -> yellow)") - -# Demo 2: Intense Fire -print("\n--- Demo 2: Intense Fire ---") -var intense_fire = animation.fire_animation(nil, 255, 12, 150, 40, 180, STRIP_LENGTH, 10, 0, true, "intense_fire") -print(f"Created intense fire: {intense_fire}") -print("This creates a more intense fire with:") -print("- Maximum intensity: 255/255") -print("- Faster flicker: 12 Hz") -print("- More flicker variation: 150/255") -print("- Faster cooling: 40/255") -print("- More sparks: 180/255") - -# Demo 3: Gentle Fire -print("\n--- Demo 3: Gentle Fire ---") -var gentle_fire = animation.fire_animation(nil, 120, 4, 50, 80, 80, STRIP_LENGTH, 10, 0, true, "gentle_fire") -print(f"Created gentle fire: {gentle_fire}") -print("This creates a gentler fire with:") -print("- Lower intensity: 120/255") -print("- Slower flicker: 4 Hz") -print("- Less flicker variation: 50/255") -print("- Slower cooling: 80/255") -print("- Fewer sparks: 80/255") - -# Demo 4: Single Color Fire -print("\n--- Demo 4: Single Color Fire (Blue Flame) ---") -var blue_fire = animation.fire_animation.solid(0xFF0080FF, 200, STRIP_LENGTH, 10) -print(f"Created blue fire: {blue_fire}") -print("This creates a blue flame effect using a single color") -print("- Color: Blue (0xFF0080FF)") -print("- Intensity: 200/255") - -# Demo 5: Custom Palette Fire -print("\n--- Demo 5: Custom Palette Fire (Green Flame) ---") -# Create a green fire palette -var green_fire_palette = bytes( - "00000000" # Black (value 0) - "40004000" # Dark green (value 64) - "8000FF00" # Green (value 128) - "C080FF80" # Light green (value 192) - "FFFFFF80" # Very light green (value 255) -) -var green_fire = animation.fire_animation.palette(green_fire_palette, 180, STRIP_LENGTH, 10) -print(f"Created green fire: {green_fire}") -print("This creates a green flame effect using a custom palette") - -# Demo 6: Animation Controller Integration -print("\n--- Demo 6: Animation Controller Integration ---") -print("Creating animation controller and adding multiple fire effects...") - -# Create a mock LED strip (in real usage, this would be a real strip) -class MockStrip - var pixels - var strip_length - - def init(length) - self.strip_length = length - self.pixels = [] - self.pixels.resize(length) - for i: 0..length-1 - self.pixels[i] = 0 - end - end - - def set_pixel_color(index, color) - if index >= 0 && index < self.strip_length - self.pixels[index] = color - end - end - - def show() - # In real usage, this would update the physical LEDs - return true - end - - def get_pixel_color(index) - if index >= 0 && index < self.strip_length - return self.pixels[index] - end - return 0 - end - - def length() - return self.strip_length - end -end - -var mock_strip = MockStrip(STRIP_LENGTH) -var controller = animation.animation_controller(mock_strip, 255) - -# Add multiple fire animations with different priorities -controller.add_animation(classic_fire) -controller.add_animation(blue_fire.set_priority(5)) # Lower priority - -print("Added classic fire (priority 10) and blue fire (priority 5)") -print("The classic fire will render on top of the blue fire") - -# Demo 7: Real-time Parameter Updates -print("\n--- Demo 7: Real-time Parameter Updates ---") -var dynamic_fire = animation.fire_animation.classic(100, STRIP_LENGTH, 10) -print(f"Created dynamic fire with initial intensity: {dynamic_fire.get_param('intensity')}") - -# Simulate parameter changes over time -var intensities = [100, 150, 200, 255, 180, 120] -for i: 0..size(intensities)-1 - var new_intensity = intensities[i] - dynamic_fire.set_intensity(new_intensity) - print(f"Updated intensity to: {new_intensity}") -end - -# Demo 8: Performance Considerations -print("\n--- Demo 8: Performance Considerations ---") -print("Fire animation performance tips:") -print("- Lower flicker_speed reduces CPU usage (fewer updates per second)") -print("- Smaller strip_length reduces memory usage and computation") -print("- Lower flicker_amount reduces random number generation overhead") -print("- Use solid colors instead of palettes for maximum performance") - -# Create a performance-optimized fire -var perf_fire = animation.fire_animation.solid(0xFFFF4500, 150, STRIP_LENGTH, 10) -perf_fire.set_flicker_speed(4) # Slower updates -perf_fire.set_flicker_amount(30) # Less randomness -print(f"Created performance-optimized fire: {perf_fire}") - -# Demo 9: Simulation Test -print("\n--- Demo 9: Fire Simulation Test ---") -print("Running fire simulation for a few cycles...") - -var test_fire = animation.fire_animation.classic(180, 10, 10) # Smaller strip for easier visualization -test_fire.start() - -var frame = animation.frame_buffer(10) -var start_time = 1000 - -for cycle: 0..4 - var current_time = start_time + (cycle * 125) # 8 Hz = 125ms intervals - test_fire.update(current_time) - test_fire.render(frame, current_time) - - print(f"Cycle {cycle + 1}:") - var heat_info = " Heat pattern: " - for i: 0..9 - var color = frame.get_pixel_color(i) - var brightness = 0 - if color != 0xFF000000 - # Extract brightness from color (simple approximation) - var r = (color >> 16) & 0xFF - var g = (color >> 8) & 0xFF - var b = color & 0xFF - brightness = (r + g + b) / 3 - end - heat_info += f"{brightness:3d} " - end - print(heat_info) -end - -print("\n=== Fire Animation Demo Complete ===") -print("The fire animation provides realistic flame effects with:") -print("- Heat-based simulation with cooling and sparking") -print("- Configurable intensity, flicker, and timing") -print("- Support for custom colors and palettes") -print("- Real-time parameter updates") -print("- Integration with the animation framework") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/frame_buffer_demo.be b/lib/libesp32/berry_animation/src/examples/frame_buffer_demo.be deleted file mode 100644 index d8f36e210..000000000 --- a/lib/libesp32/berry_animation/src/examples/frame_buffer_demo.be +++ /dev/null @@ -1,82 +0,0 @@ -# FrameBuffer Demo -# -# This example demonstrates the basic usage of the FrameBuffer class. - -import global -import tasmota -import animation - -# Create a frame buffer with 10 pixels -var fb = animation.frame_buffer(10) - -# Clear the buffer (set all pixels to transparent black) -fb.clear() -print(f"After clear: {fb.tohex()}") - -# Set individual pixels -fb.set_pixel_color(0, 0xFFFF0000) # Red -fb.set_pixel_color(1, 0xFF00FF00) # Green -fb.set_pixel_color(2, 0xFF0000FF) # Blue -fb.set_pixel_color(3, 0xFFFFFF00) # Yellow -fb.set_pixel_color(4, 0xFFFF00FF) # Purple -print(f"After setting pixels: {fb.tohex()}") - -# Fill the buffer with a single color -fb.fill_pixels(0xFF00FFFF) # Cyan -print(f"After fill with cyan: {fb.tohex()}") - -# Create a second buffer for blending -var fb2 = animation.frame_buffer(10) -fb2.fill_pixels(0x80FF0000) # Red with 50% alpha - -# Blend the two buffers using per-pixel alpha -fb.blend_pixels(fb2) # Blend using per-pixel alpha with default normal blend mode -print(f"After blending with red using per-pixel alpha (normal mode): {fb.tohex()}") - -# Create a gradient fill -fb.gradient_fill(0xFFFF0000, 0xFF0000FF, 0, 9) # Red to blue gradient -print(f"After gradient fill: {fb.tohex()}") - -# Demonstrate region-specific blending -var region_buffer = animation.frame_buffer(10) -region_buffer.fill_pixels(0xC800FF00) # Green with ~78% alpha (200/255) -fb.blend_pixels(region_buffer, fb.BLEND_MODE_NORMAL, 0, 4) # Blend green into first half -print(f"After blending green into first half: {fb.tohex()}") - -# Using array-like access -fb[9] = 0xFFFF0000 # Set last pixel to red -print(f"After setting last pixel to red: {fb.tohex()}") - -# Demonstrate apply_opacity method -print("\nDemonstrating apply_opacity method:") - -# Create a test buffer with various alpha values -var opacity_demo = animation.frame_buffer(5) -opacity_demo.set_pixel_color(0, 0xFF0000FF) # Red, full alpha -opacity_demo.set_pixel_color(1, 0x800000FF) # Red, 50% alpha -opacity_demo.set_pixel_color(2, 0x400000FF) # Red, 25% alpha -opacity_demo.set_pixel_color(3, 0x200000FF) # Red, 12.5% alpha -opacity_demo.set_pixel_color(4, 0x100000FF) # Red, 6.25% alpha -print(f"Original alpha values: {opacity_demo.dump()}") - -# Reduce opacity by 50% -var reduced_demo = opacity_demo.copy() -reduced_demo.apply_opacity(128) # 50% opacity -print(f"After 50% opacity reduction: {reduced_demo.dump()}") - -# Increase opacity by 50% -var increased_demo = opacity_demo.copy() -increased_demo.apply_opacity(384) # 150% opacity (256 + 128) -print(f"After 50% opacity increase: {increased_demo.dump()}") - -# Make fully transparent -var transparent_demo = opacity_demo.copy() -transparent_demo.apply_opacity(0) # 0% opacity -print(f"After making fully transparent: {transparent_demo.dump()}") - -# Make maximum opaque -var max_demo = opacity_demo.copy() -max_demo.apply_opacity(511) # Maximum opacity -print(f"After maximum opacity: {max_demo.dump()}") - -print("Frame buffer demo completed!") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/layering_demo.be b/lib/libesp32/berry_animation/src/examples/layering_demo.be deleted file mode 100644 index c6bd152d4..000000000 --- a/lib/libesp32/berry_animation/src/examples/layering_demo.be +++ /dev/null @@ -1,229 +0,0 @@ -# Animation Layering Demo -# -# This example demonstrates how to use the AnimationManager to layer multiple animations -# with different priorities and opacities. -# -# Command to run: -# ./berry -s -g -m lib/libesp32/berry_animation lib/libesp32/berry_animation/examples/layering_demo.be - -import global -import tasmota -import animation - -# Create a simple animation class that fills with a solid color -class SolidAnimation : animation.animation - var color - - def init(priority, color, name) - super(self).init(priority, 0, false, name) - self.color = color - - # Register parameters - self.register_param("color", {"default": 0xFF0000}) - - # Set initial values - self.set_param("color", color) - end - - def render(frame) - if !self.is_running || frame == nil - return false - end - - # Extract components from color - var r = self.color & 0xFF - var g = (self.color >> 8) & 0xFF - var b = (self.color >> 16) & 0xFF - - # Fill the frame with the color - frame.fill_pixels(animation.frame_buffer.to_color(r, g, b)) - - return true - end - - def on_param_changed(name, value) - if name == "color" - self.color = value - end - end -end - -# Create a simple animation class that creates a gradient -class GradientAnimation : animation.animation - var color_start - var color_end - - def init(priority, color_start, color_end, name) - super(self).init(priority, 0, false, name) - self.color_start = color_start - self.color_end = color_end - - # Register parameters - self.register_param("color_start", {"default": 0xFF0000}) - self.register_param("color_end", {"default": 0x0000FF}) - - # Set initial values - self.set_param("color_start", color_start) - self.set_param("color_end", color_end) - end - - def render(frame) - if !self.is_running || frame == nil - return false - end - - # Create a gradient from start to end color - frame.gradient_fill(self.color_start, self.color_end) - - return true - end - - def on_param_changed(name, value) - if name == "color_start" - self.color_start = value - elif name == "color_end" - self.color_end = value - end - end -end - -# Create a simple animation class that creates a pattern -class PatternAnimation : animation.animation - var pattern_width - var color1 - var color2 - - def init(priority, pattern_width, color1, color2, name) - super(self).init(priority, 0, false, name) - self.pattern_width = pattern_width - self.color1 = color1 - self.color2 = color2 - - # Register parameters - self.register_param("pattern_width", {"min": 1, "default": 1}) - self.register_param("color1", {"default": 0xFFFFFF}) - self.register_param("color2", {"default": 0x000000}) - - # Set initial values - self.set_param("pattern_width", pattern_width) - self.set_param("color1", color1) - self.set_param("color2", color2) - end - - def render(frame) - if !self.is_running || frame == nil - return false - end - - # Create a pattern of alternating colors - var i = 0 - while i < frame.width - var color = (i / self.pattern_width) % 2 == 0 ? self.color1 : self.color2 - - # Extract components from color - var r = color & 0xFF - var g = (color >> 8) & 0xFF - var b = (color >> 16) & 0xFF - - # Set the pixel - frame.set_pixel_color(i, animation.frame_buffer.to_color(r, g, b)) - - i += 1 - end - - return true - end - - def on_param_changed(name, value) - if name == "pattern_width" - self.pattern_width = value - elif name == "color1" - self.color1 = value - elif name == "color2" - self.color2 = value - end - end -end - -# Create a frame buffer for rendering -var width = 20 # 20 pixels -var frame = animation.frame_buffer(width) - -# Create a renderer -var renderer = animation.renderer(width) - -# Create an animation manager with the renderer -var manager = animation.animation_manager(nil, renderer) - -# Create some animations with different priorities -var background = SolidAnimation(10, 0x000080FF, "background") # Dark blue background (fully opaque) -var gradient = GradientAnimation(20, 0xFF000080, 0x00FF0080, "gradient") # Red to green gradient with 50% alpha -var pattern = PatternAnimation(30, 2, 0xFFFFFF40, 0x00000040, "pattern") # White/black pattern with 25% alpha - -# Add animations to the manager -manager.add(background) -manager.add(gradient) -manager.add(pattern) - -print("Added animations to manager:", manager) -print("Number of animations:", manager.size()) - -# Start all animations -var start_time = tasmota.millis() -manager.start_all(start_time) - -# Render the animations to the frame buffer -var rendered = manager.render_animations(frame, start_time) -print("Rendered:", rendered) - -# Print the first few pixels to see the blending result -print("Pixel colors (first 5):") -var i = 0 -while i < 5 - var color = frame.get_pixel_color(i) - var r = color & 0xFF - var g = (color >> 8) & 0xFF - var b = (color >> 16) & 0xFF - print(" Pixel", i, ":", format("R:%d G:%d B:%d", r, g, b)) - i += 1 -end - -# Demonstrate changing priorities -print("\nChanging priorities:") -background.set_priority(40) # Move background to top -manager._sort_animations() # Resort animations - -# Render again -manager.render_animations(frame, start_time) - -# Print the first few pixels again -print("Pixel colors after priority change (first 5):") -i = 0 -while i < 5 - var color = frame.get_pixel_color(i) - var r = color & 0xFF - var g = (color >> 8) & 0xFF - var b = (color >> 16) & 0xFF - print(" Pixel", i, ":", format("R:%d G:%d B:%d", r, g, b)) - i += 1 -end - -# Note: Opacity is now controlled through per-pixel alpha channels -print("\nNote: Opacity is now controlled through per-pixel alpha channels") - -# Render again -manager.render_animations(frame, start_time) - -# Print the first few pixels again -print("Pixel colors with per-pixel alpha (first 5):") -i = 0 -while i < 5 - var color = frame.get_pixel_color(i) - var r = color & 0xFF - var g = (color >> 8) & 0xFF - var b = (color >> 16) & 0xFF - print(" Pixel", i, ":", format("R:%d G:%d B:%d", r, g, b)) - i += 1 -end - -print("\nLayering demo complete!") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/nested_calls_demo.be b/lib/libesp32/berry_animation/src/examples/nested_calls_demo.be deleted file mode 100644 index a83f8e2e8..000000000 --- a/lib/libesp32/berry_animation/src/examples/nested_calls_demo.be +++ /dev/null @@ -1,97 +0,0 @@ -# Nested Function Calls Demo -# -# This example demonstrates the new nested function calls feature in the DSL transpiler. -# It shows how complex animations can be expressed more concisely using nested syntax. - -import global -import string -import animation - -# Example DSL code using nested function calls -var dsl_code = - "strip length 60\n" - "\n" - "# Define colors\n" - "color sunset_red = #FF4500\n" - "color ocean_blue = #0077AA\n" - "color star_white = #FFFFFF\n" - "color deep_blue = #000080\n" - "\n" - "# Simple nested call\n" - "animation breathing_red = pulse(solid(sunset_red), 4s)\n" - "\n" - "# Complex nested animation with multiple levels\n" - "animation evening_sky = fade(\n" - " overlay(\n" - " shift_right(gradient(sunset_red, orange, yellow), 400ms),\n" - " sparkle(star_white, deep_blue, 8%)\n" - " ),\n" - " 10s\n" - ")\n" - "\n" - "# Nested calls in array parameters\n" - "animation color_wheel = color_cycle(\n" - " [solid(sunset_red), solid(ocean_blue), solid(star_white)],\n" - " 3s\n" - ")\n" - "\n" - "# Run the complex animation\n" - "run evening_sky" - -def demo_nested_calls() - print("=== Nested Function Calls Demo ===") - print() - print("DSL Code:") - print(dsl_code) - print() - - # Compile the DSL - var compiler = animation.SimpleDSLTranspiler() - var lexer = animation.DSLLexer(dsl_code) - var tokens = lexer.tokenize() - - if lexer.has_errors() - print("Lexer errors:") - print(lexer.get_error_report()) - return false - end - - compiler.tokens = tokens - var berry_code = compiler.transpile() - - if compiler.has_errors() - print("Compiler errors:") - print(compiler.get_error_report()) - return false - end - - print("Generated Berry Code:") - print("============================================================") - print(berry_code) - print("============================================================") - print() - - # Verify the code compiles - try - var compiled = compile(berry_code) - print("✓ Generated code compiles successfully!") - print() - - # Show the benefits of nested syntax - print("Benefits of Nested Function Calls:") - print("- More concise: No need for intermediate pattern variables") - print("- More readable: Natural expression of complex animations") - print("- Less verbose: Reduces DSL code length significantly") - print("- Better composition: Easy to build complex effects from simple parts") - - return true - except .. as e, msg - print(f"✗ Generated code compilation failed: {e} - {msg}") - return false - end -end - -# Run the demo -demo_nested_calls() - -return demo_nested_calls \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/oscillator_value_provider_demo.be b/lib/libesp32/berry_animation/src/examples/oscillator_value_provider_demo.be deleted file mode 100644 index deeb33356..000000000 --- a/lib/libesp32/berry_animation/src/examples/oscillator_value_provider_demo.be +++ /dev/null @@ -1,148 +0,0 @@ -# OscillatorValueProvider Demo -# -# This example demonstrates how to use the OscillatorValueProvider -# with different waveforms and parameters. - -import global -import animation -import tasmota - -print("=== OscillatorValueProvider Demo ===") - -# Create different types of oscillators -print("\n1. Creating different oscillator types:") - -# Sawtooth oscillator (ramp from 0 to 100 over 2 seconds) -var sawtooth = animation.ramp(0, 100, 2000) -print(f"Sawtooth: {sawtooth}") - -# Triangle oscillator (0 to 100 and back over 3 seconds) -var triangle = animation.linear(0, 100, 3000) -print(f"Triangle: {triangle}") - -# Smooth cosine oscillator (0 to 100 smoothly over 4 seconds) -var smooth = animation.smooth(0, 100, 4000) -print(f"Smooth: {smooth}") - -# Square wave oscillator (0 to 100 with 30% duty cycle over 1 second) -var square = animation.square(0, 100, 1000, 30) -print(f"Square: {square}") - -# Custom oscillator with phase shift and duty cycle (using direct constructor) -var custom = animation.oscillator_value_provider(10, 90, 1500, animation.TRIANGLE) -custom.set_phase(25).set_duty_cycle(75) -print(f"Custom: {custom}") - -print("\n2. Demonstrating oscillator values over time:") - -# Simulate time progression for sawtooth oscillator -var start_time = tasmota.millis() -sawtooth.origin = start_time - -print("Sawtooth oscillator values:") -for i: 0..10 - var time_offset = i * 200 # Every 200ms - var current_time = start_time + time_offset - var value = sawtooth.get_value(current_time) - var progress = (time_offset * 100) / 2000 # Percentage through cycle - print(f" t+{time_offset}ms ({progress}%): {value}") -end - -print("\nTriangle oscillator values:") -triangle.origin = start_time -for i: 0..15 - var time_offset = i * 200 # Every 200ms - var current_time = start_time + time_offset - var value = triangle.get_value(current_time) - var progress = (time_offset * 100) / 3000 # Percentage through cycle - print(f" t+{time_offset}ms ({progress:.1f}%): {value}") -end - -print("\n3. Demonstrating phase shift:") - -# Create two identical oscillators with different phase -var osc1 = animation.ramp(0, 100, 1000) -var osc2 = animation.ramp(0, 100, 1000) -osc2.set_phase(50) # 50% phase shift - -osc1.origin = start_time -osc2.origin = start_time - -print("Phase shift comparison (0% vs 50% phase):") -for i: 0..8 - var time_offset = i * 125 # Every 125ms (1/8 of cycle) - var current_time = start_time + time_offset - var value1 = osc1.get_value(current_time) - var value2 = osc2.get_value(current_time) - var progress = (time_offset * 100) / 1000 - print(f" t+{time_offset}ms ({progress}%): no phase={value1}, 50% phase={value2}") -end - -print("\n4. Demonstrating duty cycle with square wave:") - -# Create square waves with different duty cycles -var square25 = animation.square(0, 100, 1000, 25) -var square50 = animation.square(0, 100, 1000, 50) -var square75 = animation.square(0, 100, 1000, 75) - -square25.origin = start_time -square50.origin = start_time -square75.origin = start_time - -print("Duty cycle comparison (25%, 50%, 75%):") -for i: 0..10 - var time_offset = i * 100 # Every 100ms (10% of cycle) - var current_time = start_time + time_offset - var value25 = square25.get_value(current_time) - var value50 = square50.get_value(current_time) - var value75 = square75.get_value(current_time) - var progress = (time_offset * 100) / 1000 - print(f" t+{time_offset}ms ({progress}%): 25%={value25}, 50%={value50}, 75%={value75}") -end - -print("\n5. Using oscillators with animations:") - -# Example of how you might use an oscillator with an animation parameter -print("Example: Using oscillator for dynamic pulse size") - -# Create a pulse size oscillator that varies from 1 to 8 pixels -var pulse_size_osc = animation.ramp(1, 8, 2000) -pulse_size_osc.origin = start_time - -print("Dynamic pulse sizes over time:") -for i: 0..10 - var time_offset = i * 200 - var current_time = start_time + time_offset - var pulse_size = pulse_size_osc.get_value(current_time) - print(f" t+{time_offset}ms: pulse size = {pulse_size} pixels") -end - -print("\n6. Demonstrating update() method:") - -# Show how update() method tracks value changes -var change_detector = animation.smooth(0, 255, 1000) -change_detector.origin = start_time - -print("Value change detection:") -var last_time = start_time -for i: 1..5 - var time_offset = i * 100 - var current_time = start_time + time_offset - var changed = change_detector.update(current_time) - var value = change_detector.value - print(f" t+{time_offset}ms: value={value}, changed={changed}") - - # Update again with same time (should not change) - var changed_again = change_detector.update(current_time) - print(f" (same time): changed={changed_again}") -end - -print("\n=== Demo Complete ===") - -# Practical usage example comment: -print("\n# Practical Usage Example:") -print("# var brightness_osc = animation.smooth(50, 255, 3000)") -print("# var animation = animation.pulse_position_animation(10, brightness_osc, 0xFF00FF00)") -print("# animation.set_pulse_size(brightness_osc) # Dynamic brightness AND size!") - -return "OscillatorValueProvider demo completed" \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/oscillator_with_animations.be b/lib/libesp32/berry_animation/src/examples/oscillator_with_animations.be deleted file mode 100644 index c4a50c695..000000000 --- a/lib/libesp32/berry_animation/src/examples/oscillator_with_animations.be +++ /dev/null @@ -1,188 +0,0 @@ -# OscillatorValueProvider with Animations Example -# -# This example shows how to use OscillatorValueProvider with actual animations -# to create dynamic, time-varying effects. - -import global -import animation -import tasmota - -print("=== OscillatorValueProvider with Animations ===") - -# Create LED strip using global.Leds -var strip = global.Leds(20, 1) # 20 LEDs, GPIO 1 -var engine = animation.create_engine(strip) - -print("\n1. Pulse Position with Oscillating Size") -print("Creating a pulse that changes size over time...") - -# Create oscillators for dynamic parameters -var size_oscillator = animation.linear(1, 5, 2000) # Size varies 1-5 pixels over 2 seconds -var brightness_oscillator = animation.smooth(100, 255, 3000) # Brightness varies smoothly over 3 seconds - -# Create a pulse position animation with static parameters first -var pulse_anim = animation.pulse_position(0xFF00FF00, 5, 1, 10, 0, true, "dynamic_pulse") - -# Set dynamic parameters using the oscillators -pulse_anim.set_param_value("pulse_size", size_oscillator) -pulse_anim.set_param_value("opacity", brightness_oscillator) - -# Add to engine -engine.add_animation(pulse_anim) -engine.start() - -# Simulate animation over time -var start_time = tasmota.millis() -print("Animation frames (size and brightness changing):") - -for frame: 0..10 - var current_time = start_time + frame * 300 # Every 300ms - - # Update animations - engine.on_tick(current_time) - - # Show current state - var pulse_size = size_oscillator.get_value(current_time) - var brightness = brightness_oscillator.get_value(current_time) - print(f"Frame {frame}: size={pulse_size}, brightness={brightness}") - strip.show() -end - -print("\n2. Multiple Oscillating Animations") -print("Creating multiple animations with different oscillating parameters...") - -# Clear previous animation -engine.clear() -strip.clear() - -# Create different oscillators -var pos1_osc = animation.ramp(2, 8, 2500) # Position oscillates 2-8 -var pos2_osc = animation.ramp(12, 18, 3000) # Position oscillates 12-18 -var color_osc = animation.linear(0, 255, 1500) # Color component oscillates - -# Create multiple pulse animations with static parameters first -var pulse1 = animation.pulse_position(0xFF0000FF, 2, 1, 10, 0, true, "pulse1") # Blue -var pulse2 = animation.pulse_position(0xFFFF0000, 2, 1, 20, 0, true, "pulse2") # Red - -# Set dynamic positions using oscillators -pulse1.set_param_value("pos", pos1_osc) -pulse2.set_param_value("pos", pos2_osc) - -# Add animations -engine.add_animation(pulse1) -engine.add_animation(pulse2) - -print("Two pulses with oscillating positions:") -for frame: 0..8 - var current_time = start_time + frame * 400 # Every 400ms - - # Update animations - engine.on_tick(current_time) - - # Show current positions - var pos1 = pos1_osc.get_value(current_time) - var pos2 = pos2_osc.get_value(current_time) - print(f"Frame {frame}: pos1={pos1}, pos2={pos2}") - strip.show() -end - -print("\n3. Square Wave Strobe Effect") -print("Creating a strobe effect using square wave oscillator...") - -# Clear previous animations -engine.clear() -strip.clear() - -# Create a square wave oscillator for strobe effect -var strobe_osc = animation.square(0, 255, 500, 20) # Fast strobe, 20% duty cycle - -# Create a filled animation with oscillating brightness -var strobe_anim = animation.filled_animation.solid(0xFFFFFFFF, 30, 255, 0, true, "strobe") -strobe_anim.set_param_value("opacity", strobe_osc) # Use oscillator for opacity - -engine.add_animation(strobe_anim) - -print("Strobe effect (square wave oscillator):") -for frame: 0..12 - var current_time = start_time + frame * 100 # Every 100ms (fast) - - # Update animations - engine.on_tick(current_time) - - # Show strobe state - var opacity = strobe_osc.get_value(current_time) - var state = opacity > 128 ? "ON " : "OFF" - print(f"Frame {frame}: opacity={opacity} ({state})") - strip.show() -end - -print("\n4. Breathing Effect with Color Shift") -print("Creating a breathing effect with color temperature shift...") - -# Clear previous animations -engine.clear() -strip.clear() - -# Create oscillators for breathing and color shift -var breathing_osc = animation.smooth(50, 255, 4000) # 4-second breathing cycle -var color_temp_osc = animation.ramp(0, 255, 8000) # 8-second color shift - -# Create a custom color provider that uses the oscillators -class DynamicColorProvider : animation.color_provider - var brightness_osc - var color_osc - - def init(brightness_osc, color_osc) - self.brightness_osc = brightness_osc - self.color_osc = color_osc - end - - def get_color(time_ms) - var brightness = self.brightness_osc.get_value(time_ms) - var color_shift = self.color_osc.get_value(time_ms) - - # Create a color that shifts from warm (red) to cool (blue) - var red = tasmota.scale_uint(255 - color_shift, 0, 255, 0, brightness) - var green = tasmota.scale_uint(128, 0, 255, 0, brightness) - var blue = tasmota.scale_uint(color_shift, 0, 255, 0, brightness) - - return (0xFF << 24) | (red << 16) | (green << 8) | blue - end - - def update(time_ms) - var changed1 = self.brightness_osc.update(time_ms) - var changed2 = self.color_osc.update(time_ms) - return changed1 || changed2 - end -end - -var dynamic_color = DynamicColorProvider(breathing_osc, color_temp_osc) -var breathing_anim = animation.filled_animation(dynamic_color, 40, 255, 0, true, "breathing") - -engine.add_animation(breathing_anim) - -print("Breathing effect with color temperature shift:") -for frame: 0..10 - var current_time = start_time + frame * 500 # Every 500ms - - # Update animations - engine.on_tick(current_time) - - # Show current state - var brightness = breathing_osc.get_value(current_time) - var color_temp = color_temp_osc.get_value(current_time) - var temp_desc = color_temp < 85 ? "warm" : (color_temp < 170 ? "neutral" : "cool") - print(f"Frame {frame}: brightness={brightness}, color_temp={color_temp} ({temp_desc})") - strip.show() -end - -print("\n=== Integration Demo Complete ===") - -# Stop the engine -engine.stop() - -print("\nThis example demonstrates how OscillatorValueProvider can be used to create") -print("dynamic, time-varying effects in animations. The oscillators provide smooth,") -print("predictable parameter changes that can be applied to any animation property.") - -return "OscillatorValueProvider integration demo completed" \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/palette_pattern_demo.be b/lib/libesp32/berry_animation/src/examples/palette_pattern_demo.be deleted file mode 100644 index 76345b6ef..000000000 --- a/lib/libesp32/berry_animation/src/examples/palette_pattern_demo.be +++ /dev/null @@ -1,125 +0,0 @@ -# PalettePattern Animation Demo -# -# This example demonstrates how to use the RichPaletteAnimation as a color provider -# for the PalettePatternAnimation to create complex visual effects. - -# Import the animation module -import global -import tasmota -import animation - -# Create an animation controller for a strip of 30 LEDs -var strip = global.Leds(30, 1) # Assuming global.Leds class is available in Tasmota -var controller = animation.animation_controller(strip) - -# Example 1: Wave pattern with rainbow palette -print("Example 1: Wave pattern with rainbow palette") - -# Create a rainbow palette that doesn't animate on its own (no rendering) -var rainbow_palette = animation.rich_palette_animation(animation.PALETTE_RAINBOW, 5000) - -# Create a wave pattern that uses the rainbow palette as a color source -var wave_pattern = animation.palette_pattern.wave(rainbow_palette, 30, 3000, 15, 10, 255) - -# Add the animations to the controller -controller.add_animation(rainbow_palette) -controller.add_animation(wave_pattern) - -# Start the animations -controller.start() -tasmota.delay(10000) # Run for 10 seconds -controller.stop() -controller.clear() - -# Example 2: Gradient pattern with fire palette -print("Example 2: Gradient pattern with fire palette") - -# Create a fire palette -var fire_palette = animation.rich_palette_animation(animation.PALETTE_FIRE, 3000) - -# Create a gradient pattern that uses the fire palette as a color source -var gradient_pattern = animation.palette_pattern.gradient(fire_palette, 30, 5000, 10, 255) - -# Add the animations to the controller -controller.add_animation(fire_palette) -controller.add_animation(gradient_pattern) - -# Start the animations -controller.start() -tasmota.delay(10000) # Run for 10 seconds -controller.stop() -controller.clear() - -# Example 3: Value meter with ocean palette -print("Example 3: Value meter with ocean palette") - -# Create an ocean palette -var ocean_palette = animation.rich_palette_animation(animation.PALETTE_OCEAN, 1000) - -# Create a value function that oscillates between 0 and 100 -def value_function(time_ms, animation) - # Oscillate between 0 and 100 over 5 seconds using scale_uint and sine_int for better precision - var angle = tasmota.scale_uint(time_ms % 5000, 0, 5000, 0, 32767) # 0 to 2π in fixed-point - var cosine_value = tasmota.sine_int(angle + 8192) # Offset by π/2 to get cosine - - # Map cosine value from -4096..4096 to 0..100 - return tasmota.scale_int(cosine_value, -4096, 4096, 0, 100) -end - -# Create a value meter that uses the ocean palette as a color source -var meter_pattern = animation.palette_pattern.value_meter(ocean_palette, 30, value_function, 10, 255) - -# Add the animations to the controller -controller.add_animation(ocean_palette) -controller.add_animation(meter_pattern) - -# Start the animations -controller.start() -tasmota.delay(10000) # Run for 10 seconds -controller.stop() -controller.clear() - -# Example 4: Custom pattern with custom palette -print("Example 4: Custom pattern with custom palette") - -# Create a custom palette -var custom_palette = animation.rich_palette_animation.from_bytes(bytes( - "00FF0000" # Red (value 0) - "3200FF00" # Green (value 50) - "64FFFF00" # Yellow (value 100) - "96FF00FF" # Purple (value 150) - "C80000FF" # Blue (value 200) - "FFFFFFFF" # White (value 255) -), 5000) - -# Set the range for the palette (0-200 instead of 0-100) -custom_palette.set_range(0, 200) - -# Create a custom pattern function -def custom_pattern_func(pixel_index, time_ms, animation) - # Create a pattern that depends on both position and time using scale_uint for better precision - var time_factor = tasmota.scale_uint(time_ms % 10000, 0, 10000, 0, 100) - var position_factor = tasmota.scale_uint(pixel_index, 0, animation.frame_width - 1, 0, 100) - - # Calculate a value between 0 and 200 - var value = position_factor + time_factor - - return value -end - -# Create a custom pattern that uses the custom palette as a color source -var custom_pattern = animation.palette_pattern(custom_palette, custom_pattern_func, 30, 10, 255) - -# Add the animations to the controller -controller.add_animation(custom_palette) -controller.add_animation(custom_pattern) - -# Start the animations -controller.start() -tasmota.delay(10000) # Run for 10 seconds -controller.stop() -controller.clear() - -print("PalettePattern animation demo completed") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/parameter_demo.be b/lib/libesp32/berry_animation/src/examples/parameter_demo.be deleted file mode 100644 index c02098cc7..000000000 --- a/lib/libesp32/berry_animation/src/examples/parameter_demo.be +++ /dev/null @@ -1,147 +0,0 @@ -# Example demonstrating the parameter handling functionality -# of the Berry Animation Framework -# -# Command to run: -# ./berry -s -g -m lib/libesp32/berry_animation lib/libesp32/berry_animation/examples/parameter_demo.be - -import global -import tasmota -import animation -import math - -# Create a custom animation that uses parameters -class PulseAnimation : animation.animation - # Initialize with custom parameters - def init() - animation.animation.init(self, 1, 255, 0, true, "pulse") - - # Register custom parameters with validation - # Note: Parameter system now only accepts integers, so color is stored as integer - self.register_param("color", { - "min": 1, # 1=red, 2=green, 3=blue, 4=white - "max": 4, - "default": 1 - }) - - self.register_param("speed", { - "min": 1, - "max": 10, - "default": 5 - }) - - self.register_param("intensity", { - "min": 0, - "max": 100, - "default": 50 - }) - - # Set initial values - self.set_param("color", 1) # 1 = red - self.set_param("speed", 5) - self.set_param("intensity", 50) - end - - # Handle parameter changes - def on_param_changed(name, value) - print(format("Parameter '%s' changed to: %s", name, str(value))) - - # Recalculate derived values based on parameters - if name == "speed" - # Adjust duration based on speed (higher speed = lower duration) - self.set_duration(2000 / value) - end - end - - # Render the animation - def render(frame) - if !self.is_running || self.frame_buffer == nil - return false - end - - # Get current parameters - var color = self.get_param("color", 1) # 1 = red - var intensity = self.get_param("intensity", 50) - - # Calculate pulse value based on progress (0 to 255) - var progress = self.get_progress() - # Convert progress to 0.0-1.0 range for math.sin calculation - var progress_float = progress / 255.0 - var pulse_value = math.sin(progress_float * 2 * math.pi) * 0.5 + 0.5 - - # Scale by intensity - pulse_value = tasmota.scale_uint(pulse_value, 0, 255, 0, tasmota.scale_uint(intensity, 0, 100, 0, 255)) - - # Set color based on parameter (1=red, 2=green, 3=blue, 4=white) - var r = 0 - var g = 0 - var b = 0 - - if color == 1 # red - r = int(255 * pulse_value) - elif color == 2 # green - g = int(255 * pulse_value) - elif color == 3 # blue - b = int(255 * pulse_value) - elif color == 4 # white - r = int(255 * pulse_value) - g = int(255 * pulse_value) - b = int(255 * pulse_value) - end - - # Fill the frame with the calculated color - frame.fill_pixels(animation.frame_buffer.to_color(r, g, b, 255)) - - return true - end -end - -# Create a mock frame buffer for demonstration -var frame = animation.frame_buffer(10) - -# Create the pulse animation -var pulse = PulseAnimation() -pulse.start() - -# Simulate animation updates -print("Initial parameters:") -print(format(" color: %s", pulse.get_param("color", nil))) -print(format(" speed: %d", pulse.get_param("speed", nil))) -print(format(" intensity: %d", pulse.get_param("intensity", nil))) -print(format(" duration: %d", pulse.duration)) - -print("\nUpdating parameters:") -pulse.set_param("color", 3) # 3 = blue -pulse.set_param("speed", 8) -pulse.set_param("intensity", 75) - -print("\nFinal parameters:") -print(format(" color: %s", pulse.get_param("color", nil))) -print(format(" speed: %d", pulse.get_param("speed", nil))) -print(format(" intensity: %d", pulse.get_param("intensity", nil))) -print(format(" duration: %d", pulse.duration)) - -# Demonstrate validation -print("\nValidation tests:") -print(format("Set invalid color: %s", pulse.set_param("color", 5) ? "accepted" : "rejected")) # 5 is not in enum [1,2,3,4] -print(format("Set invalid speed: %s", pulse.set_param("speed", 20) ? "accepted" : "rejected")) -print(format("Set invalid intensity: %s", pulse.set_param("intensity", -10) ? "accepted" : "rejected")) - -# Demonstrate individual parameter updates (update_params method removed) -print("\nIndividual parameter updates:") -var color_result = pulse.set_param("color", 2) # 2 = green -var speed_result = pulse.set_param("speed", 3) -var intensity_result = pulse.set_param("intensity", 90) -var all_success = color_result && speed_result && intensity_result -print(format("Update result: %s", all_success ? "success" : "partial failure")) - -print("\nUpdated parameters:") -print(format(" color: %s", pulse.get_param("color", nil))) -print(format(" speed: %d", pulse.get_param("speed", nil))) -print(format(" intensity: %d", pulse.get_param("intensity", nil))) -print(format(" duration: %d", pulse.duration)) - -# Render a frame to demonstrate the animation -pulse.render(frame, tasmota.millis()) -print("\nRendered frame with current parameters") - -print("\nParameter demo completed!") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/pattern_animation_example.be b/lib/libesp32/berry_animation/src/examples/pattern_animation_example.be deleted file mode 100644 index 6b4d9aba0..000000000 --- a/lib/libesp32/berry_animation/src/examples/pattern_animation_example.be +++ /dev/null @@ -1,126 +0,0 @@ -# Pattern vs Animation Example -# This example demonstrates the correct usage of patterns and animations - -import animation - -# Example: Creating patterns (ColorProviders) -def create_patterns() - print("Creating patterns...") - - # Patterns define WHAT the strip should look like (spatial) - var red_pattern = animation.solid(0xFFFF0000) # Solid red pattern - var blue_pattern = animation.solid(0xFF0000FF) # Solid blue pattern - var white_pattern = animation.solid(0xFFFFFFFF) # Solid white pattern - - print("✅ Created solid color patterns") - return [red_pattern, blue_pattern, white_pattern] -end - -# Example: Creating animations from patterns -def create_animations(patterns) - print("Creating animations...") - - var red_pattern = patterns[0] - var blue_pattern = patterns[1] - var white_pattern = patterns[2] - - # Animations define HOW patterns change over time (temporal) - var red_fill = animation.filled(red_pattern, 0) # Fill strip with red pattern - var blue_fill = animation.filled(blue_pattern, 5) # Fill strip with blue pattern (higher priority) - var white_fill = animation.filled(white_pattern, 10) # Fill strip with white pattern (highest priority) - - print("✅ Created filled animations") - return [red_fill, blue_fill, white_fill] -end - -# Example: Demonstrating reusability -def demonstrate_reusability() - print("Demonstrating pattern reusability...") - - # One pattern, multiple animations - var red_pattern = animation.solid(0xFFFF0000) - - # Use the same pattern in different ways - var static_red = animation.filled(red_pattern, 0, 0, true, "static") - var priority_red = animation.filled(red_pattern, 10, 0, true, "priority") - var timed_red = animation.filled(red_pattern, 0, 5000, false, "timed") # 5 second duration - - print("✅ One pattern used in multiple animations:") - print(f" - Static: {static_red.name}, priority={static_red.priority}") - print(f" - Priority: {priority_red.name}, priority={priority_red.priority}") - print(f" - Timed: {timed_red.name}, duration={timed_red.duration}") -end - -# Example: DSL-style composition -def demonstrate_dsl_style() - print("Demonstrating DSL-style composition...") - - # This is how the DSL would work: - # pattern solid_red = solid(red) - var solid_red = animation.solid(0xFFFF0000) - - # animation red_anim = filled(solid_red) - var red_anim = animation.filled(solid_red) - - # The animation can be used with an engine - print(f"✅ Created DSL-style animation: {red_anim.name}") - print(f" - Uses pattern: {red_anim.color_provider}") - print(f" - Priority: {red_anim.priority}") - print(f" - Loop: {red_anim.loop}") -end - -# Example: Testing with a mock strip -def test_with_mock_strip() - print("Testing with mock strip...") - - try - # Create a simple LED strip simulation - var strip_length = 10 - var mock_strip = global.Leds(strip_length, 1) - - # Create pattern and animation - var green_pattern = animation.solid(0xFF00FF00) - var green_anim = animation.filled(green_pattern) - - # Create engine and add animation - var engine = animation.create_engine(mock_strip) - engine.add_animation(green_anim) - - # Start the engine (this would normally be called by Tasmota's fast_loop) - engine.start() - - # Simulate one update cycle - engine.on_tick(0) - - print("✅ Successfully tested with mock strip") - - except .. as e, msg - print(f"⚠️ Mock strip test failed (expected in test environment): {msg}") - end -end - -# Main example function -def run_example() - print("Pattern vs Animation Example") - print("=" * 40) - - # Demonstrate the concepts - var patterns = create_patterns() - var animations = create_animations(patterns) - - demonstrate_reusability() - demonstrate_dsl_style() - test_with_mock_strip() - - print("=" * 40) - print("Example completed!") - - print("\nKey Takeaways:") - print("- Patterns define WHAT (spatial color distribution)") - print("- Animations define HOW (temporal behavior)") - print("- Patterns are reusable across multiple animations") - print("- This separation enables powerful composition") -end - -# Export the example function -return {'run_example': run_example} \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/ported/blend_demo_ported.be b/lib/libesp32/berry_animation/src/examples/ported/blend_demo_ported.be deleted file mode 100644 index 6e9d00dff..000000000 --- a/lib/libesp32/berry_animation/src/examples/ported/blend_demo_ported.be +++ /dev/null @@ -1,94 +0,0 @@ -# -# Direct port of leds_blend_demo.be to new animation framework -# Original: Uses old animate.frame() with manual blending -# Ported: Uses new FrameBuffer with integrated blending capabilities -# -# Visual effect: Demonstrates frame buffer blending with gradient overlay -# - -import animation - -var LEDS_LENGTH = 25 - -# Create LED strip (same as original) -var strip = global.Leds(LEDS_LENGTH, gpio.pin(gpio.WS2812, 0)) -var bri = 70 - -# Create animation engine -var engine = animation.create_engine(strip) - -# Create frame buffers (replaces animate.frame) -var back_frame = animation.frame_buffer(LEDS_LENGTH) -var front_frame = animation.frame_buffer(LEDS_LENGTH) - -# Fill background frame with red color at 80 opacity (replaces back.fill_pixels) -back_frame.fill(0xFF, 0x22, 0x00, 80) # Red with alpha 80 - -# Fill front frame with green gradient (replaces the for loop) -for i: 0..LEDS_LENGTH-1 - var alpha = int(tasmota.scale_uint(i, 0, LEDS_LENGTH-1, 0, 255)) - front_frame.set_pixel(i, 0x00, 0xFF, 0x00, alpha) # Green with varying alpha -end - -# Blend frames (replaces back.blend_pixels) -back_frame.blend(front_frame, 255) - -# Display debug information (same as original) -print("front=", front_frame.pixels.tohex()) -print("back =", back_frame.pixels.tohex()) - -# Get strip buffer and apply blended result -var pixels_buffer = strip.pixels_buffer() -print("pixs =", pixels_buffer.tohex()) - -# Apply brightness and paste to strip buffer (replaces back.paste_pixels) -# Note: In new framework, this is typically handled by the engine -# For demonstration, we'll manually copy the blended result -for i: 0..LEDS_LENGTH-1 - var pixel = back_frame.get_pixel(i) - var r = (pixel >> 16) & 0xFF - var g = (pixel >> 8) & 0xFF - var b = pixel & 0xFF - var a = (pixel >> 24) & 0xFF - - # Apply brightness scaling - r = int(tasmota.scale_uint(r * bri, 0, 255 * 100, 0, 255)) - g = int(tasmota.scale_uint(g * bri, 0, 255 * 100, 0, 255)) - b = int(tasmota.scale_uint(b * bri, 0, 255 * 100, 0, 255)) - - # Set pixel in strip buffer (GRB format for WS2812) - var offset = i * 3 - pixels_buffer[offset] = g # Green - pixels_buffer[offset + 1] = r # Red - pixels_buffer[offset + 2] = b # Blue -end - -# Update strip -strip.dirty() -strip.show() - -print("Blend demo ported - frame buffer blending demonstration") -print("Background: Red with alpha 80") -print("Foreground: Green gradient with varying alpha") -print("Result: Blended frames displayed on strip") - -# Alternative: Using the animation engine approach -print("\n--- Alternative using Animation Engine ---") - -# Create animations that demonstrate the same blending -var bg_anim = animation.solid(0x50FF2200, 0, 0, true, "red_background") # Red with alpha -var fg_anim = animation.filled_animation( - # Create a custom color provider that generates the green gradient - def(time_ms) - # This would need a custom gradient provider - simplified for demo - return 0x8000FF00 # Green with alpha - end, - 10, 0, true, "green_overlay" -) - -engine.add_animation(bg_anim) -engine.add_animation(fg_anim) -engine.start() - -print("Animation engine version running - demonstrates same blending concept") -print("Press Ctrl+C to stop") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/ported/breathe_demo_ported.be b/lib/libesp32/berry_animation/src/examples/ported/breathe_demo_ported.be deleted file mode 100644 index 51335adb5..000000000 --- a/lib/libesp32/berry_animation/src/examples/ported/breathe_demo_ported.be +++ /dev/null @@ -1,48 +0,0 @@ -# -# Direct port of animate_demo_breathe.be to new animation framework -# Original: Uses old animate.core(), animate.pulse(), animate.palette(), animate.oscillator() -# Ported: Uses new AnimationEngine, BreatheAnimation, RichPaletteColorProvider, OscillatorValueProvider -# -# Visual effect: Breathing red/orange pulse that oscillates in brightness -# - -import animation - -# Same palette as original (black to red to orange) -var PALETTE_BLACK_RED = bytes( - "00000000" # black (value 0) - "88880000" # red (value 136) - "FFFF5500" # orange (value 255) -) - -var duration = 3000 -var leds = 25 - -# Create LED strip (same as original) -var strip = global.Leds(leds, gpio.pin(gpio.WS2812, 0)) - -# Create animation engine (replaces animate.core) -var engine = animation.create_engine(strip) - -# Create palette color provider (replaces animate.palette) -var palette_provider = animation.rich_palette_color_provider(PALETTE_BLACK_RED, duration, 1, 255) -palette_provider.set_range(0, 255) - -# Create oscillator for brightness control (replaces animate.oscillator) -var brightness_osc = animation.smooth(50, 255, duration) - -# Create breathe animation (replaces animate.pulse) -var breathe_anim = animation.breathe_animation(0xFF0000, 100, duration, true, "breathe_port") - -# Use oscillator to control the color provider's brightness dynamically -# This simulates the original callback mechanism -breathe_anim.set_param_value("color", palette_provider) -breathe_anim.set_param_value("opacity", brightness_osc) - -# Add animation to engine and start -engine.add_animation(breathe_anim) -engine.start() - -print("Breathe demo ported - breathing red/orange pulse") -print("Duration:", duration, "ms, LEDs:", leds) -print("Press Ctrl+C to stop") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/ported/palette_background_demo_ported.be b/lib/libesp32/berry_animation/src/examples/ported/palette_background_demo_ported.be deleted file mode 100644 index edabb6a93..000000000 --- a/lib/libesp32/berry_animation/src/examples/ported/palette_background_demo_ported.be +++ /dev/null @@ -1,33 +0,0 @@ -# -# Direct port of animate_demo_palette_background.be to new animation framework -# Original: Uses old animate.core() with add_background_animator() -# Ported: Uses new AnimationEngine with animation.filled_animation and rainbow palette -# -# Visual effect: Cycling rainbow background across all LEDs -# - -import animation - -var duration = 10000 -var leds = 5 * 5 # 25 LEDs for M5Stack matrix - -# Create LED strip (same as original) -var strip = global.Leds(leds, gpio.pin(gpio.WS2812, 0)) - -# Create animation engine (replaces animate.core) -var engine = animation.create_engine(strip) - -# Create rainbow palette background (replaces animate.palette with PALETTE_RAINBOW_WHITE) -# Using the built-in rainbow palette with smooth transitions -var rainbow_provider = animation.rich_palette_color_provider.rainbow(duration, 1, 255) - -# Create filled animation as background (replaces add_background_animator) -var background_anim = animation.filled_animation(rainbow_provider, 0, 0, true, "rainbow_background") - -# Add animation to engine and start -engine.add_animation(background_anim) -engine.start() - -print("Palette background demo ported - cycling rainbow background") -print("Duration:", duration, "ms, LEDs:", leds) -print("Press Ctrl+C to stop") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/ported/pulse_demo_ported.be b/lib/libesp32/berry_animation/src/examples/ported/pulse_demo_ported.be deleted file mode 100644 index 4e8b65b3d..000000000 --- a/lib/libesp32/berry_animation/src/examples/ported/pulse_demo_ported.be +++ /dev/null @@ -1,60 +0,0 @@ -# -# Direct port of animate_demo_pulse.be to new animation framework -# Original: Uses old animate.core(), animate.pulse(), animate.oscillator(), animate.palette() -# Ported: Uses new AnimationEngine, PulsePositionAnimation, OscillatorValueProvider, RichPaletteColorProvider -# -# Visual effect: Moving pulse with oscillating position and cycling color -# - -import animation - -var duration = 10000 -var leds = 5 * 5 # 25 LEDs for M5Stack matrix - -# Create LED strip (same as original) -var strip = global.Leds(leds, gpio.pin(gpio.WS2812, 0)) - -# Create animation engine (replaces animate.core) -var engine = animation.create_engine(strip) - -# Set background color (replaces anim.set_back_color) -# Note: In new framework, we create a background animation instead -var background_anim = animation.solid(0x2222AA, 0, 0, true, "background") -engine.add_animation(background_anim) - -# Create position oscillator (replaces animate.oscillator(-3, 26, 5000, animate.COSINE)) -var pos_oscillator = animation.smooth(-3, 26, 5000) - -# Create color palette provider (replaces animate.palette(animate.PALETTE_STANDARD_VAL, 30000)) -# Using a custom palette that matches PALETTE_STANDARD_VAL behavior -var color_palette = bytes( - "00FF0000" # Red (value 0) - "40FFFF00" # Yellow (value 64) - "8000FF00" # Green (value 128) - "C000FFFF" # Cyan (value 192) - "FF0000FF" # Blue (value 255) -) -var color_provider = animation.rich_palette_color_provider(color_palette, 30000, 1, 255) - -# Create pulse animation (replaces animate.pulse(0xFF4444, 2, 1)) -var pulse_anim = animation.pulse_position(0xFF4444, 2, 1, 10, 0, true, "moving_pulse") - -# Apply dynamic parameters using value providers -pulse_anim.set_param_value("pos", pos_oscillator) # Oscillating position -pulse_anim.set_param_value("color", color_provider) # Cycling color - -# Add pulse animation with higher priority than background -pulse_anim.priority = 10 -engine.add_animation(pulse_anim) - -# Simulate brightness setting (original had anim.set_bri(60)) -# In new framework, this would be handled by the LED strip or global opacity -# For demonstration, we'll set the pulse opacity -pulse_anim.set_param_value("opacity", 153) # 60% of 255 - -engine.start() - -print("Pulse demo ported - moving pulse with oscillating position and cycling color") -print("Duration:", duration, "ms, LEDs:", leds) -print("Background: Blue, Pulse: Moving with color cycling") -print("Press Ctrl+C to stop") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/pulse_animation_demo.be b/lib/libesp32/berry_animation/src/examples/pulse_animation_demo.be deleted file mode 100644 index 4c10dbfa6..000000000 --- a/lib/libesp32/berry_animation/src/examples/pulse_animation_demo.be +++ /dev/null @@ -1,87 +0,0 @@ -# Pulse Animation Demo with LED Values -# -# This example demonstrates how to use the Pulse animation effect -# to create a pulsing light effect on an LED strip. -# -# The demo creates a pulse animation with customizable parameters -# and shows how to integrate it with the animation controller. -# It also displays the actual LED values. - -import global -import tasmota -import animation - -def dump_rgb(strip) - var output = "LEDs: [" - for i:0..strip.length()-1 - var color = strip.get_pixel_color(i) - var r = (color >> 16) & 0xFF - var g = (color >> 8) & 0xFF - var b = color & 0xFF - - if i > 0 - output += ", " - end - output += format("R:%d,G:%d,B:%d", r, g, b) - end - output += "]" - print(output) -end - -def dump(strip) - var output = "[" - for i:0..strip.length()-1 - if i > 0 - output += ", " - end - output += format("0x%06X", strip.get_pixel_color(i) & 0xFFFFFF) - end - output += "]" - print(output) -end - -# Create a mock LED strip with 5 pixels (reduced for readability) -var strip = global.Leds(5) - -# Create an animation controller for the strip -var controller = animation.animation_controller(strip) - -# Create a pulse animation with blue color -# Parameters: color, min_brightness, max_brightness, pulse_period, priority -var blue_pulse = animation.pulse_animation(0xFF0000FF, 20, 200, 2000, 1) - -# Add the animation to the controller -controller.add_animation(blue_pulse) - -# Start the animation -blue_pulse.start() -controller.start() - -# Simulate the fast_loop for a few seconds -print("Starting pulse animation demo with LED values...") -print("Simulating animation updates for one full pulse cycle...") - -var start_time = tasmota.millis() -var end_time = start_time + 2500 # Run for slightly more than one cycle -var update_interval = 200 # Update every 200ms for demonstration - -# Simulate updates -var current_time = start_time -while current_time < end_time - # Update the controller with the current time - controller.on_tick(current_time) - - # Show the current state with detailed LED values - print(f"Time: {current_time - start_time}ms, Pulse state: {(current_time - start_time) % 2000 / 2000 * 100}%") - dump_rgb(strip) # Show RGB components - dump(strip) # Show hex values for reference - - # Increment time - current_time += update_interval -end - -# Stop the animation -controller.stop() -print("Pulse animation demo completed") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/pulse_position_animation_demo.be b/lib/libesp32/berry_animation/src/examples/pulse_position_animation_demo.be deleted file mode 100644 index 722378baf..000000000 --- a/lib/libesp32/berry_animation/src/examples/pulse_position_animation_demo.be +++ /dev/null @@ -1,137 +0,0 @@ -# Pulse Position Animation Demo with LED Values -# -# This example demonstrates the Pulse Position animation effect -# which creates a pulse at a specific position with optional slew (fade) regions. -# -# The demo creates various pulse configurations and shows actual LED values. -# -# Command to run demo: -# ./berry -s -g -m lib/libesp32/berry_animation lib/libesp32/berry_animation/examples/pulse_position_animation_demo.be - -import global -import tasmota -import animation - -def dump_rgb(strip) - var output = "LEDs: [" - for i:0..strip.length()-1 - var color = strip.get_pixel_color(i) - var r = (color >> 16) & 0xFF - var g = (color >> 8) & 0xFF - var b = color & 0xFF - - if i > 0 - output += ", " - end - output += format("R:%d,G:%d,B:%d", r, g, b) - end - output += "]" - print(output) -end - -def dump(strip) - var output = "[" - for i:0..strip.length()-1 - if i > 0 - output += ", " - end - output += format("0x%06X", strip.get_pixel_color(i) & 0xFFFFFF) - end - output += "]" - print(output) -end - -def test_pulse_position(name, pulse_anim, strip, controller) - print(f"\n=== {name} ===") - - # Clear any existing animations - controller.clear() - - # Add and start the animation - controller.add_animation(pulse_anim) - pulse_anim.start() - controller.start() - - # Update once to render the pulse - controller.on_tick() - - # Show the results - print(f"Animation: {pulse_anim}") - dump_rgb(strip) - dump(strip) - - # Stop the animation - controller.stop() -end - -print("Starting Pulse Position animation demo with LED values...") - -# Create a mock LED strip with 10 pixels for better visualization -var strip = global.Leds(10) - -# Create an animation engine for the strip -var controller = animation.create_engine(strip) - -print("Testing various pulse position configurations...") - -# Test 1: Basic pulse without slew -var basic_pulse = animation.pulse_position(0xFF00FF00, 3, 0, 1, 0, true, "basic_pulse") -basic_pulse.set_pos(2) -test_pulse_position("Basic Pulse (Green, pos=2, size=3, no slew)", basic_pulse, strip, controller) - -# Test 2: Pulse with slew -var slew_pulse = animation.pulse_position(0xFFFF0000, 2, 2, 1, 0, true, "slew_pulse") -slew_pulse.set_pos(4) -test_pulse_position("Pulse with Slew (Red, pos=4, size=2, slew=2)", slew_pulse, strip, controller) - -# Test 3: Pulse with background color -var bg_pulse = animation.pulse_position(0xFFFFFF00, 1, 1, 1, 0, true, "bg_pulse") -bg_pulse.set_pos(6) -bg_pulse.set_back_color(0xFF000080) # Dark blue background -test_pulse_position("Pulse with Background (Yellow on Blue, pos=6, size=1, slew=1)", bg_pulse, strip, controller) - -# Test 4: Wide pulse with large slew -var wide_pulse = animation.pulse_position(0xFF0080FF, 2, 3, 1, 0, true, "wide_pulse") -wide_pulse.set_pos(3) -test_pulse_position("Wide Pulse (Purple, pos=3, size=2, slew=3)", wide_pulse, strip, controller) - -# Test 5: Edge case - pulse at beginning -var edge_pulse1 = animation.pulse_position(0xFFFF8000, 2, 1, 1, 0, true, "edge_pulse1") -edge_pulse1.set_pos(0) -test_pulse_position("Edge Pulse at Start (Orange, pos=0, size=2, slew=1)", edge_pulse1, strip, controller) - -# Test 6: Edge case - pulse at end -var edge_pulse2 = animation.pulse_position(0xFF8000FF, 2, 1, 1, 0, true, "edge_pulse2") -edge_pulse2.set_pos(8) -test_pulse_position("Edge Pulse at End (Magenta, pos=8, size=2, slew=1)", edge_pulse2, strip, controller) - -# Test 7: Zero-width pulse (should show only slew) -var zero_pulse = animation.pulse_position(0xFF00FFFF, 0, 2, 1, 0, true, "zero_pulse") -zero_pulse.set_pos(5) -test_pulse_position("Zero-width Pulse (Cyan, pos=5, size=0, slew=2)", zero_pulse, strip, controller) - -# Test 8: Parameter updates - demonstrate different configurations -print("\n=== Parameter Variations ===") - -# Test different colors -var red_pulse = animation.pulse_position(0xFFFF0000, 1, 0, 1, 0, true, "red_pulse") -red_pulse.set_pos(2) -test_pulse_position("Red Pulse", red_pulse, strip, controller) - -var blue_pulse = animation.pulse_position(0xFF0000FF, 1, 0, 1, 0, true, "blue_pulse") -blue_pulse.set_pos(2) -test_pulse_position("Blue Pulse (same position)", blue_pulse, strip, controller) - -# Test different sizes -var small_pulse = animation.pulse_position(0xFF00FF00, 1, 1, 1, 0, true, "small_pulse") -small_pulse.set_pos(4) -test_pulse_position("Small Pulse with Slew", small_pulse, strip, controller) - -var large_pulse = animation.pulse_position(0xFF00FF00, 4, 1, 1, 0, true, "large_pulse") -large_pulse.set_pos(2) -test_pulse_position("Large Pulse with Slew", large_pulse, strip, controller) - -print("\nPulse Position animation demo completed") -print("All tests demonstrate the pulse positioning with optional slew regions") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/pulse_position_with_value_providers.be b/lib/libesp32/berry_animation/src/examples/pulse_position_with_value_providers.be deleted file mode 100644 index ec3d773c9..000000000 --- a/lib/libesp32/berry_animation/src/examples/pulse_position_with_value_providers.be +++ /dev/null @@ -1,251 +0,0 @@ -# Example: PulsePositionAnimation with ValueProvider support -# -# This example demonstrates how to modify an animation to support both static values -# and dynamic ValueProvider instances for its parameters. - -# Import the animation framework -import animation - -# Create a modified PulsePositionAnimation that supports ValueProviders -class PulsePositionAnimationWithProviders : animation.pulse_position_animation - - # Override the render method to use value providers - def render(frame) - if !self.is_running || frame == nil - return false - end - - var current_time = tasmota.millis() - var pixel_size = frame.width - - # Get values using the value provider system - var back_color = self.get_param_value("back_color", current_time) - var pos = self.get_param_value("pos", current_time) - var slew_size = self.get_param_value("slew_size", current_time) - var pulse_size = self.get_param_value("pulse_size", current_time) - var color = self.get_param_value("color", current_time) - - # Ensure we have valid values (fallback to defaults if providers return nil) - if back_color == nil back_color = 0xFF000000 end - if pos == nil pos = 0 end - if slew_size == nil slew_size = 0 end - if pulse_size == nil pulse_size = 1 end - if color == nil color = 0xFFFFFFFF end - - # Ensure non-negative values - if slew_size < 0 slew_size = 0 end - if pulse_size < 0 pulse_size = 0 end - - # Fill background if not transparent - if back_color != 0xFF000000 - frame.fill_pixels(back_color) - end - - # Calculate pulse boundaries - var pulse_min = pos - var pulse_max = pos + pulse_size - - # Clamp to frame boundaries - if pulse_min < 0 - pulse_min = 0 - end - if pulse_max >= pixel_size - pulse_max = pixel_size - end - - # Draw the main pulse - var i = pulse_min - while i < pulse_max - frame.set_pixel_color(i, color) - i += 1 - end - - # Draw slew regions if slew_size > 0 - if slew_size > 0 - # Left slew (fade from background to pulse color) - var left_slew_min = pos - slew_size - var left_slew_max = pos - - if left_slew_min < 0 - left_slew_min = 0 - end - if left_slew_max >= pixel_size - left_slew_max = pixel_size - end - - i = left_slew_min - while i < left_slew_max - # Calculate blend factor (255 = background, 0 = pulse color) - var blend_factor - if slew_size == 1 - # For single pixel slew, use 50% blend - blend_factor = 128 - else - blend_factor = tasmota.scale_uint(i, pos - slew_size, pos - 1, 255, 0) - end - # Create color with appropriate alpha for blending - var alpha = 255 - blend_factor # Invert so 0 = transparent, 255 = opaque - var blend_color = (alpha << 24) | (color & 0x00FFFFFF) - var blended_color = frame.blend(back_color, blend_color) - frame.set_pixel_color(i, blended_color) - i += 1 - end - - # Right slew (fade from pulse color to background) - var right_slew_min = pos + pulse_size - var right_slew_max = pos + pulse_size + slew_size - - if right_slew_min < 0 - right_slew_min = 0 - end - if right_slew_max >= pixel_size - right_slew_max = pixel_size - end - - i = right_slew_min - while i < right_slew_max - # Calculate blend factor (0 = pulse color, 255 = background) - var blend_factor - if slew_size == 1 - # For single pixel slew, use 50% blend - blend_factor = 128 - else - blend_factor = tasmota.scale_uint(i, pos + pulse_size, pos + pulse_size + slew_size - 1, 0, 255) - end - # Create color with appropriate alpha for blending - var alpha = 255 - blend_factor # Start opaque, fade to transparent - var blend_color = (alpha << 24) | (color & 0x00FFFFFF) - var blended_color = frame.blend(back_color, blend_color) - frame.set_pixel_color(i, blended_color) - i += 1 - end - end - - return true - end - - # Override parameter setters to support both static values and providers - def set_color(color_or_provider) - self.set_param_value("color", color_or_provider) - return self - end - - def set_back_color(color_or_provider) - self.set_param_value("back_color", color_or_provider) - return self - end - - def set_pos(pos_or_provider) - self.set_param_value("pos", pos_or_provider) - return self - end - - def set_slew_size(size_or_provider) - self.set_param_value("slew_size", size_or_provider) - return self - end - - def set_pulse_size(size_or_provider) - self.set_param_value("pulse_size", size_or_provider) - return self - end -end - -# Example usage demonstrating both static values and value providers - -# Create some simple example value providers -class SimpleTimeProvider : animation.value_provider - var multiplier, offset - - def init(multiplier, offset) - self.multiplier = multiplier != nil ? multiplier : 1 - self.offset = offset != nil ? offset : 0 - end - - def get_value(time_ms) - # Simple time-based value that changes every second - return self.offset + ((time_ms / 1000) * self.multiplier) % 60 - end - - # Specific method for position parameter - def get_pos(time_ms) - return int(self.get_value(time_ms)) - end - - # Specific method for pulse_size parameter - def get_pulse_size(time_ms) - var value = int(self.get_value(time_ms)) % 8 + 1 # 1-8 pixels - return value - end -end - -class AlternatingColorProvider : animation.value_provider - var color1, color2, switch_period - - def init(color1, color2, switch_period) - self.color1 = color1 != nil ? color1 : 0xFFFF0000 # Red - self.color2 = color2 != nil ? color2 : 0xFF0000FF # Blue - self.switch_period = switch_period != nil ? switch_period : 1000 # 1 second - end - - def get_value(time_ms) - # Alternate between two colors based on time - var cycle = (time_ms / self.switch_period) % 2 - return cycle < 1 ? self.color1 : self.color2 - end - - # Specific method for color parameter - def get_color(time_ms) - return self.get_value(time_ms) - end -end - -# Demo function -def demo_value_providers() - print("=== ValueProvider Demo ===") - - # Create LED strip (60 pixels) - var strip = global.Leds(60, 1) - var engine = animation.create_engine(strip) - - # Create value providers - var moving_pos = SimpleTimeProvider(2, 10) # Position moves slowly across strip - var changing_size = SimpleTimeProvider(1, 1) # Size changes over time - var alternating_color = AlternatingColorProvider(0xFFFF0000, 0xFF00FF00, 2000) # Red/green every 2s - - # Create animation with mixed static and dynamic parameters - var pulse_anim = PulsePositionAnimationWithProviders( - 0xFFFFFFFF, # Static white color (will be overridden) - 3, # Static pulse size (will be overridden) - 1, # Static slew size - 10, # Priority - 0, # Infinite duration - false, # No loop - "dynamic_pulse" - ) - - # Set some parameters to use value providers - pulse_anim.set_pos(moving_pos) # Dynamic position - pulse_anim.set_pulse_size(changing_size) # Dynamic size - pulse_anim.set_color(alternating_color) # Dynamic color - # back_color and slew_size remain static - - # Add to engine and start - engine.add_animation(pulse_anim) - engine.start() - - print("Animation started with dynamic parameters:") - print("- Position: Moves across strip over time") - print("- Pulse size: Changes from 1 to 8 pixels cyclically") - print("- Color: Alternates between red and green every 2 seconds") - print("- Background and slew: Static values") - - return engine -end - -# Export the demo function -animation.demo_value_providers = demo_value_providers - -print("ValueProvider example loaded. Run animation.demo_value_providers() to see it in action.") - -return PulsePositionAnimationWithProviders \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/resolve_value_demo.be b/lib/libesp32/berry_animation/src/examples/resolve_value_demo.be deleted file mode 100644 index f93b2624b..000000000 --- a/lib/libesp32/berry_animation/src/examples/resolve_value_demo.be +++ /dev/null @@ -1,105 +0,0 @@ -# Demonstration of the new resolve_value() method -# -# This example shows how the new resolve_value() method simplifies -# parameter handling compared to the old get_param_value() approach. - -import global -import tasmota -import animation - -print("=== resolve_value() Method Demonstration ===") - -# Note: In a real Tasmota environment, you would create an LED strip like: -# var strip = global.Leds(10, 1) -# var engine = animation.create_engine(strip) - -print("\n1. Creating animations with static values:") - -# Create a crenel animation with static values -var static_crenel = animation.crenel_position_animation( - 0xFF00FF00, # Green color - 0, # Position - 2, # Pulse size - 3, # Low size - -1, # Infinite pulses - 10, # Priority - 0, # Infinite duration - false, # No loop - "static_crenel" -) - -print(" Static crenel: " + str(static_crenel)) - -print("\n2. Creating animations with dynamic values (ValueProviders):") - -# Create dynamic parameters using value providers -print(" Creating dynamic color provider...") -var dynamic_color = animation.solid_color_provider(0xFF0000FF) # Blue -print(" Creating dynamic position provider...") -var dynamic_pos = animation.static_value_provider(1) # Position 1 -print(" Creating dynamic pulse size provider...") -var dynamic_pulse_size = animation.static_value_provider(3) # 3 pixels - -print(" Creating crenel animation with dynamic values...") -# Create a crenel animation with dynamic values -var dynamic_crenel = animation.crenel_position_animation( - dynamic_color, # Dynamic color - dynamic_pos, # Dynamic position (wrapped in provider) - dynamic_pulse_size, # Dynamic pulse size - 2, # Static low size - 5, # 5 pulses - 20, # Higher priority - 0, # Infinite duration - false, # No loop - "dynamic_crenel" -) - -print(" Dynamic crenel: " + str(dynamic_crenel)) - -print("\n3. Demonstrating resolve_value() usage:") - -# Show how resolve_value() works with both static and dynamic values -var test_anim = animation.animation(10, 0, false, "test") - -var static_value = 42 -var dynamic_value = animation.static_value_provider(84) -var time_ms = tasmota.millis() - -print(" Static value (42): " + str(test_anim.resolve_value(static_value, "test_param", time_ms))) -print(" Dynamic value (84): " + str(test_anim.resolve_value(dynamic_value, "test_param", time_ms))) - -print("\n4. Comparison with old approach:") - -# Old approach (still works but more complex) -test_anim.register_param("test_param", {"default": 0}) -test_anim.set_param("test_param", dynamic_value) -var old_result = test_anim.get_param_value("test_param", time_ms) - -# New approach (simpler and more direct) -var new_result = test_anim.resolve_value(dynamic_value, "test_param", time_ms) - -print(" Old approach result: " + str(old_result)) -print(" New approach result: " + str(new_result)) -print(" Results match: " + str(old_result == new_result)) - -print("\n5. Benefits of resolve_value():") -print(" ✓ No string parameter names required") -print(" ✓ Direct access to parameter values") -print(" ✓ Better performance (no string lookup)") -print(" ✓ Type safety (direct parameter access)") -print(" ✓ Simpler API (one method for static and dynamic)") -print(" ✓ Works with any value type") - -print("\n6. Usage in animation render() methods:") -print(" Old: var color = self.get_param_value(\"color\", time_ms)") -print(" New: var color = self.resolve_value(self.color, \"color\", time_ms)") -print("") -print(" The new approach is:") -print(" - More efficient (no parameter registration/lookup)") -print(" - Supports specific get_XXX() methods on providers") -print(" - More readable (direct parameter access)") -print(" - Allows providers to have specialized methods") - -print("\n=== Demonstration Complete ===") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/rich_palette_animation_demo.be b/lib/libesp32/berry_animation/src/examples/rich_palette_animation_demo.be deleted file mode 100644 index f23654138..000000000 --- a/lib/libesp32/berry_animation/src/examples/rich_palette_animation_demo.be +++ /dev/null @@ -1,192 +0,0 @@ -# RichPalette Animation Demo with LED Values -# -# This example demonstrates the Filled animation with a rich palette provider -# which smoothly transitions between colors in a compact palette format. -# It also displays the actual LED values during the animation. - -import global -import tasmota -import animation -import math - -# Helper functions to display LED values -def dump_rgb(strip) - var output = "LEDs: [" - for i:0..math.min(4, strip.length()-1) # Show first 5 LEDs for readability - var color = strip.get_pixel_color(i) - var r = (color >> 16) & 0xFF - var g = (color >> 8) & 0xFF - var b = color & 0xFF - - if i > 0 - output += ", " - end - output += format("R:%d,G:%d,B:%d", r, g, b) - end - if strip.length() > 5 - output += ", ..." # Indicate there are more LEDs - end - output += "]" - print(output) -end - -def dump_hex(strip) - var output = "Hex: [" - for i:0..math.min(4, strip.length()-1) # Show first 5 LEDs for readability - if i > 0 - output += ", " - end - output += format("0x%06X", strip.get_pixel_color(i) & 0xFFFFFF) - end - if strip.length() > 5 - output += ", ..." # Indicate there are more LEDs - end - output += "]" - print(output) -end - -def simulate_animation(controller, strip, duration, interval, description) - print(f"\n--- {description} ---") - - var start_time = tasmota.millis() - var end_time = start_time + duration - var update_interval = interval - - # Simulate updates - var current_time = start_time - while current_time < end_time - # Update the controller with the current time - controller.on_tick(current_time) - - # Show the current state with detailed LED values - print(f"Time: {current_time - start_time}ms, Progress: {(current_time - start_time) * 100 / duration}%") - dump_rgb(strip) - dump_hex(strip) - - # Increment time - current_time += update_interval - end - - print(f"--- End of {description} ---\n") -end - -# Create a mock LED strip with 10 pixels (reduced for readability) -var strip = global.Leds(10) - -# Create an animation controller for the strip -var controller = animation.animation_controller(strip) - -print("Starting RichPalette animation demo with LED values...") - -# Example 1: Rainbow palette -print("\nExample 1: Rainbow palette") -var rainbow = animation.rich_palette_animation(animation.PALETTE_RAINBOW, 2000, 1, 255, 0, 255) -rainbow.start() # Start the animation -controller.add_animation(rainbow) -controller.start() - -# Simulate the animation for one cycle -simulate_animation(controller, strip, 2500, 200, "Rainbow Palette Animation") - -controller.stop() -controller.clear() - -# Example 2: Fire effect palette -print("\nExample 2: Fire effect palette") -var fire_palette = animation.rich_palette_animation(animation.PALETTE_FIRE, 2000, 1, 255, 0, 255) -fire_palette.start() # Start the animation -controller.add_animation(fire_palette) -controller.start() - -# Simulate the animation for one cycle -simulate_animation(controller, strip, 2500, 200, "Fire Effect Animation") - -controller.stop() -controller.clear() - -# Example 3: Tick-based palette -print("\nExample 3: Tick-based palette") -var tick_palette = animation.rich_palette_animation(animation.PALETTE_SUNSET_TICKS, 2000, 1, 255, 0, 255) -tick_palette.start() # Start the animation -controller.add_animation(tick_palette) -controller.start() - -# Simulate the animation for one cycle -simulate_animation(controller, strip, 2500, 200, "Tick-based Palette Animation") - -controller.stop() -controller.clear() - -# Example 4: Custom palette with get_color_for_value demonstration -print("\nExample 4: Custom palette with get_color_for_value demonstration") -var custom_palette_bytes = bytes( - "00FF0000" # Red (value 0) - "3200FF00" # Green (value 50) - "64FFFF00" # Yellow (value 100) - "96FF00FF" # Purple (value 150) - "C80000FF" # Blue (value 200) - "FFFFFFFF" # White (value 255) -) - -# Create a rich palette provider first -var rich_palette_provider = animation.rich_palette_color_provider(custom_palette_bytes, 2000, 1, 255) - -# Set the range for the palette (0-200) -rich_palette_provider.set_range(0, 200) - -# Create a filled animation with this provider -var custom_palette = animation.filled_animation(rich_palette_provider, 0, 255) - -# Demonstrate get_color_for_value -print("Demonstrating get_color_for_value:") -for value : [0, 25, 50, 75, 100, 125, 150, 175, 200] - var color = rich_palette_provider.get_color_for_value(value, tasmota.millis()) - var r = (color >> 16) & 0xFF - var g = (color >> 8) & 0xFF - var b = color & 0xFF - print(f"Value: {value}, Color: 0x{color & 0xFFFFFF:06X} (R:{r}, G:{g}, B:{b})") -end - -# Now use the palette for animation -custom_palette.start() # Start the animation -controller.add_animation(custom_palette) -controller.start() - -# Simulate the animation for one cycle -simulate_animation(controller, strip, 2500, 200, "Custom Palette Animation") - -controller.stop() -controller.clear() - -# Example 5: Comparing linear vs sine transition -print("\nExample 5: Linear vs Sine transition") - -# Linear transition -print("\nLinear transition:") -var linear = animation.rich_palette_animation(animation.PALETTE_RGB, 2000, 0, 255, 0, 255) # Linear transition -linear.start() # Start the animation -controller.add_animation(linear) -controller.start() - -# Simulate the animation for one cycle -simulate_animation(controller, strip, 2500, 200, "Linear Transition Animation") - -controller.stop() -controller.clear() - -# Sine transition -print("\nSine transition:") -var sine = animation.rich_palette_animation(animation.PALETTE_RGB, 2000, 1, 255, 0, 255) # Sine transition -sine.start() # Start the animation -controller.add_animation(sine) -controller.start() - -# Simulate the animation for one cycle -simulate_animation(controller, strip, 2500, 200, "Sine Transition Animation") - -controller.stop() -controller.clear() - -print("\nRichPalette animation demo completed") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/run_all_demos.be b/lib/libesp32/berry_animation/src/examples/run_all_demos.be deleted file mode 100644 index 66385a7b5..000000000 --- a/lib/libesp32/berry_animation/src/examples/run_all_demos.be +++ /dev/null @@ -1,177 +0,0 @@ -# Run all demos for the Berry Animation Framework -# -# This script runs all the demo files in the examples directory -# and provides a simple menu to select which demo to run. - -import global -import tasmota -import animation - -# Define a function to run a demo file -def run_demo_file(file_path) - print("Running " + file_path + "...") - - # Load the file content - var f = open(file_path, "r") - if f == nil - print("Error: Could not open file " + file_path) - return false - end - - var content = f.read() - f.close() - - # Compile and execute the file content - try - var compiled = compile(content) - var result = compiled() - - # If the demo returns a handler, store it for later use - if type(result) == 'instance' && result.contains('handler') - return result - end - - return true - except .. as e - print("Error executing " + file_path + ": " + str(e)) - return false - end -end - -# Main function to run demos -def run_demos() - print("=== Berry Animation Framework Demo Suite ===") - print("") - - var demo_files = [ - "lib/libesp32/berry_animation/examples/sine_int_demo.be", - "lib/libesp32/berry_animation/examples/frame_buffer_demo.be", - "lib/libesp32/berry_animation/examples/renderer_demo.be", - "lib/libesp32/berry_animation/examples/advanced_renderer_demo.be", - "lib/libesp32/berry_animation/examples/parameter_demo.be", - "lib/libesp32/berry_animation/examples/animation_manager_demo.be", - "lib/libesp32/berry_animation/examples/layering_demo.be", - "lib/libesp32/berry_animation/examples/animation_controller_demo.be", - "lib/libesp32/berry_animation/examples/fast_loop_demo.be", - "lib/libesp32/berry_animation/examples/solid_animation_demo.be", # Unified solid() demo - "lib/libesp32/berry_animation/examples/pulse_animation_demo.be", - "lib/libesp32/berry_animation/examples/breathe_animation_demo.be", - "lib/libesp32/berry_animation/examples/color_cycle_animation_demo.be", - "lib/libesp32/berry_animation/examples/rich_palette_animation_demo.be", - "lib/libesp32/berry_animation/examples/palette_pattern_demo.be" - ] - - var demo_names = [ - "Fixed-point Sine Demo", - "Frame Buffer Demo", - "Basic Renderer Demo", - "Advanced Renderer Demo", - "Animation Parameter Demo", - "Animation Manager Demo", - "Animation Layering Demo", - "Animation Controller Demo", - "Fast Loop Integration Demo", - "Solid Animation Demo", - "Pulse Animation Demo", - "Breathe Animation Demo", - "Color Cycle Animation Demo", - "Rich Palette Animation Demo", - "Palette Pattern Demo" - ] - - var demo_descriptions = [ - "Demonstrates the optimized fixed-point sine function", - "Demonstrates basic frame buffer operations", - "Shows basic rendering capabilities", - "Demonstrates advanced rendering features", - "Shows how to use animation parameters", - "Demonstrates animation management features", - "Shows how to layer multiple animations", - "Demonstrates the complete animation controller", - "Shows the fast_loop integration for efficient updates", - "Demonstrates the Solid animation effect", - "Demonstrates the Pulse animation effect with color pulsing", - "Demonstrates the Breathe animation effect with natural breathing curve", - "Demonstrates the Color Cycle animation with smooth transitions between colors", - "Demonstrates the Rich Palette animation with compact palette formats", - "Demonstrates using RichPalette as a color provider for patterns" - ] - - # Print menu - print("Available demos:") - print("") - - var i = 0 - while i < size(demo_files) - print(format("%d. %s - %s", i + 1, demo_names[i], demo_descriptions[i])) - i += 1 - end - - print("0. Run all demos sequentially") - print("q. Quit") - print("") - - # Get user choice - print("Enter your choice (0-" + str(size(demo_files)) + " or q): ") - var choice = input() - - if choice == "q" || choice == "Q" - print("Exiting demo suite.") - return - end - - var choice_num = number(choice) - - if choice_num == 0 - # Run all demos - print("Running all demos sequentially...") - print("") - - var demo_handlers = [] - - i = 0 - while i < size(demo_files) - print("=== " + demo_names[i] + " ===") - var result = run_demo_file(demo_files[i]) - - if type(result) == 'instance' && result.contains('handler') - demo_handlers.push(result) - end - - print("") - print("Press Enter to continue to the next demo...") - input() - print("") - - i += 1 - end - - print("All demos completed!") - - # Return the handlers for the last demo - if size(demo_handlers) > 0 - return demo_handlers[size(demo_handlers) - 1] - end - elif choice_num >= 1 && choice_num <= size(demo_files) - # Run selected demo - var index = choice_num - 1 - print("=== " + demo_names[index] + " ===") - return run_demo_file(demo_files[index]) - else - print("Invalid choice. Please run the script again and select a valid option.") - end - - return nil -end - -# Run demos and get the result -var demo_result = run_demos() - -# If the demo returned a handler, return it for interactive use -if demo_result != nil - print("Demo handler available for interactive use.") - return demo_result -end - -# Return success -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/simple_comet_test.be b/lib/libesp32/berry_animation/src/examples/simple_comet_test.be deleted file mode 100644 index 496a6488a..000000000 --- a/lib/libesp32/berry_animation/src/examples/simple_comet_test.be +++ /dev/null @@ -1,38 +0,0 @@ -# Simple Comet Test -# Basic test to verify comet animation works - -import animation - -print("=== Simple Comet Test ===") - -# Create a frame buffer -var frame = animation.frame_buffer(10) -print("Created frame buffer:", frame) - -# Create a simple comet -var comet = animation.comet.solid(0xFFFF0000, 3, 256, 10, 1) # Red, 3-pixel tail, slow -print("Created comet:", comet) - -# Start the animation -comet.start() -print("Started comet") - -# Update and render -comet.update(0) -print(f"Updated comet - head_position: {comet.head_position}") - -# Clear frame and render -frame.clear() -var rendered = comet.render(frame, tasmota.millis()) -print("Rendered:", rendered) - -# Check pixels -print("Frame buffer contents:") -for i: 0..9 - var color = frame.get_pixel_color(i) - if color != 0 - print(f" Pixel {i}: 0x{color:08X}") - end -end - -print("=== Simple Comet Test Complete ===") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/simple_ease_demo.be b/lib/libesp32/berry_animation/src/examples/simple_ease_demo.be deleted file mode 100644 index b0faa3cf7..000000000 --- a/lib/libesp32/berry_animation/src/examples/simple_ease_demo.be +++ /dev/null @@ -1,70 +0,0 @@ -# Simple demo of ease_in and ease_out functionality -# This demo only tests the oscillator provider without the full animation framework - -import tasmota - -# Mock tasmota functions for testing -import global -if !global.contains("tasmota") - tasmota = {} - tasmota.millis = def() return 1000 end - tasmota.scale_uint = def(value, from_min, from_max, to_min, to_max) - if from_max == from_min return to_min end - return to_min + ((value - from_min) * (to_max - to_min)) / (from_max - from_min) - end - tasmota.sine_int = def(angle) - import math - return int(4096 * math.sin(angle * math.pi / 16384)) - end -end - -# Load just the oscillator provider -import "providers/oscillator_value_provider.be" as osc_provider - -print("=== Simple Ease In/Out Demo ===") - -# Test EASE_IN -print("\nTesting EASE_IN (0->100 over 1000ms):") -var ease_in = osc_provider.ease_in(0, 100, 1000) -var start_time = 1000 - -for i: [0, 250, 500, 750, 1000] - var value = ease_in.get_value(start_time + i) - var percent = i / 10 # Convert to percentage - print(f" {percent:3.0f}% ({i:4d}ms): value = {value:3d}") -end - -# Test EASE_OUT -print("\nTesting EASE_OUT (0->100 over 1000ms):") -var ease_out = osc_provider.ease_out(0, 100, 1000) -start_time = 2000 - -for i: [0, 250, 500, 750, 1000] - var value = ease_out.get_value(start_time + i) - var percent = i / 10 # Convert to percentage - print(f" {percent:3.0f}% ({i:4d}ms): value = {value:3d}") -end - -# Compare with linear -print("\nComparison with LINEAR (0->100 over 1000ms):") -var linear = osc_provider.linear(0, 100, 1000) -start_time = 3000 - -print("Time% Linear Ease-In Ease-Out") -print("---- ------ ------- --------") - -var ease_in_comp = osc_provider.ease_in(0, 100, 1000) -var ease_out_comp = osc_provider.ease_out(0, 100, 1000) - -for i: [0, 250, 500, 750, 1000] - var percent = i / 10 - var linear_val = linear.get_value(start_time + i) - var ease_in_val = ease_in_comp.get_value(start_time + i) - var ease_out_val = ease_out_comp.get_value(start_time + i) - print(f"{percent:3.0f}% {linear_val:6d} {ease_in_val:7d} {ease_out_val:8d}") -end - -print("\n=== Demo Complete ===") -print("✓ EASE_IN: Starts slow, accelerates (quadratic)") -print("✓ EASE_OUT: Starts fast, decelerates (quadratic)") -print("✓ Both integrate seamlessly with existing oscillator features") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/simple_engine_test.be b/lib/libesp32/berry_animation/src/examples/simple_engine_test.be deleted file mode 100644 index 9d049b8de..000000000 --- a/lib/libesp32/berry_animation/src/examples/simple_engine_test.be +++ /dev/null @@ -1,75 +0,0 @@ -# Simple Animation Engine Test -# Basic functionality test for the unified engine - -print("=== Simple Animation Engine Test ===") - -# Mock tasmota for testing -var tasmota = { - "millis": def() return 1000 end, - "scale_uint": def(value, from_min, from_max, to_min, to_max) - if from_max == from_min - return to_min - end - var ratio = (value - from_min) * 1.0 / (from_max - from_min) - return int(to_min + ratio * (to_max - to_min)) - end, - "add_fast_loop": def(closure) print("Fast loop added") end, - "remove_fast_loop": def(closure) print("Fast loop removed") end -} - -# Mock global for testing -var global = { - "animation": {} -} - -# Simple mock strip -class SimpleStrip - var len - def init(length) self.len = length end - def length() return self.len end - def set_pixel_color(i, color) end - def show() end - def can_show() return true end -end - -# Test the engine creation and basic functionality -try - # Load the animation engine - import "core/frame_buffer" - import "core/animation" - import "core/animation_engine" - - print("✓ Modules loaded successfully") - - # Create a test strip - var strip = SimpleStrip(10) - print(f"✓ Created test strip with {strip.length()} pixels") - - # Create the engine - var engine = global.animation.animation_engine(strip) - print(f"✓ Created engine: {engine}") - - # Test basic operations - print(f"✓ Engine width: {engine.width}") - print(f"✓ Engine active: {engine.is_active()}") - print(f"✓ Engine size: {engine.size()}") - - # Test start/stop - engine.start() - print(f"✓ Engine started: {engine.is_active()}") - - engine.stop() - print(f"✓ Engine stopped: {engine.is_active()}") - - print("\n🎉 Basic engine functionality works!") - -except .. as e, msg - print(f"❌ Error: {e} - {msg}") -end - -print("\n=== Test Complete ===") -print("The unified AnimationEngine successfully:") -print("- Replaces AnimationController + AnimationManager + Renderer") -print("- Provides the same API with better performance") -print("- Reduces complexity from 3 objects to 1") -print("- Maintains full backward compatibility") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/simple_led_demo.be b/lib/libesp32/berry_animation/src/examples/simple_led_demo.be deleted file mode 100644 index 3c6ebe6a7..000000000 --- a/lib/libesp32/berry_animation/src/examples/simple_led_demo.be +++ /dev/null @@ -1,73 +0,0 @@ -# Simple LED Demo -# This is a very basic demo that just sets different LED values directly -# to verify that we can display changing values - -import global -import tasmota - -# Helper function to dump LED values -def dump_strip(strip, size) - var output = "[" - for i:0..size-1 - if i > 0 - output += ", " - end - output += format("0x%06X", strip.get_pixel_color(i) & 0xFFFFFF) - end - output += "]" - print(output) -end - -print("Starting Simple LED Demo") - -# Create a strip with 3 LEDs -var strip = global.Leds(3) - -# Define some test values -var test_values = [ - 0x0000FF, # Blue - 0x00FF00, # Green - 0xFF0000, # Red - 0xFFFF00, # Yellow - 0xFF00FF, # Magenta - 0x00FFFF, # Cyan - 0xFFFFFF # White -] - -# Set each value and display the result -for i:0..size(test_values)-1 - var color = test_values[i] - - # Extract RGB components - var r = (color >> 16) & 0xFF - var g = (color >> 8) & 0xFF - var b = color & 0xFF - - print(f"Setting color #{i+1}: RGB({r},{g},{b}) = 0x{color:06X}") - - # Set all LEDs to this color - for j:0..2 # strip has 3 LEDs - strip.set_pixel_color(j, color) - end - - # Display the LED values - var led_values = "LEDs: [" - for j:0..strip.size-1 - if j > 0 - led_values += ", " - end - led_values += format("R:%d,G:%d,B:%d", r, g, b) - end - led_values += "]" - print(led_values) - - # Show hex values - dump_strip(strip, 3) - - # Add a separator - print("---") -end - -print("Simple LED Demo completed") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/sine_int_demo.be b/lib/libesp32/berry_animation/src/examples/sine_int_demo.be deleted file mode 100644 index 6f328adf6..000000000 --- a/lib/libesp32/berry_animation/src/examples/sine_int_demo.be +++ /dev/null @@ -1,91 +0,0 @@ -# Sine Int Demo -# -# This example demonstrates the fixed-point sine implementation -# that is optimized for performance on embedded systems. -# -# It shows how to use tasmota.sine_int() for efficient sine calculations -# in animations and other applications. - -import global -import tasmota - -print("Fixed-point sine demo") -print("=====================") -print("tasmota.sine_int() is an optimized fixed-point sine function") -print("Input: angle in range [0, 32767] representing [0, 2π]") -print(" where 8192 represents π/2") -print("Output: value in range [-4096, 4096] representing [-1.0, 1.0]") -print("") - -# Print a table of sine values at different angles -print("Angle (degrees) | Angle (internal) | Sine value") -print("--------------- | --------------- | ----------") - -# Calculate sine values for angles from 0 to 360 degrees in 30-degree increments -var degrees = 0 -while (degrees < 361) - # Convert degrees to the internal angle representation - # 360 degrees = 32768 units - var angle = tasmota.scale_uint(degrees, 0, 360, 0, 32768) - - # Calculate the sine value - var sine = tasmota.sine_int(angle) - - # Print the result - print(format("%15d | %15d | %10d", degrees, angle, sine)) - - degrees += 30 -end - -print("") -print("Visualization of sine wave:") -print("") - -# Create a simple ASCII visualization of the sine wave -var width = 60 # Width of the visualization -var height = 10 # Height of the visualization - -# Create a buffer for the visualization -var buffer = [] -for i:0..height-1 - var line = [] - for j:0..width-1 - line.push(" ") - end - buffer.push(line) -end - -# Draw the sine wave -for x:0..width-1 - # Calculate the angle (0 to 2π over the width) - var angle = tasmota.scale_uint(x, 0, width, 0, 32768) - - # Calculate the sine value (-4096 to 4096) - var sine = tasmota.sine_int(angle) - - # Map the sine value to the height of the visualization - var y = (height / 2) - tasmota.scale_uint(sine, -4096, 4096, -height/2, height/2) - y = y < 0 ? 0 : (y >= height ? height - 1 : y) - - # Draw the point - buffer[y][x] = "*" -end - -# Draw the x-axis -var x_axis = height / 2 -for x:0..width-1 - buffer[x_axis][x] = "-" -end - -# Print the visualization -for y:0..height-1 - var line = "" - for x:0..width-1 - line += buffer[y][x] - end - print(line) -end - -print("") -print("Demo completed!") -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/solid_animation_demo.be b/lib/libesp32/berry_animation/src/examples/solid_animation_demo.be deleted file mode 100644 index ee9c702f9..000000000 --- a/lib/libesp32/berry_animation/src/examples/solid_animation_demo.be +++ /dev/null @@ -1,89 +0,0 @@ -# Unified Solid Animation Demo -# -# This example demonstrates how to use the unified solid() function -# to display a static color on an LED strip. - -import global -import tasmota -import animation - -# Using global.Leds instead of MockLEDStrip -import global - -# Helper function to display LED strip state -def show_strip_state(strip, width) - print("LED Strip state:") - var output = "[" - for i: 0..width-1 - var color = strip.get_pixel_color(i) - var r = (color >> 16) & 0xFF - var g = (color >> 8) & 0xFF - var b = color & 0xFF - output += format("RGB(%d,%d,%d)", r, g, b) - if i < width - 1 - output += ", " - end - end - output += "]" - print(output) -end - -# Create an LED strip with 10 pixels -var strip = global.Leds(10) - -# Create an animation controller for the strip -var controller = animation.animation_controller(strip) - -# Create a solid animation with red color (unified function) -var solid_red = animation.solid(0xFFFF0000) # Red color (ARGB format) - -# Add the animation to the controller -controller.add_animation(solid_red) - -# Start the controller -controller.start() - -# Simulate a few ticks to update the animation -print("Initial state (red):") -controller.on_tick(tasmota.millis()) -strip.show() -show_strip_state(strip, 10) - -# Change the color to green -print("\nChanging color to green:") -solid_red.set_color(0xFF00FF00) # Green color -controller.on_tick(tasmota.millis() + 100) -strip.show() -show_strip_state(strip, 10) - -# Create a second solid animation with blue color and higher priority -var solid_blue = animation.solid(0xFF0000FF, 10) # Blue color, priority 10 -controller.add_animation(solid_blue) - -# Update to show the blue animation (higher priority) -print("\nAdding blue animation with higher priority:") -controller.on_tick(tasmota.millis() + 300) -strip.show() -show_strip_state(strip, 10) - -# Note: Opacity is now controlled at the pixel level through alpha channels -print("\nNote: Opacity is now controlled through per-pixel alpha channels") -controller.on_tick(tasmota.millis() + 400) -strip.show() -show_strip_state(strip, 10) - -# Stop the blue animation -print("\nStopping blue animation (should return to green):") -solid_blue.stop() -controller.on_tick(tasmota.millis() + 500) -strip.show() -show_strip_state(strip, 10) - -# Stop the controller -print("\nStopping controller:") -controller.stop() -strip.clear() -strip.show() -show_strip_state(strip, 10) - -print("\nUnified solid animation demo completed!") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/test_token_system.be b/lib/libesp32/berry_animation/src/examples/test_token_system.be deleted file mode 100644 index 5de4800a4..000000000 --- a/lib/libesp32/berry_animation/src/examples/test_token_system.be +++ /dev/null @@ -1,93 +0,0 @@ -# Test Token System -# Quick test to verify the token system is working correctly - -import "animation" as animation - -print("Testing Animation DSL Token System...") - -# Test 1: Basic token creation -print("\n1. Testing basic token creation...") -try - var token = animation.Token(animation.Token.KEYWORD, "color", 1, 5) - print(f"✓ Created token: {token}") -except .. as error_type, error_message - print(f"✗ Failed to create token: {error_type} - {error_message}") - return false -end - -# Test 2: Token type constants -print("\n2. Testing token type constants...") -try - assert(animation.Token.KEYWORD == 0) - assert(animation.Token.IDENTIFIER == 1) - assert(animation.Token.EOF == 38) - print("✓ Token type constants are correct") -except .. as error_type, error_message - print(f"✗ Token type constants failed: {error_type} - {error_message}") - return false -end - -# Test 3: Token methods -print("\n3. Testing token methods...") -try - var token = animation.Token(animation.Token.TIME, "2s", 1, 1) - assert(token.is_type(animation.Token.TIME)) - assert(token.is_numeric()) - assert(token.get_numeric_value() == 2000) - print("✓ Token methods work correctly") -except .. as error_type, error_message - print(f"✗ Token methods failed: {error_type} - {error_message}") - return false -end - -# Test 4: Utility functions -print("\n4. Testing utility functions...") -try - assert(animation.is_keyword("color")) - assert(!animation.is_keyword("my_color")) - assert(animation.is_color_name("red")) - assert(!animation.is_color_name("my_red")) - print("✓ Utility functions work correctly") -except .. as error_type, error_message - print(f"✗ Utility functions failed: {error_type} - {error_message}") - return false -end - -# Test 5: Token creation utilities -print("\n5. Testing token creation utilities...") -try - var eof_token = animation.create_eof_token(10, 1) - var error_token = animation.create_error_token("Test error", 5, 3) - var newline_token = animation.create_newline_token(2, 15) - - assert(eof_token.type == animation.Token.EOF) - assert(error_token.type == animation.Token.ERROR) - assert(newline_token.type == animation.Token.NEWLINE) - print("✓ Token creation utilities work correctly") -except .. as error_type, error_message - print(f"✗ Token creation utilities failed: {error_type} - {error_message}") - return false -end - -# Test 6: Operator precedence -print("\n6. Testing operator precedence...") -try - var plus_token = animation.Token(animation.Token.PLUS, "+", 1, 1) - var mult_token = animation.Token(animation.Token.MULTIPLY, "*", 1, 1) - - var plus_prec = animation.get_operator_precedence(plus_token) - var mult_prec = animation.get_operator_precedence(mult_token) - - assert(mult_prec > plus_prec) - print("✓ Operator precedence works correctly") -except .. as error_type, error_message - print(f"✗ Operator precedence failed: {error_type} - {error_message}") - return false -end - -print("\n🎉 All token system tests passed!") -print("The DSL token system is ready for use.") - -# Using built-in assert function - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/token_demo.be b/lib/libesp32/berry_animation/src/examples/token_demo.be deleted file mode 100644 index 31863aea2..000000000 --- a/lib/libesp32/berry_animation/src/examples/token_demo.be +++ /dev/null @@ -1,177 +0,0 @@ -# Token System Demo -# Demonstrates the DSL token system functionality - -import "animation" as animation - -print("=== Animation DSL Token System Demo ===") - -# Demo 1: Basic token creation and inspection -print("\n--- Demo 1: Basic Token Creation ---") - -var keyword_token = animation.Token(animation.Token.KEYWORD, "color", 1, 5) -var identifier_token = animation.Token(animation.Token.IDENTIFIER, "red", 1, 11) -var color_token = animation.Token(animation.Token.COLOR, "#FF0000", 1, 15) -var time_token = animation.Token(animation.Token.TIME, "2s", 2, 1) -var number_token = animation.Token(animation.Token.NUMBER, "123.45", 2, 5) - -print(f"Keyword token: {keyword_token}") -print(f"Identifier token: {identifier_token}") -print(f"Color token: {color_token}") -print(f"Time token: {time_token}") -print(f"Number token: {number_token}") - -# Demo 2: Token type checking -print("\n--- Demo 2: Token Type Checking ---") - -print(f"Is '{keyword_token.value}' a keyword? {keyword_token.is_type(animation.Token.KEYWORD)}") -print(f"Is '{keyword_token.value}' the 'color' keyword? {keyword_token.is_keyword('color')}") -print(f"Is '{identifier_token.value}' an identifier? {identifier_token.is_type(animation.Token.IDENTIFIER)}") -print(f"Is '{identifier_token.value}' the 'red' identifier? {identifier_token.is_identifier('red')}") - -print(f"Is '{color_token.value}' a literal? {color_token.is_literal()}") -print(f"Is '{time_token.value}' numeric? {time_token.is_numeric()}") - -# Demo 3: Value extraction -print("\n--- Demo 3: Value Extraction ---") - -var true_token = animation.Token(animation.Token.KEYWORD, "true", 3, 1) -var false_token = animation.Token(animation.Token.KEYWORD, "false", 3, 6) -var percent_token = animation.Token(animation.Token.PERCENTAGE, "75%", 3, 12) -var multiplier_token = animation.Token(animation.Token.MULTIPLIER, "2.5x", 3, 17) - -print(f"Boolean value of 'true': {true_token.get_boolean_value()}") -print(f"Boolean value of 'false': {false_token.get_boolean_value()}") -print(f"Numeric value of '2s': {time_token.get_numeric_value()}ms") -print(f"Time in ms of '2s': {time_token.get_numeric_value()}ms") -print(f"Percentage as 0-255: {percent_token.get_numeric_value()}") -print(f"Multiplier value: {multiplier_token.get_numeric_value()}") - -# Demo 4: Different time units -print("\n--- Demo 4: Time Unit Conversion ---") - -var time_tokens = [ - animation.Token(animation.Token.TIME, "500ms", 4, 1), - animation.Token(animation.Token.TIME, "3s", 4, 7), - animation.Token(animation.Token.TIME, "2m", 4, 11), - animation.Token(animation.Token.TIME, "1h", 4, 15) -] - -for token : time_tokens - print(f"Time '{token.value}' = {token.get_numeric_value()}ms") -end - -# Demo 5: Operator precedence -print("\n--- Demo 5: Operator Precedence ---") - -var operators = [ - animation.Token(animation.Token.LOGICAL_OR, "||", 5, 1), - animation.Token(animation.Token.LOGICAL_AND, "&&", 5, 4), - animation.Token(animation.Token.EQUAL, "==", 5, 7), - animation.Token(animation.Token.PLUS, "+", 5, 10), - animation.Token(animation.Token.MULTIPLY, "*", 5, 12), - animation.Token(animation.Token.POWER, "^", 5, 14) -] - -print("Operator precedence (higher number = higher precedence):") -for op : operators - var precedence = animation.get_operator_precedence(op) - var associativity = animation.is_right_associative(op) ? "right" : "left" - print(f" {op.value} : precedence={precedence}, associativity={associativity}") -end - -# Demo 6: Keyword and color name checking -print("\n--- Demo 6: Keyword and Color Name Checking ---") - -var test_words = ["color", "pattern", "red", "blue", "my_variable", "gradient", "transparent"] - -for word : test_words - var is_kw = animation.is_keyword(word) - var is_color = animation.is_color_name(word) - var type_str = "" - if is_kw && is_color - type_str = "keyword + color" - elif is_kw - type_str = "keyword" - elif is_color - type_str = "color" - else - type_str = "identifier" - end - print(f" '{word}' -> {type_str}") -end - -# Demo 7: Token utilities -print("\n--- Demo 7: Token Utilities ---") - -var original_token = animation.Token(animation.Token.IDENTIFIER, "test", 6, 10, 4) -print(f"Original token: {original_token}") -print(f"End column: {original_token.end_column()}") - -var new_type_token = original_token.with_type(animation.Token.KEYWORD) -print(f"With new type: {new_type_token}") - -var new_value_token = original_token.with_value("newname") -print(f"With new value: {new_value_token}") - -# Demo 8: Expression checking -print("\n--- Demo 8: Expression Checking ---") - -var expression_tokens = [ - animation.Token(animation.Token.NUMBER, "123", 7, 1), - animation.Token(animation.Token.IDENTIFIER, "red", 7, 5), - animation.Token(animation.Token.LEFT_PAREN, "(", 7, 9), - animation.Token(animation.Token.RIGHT_PAREN, ")", 7, 10), - animation.Token(animation.Token.KEYWORD, "color", 7, 12), - animation.Token(animation.Token.PLUS, "+", 7, 18) -] - -print("Expression analysis:") -for token : expression_tokens - var can_start = token.can_start_expression() - var can_end = token.can_end_expression() - print(f" {token.to_error_string()}: can_start={can_start}, can_end={can_end}") -end - -# Demo 9: Error handling and edge cases -print("\n--- Demo 9: Error Handling ---") - -var eof_token = animation.create_eof_token(10, 1) -var error_token = animation.create_error_token("Unexpected character '&'", 8, 15) -var newline_token = animation.create_newline_token(9, 20) - -print(f"EOF token: {eof_token}") -print(f"Error token: {error_token}") -print(f"Newline token: {newline_token}") - -print(f"EOF error string: {eof_token.to_error_string()}") -print(f"Error error string: {error_token.to_error_string()}") - -# Demo 10: Token type string conversion -print("\n--- Demo 10: Token Type Names ---") - -var sample_types = [ - animation.Token.KEYWORD, - animation.Token.IDENTIFIER, - animation.Token.COLOR, - animation.Token.TIME, - animation.Token.LOGICAL_AND, - animation.Token.LEFT_PAREN, - animation.Token.EOF -] - -print("Token type names:") -for token_type : sample_types - print(f" {token_type} -> {animation.Token.to_string(token_type)}") -end - -print("\n=== Token System Demo Complete ===") -print("The token system provides comprehensive support for:") -print("- All DSL token types with proper classification") -print("- Line and column tracking for error reporting") -print("- Value extraction with type conversion") -print("- Operator precedence and associativity") -print("- Keyword and color name recognition") -print("- Expression boundary detection") -print("- Comprehensive string representations") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/twinkle_animation_demo.be b/lib/libesp32/berry_animation/src/examples/twinkle_animation_demo.be deleted file mode 100644 index 7f5dfb132..000000000 --- a/lib/libesp32/berry_animation/src/examples/twinkle_animation_demo.be +++ /dev/null @@ -1,215 +0,0 @@ -# Twinkle Animation Demo -# Demonstrates the TwinkleAnimation class with various configurations - -import global -import animation - -print("=== Twinkle Animation Demo ===") - -# Demo configuration -var STRIP_LENGTH = 30 -var DEMO_DURATION = 8000 # 8 seconds per demo - -print(f"Strip length: {STRIP_LENGTH} pixels") -print(f"Demo duration: {DEMO_DURATION}ms per animation") - -# Demo 1: Classic White Twinkle -print("\n--- Demo 1: Classic White Twinkle ---") -var classic_twinkle = animation.twinkle_animation.classic(128, STRIP_LENGTH, 10) -print(f"Created classic twinkle: {classic_twinkle}") -print("This creates a classic twinkling stars effect with:") -print("- White color") -print("- Medium density (128/255)") -print("- 6 Hz twinkle speed") -print("- Moderate fade speed") - -# Demo 2: Gentle Blue Twinkle -print("\n--- Demo 2: Gentle Blue Twinkle ---") -var gentle_twinkle = animation.twinkle_animation.gentle(0xFF4169E1, STRIP_LENGTH, 10) # Royal Blue -print(f"Created gentle twinkle: {gentle_twinkle}") -print("This creates a gentle twinkling effect with:") -print("- Royal blue color") -print("- Low density (64/255)") -print("- Slow twinkle speed (3 Hz)") -print("- Slow fade for longer-lasting twinkles") - -# Demo 3: Intense Red Twinkle -print("\n--- Demo 3: Intense Red Twinkle ---") -var intense_twinkle = animation.twinkle_animation.intense(0xFFDC143C, STRIP_LENGTH, 10) # Crimson -print(f"Created intense twinkle: {intense_twinkle}") -print("This creates an intense twinkling effect with:") -print("- Crimson red color") -print("- High density (200/255)") -print("- Fast twinkle speed (12 Hz)") -print("- Fast fade for rapid twinkling") - -# Demo 4: Rainbow Twinkle -print("\n--- Demo 4: Rainbow Twinkle ---") -var rainbow_twinkle = animation.twinkle_animation.rainbow(100, STRIP_LENGTH, 10) -print(f"Created rainbow twinkle: {rainbow_twinkle}") -print("This creates a rainbow twinkling effect with:") -print("- Rainbow color palette") -print("- Medium density (100/255)") -print("- Standard timing") - -# Demo 5: Custom Twinkle Configuration -print("\n--- Demo 5: Custom Twinkle Configuration ---") -var custom_twinkle = animation.twinkle_animation( - 0xFFFFD700, # Gold color - 150, # High density - 8, # 8 Hz speed - 200, # Fast fade - 16, # Very dim minimum - 240, # Bright maximum - STRIP_LENGTH, - 10, 0, true, "custom_gold" -) -print(f"Created custom twinkle: {custom_twinkle}") -print("This creates a custom gold twinkling effect with:") -print("- Gold color (0xFFFFD700)") -print("- High density (150/255)") -print("- 8 Hz twinkle speed") -print("- Fast fade (200/255)") -print("- Wide brightness range (16-240)") - -# Demo 6: Animation Controller Integration -print("\n--- Demo 6: Animation Controller Integration ---") -print("Creating animation controller and adding multiple twinkle effects...") - -# Create a mock LED strip (in real usage, this would be a real strip) -class MockStrip - var pixels - var strip_length - - def init(length) - self.strip_length = length - self.pixels = [] - self.pixels.resize(length) - for i: 0..length-1 - self.pixels[i] = 0 - end - end - - def set_pixel_color(index, color) - if index >= 0 && index < self.strip_length - self.pixels[index] = color - end - end - - def show() - # In real usage, this would update the physical LEDs - return true - end - - def get_pixel_color(index) - if index >= 0 && index < self.strip_length - return self.pixels[index] - end - return 0 - end - - def length() - return self.strip_length - end -end - -var strip = global.Leds(STRIP_LENGTH) -var controller = animation.animation_controller(strip) - -# Add multiple twinkle animations with different priorities -controller.add_animation(classic_twinkle) -controller.add_animation(gentle_twinkle.set_priority(5)) # Lower priority - -print("Added classic twinkle (priority 10) and gentle twinkle (priority 5)") -print("The classic twinkle will render on top of the gentle twinkle") - -# Demo 7: Real-time Parameter Updates -print("\n--- Demo 7: Real-time Parameter Updates ---") -var dynamic_twinkle = animation.twinkle_animation.classic(64, STRIP_LENGTH, 10) -print(f"Created dynamic twinkle with initial density: {dynamic_twinkle.get_param('density')}") - -# Simulate parameter changes over time -var densities = [64, 100, 150, 200, 255, 128, 80] -for i: 0..size(densities)-1 - var new_density = densities[i] - dynamic_twinkle.set_density(new_density) - print(f"Updated density to: {new_density}") -end - -# Demo 8: Performance Considerations -print("\n--- Demo 8: Performance Considerations ---") -print("Twinkle animation performance tips:") -print("- Lower twinkle_speed reduces CPU usage (fewer updates per second)") -print("- Lower density reduces computation and random number generation") -print("- Smaller strip_length reduces memory usage and computation") -print("- Use solid colors instead of color providers for maximum performance") - -# Create a performance-optimized twinkle -var perf_twinkle = animation.twinkle_animation.solid(0xFFFFFFFF, 80, STRIP_LENGTH, 10) -perf_twinkle.set_twinkle_speed(4) # Slower updates -perf_twinkle.set_fade_speed(150) # Moderate fade -print(f"Created performance-optimized twinkle: {perf_twinkle}") - -# Demo 9: Simulation Test -print("\n--- Demo 9: Twinkle Simulation Test ---") -print("Running twinkle simulation for a few cycles...") - -var test_twinkle = animation.twinkle_animation.classic(180, 10, 10) # Smaller strip for easier visualization -test_twinkle.start() - -var frame = animation.frame_buffer(10) -var start_time = 1000 - -for cycle: 0..4 - var current_time = start_time + (cycle * 167) # 6 Hz = 167ms intervals - test_twinkle.update(current_time) - test_twinkle.render(frame, current_time) - - print(f"Cycle {cycle + 1}:") - var twinkle_info = " Brightness: " - for i: 0..9 - var color = frame.get_pixel_color(i) - var brightness = 0 - if color != 0xFF000000 - # Extract brightness from color (simple approximation) - var r = (color >> 16) & 0xFF - var g = (color >> 8) & 0xFF - var b = color & 0xFF - brightness = (r + g + b) / 3 - end - twinkle_info += f"{brightness:3d} " - end - print(twinkle_info) -end - -# Demo 10: Different Twinkle Styles Comparison -print("\n--- Demo 10: Different Twinkle Styles Comparison ---") -print("Comparing different twinkle styles:") - -var styles = [ - ["Gentle", animation.twinkle_animation.gentle(0xFFFFFFFF, 10, 10)], - ["Classic", animation.twinkle_animation.classic(128, 10, 10)], - ["Intense", animation.twinkle_animation.intense(0xFFFFFFFF, 10, 10)] -] - -for style_info: styles - var style_name = style_info[0] - var style_twinkle = style_info[1] - - print(f"\n{style_name} style:") - print(f" Density: {style_twinkle.get_param('density')}") - print(f" Speed: {style_twinkle.get_param('twinkle_speed')} Hz") - print(f" Fade: {style_twinkle.get_param('fade_speed')}") - print(f" Brightness: {style_twinkle.get_param('brightness_min')}-{style_twinkle.get_param('brightness_max')}") -end - -print("\n=== Twinkle Animation Demo Complete ===") -print("The twinkle animation provides realistic twinkling effects with:") -print("- Random light placement and timing") -print("- Configurable density and fade characteristics") -print("- Support for custom colors and palettes") -print("- Multiple preset styles (gentle, classic, intense)") -print("- Real-time parameter updates") -print("- Integration with the animation framework") - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/unified_engine_demo.be b/lib/libesp32/berry_animation/src/examples/unified_engine_demo.be deleted file mode 100644 index 46bce2fba..000000000 --- a/lib/libesp32/berry_animation/src/examples/unified_engine_demo.be +++ /dev/null @@ -1,108 +0,0 @@ -# Unified Animation Engine Demo -# Demonstrates the simplified API using the new AnimationEngine - -import animation -import global -import tasmota - -print("=== Unified Animation Engine Demo ===") - -# Create a strip with 10 pixels -var strip = global.Leds(10) - -print(f"Created strip with {strip.length()} pixels") - -# Create the unified animation engine -var engine = animation.create_engine(strip) -print(f"Created animation engine: {engine}") - -# Create some animations -var red_solid = animation.solid(0xFFFF0000, 10) # Red with priority 10 -var blue_pulse = animation.pulse_animation(0xFF0000FF, 2000, 5) # Blue pulse, 2s period, priority 5 - -print("Created animations:") -print(f" Red solid: {red_solid}") -print(f" Blue pulse: {blue_pulse}") - -# Add animations to engine -engine.add_animation(red_solid) -engine.add_animation(blue_pulse) - -print(f"Engine now has {engine.size()} animations") - -# Start the engine -engine.start() -print("Engine started") - -# Simulate some ticks -print("\nSimulating animation ticks...") -var current_time = tasmota.millis() - -for i : 0..4 - print(f"Tick {i+1}:") - engine.on_tick(current_time + (i * 100)) # 100ms intervals - - # Show current animations - var animations = engine.get_animations() - print(f" Active animations: {size(animations)}") - for anim : animations - print(f" - {anim.name} (priority: {anim.priority}, running: {anim.is_running})") - end -end - -# Test sequence management -print("\n=== Testing Sequence Management ===") - -# Create a sequence manager -var seq_manager = animation.SequenceManager(engine) - -# Create sequence steps -var steps = [] -steps.push(animation.create_play_step(red_solid, 1000)) # Play red for 1s -steps.push(animation.create_wait_step(500)) # Wait 0.5s -steps.push(animation.create_play_step(blue_pulse, 2000)) # Play blue pulse for 2s - -print(f"Created sequence with {size(steps)} steps") - -# Add sequence manager to engine -engine.add_sequence_manager(seq_manager) - -# Start the sequence -seq_manager.start_sequence(steps) -print("Sequence started") - -# Simulate sequence execution -for i : 0..10 - print(f"Sequence tick {i+1}:") - engine.on_tick(current_time + (i * 200)) # 200ms intervals - - if seq_manager.is_sequence_running() - var step_info = seq_manager.get_current_step_info() - print(f" Current step: {step_info}") - else - print(" Sequence completed") - break - end -end - -# Clean up -engine.stop() -print("\nEngine stopped") - -print("\n=== API Consistency ===") - -print("Main API:") -var main_engine = animation.create_engine(strip) -print(f"Main engine: {main_engine}") - -print("\nDirect class access:") -var direct_engine = animation.animation_engine(strip) -print(f"Direct engine: {direct_engine}") - -print("\n=== Demo Complete ===") -print("The unified AnimationEngine provides:") -print("- Single class replacing multiple components") -print("- Simplified API with same functionality") -print("- Better performance through reduced object overhead") -print("- Cleaner code organization") -print("- Streamlined development experience") \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/examples/user_functions_demo.be b/lib/libesp32/berry_animation/src/examples/user_functions_demo.be deleted file mode 100644 index 34bc9a62d..000000000 --- a/lib/libesp32/berry_animation/src/examples/user_functions_demo.be +++ /dev/null @@ -1,85 +0,0 @@ -# Demo showing user-defined functions in DSL -# -# This example demonstrates how user-defined functions can be used in DSL -# after being registered in Berry code. - -import animation - -# Load user functions (this registers them with the animation module) -import "user_functions" as user_funcs - -# Example DSL using user-defined functions -var dsl_code = - "strip length 60\n" + - "\n" + - "# Define colors\n" + - "color red = #FF0000\n" + - "color blue = #0000FF\n" + - "color white = #FFFFFF\n" + - "color orange = #FFA500\n" + - "\n" + - "# Use user-defined functions just like built-in functions\n" + - "animation calm_breathing = breathing(blue, 4s)\n" + - "animation emergency_lights = police_lights(200ms)\n" + - "animation fire_effect = fire(200, 300ms)\n" + - "animation sparkles = sparkle(white, blue, 10%)\n" + - "animation rainbow = color_wheel(5s)\n" + - "\n" + - "# Nested calls with user functions\n" + - "animation complex = fade(breathing(red, 2s), 3s)\n" + - "\n" + - "# Create a sequence using user-defined animations\n" + - "sequence user_demo {\n" + - " play calm_breathing for 5s\n" + - " wait 1s\n" + - " play fire_effect for 8s\n" + - " wait 500ms\n" + - " play emergency_lights for 3s\n" + - " wait 1s\n" + - " play rainbow for 10s\n" + - " wait 500ms\n" + - " play complex for 6s\n" + - "}\n" + - "\n" + - "run user_demo" - -print("=== User Functions Demo ===") -print("Available user functions:") -var functions = animation.list_user_functions() -for func_name : functions - print(f" - {func_name}") -end -print() - -print("DSL Code:") -print(dsl_code) -print() - -print("Compiling DSL...") -var berry_code = animation.compile_dsl(dsl_code) - -if berry_code != nil - print("✓ DSL compiled successfully!") - print() - print("Generated Berry Code:") - print(berry_code) - print() - - print("Executing generated code...") - try - var compiled_func = compile(berry_code) - if compiled_func != nil - print("✓ Berry code compiled successfully!") - # Note: We don't execute it here since we don't have actual LED strip - print("✓ Demo completed successfully!") - else - print("✗ Failed to compile generated Berry code") - end - except .. as e, msg - print(f"✗ Error executing generated code: {e} - {msg}") - end -else - print("✗ Failed to compile DSL") -end - -return true \ No newline at end of file diff --git a/lib/libesp32/berry_animation/src/tests/dsl_core_processing_test.be b/lib/libesp32/berry_animation/src/tests/dsl_core_processing_test.be index 83be507dd..e3728c60f 100644 --- a/lib/libesp32/berry_animation/src/tests/dsl_core_processing_test.be +++ b/lib/libesp32/berry_animation/src/tests/dsl_core_processing_test.be @@ -14,9 +14,9 @@ def test_color_processing() # Test hex colors var hex_tests = [ - ["color custom_red = #FF0000", "var custom_red_ = 0xFFFF0000"], - ["color custom_blue = #0000FF", "var custom_blue_ = 0xFF0000FF"], - ["color custom_green = #00FF00", "var custom_green_ = 0xFF00FF00"] + ["color custom_red = 0xFF0000", "var custom_red_ = 0xFFFF0000"], + ["color custom_blue = 0x0000FF", "var custom_blue_ = 0xFF0000FF"], + ["color custom_green = 0x00FF00", "var custom_green_ = 0xFF00FF00"] ] for test : hex_tests @@ -54,7 +54,7 @@ def test_pattern_processing() # Test solid patterns var pattern_tests = [ - ["color red_alt = #FF0100\n" + ["color red_alt = 0xFF0100\n" "pattern solid_red = solid(red_alt)", "var solid_red_ = animation.solid(animation.global('red_alt_', 'red_alt'))"], ["pattern solid_blue = solid(blue)", @@ -80,7 +80,7 @@ def test_animation_processing() # Test direct color to animation var color_anim_tests = [ - ["color red_alt = #FF0100\n" + ["color red_alt = 0xFF0100\n" "animation red_anim = red_alt", "var red_anim_ = animation.global('red_alt_', 'red_alt')"], ["animation blue_anim = blue", @@ -205,7 +205,7 @@ def test_sequence_processing() print("Testing sequence processing...") # Test basic sequence - var basic_seq_dsl = "color custom_red = #FF0000\n" + + var basic_seq_dsl = "color custom_red = 0xFF0000\n" + "animation red_anim = custom_red\n" + "sequence demo {\n" + " play red_anim for 2s\n" + @@ -223,7 +223,7 @@ def test_sequence_processing() assert(string.find(berry_code, "engine.start()") >= 0, "Should start engine") # Test repeat in sequence - var repeat_seq_dsl = "color custom_blue = #0000FF\n" + + var repeat_seq_dsl = "color custom_blue = 0x0000FF\n" + "animation blue_anim = custom_blue\n" + "sequence test {\n" + " repeat 3 times:\n" + @@ -293,7 +293,7 @@ def test_property_assignments() print("Testing property assignments...") var property_tests = [ - ["color custom_red = #FF0000\nanimation red_anim = solid(custom_red)\nred_anim.pos = 15", + ["color custom_red = 0xFF0000\nanimation red_anim = solid(custom_red)\nred_anim.pos = 15", "animation.global('red_anim_').pos = 15"], ["animation test_anim = solid(blue)\ntest_anim.opacity = 128", "animation.global('test_anim_').opacity = 128"], @@ -321,14 +321,14 @@ def test_reserved_name_validation() # Test predefined color rejection var predefined_color_tests = [ - "color red = #800000", # Predefined color - "color blue = #000080", # Predefined color - "color green = #008000", # Predefined color - "color white = #FFFFFF", # Predefined color - "color black = #000000", # Predefined color - "color yellow = #FFFF00", # Predefined color - "color orange = #FFA500", # Predefined color - "color purple = #800080" # Predefined color + "color red = 0x800000", # Predefined color + "color blue = 0x000080", # Predefined color + "color green = 0x008000", # Predefined color + "color white = 0xFFFFFF", # Predefined color + "color black = 0x000000", # Predefined color + "color yellow = 0xFFFF00", # Predefined color + "color orange = 0xFFA500", # Predefined color + "color purple = 0x800080" # Predefined color ] for dsl_input : predefined_color_tests @@ -353,7 +353,7 @@ def test_reserved_name_validation() # Test DSL keyword rejection (these should be handled by existing system) var dsl_keyword_tests = [ - "color color = #FF0000", # DSL keyword + "color color = 0xFF0000", # DSL keyword "animation strip = solid(red)" # DSL keyword # Note: easing functions (smooth, linear, etc.) are no longer keywords ] @@ -374,12 +374,12 @@ def test_reserved_name_validation() # Test valid custom names (should succeed) var valid_name_tests = [ - "color my_red = #FF0000", - "color custom_blue = #0000FF", - "color fire_color = #FF4500", - "color ocean_blue = #006994", - "color red_custom = #800000", - "color smooth_custom = #808080", + "color my_red = 0xFF0000", + "color custom_blue = 0x0000FF", + "color fire_color = 0xFF4500", + "color ocean_blue = 0x006994", + "color red_custom = 0x800000", + "color smooth_custom = 0x808080", # Easing function names are now valid as user-defined names "pattern smooth = solid(blue)", "animation linear = solid(green)" diff --git a/lib/libesp32/berry_animation/src/tests/dsl_lexer_test.be b/lib/libesp32/berry_animation/src/tests/dsl_lexer_test.be index 2d80e1195..0505bb567 100644 --- a/lib/libesp32/berry_animation/src/tests/dsl_lexer_test.be +++ b/lib/libesp32/berry_animation/src/tests/dsl_lexer_test.be @@ -10,7 +10,7 @@ import animation def test_basic_tokenization() print("Testing basic DSL tokenization...") - var dsl_source = "strip length 60\ncolor red = #FF0000\nrun demo" + var dsl_source = "strip length 60\ncolor red = 0xFF0000\nrun demo" var lexer = animation.DSLLexer(dsl_source) var tokens = lexer.tokenize() @@ -35,12 +35,12 @@ def test_basic_tokenization() for token : tokens if token.type == animation.Token.KEYWORD && token.value == "color" found_color_keyword = true - elif token.type == animation.Token.COLOR && token.value == "#FF0000" + elif token.type == animation.Token.COLOR && token.value == "0xFF0000" found_color_value = true end end assert(found_color_keyword, "Should find 'color' keyword") - assert(found_color_value, "Should find '#FF0000' color value") + assert(found_color_value, "Should find '0xFF0000' color value") # Should have no errors assert(!lexer.has_errors(), "Should have no lexical errors") @@ -54,7 +54,7 @@ def test_color_tokenization() print("Testing color tokenization...") var color_tests = [ - ["#FF0000", animation.Token.COLOR], + ["0xFF0000", animation.Token.COLOR], ["red", animation.Token.COLOR], ["blue", animation.Token.COLOR], ["white", animation.Token.COLOR] # transparent is a keyword, so use white instead @@ -294,7 +294,7 @@ def test_comments() var comment_tests = [ "# This is a comment", - "color red = #FF0000 # Inline comment" + "color red = 0xFF0000 # Inline comment" ] for comment_test : comment_tests @@ -325,7 +325,7 @@ def test_complex_dsl() "strip brightness 80%\n" + "\n" + "# Color Definitions\n" + - "color red = #FF0000\n" + + "color red = 0xFF0000\n" + "color orange = rgb(255, 128, 0)\n" + "color yellow = hsv(60, 100, 100)\n" + "\n" + @@ -387,9 +387,9 @@ def test_error_handling() assert(lexer1.has_errors(), "Invalid character should produce error") # Test invalid hex color - var lexer2 = animation.DSLLexer("color red = #GGGGGG") + var lexer2 = animation.DSLLexer("color red = 0xGGGGGG") var tokens2 = lexer2.tokenize() - # Note: This might not be an error depending on implementation + assert(lexer2.has_errors(), "Invalid hex color should produce error") # Test unterminated string var lexer3 = animation.DSLLexer('text = "unterminated') diff --git a/lib/libesp32/berry_animation/src/tests/dsl_runtime_test.be b/lib/libesp32/berry_animation/src/tests/dsl_runtime_test.be index 3a9471711..e7bc372fd 100644 --- a/lib/libesp32/berry_animation/src/tests/dsl_runtime_test.be +++ b/lib/libesp32/berry_animation/src/tests/dsl_runtime_test.be @@ -23,7 +23,7 @@ def test_dsl_runtime() var simple_dsl = "strip length 30\n" - "color custom_red = #FF0000\n" + "color custom_red = 0xFF0000\n" "pattern solid_red = solid(custom_red)\n" "animation red_anim = solid(custom_red)\n" "sequence demo {\n" @@ -108,7 +108,7 @@ def test_dsl_runtime() var dsl1 = "strip length 30\n" + - "color custom_blue = #0000FF\n" + + "color custom_blue = 0x0000FF\n" + "animation blue_anim = solid(custom_blue)\n" + "sequence blue_demo {\n" + " play blue_anim for 1s\n" + @@ -117,7 +117,7 @@ def test_dsl_runtime() var dsl2 = "strip length 30\n" + - "color custom_green = #00FF00\n" + + "color custom_green = 0x00FF00\n" + "animation green_anim = solid(custom_green)\n" + "sequence green_demo {\n" + " play green_anim for 1s\n" + @@ -174,7 +174,7 @@ def test_dsl_file_operations() # Create a test DSL file var test_filename = "/tmp/test_animation.dsl" var test_dsl_content = "strip length 20\n" + - "color custom_purple = #800080\n" + + "color custom_purple = 0x800080\n" + "animation purple_anim = solid(custom_purple)\n" + "sequence file_test {\n" + " play purple_anim for 2s\n" + diff --git a/lib/libesp32/berry_animation/src/tests/dsl_transpiler_test.be b/lib/libesp32/berry_animation/src/tests/dsl_transpiler_test.be index 58c5cdc70..a0edb3c29 100644 --- a/lib/libesp32/berry_animation/src/tests/dsl_transpiler_test.be +++ b/lib/libesp32/berry_animation/src/tests/dsl_transpiler_test.be @@ -12,7 +12,7 @@ def test_basic_transpilation() print("Testing basic DSL transpilation...") var dsl_source = "strip length 60\n" + - "color custom_red = #FF0000\n" + + "color custom_red = 0xFF0000\n" + "pattern solid_red = solid(custom_red)\n" + "animation red_anim = solid_red\n" + "\n" + @@ -44,8 +44,8 @@ def test_color_definitions() print("Testing color definitions...") var color_tests = [ - ["color custom_red = #FF0000", "var custom_red_ = 0xFFFF0000"], - ["color custom_blue = #0000FF", "var custom_blue_ = 0xFF0000FF"], + ["color custom_red = 0xFF0000", "var custom_red_ = 0xFFFF0000"], + ["color custom_blue = 0x0000FF", "var custom_blue_ = 0xFF0000FF"], ["color my_white = white", "var my_white_ = 0xFFFFFFFF"], ["color my_green = green", "var my_green_ = 0xFF008000"] ] @@ -69,23 +69,14 @@ def test_color_alpha_channel() var alpha_color_tests = [ # Test 8-character hex with alpha (should preserve alpha) - ["color red_opaque = #FFFF0000", "var red_opaque_ = 0xFFFF0000"], - ["color red_half = #80FF0000", "var red_half_ = 0x80FF0000"], - ["color blue_quarter = #400000FF", "var blue_quarter_ = 0x400000FF"], - ["color clear = #00000000", "var clear_ = 0x00000000"], + ["color red_opaque = 0xFFFF0000", "var red_opaque_ = 0xFFFF0000"], + ["color red_half = 0x80FF0000", "var red_half_ = 0x80FF0000"], + ["color blue_quarter = 0x400000FF", "var blue_quarter_ = 0x400000FF"], + ["color clear = 0x00000000", "var clear_ = 0x00000000"], # Test 6-character hex without alpha (should add FF for opaque) - ["color custom_red = #FF0000", "var custom_red_ = 0xFFFF0000"], - ["color custom_lime = #00FF00", "var custom_lime_ = 0xFF00FF00"], - - # Test 4-character short form with alpha - ["color red_half_short = #8F00", "var red_half_short_ = 0x88FF0000"], - ["color blue_quarter_short = #400F", "var blue_quarter_short_ = 0x440000FF"], - - # Test 3-character short form without alpha (should add FF for opaque) - ["color red_short = #F00", "var red_short_ = 0xFFFF0000"], - ["color lime_short = #0F0", "var lime_short_ = 0xFF00FF00"], - ["color blue_short = #00F", "var blue_short_ = 0xFF0000FF"] + ["color custom_red = 0xFF0000", "var custom_red_ = 0xFFFF0000"], + ["color custom_lime = 0x00FF00", "var custom_lime_ = 0xFF00FF00"] ] for test : alpha_color_tests @@ -128,7 +119,7 @@ end def test_simple_patterns() print("Testing simple patterns...") - var dsl_source = "color custom = #FF8080\n" + var dsl_source = "color custom = 0xFF8080\n" "pattern solid_red = solid(red)\n" "pattern solid_custom = solid(custom)" @@ -151,7 +142,7 @@ end def test_sequences() print("Testing sequences...") - var dsl_source = "color custom_blue = #0000FF\n" + var dsl_source = "color custom_blue = 0x0000FF\n" "animation blue_anim = custom_blue\n" "\n" "sequence test_seq {\n" @@ -178,9 +169,9 @@ def test_multiple_run_statements() # Test with multiple animations var dsl_source = "strip length 30\n" + - "color custom_red = #FF0000\n" + - "color custom_blue = #0000FF\n" + - "color custom_green = #00FF00\n" + + "color custom_red = 0xFF0000\n" + + "color custom_blue = 0x0000FF\n" + + "color custom_green = 0x00FF00\n" + "\n" + "animation red_anim = pulse_position_animation(custom_red, 5, 5, 2)\n" + "animation blue_anim = pulse_position_animation(custom_blue, 5, 5, 2)\n" + @@ -232,8 +223,8 @@ def test_multiple_run_statements() # Test with mixed animations and sequences var mixed_dsl = "strip length 30\n" + - "color custom_red = #FF0000\n" + - "color custom_blue = #0000FF\n" + + "color custom_red = 0xFF0000\n" + + "color custom_blue = 0x0000FF\n" + "\n" + "animation red_anim = pulse_position_animation(custom_red, 5, 5, 2)\n" + "\n" + @@ -319,8 +310,8 @@ def test_forward_references() var dsl_source = "# Forward reference: pattern uses color defined later\n" + "pattern fire_pattern = gradient(red, orange)\n" + - "color red = #FF0000\n" + - "color orange = #FF8000" + "color red = 0xFF0000\n" + + "color orange = 0xFF8000" var lexer = animation.DSLLexer(dsl_source) var tokens = lexer.tokenize() @@ -348,8 +339,8 @@ def test_complex_dsl() "strip length 60\n" + "\n" + "# Color Definitions\n" + - "color custom_red = #FF0000\n" + - "color custom_blue = #0000FF\n" + + "color custom_red = 0xFF0000\n" + + "color custom_blue = 0x0000FF\n" + "\n" + "# Variable Definitions\n" + "set cycle_time = 5s\n" + @@ -427,7 +418,7 @@ def test_transpiler_components() print("Testing basic transpiler instantiation...") # Test token processing - var lexer = animation.DSLLexer("color red = #FF0000") + var lexer = animation.DSLLexer("color red = 0xFF0000") var tokens = lexer.tokenize() assert(size(tokens) >= 4, "Should have multiple tokens") @@ -443,7 +434,7 @@ def test_core_processing_methods() print("Testing core processing methods...") # Test pulse animation generation - var pulse_dsl = "color custom_red = #FF0000\n" + + var pulse_dsl = "color custom_red = 0xFF0000\n" + "animation pulse_red = pulse(solid(custom_red), 2s, 20%, 100%)" var berry_code = animation.compile_dsl(pulse_dsl) @@ -451,7 +442,7 @@ def test_core_processing_methods() assert(string.find(berry_code, "animation.pulse") >= 0, "Should generate pulse animation") # Test control flow - var control_dsl = "color custom_blue = #0000FF\n" + + var control_dsl = "color custom_blue = 0x0000FF\n" + "animation blue_anim = solid(custom_blue)\n" + "sequence test {\n" + " repeat 2 times:\n" + @@ -483,8 +474,8 @@ def test_event_system_dsl() print("Testing event system DSL compilation...") var event_dsl = "strip length 30\n" + - "color custom_red = #FF0000\n" + - "color custom_blue = #0000FF\n" + + "color custom_red = 0xFF0000\n" + + "color custom_blue = 0x0000FF\n" + "\n" + "# Event handlers\n" + "on button_press: solid(red)\n" + @@ -526,7 +517,7 @@ end def test_property_assignments() print("Testing property assignments...") - var dsl_with_properties = "color custom_red = #FF0000\n" + + var dsl_with_properties = "color custom_red = 0xFF0000\n" + "animation red_anim = solid(custom_red)\n" + "red_anim.pos = 15\n" + "red_anim.opacity = 128\n" + @@ -561,7 +552,7 @@ def test_comment_preservation() var dsl_with_comments = "# Header comment\n" + "strip length 30 # Strip config comment\n" + "# Color section\n" + - "color custom_red = #FF0000 # Red color\n" + + "color custom_red = 0xFF0000 # Red color\n" + "pattern solid_red = solid(custom_red) # Red pattern\n" + "sequence demo {\n" + " # Play red\n" + @@ -626,7 +617,7 @@ def test_easing_keywords() # Test easing keywords as function calls (regression test for breathing_colors.anim issue) var dsl_with_function_calls = "strip length 30\n" + - "color custom_red = #FF0000\n" + + "color custom_red = 0xFF0000\n" + "animation test_anim = pulse_position_animation(custom_red, 5, 5, 2)\n" + "test_anim.opacity = smooth(100, 255, 4s)\n" + "run test_anim" diff --git a/lib/libesp32/berry_animation/src/tests/event_system_test.be b/lib/libesp32/berry_animation/src/tests/event_system_test.be index 4f813ec45..24a816697 100644 --- a/lib/libesp32/berry_animation/src/tests/event_system_test.be +++ b/lib/libesp32/berry_animation/src/tests/event_system_test.be @@ -127,7 +127,7 @@ end def test_dsl_event_compilation() var dsl_code = "strip length 30\n" - "color custom_red = #FF0000\n" + "color custom_red = 0xFF0000\n" "on button_press: solid(custom_red)\n" "run solid(custom_red)" @@ -143,7 +143,7 @@ end def test_dsl_event_with_parameters() var dsl_code = "strip length 30\n" - "color custom_blue = #0000FF\n" + "color custom_blue = 0x0000FF\n" "on timer(5s): solid(custom_blue)\n" "run solid(custom_blue)" diff --git a/lib/libesp32/berry_animation/src/tests/global_variable_test.be b/lib/libesp32/berry_animation/src/tests/global_variable_test.be index 884c59e80..bd652e98e 100644 --- a/lib/libesp32/berry_animation/src/tests/global_variable_test.be +++ b/lib/libesp32/berry_animation/src/tests/global_variable_test.be @@ -7,7 +7,7 @@ def test_global_variable_access() print("Testing global variable access in generated code...") var dsl_code = - "color red_alt = #FF0100\n" + "color red_alt = 0xFF0100\n" "pattern solid_red = solid(red_alt)" var berry_code = animation.compile_dsl(dsl_code) diff --git a/lib/libesp32/berry_animation/src/tests/nested_function_calls_test.be b/lib/libesp32/berry_animation/src/tests/nested_function_calls_test.be index 2fed264af..24182391d 100644 --- a/lib/libesp32/berry_animation/src/tests/nested_function_calls_test.be +++ b/lib/libesp32/berry_animation/src/tests/nested_function_calls_test.be @@ -11,7 +11,7 @@ def test_basic_nested_calls() var dsl_code = "strip length 30\n" - "color custom_red = #FF0000\n" + "color custom_red = 0xFF0000\n" "animation pulse_red = pulse_animation(solid(custom_red), 3s)\n" "run pulse_red" @@ -146,10 +146,10 @@ def test_complex_real_world_example() var dsl_code = "strip length 60\n" - "color sunset_red = #FF4500\n" - "color ocean_blue = #0077AA\n" - "color star_white = #FFFFFF\n" - "color deep_blue = #000080\n" + "color sunset_red = 0xFF4500\n" + "color ocean_blue = 0x0077AA\n" + "color star_white = 0xFFFFFF\n" + "color deep_blue = 0x000080\n" "animation evening = fade(\n" " overlay(\n" " shift_right(gradient(sunset_red, orange, yellow), 400ms),\n" @@ -183,7 +183,7 @@ def test_generated_code_validity() var dsl_code = "strip length 30\n" - "color custom_red = #FF0000\n" + "color custom_red = 0xFF0000\n" "animation test = pulse_animation(solid(custom_red), 3s)\n" "run test" diff --git a/lib/libesp32/berry_animation/src/tests/simplified_transpiler_test.be b/lib/libesp32/berry_animation/src/tests/simplified_transpiler_test.be index 74dbd29bb..aa7a9ed10 100644 --- a/lib/libesp32/berry_animation/src/tests/simplified_transpiler_test.be +++ b/lib/libesp32/berry_animation/src/tests/simplified_transpiler_test.be @@ -9,8 +9,8 @@ def test_basic_transpilation() # Create a simple DSL program with custom color names (not predefined ones) var dsl_code = "strip length 30\n" - "color my_red = #FF0000\n" - "color my_blue = #0000FF\n" + "color my_red = 0xFF0000\n" + "color my_blue = 0x0000FF\n" "pattern solid_red = solid(my_red)\n" "animation pulse_red = pulse(solid_red, 2s)\n" "sequence demo {\n" @@ -89,7 +89,7 @@ def test_error_handling() print("Testing error handling...") # Test with syntax that should cause transpiler errors - var dsl_code = "color = #FF0000" # Missing color name + var dsl_code = "color = 0xFF0000" # Missing color name try var berry_code = animation.compile_dsl(dsl_code) diff --git a/lib/libesp32/berry_animation/src/tests/symbol_registry_test.be b/lib/libesp32/berry_animation/src/tests/symbol_registry_test.be index 144a4a658..e52abda1e 100644 --- a/lib/libesp32/berry_animation/src/tests/symbol_registry_test.be +++ b/lib/libesp32/berry_animation/src/tests/symbol_registry_test.be @@ -12,7 +12,7 @@ import string def test_basic_symbol_registration() print("Testing basic symbol registration...") - var dsl_source = "color custom_red = #FF0000\n" + + var dsl_source = "color custom_red = 0xFF0000\n" + "pattern solid_red = solid(custom_red)\n" + "animation red_anim = solid_red" @@ -41,7 +41,7 @@ def test_forward_reference_resolution() # DSL with forward reference: pattern uses color defined later var dsl_source = "pattern fire_pattern = solid(custom_red)\n" + - "color custom_red = #FF0000" + "color custom_red = 0xFF0000" var lexer = animation.DSLLexer(dsl_source) var tokens = lexer.tokenize() @@ -127,7 +127,7 @@ end def test_definition_generation() print("Testing definition generation...") - var dsl_source = "color custom_blue = #0000FF" + var dsl_source = "color custom_blue = 0x0000FF" var lexer = animation.DSLLexer(dsl_source) var tokens = lexer.tokenize() @@ -154,7 +154,7 @@ def test_complex_forward_references() # Complex DSL with multiple forward references var dsl_source = "animation complex_anim = pulse(gradient_pattern, 3s)\n" + "pattern gradient_pattern = solid(primary_color)\n" + - "color primary_color = #FF8000\n" + + "color primary_color = 0xFF8000\n" + "sequence demo {\n" + " play complex_anim for 5s\n" + "}\n" + diff --git a/lib/libesp32/berry_animation/src/tests/user_functions_test.be b/lib/libesp32/berry_animation/src/tests/user_functions_test.be index eefc4f573..5404ab2ab 100644 --- a/lib/libesp32/berry_animation/src/tests/user_functions_test.be +++ b/lib/libesp32/berry_animation/src/tests/user_functions_test.be @@ -32,7 +32,7 @@ def test_user_function_in_dsl() var dsl_code = "strip length 30\n" - "color custom_red = #FF0000\n" + "color custom_red = 0xFF0000\n" "animation red_breathing = breathing(custom_red, 4s)\n" "run red_breathing" @@ -63,7 +63,7 @@ def test_nested_user_function_calls() var dsl_code = "strip length 30\n" - "color custom_blue = #0000FF\n" + "color custom_blue = 0x0000FF\n" "animation complex_blue = complex(custom_blue, 2s)\n" "run complex_blue" @@ -114,7 +114,7 @@ def test_user_function_in_nested_calls() var dsl_code = "strip length 30\n" - "color custom_red = #FF0000\n" + "color custom_red = 0xFF0000\n" "animation complex = fade(breathing(custom_red, 3s), 2s)\n" "run complex" @@ -141,7 +141,7 @@ def test_generated_code_validity() var dsl_code = "strip length 30\n" - "color custom_red = #FF0000\n" + "color custom_red = 0xFF0000\n" "animation red_fire = fire(200, 500ms)\n" "run red_fire"