# Specification: Update HSBK RGB Conversion to Float

**Track ID:** hsbk-rgb-float_20260318
**Type:** Refactor
**Created:** 2026-03-18
**Status:** Draft

## Summary

Update `HSBK.to_rgb()` and `HSBK.from_rgb()` to use float values (0.0–1.0) instead of integers (0–255), eliminating the precision loss caused by quantization and rounding in the current implementation.

## Context

lifx-async is a type-safe async Python library for LIFX light control. The `HSBK` class is the core color representation used throughout the library. The current int-based RGB conversion loses significant precision: 84% of colors produce a mismatch on round-trip, with errors up to 3/255. The fireworks effect already implements its own float-based private helpers (`_hsb_to_rgb`/`_rgb_to_hsb`) to avoid this precision loss during additive blending.

## Acceptance Criteria

- [ ] `HSBK.to_rgb()` returns `tuple[float, float, float]` with values in 0.0–1.0
- [ ] `HSBK.from_rgb()` accepts float values in 0.0–1.0
- [ ] Round-trip conversion error is within floating-point epsilon (~10⁻¹⁵)
- [ ] No rounding applied to intermediate HSB values during conversion
- [ ] All existing callers updated (Colors enum, docstrings, tests, effects)
- [ ] Fireworks private `_hsb_to_rgb`/`_rgb_to_hsb` replaced with `HSBK` methods
- [ ] All tests passing with 100% coverage on modified code
- [ ] Pyright and ruff pass cleanly

## Dependencies

- `src/lifx/color.py` — core HSBK class (from_rgb, to_rgb, Colors enum with ~148 entries)
- `src/lifx/effects/fireworks.py` — private RGB helpers that can be replaced
- Docstring-only references in: `light.py`, `multizone.py`, `matrix.py`, `api.py`, `effects/base.py`, `effects/pulse.py`
- Tests: `test_color.py`, `test_effects/test_pulse.py`

## Out of Scope

- Changing `HSBK` internal representation (hue 0–360, sat/bri 0.0–1.0, kelvin int)
- Modifying `to_protocol()` / `from_protocol()` uint16 conversion
- Adding RGB as an alternative internal color model
- kelvin-aware RGB conversion (white point adjustment)

## Technical Notes

- The `Colors` enum has ~148 entries using `from_rgb(int, int, int)` — all need converting to `from_rgb(float, float, float)` by dividing each value by 255
- `from_rgb` should stop rounding hue to int and s/b to 2 decimal places
- `colorsys` already works with 0.0–1.0 floats internally, so the normalization step (`value / 255`) and denormalization (`value * 255`) can be removed
- Fireworks `_hsb_to_rgb`/`_rgb_to_hsb` can be replaced with `HSBK.to_rgb()`/`HSBK.from_rgb()` since precision parity will be achieved

---

_Generated by Conductor. Review and edit as needed._
