[light] Use compact per-field union storage in LightControlAction

Replace 14 TemplatableValue fields with a per-field union that stores
either a constant value or a callable pointer in the same 4 bytes
(on 32-bit targets). A 2-bit-per-field type tag in a uint32_t tracks
field state (unset/constant/stateless lambda/stateful lambda).

Reduces LightControlAction from 128 to 76 bytes per instance on ESP32.
For a config with 8 light actions, this saves 416 bytes of RAM and
476 bytes of flash (from eliminated TemplatableValue template
instantiations).
This commit is contained in:
J. Nick Koston
2026-03-23 19:48:44 -10:00
parent 332118db56
commit 57c8ab861e
3 changed files with 337 additions and 31 deletions
@@ -0,0 +1,139 @@
esphome:
name: light-control-action-test
host:
api: # Port will be automatically injected
logger:
level: DEBUG
globals:
- id: test_brightness
type: float
initial_value: "0.75"
output:
- platform: template
id: test_red
type: float
write_action:
- lambda: ""
- platform: template
id: test_green
type: float
write_action:
- lambda: ""
- platform: template
id: test_blue
type: float
write_action:
- lambda: ""
- platform: template
id: test_cold_white
type: float
write_action:
- lambda: ""
- platform: template
id: test_warm_white
type: float
write_action:
- lambda: ""
light:
- platform: rgbww
name: "Test Light"
id: test_light
red: test_red
green: test_green
blue: test_blue
cold_white: test_cold_white
warm_white: test_warm_white
cold_white_color_temperature: 6536 K
warm_white_color_temperature: 2000 K
effects:
- random:
name: "Test Effect"
transition_length: 10ms
update_interval: 10ms
button:
# Test 1: light.turn_on with RGB constants
- platform: template
id: btn_turn_on_rgb
name: "Turn On RGB"
on_press:
- light.turn_on:
id: test_light
brightness: 1.0
red: 0.0
green: 0.0
blue: 1.0
# Test 2: light.turn_off
- platform: template
id: btn_turn_off
name: "Turn Off"
on_press:
- light.turn_off:
id: test_light
# Test 3: light.turn_on with color_temperature
- platform: template
id: btn_turn_on_ct
name: "Turn On CT"
on_press:
- light.turn_on:
id: test_light
color_temperature: 4000 K
brightness: 0.8
# Test 4: light.turn_on with effect
- platform: template
id: btn_turn_on_effect
name: "Turn On Effect"
on_press:
- light.turn_on:
id: test_light
effect: "Test Effect"
# Test 5: light.turn_on with effect none to clear it
- platform: template
id: btn_clear_effect
name: "Clear Effect"
on_press:
- light.turn_on:
id: test_light
effect: "None"
# Test 6: light.control with cold/warm white
- platform: template
id: btn_control_cw
name: "Control CW"
on_press:
- light.control:
id: test_light
cold_white: 0.9
warm_white: 0.1
# Test 7: light.turn_on with lambda brightness (tests lambda path)
- platform: template
id: btn_lambda_brightness
name: "Lambda Brightness"
on_press:
- light.turn_on:
id: test_light
brightness: !lambda "return id(test_brightness);"
red: 1.0
green: 0.0
blue: 0.0
# Test 8: light.turn_on with transition_length
- platform: template
id: btn_turn_on_transition
name: "Turn On Transition"
on_press:
- light.turn_on:
id: test_light
brightness: 0.5
transition_length: 0s
red: 0.5
green: 0.5
blue: 0.0