Skip to content

Make All Lights a master over the zones instead of raw pixels - #21

Merged
bharvey88 merged 1 commit into
betafrom
fix/all-lights-as-master
Aug 27, 2026
Merged

Make All Lights a master over the zones instead of raw pixels#21
bharvey88 merged 1 commit into
betafrom
fix/all-lights-as-master

Conversation

@bharvey88

@bharvey88 bharvey88 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Version: 26.8.27.1

What does this implement/fix?

The All Lights entity added in #17 spanned pixels 0-36, which are the same pixels the five zone lights own. Two independent LightState objects, no reconciliation. Turn on All Lights, turn on Body Light, then turn All Lights off, and Body either stays physically lit (an effect selected on it repaints 0-23 on its own interval) or goes dark while its entity still reports on.

Rebuilds the master on partition's other segment form. single_light_id accepts any light (partition/light.py:69 is cv.use_id(light.LightState)), so the master wraps the five zone lights instead of a pixel range:

  - platform: partition
    id: all_lights
    name: "All Lights"
    segments:
      - single_light_id: body_light
      - single_light_id: mouth_light
      - single_light_id: nose_light
      - single_light_id: eyes_light
      - single_light_id: hat_light

AddressableLightWrapper was built for this. Its write_state() opens with:

    // Don't overwrite state if the underlying light is turned on
    if (this->light_state_->remote_values.is_on()) {
      this->mark_shown_();
      return;
    }

so a zone the user turned on is never painted over by the master. When the master does drive a zone it uses call.set_publish(false) and call.set_save(false), so a master-driven zone never falsely reports on in Home Assistant. Both failure modes above go away.

The cleanup wiring from #17 is deliberately kept. all_lights_off, both on_shutdown blocks and each play_song_* still clear the master. Dropping the all_lights_off line in particular would let a master left on repaint the zones after a song ends, leaving the ornament lit.

Trade-off

AddressableLightWrapper::size() returns 1, one pixel per wrapped light, so the master sees a five-pixel strip rather than 37. Solid color and brightness across the whole ornament, which is what the entity exists for, work exactly as before. An effect selected on All Lights now renders as five blocks, one per zone, instead of a smooth 37-LED gradient. Effects selected on an individual zone are unaffected and still address that zone's real pixels.

Types of changes

  • Bugfix (fixed change that fixes an issue)
  • New feature (thanks!)
  • Breaking change (repair/feature that breaks existing functionality)
  • Dependency Update - Does not publish
  • Other - Does not publish
  • Website of github readme file update - Does not publish
  • Github workflows - Does not publish

Checklist / Checklijst:

  • The code change has been tested and works locally
  • The code change has not yet been tested

If user-visible functionality or configuration variables are added/modified:

  • Added/updated documentation for the web page

esphome config passes on both H-3.yaml and H-3D.yaml, and the merged config shows the master with its five wrapped segments. Not yet tested on hardware.

Conflicts with #20 on the version substitution and the all_lights block. Whichever merges second needs a merge from beta.

🤖 Generated with Claude Code

The 0-36 partition added in #17 owned the same pixels as the five zone
lights with independent state, so turning All Lights off left a zone
either physically lit (its effect repaints on its own interval) or dark
while still reporting on.

Rebuilds it on partition's single_light_id segment form, which wraps each
zone light instead of a pixel range. AddressableLightWrapper::write_state
returns early when the wrapped light's remote_values.is_on(), so a zone
the user turned on is never painted over, and it drives zones with
set_publish(false) so a master-driven zone never falsely reports on.

The cleanup wiring from #17 is kept: all_lights_off, both on_shutdown
blocks, and each play_song_* still clear the master.

TRADE-OFF: the wrapper is one pixel per wrapped light, so effects
selected on All Lights render as five blocks rather than a 37-LED
gradient. Effects on an individual zone are unaffected.

Version 26.8.27.1

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@bharvey88 bharvey88 added the bugfix Something isn't working label Aug 27, 2026
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a01cd343-1b94-4754-9c80-7d084f97a253


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@bharvey88
bharvey88 merged commit 4e89660 into beta Aug 27, 2026
11 checks passed
@bharvey88
bharvey88 deleted the fix/all-lights-as-master branch August 28, 2026 00:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant