Themes API Reference¶
The theme system provides professionally-curated color palettes for coordinated lighting across LIFX devices.
Theme Class¶
The Theme class represents a collection of HSBK colors forming a coordinated palette.
Theme
¶
Theme(
colors: list[HSBK] | None = None,
*,
slug: str | None = None,
name: str | None = None,
category: str | None = None,
disposition: Disposition | None = None,
replaced_by: str | None = None,
)
A collection of colors representing a theme or color palette.
Themes can be applied to LIFX devices to coordinate colors across multiple lights. Supports both single-zone and multi-zone devices.
| ATTRIBUTE | DESCRIPTION |
|---|---|
colors |
List of HSBK colors in the theme |
slug |
Library key for a theme from
|
name |
Display name for a theme from
|
category |
Category for a theme from
|
disposition |
Recorded fate of a theme from
|
replaced_by |
Successor key of a deprecated or renamed theme from
|
Note
shuffled() returns an identity-less copy: slug, name, category,
disposition and replaced_by do not propagate. This is a known
deferred limitation of the identity round-trip guarantee.
(random() returns a single HSBK, not a Theme, so it carries
no identity to begin with.)
Note
== compares identity, so a Theme stays hashable and usable as
a dict key or set member. To compare palettes, call
palette_equals().
Example
# Create a theme with specific colors
theme = Theme(
[
HSBK(hue=0, saturation=1.0, brightness=1.0, kelvin=3500), # Red
HSBK(hue=120, saturation=1.0, brightness=1.0, kelvin=3500), # Green
HSBK(hue=240, saturation=1.0, brightness=1.0, kelvin=3500), # Blue
]
)
# Access colors
for color in theme:
print(f"Color: {color.hue}°")
# Get a specific color
first_color = theme[0]
# Add more colors
theme.add_color(HSBK(hue=180, saturation=1.0, brightness=1.0, kelvin=3500))
| PARAMETER | DESCRIPTION |
|---|---|
colors
|
List of HSBK colors (defaults to white if None or empty) |
slug
|
Library key for the theme (attached by
TYPE:
|
name
|
Display name for the theme (attached by
TYPE:
|
category
|
Category for the theme (attached by
TYPE:
|
disposition
|
Recorded fate of the theme (attached by
TYPE:
|
replaced_by
|
Successor key of a deprecated or renamed theme
(attached by
TYPE:
|
Example
| METHOD | DESCRIPTION |
|---|---|
add_color |
Add a color to the theme. |
random |
Get a random color from the theme. |
shuffled |
Get a new theme with colors in random order. |
get_next_bounds_checked |
Get the next color after index or the last color if at end. |
ensure_color |
Ensure the theme has at least one color. |
__len__ |
Get the number of colors in the theme. |
__iter__ |
Iterate over colors in the theme. |
__getitem__ |
Get a color by index. |
__contains__ |
Check if a color is in the theme. |
palette_equals |
Check whether two themes carry the same palette. |
__repr__ |
Return a string representation of the theme. |
Source code in src/lifx/theme/theme.py
Methods:¶
add_color
¶
add_color(color: HSBK) -> None
Add a color to the theme.
| PARAMETER | DESCRIPTION |
|---|---|
color
|
HSBK color to add
TYPE:
|
Source code in src/lifx/theme/theme.py
random
¶
random() -> HSBK
Get a random color from the theme.
| RETURNS | DESCRIPTION |
|---|---|
HSBK
|
A random HSBK color from the theme |
Source code in src/lifx/theme/theme.py
shuffled
¶
shuffled() -> Theme
Get a new theme with colors in random order.
| RETURNS | DESCRIPTION |
|---|---|
Theme
|
New Theme instance with shuffled colors |
Source code in src/lifx/theme/theme.py
get_next_bounds_checked
¶
Get the next color after index or the last color if at end.
| PARAMETER | DESCRIPTION |
|---|---|
index
|
Index of current color
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
HSBK
|
Next HSBK color or the last color if index is at the end |
Example
Source code in src/lifx/theme/theme.py
ensure_color
¶
Ensure the theme has at least one color.
If the theme is empty, adds a default white color.
Source code in src/lifx/theme/theme.py
__iter__
¶
__getitem__
¶
Get a color by index.
| PARAMETER | DESCRIPTION |
|---|---|
index
|
Index of the color (0-based)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
HSBK
|
HSBK color at the given index |
| RAISES | DESCRIPTION |
|---|---|
IndexError
|
If index is out of range |
Source code in src/lifx/theme/theme.py
__contains__
¶
Check if a color is in the theme.
| PARAMETER | DESCRIPTION |
|---|---|
color
|
HSBK color to check
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if color is in theme (by value comparison) |
Source code in src/lifx/theme/theme.py
palette_equals
¶
Check whether two themes carry the same palette.
Order is never compared because the app shuffles palette order on every application, so two orderings of one palette are the same palette. Identity (slug, name, category, disposition and replaced_by) is excluded too: an identity-bearing library theme and a caller-built theme with the same colors have the same palette. Colors compare at uint16 (protocol) granularity via HSBK equality, and duplicate counts matter — a multiset comparison, not a set comparison.
This is deliberately a named method rather than __eq__. A
Theme's palette is mutable via add_color(), so value equality
could not be paired with a stable __hash__; making ==
compare palettes would leave Theme unhashable and silently change
what theme in [a, b], list.index() and list.remove()
mean. == therefore stays identity comparison and the palette
comparison is spelled out at the call site.
| PARAMETER | DESCRIPTION |
|---|---|
other
|
Theme to compare palettes with.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if both palettes are the same multiset of colors. |
Example
Source code in src/lifx/theme/theme.py
ThemeLibrary Class¶
The ThemeLibrary provides access to 166 themes, resolvable under 168 names.
ThemeLibrary
¶
Collection of built-in colour themes for LIFX devices.
Provides access to every theme in the LIFX app (sport themes excluded) plus the pre-6.3.0 library keys, organised by the app's own categories.
Example
# Get a specific theme
evening_theme = ThemeLibrary.get("evening")
# List all available themes
all_themes = ThemeLibrary.get_available_themes()
# Get themes by category
categories = ThemeLibrary.get_categories()
holidays = ThemeLibrary.get_by_category("Holidays")
# Apply to a light
await light.apply_theme(evening_theme, power_on=True)
| METHOD | DESCRIPTION |
|---|---|
get |
Get a theme by name. |
get_available_themes |
Get all available themes by name. |
get_categories |
Get every category present in the library's data. |
get_by_category |
Get all themes in a category. |
Methods:¶
get
classmethod
¶
Get a theme by name.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Theme name (case-insensitive)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Theme
|
Theme object |
| RAISES | DESCRIPTION |
|---|---|
KeyError
|
If theme name is not found |
Example
Source code in src/lifx/theme/library.py
get_available_themes
classmethod
¶
Get all available themes by name.
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
Sorted list of theme names |
Example
Source code in src/lifx/theme/library.py
get_categories
classmethod
¶
Get every category present in the library's data.
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
Sorted |
list[str]
|
library's theme records. |
Example
Source code in src/lifx/theme/library.py
get_by_category
classmethod
¶
Get all themes in a category.
| PARAMETER | DESCRIPTION |
|---|---|
category
|
Category name. Matching is case- and punctuation-
insensitive: both sides are normalised by the slug rule, so
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict[str, Theme]
|
Dictionary of Theme objects in the category, keyed by slug and |
dict[str, Theme]
|
sorted by slug. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
Source code in src/lifx/theme/library.py
Convenience Function¶
get_theme
¶
Get a theme by name.
Convenience function equivalent to ThemeLibrary.get(name).
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Theme name (case-insensitive)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Theme
|
Theme object |
Example
Source code in src/lifx/theme/library.py
Available Themes¶
The library carries 166 themes, resolvable under 168 names (the extra two are the
forest and aurora_borealis rename aliases). 138 are captured from the LIFX app and carry
the app's own display name and category; the remaining 28 have no app counterpart and sit
under the Library category.
Rather than reproduce the inventory here — where it rots on every resync — ask the library:
from lifx import ThemeLibrary
names = ThemeLibrary.get_available_themes() # every resolvable name
theme = ThemeLibrary.get("evening")
print(theme.slug, theme.name, theme.category) # evening Evening Library
Each theme carries its ASCII slug, the app's name (which may contain spaces and
punctuation) and its category. The categories and their theme counts are:
| Category | Themes |
|---|---|
| Archives | 60 |
| Library | 28 |
| Holidays | 15 |
| Music | 14 |
| Moods | 13 |
| Space | 11 |
| Art Series | 10 |
| Nature | 8 |
| Play | 7 |
ThemeLibrary.get_by_category() takes the categories in the table above, matched
case- and punctuation-insensitively (Art Series, art series and art_series all
resolve), and ThemeLibrary.get_categories() lists them. The six pre-6.4.0 names
(seasonal, holiday, mood, ambient, functional, atmosphere) are retired
and raise ValueError listing the categories above — none of them mapped onto a
single category, so see Theme Taxonomy Changes
for what each one used to return. Theme.disposition and Theme.replaced_by
record each theme's fate, documented on the same page.