From 9393dd019ee3a26b6c67833d578248fbb2fa24dc Mon Sep 17 00:00:00 2001 From: Andy Fraley Date: Sat, 26 Sep 2026 13:07:46 -0400 Subject: [PATCH 1/2] Start the pattern editor on the Halloween preset The editor's STARTING_PATTERN still had the old two-color orange and purple after 0.5.1 changed the preset. Match the preset, and add a test that reads the constant out of PatternPage.jsx so the two can't drift apart again. Co-Authored-By: Claude Opus 5.5 (1M context) --- CLAUDE.md | 2 +- app/presets.py | 1 + frontend/src/PatternPage.jsx | 6 ++++-- tests/test_presets.py | 15 +++++++++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 8f5981f..d6e88bf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,7 +19,7 @@ the API reference and internals. Keep them in their lanes — don't put REST tab ## Commands ```bash -.venv/bin/python -m pytest -q # 341 tests, no network, no strands +.venv/bin/python -m pytest -q # 342 tests, no network, no strands .venv/bin/pre-commit run --all-files # Black + Prettier; the git hook runs this on staged files npm --prefix frontend test # JS pattern port vs Python fixtures npm --prefix frontend run build # required before the Docker build picks up UI changes diff --git a/app/presets.py b/app/presets.py index 059bb76..bd7e89d 100644 --- a/app/presets.py +++ b/app/presets.py @@ -28,6 +28,7 @@ def default_presets() -> dict[str, Pattern]: load with both sliders at the far left. """ return { + # Also the editor's starting pattern (STARTING_PATTERN in PatternPage.jsx). "Halloween": Pattern( slots=[ Slot(rgbw=ORANGE, weight=80), diff --git a/frontend/src/PatternPage.jsx b/frontend/src/PatternPage.jsx index c074433..97a22fd 100644 --- a/frontend/src/PatternPage.jsx +++ b/frontend/src/PatternPage.jsx @@ -29,10 +29,12 @@ const LIVE_POLL_MS = 5000 /** For a pattern that doesn't say: a preset saved without one, or a new pattern. */ const DEFAULT_BRIGHTNESS = 60 +/** The built-in Halloween preset (app/presets.py); keep the two the same. */ const STARTING_PATTERN = { slots: [ - { rgbw: [255, 152, 0, 0], weight: 80 }, - { rgbw: [128, 0, 255, 0], weight: 20 }, + { rgbw: [255, 126, 0, 0], weight: 80 }, + { rgbw: [128, 0, 255, 0], weight: 15 }, + { rgbw: [255, 236, 0, 0], weight: 5 }, ], layout: 'interleaved', block_size: 1, diff --git a/tests/test_presets.py b/tests/test_presets.py index 28e2836..44a8538 100644 --- a/tests/test_presets.py +++ b/tests/test_presets.py @@ -1,6 +1,8 @@ """The preset store: seeding, round-tripping, atomic writes, bad input.""" import json +import re +from pathlib import Path import pytest @@ -184,3 +186,16 @@ def test_built_in_presets_sit_on_the_share_sliders_steps(): for name, pattern in default_presets().items(): for slot in pattern.slots: assert 5 <= slot.weight <= 100 and slot.weight % 5 == 0, name + + +def test_the_editor_starts_on_the_halloween_preset(): + """PatternPage.jsx keeps its own copy for before the presets load; it drifted once.""" + source = (Path(__file__).parent.parent / "frontend/src/PatternPage.jsx").read_text() + block = re.search(r"const STARTING_PATTERN = \{.*?\n\}", source, re.S).group() + slots = [ + (tuple(int(n) for n in rgbw.split(",")), int(weight)) + for rgbw, weight in re.findall(r"rgbw: \[([\d, ]+)\], weight: (\d+)", block) + ] + + halloween = default_presets()["Halloween"] + assert slots == [(slot.rgbw, slot.weight) for slot in halloween.slots] From 857f8933b14b22dd434721022dabb645b651b41e Mon Sep 17 00:00:00 2001 From: Andy Fraley Date: Sat, 26 Sep 2026 13:07:46 -0400 Subject: [PATCH 2/2] Release 0.6.1 Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/releases/0.6.1.md | 15 +++++++++++++++ frontend/package-lock.json | 4 ++-- frontend/package.json | 2 +- home-assistant/dapple/config.yaml | 2 +- pyproject.toml | 2 +- uv.lock | 2 +- 6 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 docs/releases/0.6.1.md diff --git a/docs/releases/0.6.1.md b/docs/releases/0.6.1.md new file mode 100644 index 0000000..5879e5f --- /dev/null +++ b/docs/releases/0.6.1.md @@ -0,0 +1,15 @@ +The pattern editor now starts on Halloween. + +## What's changed + +- **The editor's starting pattern is the built-in Halloween preset:** deeper orange (80%), purple (15%) and a touch of yellow (5%). It used to start on an older two-color orange and purple that didn't match any preset. You see it when a group has no pattern yet. + +## Upgrading + +Running Dapple as a Home Assistant app: install the update from Settings → Updates. + +With Docker, `docker compose up -d` picks this up if you have `pull_policy: always`. Otherwise run `docker compose pull && docker compose up -d`. Your settings and saved presets carry over. To stay on this release, set the image line to: + +```yaml + image: afraley/dapple:0.6.1 +``` diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ad749ff..2cfeb54 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "dapple-ui", - "version": "0.6.0", + "version": "0.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dapple-ui", - "version": "0.6.0", + "version": "0.6.1", "license": "MIT", "dependencies": { "@emotion/react": "^11.13.3", diff --git a/frontend/package.json b/frontend/package.json index c321a38..6182296 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,7 +2,7 @@ "name": "dapple-ui", "private": true, "license": "MIT", - "version": "0.6.0", + "version": "0.6.1", "type": "module", "scripts": { "dev": "vite", diff --git a/home-assistant/dapple/config.yaml b/home-assistant/dapple/config.yaml index 5da5ac7..8cf3bc5 100644 --- a/home-assistant/dapple/config.yaml +++ b/home-assistant/dapple/config.yaml @@ -1,7 +1,7 @@ # The Dapple add-on. The Supervisor pulls afraley/dapple:, the same # image Docker users run, so `version` must match pyproject.toml (CI checks). name: Dapple -version: "0.6.0" +version: "0.6.1" slug: dapple description: Static multi-color patterns for Twinkly lights url: https://github.com/andrewfraley/dapple diff --git a/pyproject.toml b/pyproject.toml index 236dc91..c999b2f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "dapple" -version = "0.6.0" +version = "0.6.1" description = "Static multi-color patterns for Twinkly light strands, with a REST API for Home Assistant" requires-python = ">=3.12" dependencies = [ diff --git a/uv.lock b/uv.lock index 4fe27a0..ea51c97 100644 --- a/uv.lock +++ b/uv.lock @@ -393,7 +393,7 @@ wheels = [ [[package]] name = "dapple" -version = "0.6.0" +version = "0.6.1" source = { editable = "." } dependencies = [ { name = "aiomqtt" },