Keep strobes under 3 flashes a second (#150) #167
No reviewers
Labels
No labels
area/ai
area/backend
area/frontend
area/infra
area/scheduler
area/wled
good-first-issue
priority/high
priority/low
priority/medium
security
type/bug
type/chore
type/ci-cd
type/docs
type/feature
type/qa
v1.0.0
v1.1.0
v1.2.0
v2.0.0
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/Iris-WLED!167
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/150-photosensitivity-guard"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #150. The only acceptance item left open is the on-hardware filming check (see below).
Why
Nothing stopped a strobe reaching the house. Three paths could put one there: AI output (JSON-shape validation only), quick push /
/remote(effect_id: ge=0), and the editor. WCAG 2.3.1 sets the limit at no more than 3 general flashes per second.What
The flash table is derived from firmware source (
backend/app/data/flash_safety.json), usingwled00/FX.cppat v16.0.0 (commit4374f01). Each row cites the function and formula it came from, and uses the worst-case frame time.sx238: Blink, Strobe, Strobe Rainbow and Blink Rainbow (cycle = 20·(255−sx) + 2·FRAMETIME ms). Only the top 17 speed steps are over the line.sx247: Dynamic.docs/photosensitivity.md: single-pixel sparkles aren't general flashes, and Fire Flicker is allowed. Fire Flicker is the first row to film.One chokepoint. The translator runs
guard_stateon every payload, and the default is on, so a caller that forgets to pass the setting still gets the guard. The paths it covers:day_plan, which now carriesflash_substitutions/remotePlanning 60 nights logs at DEBUG; a real push logs once at INFO.
Entry points explain instead of silently changing:
/remote: replaced effects are hidden from the picker.effect_idbounds: checked against the controller'sfxcount, with the shipped catalogue as a fallback. Out of range is a 422.GET /api/v1/wled/flash-safety. There is no copy of the table in TypeScript.Setting:
photosensitive_safe(default on), with its own card on the Settings page explaining what turning it off means.Fixed along the way:
/remote, choosing an effect pushed the previous choice (a stale closure).blink()timing and is capped at 3/s.Verification (after rebasing onto #149)
tsc, vitest (163 passed) and build.Still open
docs/photosensitivity.md, and the table carriesverified_on_hardware: falseuntil then.plan_for_date, so it could drift from the on job (the #93 risk).SchemeSegmentUpdatehas no bounds on speed, intensity, palette or brightness.effect_id.🤖 Generated with Claude Code