Skip to content

Add support for cold white in color mode#50

Merged
jschlyter merged 4 commits intojschlyter:mainfrom
Alberto97:add_cold_white_support
Feb 4, 2026
Merged

Add support for cold white in color mode#50
jschlyter merged 4 commits intojschlyter:mainfrom
Alberto97:add_cold_white_support

Conversation

@Alberto97
Copy link
Contributor

@Alberto97 Alberto97 commented Feb 2, 2026

The Permanent Lights have a cold white led, this PR adds the support to control that in color mode.

A few notes to consider:

  • The cold white channel is only addressable since firmware v2.10.0
  • All the color channels must be specified when using the cold white otherwise the other channels might retain the old value when switching from an RGB/W color to an RGBWW one (eg. when I switch from r=0, g=0, b=0, white=255 to r=0, g=0, b=0, cold_white=255 the warm white channel remains to 255)
  • The Permanent Lights are still an RGBW product, RGBWW was not implemented as a full fledged led profile. For this reason when working with frames, they should be constructed without the cold white channel whether in realtime or when working with movies

Summary by CodeRabbit

  • New Features

    • Added support for a fifth, independent cool-white channel in color objects while preserving 3- and 4-channel behavior.
    • CLI accepts an expanded five-component color format and updates validation messaging.
  • Tests

    • Added tests for 5-color serialization/deserialization, iteration/mapping order, and backward compatibility with 3/4-channel inputs.

@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

Adds a fifth color channel cold_white to TwinklyColour, extends tuple/type aliases and (de)serialization to support 3-, 4-, and 5-element color formats, updates CLI parsing to accept an optional fifth value, and adds tests validating RGBWW behavior.

Changes

Cohort / File(s) Summary
Test Coverage
tests/test_colours.py
Added test_colours_rgbww verifying 5-channel behavior: as_twinkly_tuple, tuple(col), as_dict, and from_twinkly_tuple round-trip for RGBWW.
Core Implementation
ttls/colours.py
Added public field `cold_white: int
CLI Parsing
ttls/cli.py
Expanded colour parsing regex to accept an optional fifth component; adjusted extraction to populate w and cw; updated TwinklyColour constructor calls to pass both optional values (r, g, b, w, cw).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

I hop with joy, a tiny coder’s friend, 🐇
Cold white joins warm—our spectrum extends,
Five lights now shimmer in careful array,
I nibble tests and dance along the way,
A twinkly patch to brighten devday.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the main change: adding support for the cold white channel in color mode, which is the primary focus across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@ttls/cli.py`:
- Line 126: Update the ValueError raised in ttls/cli.py’s colour validation (the
raise ValueError(...) line) to include the newly supported "r,g,b,w,w" format in
the message; change the text so it lists all accepted formats (e.g., "r,g,b",
"r,g,b,w", and "r,g,b,w,w") to make the error clear when colour parsing fails.

@Alberto97 Alberto97 force-pushed the add_cold_white_support branch from aa155a6 to 2772d3f Compare February 2, 2026 12:08
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@ttls/cli.py`:
- Line 126: The ValueError message in ttls/cli.py currently contains a
duplicated word ("format format"); update the raise ValueError call that
produces "Colour argument is not in r,g,b, r,g,b,w or r,g,b,w,cw format format"
to remove the duplicate so it reads "...cw format" (i.e., a single "format") in
the same raise statement.

@Alberto97 Alberto97 force-pushed the add_cold_white_support branch from 2772d3f to 3721d74 Compare February 2, 2026 12:12
Copy link
Owner

@jschlyter jschlyter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No major issues, but please fix some minor nits.

@Alberto97
Copy link
Contributor Author

No major issues, but please fix some minor nits.

Sure, here you go!

Copy link
Owner

@jschlyter jschlyter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved once reformatted.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ttls/colours.py (1)

10-33: ⚠️ Potential issue | 🟠 Major

Enforce cold_white requires white to be set.

Right now cold_white can be provided without white, which makes as_twinkly_tuple/as_tuple drop the channel while as_dict emits only cold_white. That violates the PR requirement to specify all channels and can leave warm white stale. Add a validation guard (preferably in __post_init__) to fail fast when cold_white is set but white isn’t.

💡 Suggested validation guard
 `@dataclass`(frozen=True)
 class TwinklyColour:
     red: int
     green: int
     blue: int
     white: int | None = None
     cold_white: int | None = None

+    def __post_init__(self):
+        if self.cold_white is not None and self.white is None:
+            raise ValueError("cold_white requires white to be set")
🧹 Nitpick comments (1)
ttls/colours.py (1)

17-27: Clarify 5‑tuple ordering in docstrings (CW vs W).

“(W,W,…)” is ambiguous. Explicitly label cold vs warm ordering to prevent misuse.

✍️ Docstring clarification
-        """Convert TwinklyColour to a tuple as used by Twinkly: (R,G,B), (W,R,G,B) or (W,W,R,G,B)"""
+        """Convert TwinklyColour to a tuple as used by Twinkly: (R,G,B), (W,R,G,B) or (CW,W,R,G,B)"""

-        """Convert TwinklyColour to a tuple: (R,G,B), (R,G,B,W) or (R,G,B,W,W)"""
+        """Convert TwinklyColour to a tuple: (R,G,B), (R,G,B,W) or (R,G,B,W,CW)"""

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@ttls/colours.py`:
- Around line 21-25: The docstring and implementation in the TwinklyColour
to-tuple logic incorrectly claim a 5-channel "(CW,W,R,G,B)" format is "as used
by Twinkly"; remove or isolate that branch so only Twinkly-supported tuples are
returned (RGB as (R,G,B) or RGBW as (W,R,G,B)). Specifically, update the method
that checks self.cold_white and self.white (the branch returning
(self.cold_white, self.white, self.red, self.green, self.blue)) to either be
removed or moved into a new non-Twinkly-specific method (e.g.,
to_custom_5_channel) and adjust the docstring to state Twinkly uses only RGB and
RGBW and that any 5-channel output is a custom extension if retained.

@jschlyter jschlyter merged commit 851eae6 into jschlyter:main Feb 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants