{"id":50609919,"url":"https://github.com/rusty4444/ha-lightfx","last_synced_at":"2026-06-06T03:00:17.189Z","repository":{"id":359558050,"uuid":"1246616824","full_name":"rusty4444/ha-lightfx","owner":"rusty4444","description":"Virtual WLED-style light effects for any Home Assistant light. Define room layouts, map lights to positions, run ambient effects — no special hardware needed.","archived":false,"fork":false,"pushed_at":"2026-06-02T11:34:10.000Z","size":569,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-02T12:23:24.500Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rusty4444.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-22T11:24:57.000Z","updated_at":"2026-06-02T11:34:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rusty4444/ha-lightfx","commit_stats":null,"previous_names":["rusty4444/ha-lightfx"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/rusty4444/ha-lightfx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusty4444%2Fha-lightfx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusty4444%2Fha-lightfx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusty4444%2Fha-lightfx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusty4444%2Fha-lightfx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rusty4444","download_url":"https://codeload.github.com/rusty4444/ha-lightfx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusty4444%2Fha-lightfx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33967641,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-06T03:00:16.541Z","updated_at":"2026-06-06T03:00:17.177Z","avatar_url":"https://github.com/rusty4444.png","language":"Python","funding_links":["https://buymeacoffee.com/rusty4"],"categories":[],"sub_categories":[],"readme":"# HA LightFX\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://buymeacoffee.com/rusty4\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png\" alt=\"Buy Me A Coffee\" height=\"50\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"images/logo.jpg\" alt=\"HA LightFX logo\" width=\"500\"\u003e\n\u003c/p\u003e\n\n**Version 1.1.2** — virtual WLED-style light effects for ordinary Home Assistant lights.\n\nHA LightFX lets you build virtual room layouts, place Home Assistant `light` entities on a 0-100 grid, and run animated effects across them. It works with Zigbee, Z-Wave, Wi-Fi, Matter, Hue, ESPHome, or any other light that Home Assistant can control. No LED strip controller or WLED hardware is required.\n\n![HA LightFX](images/repo-preview.png)\n\n## What You Get\n\n- A Home Assistant custom integration with persistent layout storage.\n- A visual config-flow editor for layouts, lights, profiles, and layout groups.\n- A bundled Lovelace custom card served by the integration at `/ha_lightfx/ha-lightfx-card.js`.\n- 16 Home Assistant services for automation, previewing, layout management, profiles, groups, and sequences.\n- 10 built-in effects: `rainbow`, `chase`, `breathe`, `strobe`, `theater_chase`, `fire`, `color_cycle`, `sparkle`, `wave`, `twinkle`.\n- Zone-aware effects, direction control, brightness/speed/transition controls, and optional audio-reactive brightness modulation.\n\n## Supported Effects\n\n| Effect | Description | Main Controls |\n|--------|-------------|---------------|\n| `rainbow` | Smooth hue sweep across lights based on virtual position. | brightness, speed, direction |\n| `chase` | A single active light moves through the layout. | color, brightness, speed, direction |\n| `breathe` | Slow fade in/out using the primary color. | color, brightness, speed |\n| `strobe` | Alternating flash/on-off pulses. | color, brightness, speed |\n| `theater_chase` | Alternating primary/secondary color chase. | color, color2, brightness, speed, direction |\n| `fire` | Warm randomized flicker based on the primary color. | color, brightness, speed |\n| `color_cycle` | Global hue transition across all mapped lights. | brightness, speed |\n| `sparkle` | Random sparkle/twinkle flashes. | brightness, speed |\n| `wave` | HSV wave across the virtual x/y layout. | brightness, speed, direction |\n| `twinkle` | Random twinkling between two colors. | color, color2, brightness, speed |\n\n## Concepts\n\n### Layouts\n\nA layout is a named virtual space, such as `Living Room`, `Bedroom`, or `Downstairs`. Layout IDs are generated from the name by lowercasing and replacing spaces with underscores. For example:\n\n| Name | Layout ID |\n|------|-----------|\n| `Living Room` | `living_room` |\n| `Kitchen` | `kitchen` |\n| `Downstairs Hall` | `downstairs_hall` |\n\n### Light Positions\n\nEach light has:\n\n- `entity_id` — the Home Assistant light entity, for example `light.living_room_lamp`.\n- `x` — horizontal position, 0-100.\n- `y` — vertical position, 0-100.\n- `z` — optional depth, 0-100. Current effects preserve and expose it; future effects can use it for 3D-style spatial animation.\n- `zone` — one of `ceiling`, `wall`, `accent`, `floor`, `other`.\n\n### Zones\n\nZones let you run different effects on different areas in one layout. Example: ceiling lights can run `chase` while wall lights run `breathe`.\n\n### Profiles\n\nProfiles are named effect presets. They store an effect config so you can reuse it from automations or the visual editor.\n\n### Layout Groups\n\nLayout groups let you run the same effect across several layouts at once, such as `downstairs` containing `living_room`, `kitchen`, and `hallway`.\n\n### Previous State Restore\n\nWhen an effect starts, HA LightFX stores the previous state of every mapped light. `ha_lightfx.stop_effect` can restore those previous states with `restore_previous: true`.\n\n## Installation\n\n### HACS Installation (Recommended)\n\n1. Open **HACS → Integrations → ⋮ → Custom repositories**.\n2. Add this repository URL:\n   ```text\n   https://github.com/rusty4444/ha-lightfx\n   ```\n3. Select category **Integration**.\n4. Click **Add**.\n5. Find **HA LightFX** in HACS and click **Download**.\n6. Restart Home Assistant.\n7. Go to **Settings → Devices \u0026 Services → Add Integration** and search for **HA LightFX**.\n\n### Manual Installation\n\n1. Download or clone this repository.\n2. Copy the integration folder:\n   ```text\n   custom_components/ha_lightfx/\n   ```\n   into your Home Assistant config folder:\n   ```text\n   /config/custom_components/ha_lightfx/\n   ```\n3. Restart Home Assistant.\n4. Go to **Settings → Devices \u0026 Services → Add Integration** and search for **HA LightFX**.\n\n### Dashboard Resource\n\nThe Lovelace card is bundled inside the integration and served at:\n\n```text\n/ha_lightfx/ha-lightfx-card.js\n```\n\nThe Lovelace card is auto-registered as a dashboard resource when the integration starts. A hard browser refresh (Ctrl+Shift+R / Cmd+Shift+R) may be needed to pick up the card on first install.\n\nIf the card does not appear, verify the resource exists under **Settings → Dashboards → Resources**:\n\n```text\n/ha_lightfx/ha-lightfx-card.js\n```\n\nwith type **JavaScript Module**. Add it manually if needed.\n\n## Quick Start\n\n1. Install the integration and restart Home Assistant.\n2. Add the integration from **Settings → Devices \u0026 Services → Add Integration → HA LightFX**.\n3. Open the integration entry and click **Configure**.\n4. Choose **Manage Layouts → Create Layout** and create a layout, for example `Living Room`.\n5. Choose **Manage Lights → Add Light**.\n6. Pick a Home Assistant light entity.\n7. Set its `x`, `y`, optional `z`, and `zone`.\n8. Repeat for each light in the room.\n9. Add the dashboard card:\n   ```yaml\n   type: custom:ha-lightfx-card\n   ```\n10. Select the layout, choose an effect, and press **Play**.\n\n## Lovelace Card\n\nThe built-in card type is:\n\n```yaml\ntype: custom:ha-lightfx-card\n```\n\nThe card auto-discovers layouts through the integration WebSocket API. No card-level YAML options are required for basic use.\n\nThe card provides:\n\n- Lovelace visual card editor via the dashboard UI.\n- Layout selector buttons.\n- Optional default layout selection.\n- 2D layout visualization.\n- Zone-colored light dots.\n- Optional drag-and-drop light repositioning.\n- Effect selector.\n- Primary and secondary color pickers.\n- Brightness and speed sliders.\n- Optional refresh button.\n- Play/Stop controls.\n\n### Lovelace Visual Editor Options\n\nOpen the dashboard editor, add **Custom: HA LightFX**, then configure the card from the visual editor. YAML editing is optional.\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `title` | string | `HA LightFX` | Card header title. |\n| `default_layout` | string | empty | Layout ID to auto-select, for example `living_room`. Leave empty to select the first available layout. |\n| `show_layout_selector` | boolean | `true` | Show buttons for switching layouts. Disable this for a single-layout dashboard card. |\n| `show_zone_legend` | boolean | `true` | Show the zone color legend under the grid. |\n| `allow_drag` | boolean | `true` | Allow dragging light dots to update x/y positions. |\n| `show_refresh_button` | boolean | `true` | Show the header refresh button for reloading layouts. |\n| `confirm_stop` | boolean | `true` | Ask for confirmation before stopping and restoring lights. |\n\nExample YAML equivalent:\n\n```yaml\ntype: custom:ha-lightfx-card\ntitle: Living Room FX\ndefault_layout: living_room\nshow_layout_selector: false\nshow_zone_legend: true\nallow_drag: true\nshow_refresh_button: true\nconfirm_stop: true\n```\n\n## Visual Editor\n\nOpen **Settings → Devices \u0026 Services → HA LightFX → Configure**.\n\nAvailable menus:\n\n- **Manage Layouts** — create and delete layouts.\n- **Manage Lights** — add, update, and remove mapped lights.\n- **Manage Profiles** — create and delete effect profiles.\n- **Manage Groups** — create and delete layout groups.\n\nThe visual editor is the recommended setup path. Services are available for automation and advanced users.\n\n## Services Reference\n\nAll services use the domain `ha_lightfx`.\n\n| Service | Required Fields | Optional Fields | Response Support | Description |\n|---------|-----------------|-----------------|------------------|-------------|\n| `create_layout` | `name` | `icon` | Optional | Create a layout. With `return_response: true`, returns the generated `layout_id`. |\n| `remove_layout` | `layout_id` | — | No | Delete a layout. |\n| `list_layouts` | — | — | Required | Return all layouts, light counts, and status. |\n| `add_light` | `layout_id`, `entity_id`, `x`, `y` | `z`, `zone` | No | Add or update a light's layout position. |\n| `remove_light` | `layout_id`, `entity_id` | — | No | Remove a light from a layout. |\n| `start_effect` | `layout_id` | `effect`, `color`, `color2`, `brightness`, `speed`, `transition`, `direction`, `audio_entity_id`, `effect_per_zone` | No | Start an effect loop. |\n| `stop_effect` | `layout_id` | `restore_previous` | No | Stop an effect and optionally restore previous light states. |\n| `preview_effect` | `layout_id` | `effect`, `params` | Optional | Compute one preview frame without starting an effect. |\n| `create_profile` | `name` | `config` | No | Save an effect profile. |\n| `delete_profile` | `profile_id` | — | No | Delete a profile. |\n| `list_profiles` | — | — | Required | Return all saved profiles. |\n| `create_group` | `group_id`, `layout_ids` | — | No | Create or replace a layout group. |\n| `delete_group` | `group_id` | — | No | Delete a layout group. |\n| `list_groups` | — | — | Required | Return all layout groups. |\n| `start_sequence` | `layout_id`, `sequence` | `effect`, `brightness` | No | Run timed effect steps on one layout. |\n| `start_layout_group` | `group_id` | `effect`, `color`, `color2`, `brightness`, `speed`, `transition`, `direction` | No | Start the same effect across a layout group. |\n\n### Common Field Values\n\n| Field | Accepted Values |\n|-------|-----------------|\n| `effect` | `rainbow`, `chase`, `breathe`, `strobe`, `theater_chase`, `fire`, `color_cycle`, `sparkle`, `wave`, `twinkle` |\n| `color`, `color2` | RGB list such as `[255, 0, 0]` or a hex string where supported by service calls. |\n| `brightness` | Integer 0-100. |\n| `speed` | Integer 1-100. |\n| `transition` | Seconds, 0.1-5.0. |\n| `direction` | `forward`, `reverse`, `bounce`. |\n| `zone` | `ceiling`, `wall`, `accent`, `floor`, `other`. |\n\n## Service Examples\n\n### Create a Layout and Get the ID\n\n```yaml\nservice: ha_lightfx.create_layout\nreturn_response: true\ndata:\n  name: \"Living Room\"\n  icon: mdi:sofa\n```\n\nResponse:\n\n```yaml\nlayout_id: living_room\n```\n\n### Add Lights to a Layout\n\n```yaml\nservice: ha_lightfx.add_light\ndata:\n  layout_id: living_room\n  entity_id: light.living_room_ceiling\n  x: 50\n  y: 20\n  z: 10\n  zone: ceiling\n```\n\n```yaml\nservice: ha_lightfx.add_light\ndata:\n  layout_id: living_room\n  entity_id: light.floor_lamp\n  x: 20\n  y: 80\n  z: 0\n  zone: accent\n```\n\n### Start a Basic Effect\n\n```yaml\nservice: ha_lightfx.start_effect\ndata:\n  layout_id: living_room\n  effect: rainbow\n  brightness: 60\n  speed: 40\n  transition: 0.5\n  direction: forward\n```\n\n### Start a Two-Color Effect\n\n```yaml\nservice: ha_lightfx.start_effect\ndata:\n  layout_id: living_room\n  effect: theater_chase\n  color: [255, 0, 0]\n  color2: [0, 0, 255]\n  brightness: 70\n  speed: 50\n```\n\n### Stop and Restore Previous Light States\n\n```yaml\nservice: ha_lightfx.stop_effect\ndata:\n  layout_id: living_room\n  restore_previous: true\n```\n\n### Preview One Frame\n\n```yaml\nservice: ha_lightfx.preview_effect\nreturn_response: true\ndata:\n  layout_id: living_room\n  effect: fire\n  params:\n    color: [255, 100, 0]\n    brightness: 70\n    speed: 40\n```\n\n### Zone-Aware Effects\n\n```yaml\nservice: ha_lightfx.start_effect\ndata:\n  layout_id: living_room\n  brightness: 60\n  speed: 45\n  effect_per_zone:\n    ceiling: chase\n    wall: breathe\n    accent: sparkle\n    floor: wave\n```\n\n### Audio-Reactive Effect\n\n`audio_entity_id` can point at a `media_player`. HA LightFX uses the player's `volume_level` attribute to modulate effect brightness.\n\n```yaml\nservice: ha_lightfx.start_effect\ndata:\n  layout_id: living_room\n  effect: fire\n  color: [255, 100, 0]\n  brightness: 70\n  audio_entity_id: media_player.living_room\n```\n\n### Create a Profile\n\n```yaml\nservice: ha_lightfx.create_profile\ndata:\n  name: \"Warm Fire\"\n  config:\n    effect: fire\n    color: [255, 120, 20]\n    brightness: 55\n    speed: 35\n```\n\n### Create a Layout Group\n\n```yaml\nservice: ha_lightfx.create_group\ndata:\n  group_id: downstairs\n  layout_ids:\n    - living_room\n    - kitchen\n    - hallway\n```\n\n### Start an Effect Across a Group\n\n```yaml\nservice: ha_lightfx.start_layout_group\ndata:\n  group_id: downstairs\n  effect: rainbow\n  brightness: 50\n  speed: 40\n```\n\n### Run a Sequence\n\n```yaml\nservice: ha_lightfx.start_sequence\ndata:\n  layout_id: living_room\n  brightness: 80\n  sequence:\n    - effect: rainbow\n      duration_seconds: 30\n    - effect: chase\n      duration_seconds: 15\n      speed: 60\n    - effect: strobe\n      duration_seconds: 10\n      brightness: 100\n```\n\n## Automation Examples\n\n### Motion-Triggered Rainbow After Sunset\n\n```yaml\nalias: \"Rainbow on Arrival\"\ntrigger:\n  - platform: state\n    entity_id: binary_sensor.motion_living_room\n    to: \"on\"\ncondition:\n  - condition: sun\n    after: sunset\naction:\n  - service: ha_lightfx.start_effect\n    data:\n      layout_id: living_room\n      effect: rainbow\n      brightness: 40\n      speed: 30\n  - delay:\n      minutes: 5\n  - service: ha_lightfx.stop_effect\n    data:\n      layout_id: living_room\n      restore_previous: true\n```\n\n### Bedtime Breathe\n\n```yaml\nalias: \"Bedtime Breathe\"\ntrigger:\n  - platform: time\n    at: \"22:00:00\"\naction:\n  - service: ha_lightfx.start_effect\n    data:\n      layout_id: bedroom\n      effect: breathe\n      color: [255, 50, 50]\n      brightness: 20\n      speed: 20\n```\n\n### Doorbell Party Sequence\n\n```yaml\nalias: \"Doorbell Party Sequence\"\ntrigger:\n  - platform: state\n    entity_id: binary_sensor.doorbell\n    to: \"on\"\naction:\n  - service: ha_lightfx.start_sequence\n    data:\n      layout_id: living_room\n      brightness: 80\n      sequence:\n        - effect: rainbow\n          duration_seconds: 30\n        - effect: chase\n          duration_seconds: 15\n          speed: 60\n        - effect: strobe\n          duration_seconds: 10\n          brightness: 100\n```\n\n## Troubleshooting\n\n### The card is not available in the dashboard card picker\n\n- Confirm the integration is installed and Home Assistant has been restarted.\n- Confirm the dashboard resource exists:\n  ```text\n  /ha_lightfx/ha-lightfx-card.js\n  ```\n- Resource type must be **JavaScript Module**.\n- Hard refresh the browser: Ctrl+Shift+R / Cmd+Shift+R.\n- Check browser dev tools for failed requests to `/ha_lightfx/ha-lightfx-card.js`.\n\n### A layout has no lights\n\n- Open **Configure → Manage Lights** and add at least one light.\n- Or call `ha_lightfx.add_light` with the correct `layout_id` and `entity_id`.\n- Use `ha_lightfx.list_layouts` with `return_response: true` to inspect current layout state.\n\n### Effects start but lights do not visibly change\n\n- Confirm the mapped entities are real `light` entities and are available in Home Assistant.\n- Some lights may not support RGB color; try effects that rely mostly on brightness or use supported color modes.\n- Try lower `transition` and higher `brightness`.\n- Check Home Assistant logs for `ha_lightfx` warnings.\n\n### Effects stop but lights do not restore\n\n- Use:\n  ```yaml\n  service: ha_lightfx.stop_effect\n  data:\n    layout_id: living_room\n    restore_previous: true\n  ```\n- Restore only applies to lights that were part of the layout when the effect started.\n\n### A grouped layout was deleted\n\n`start_layout_group` skips stale/missing layout IDs and logs a warning. Recreate the missing layout or update the group with `create_group` using the current list of layout IDs.\n\n## Storage and Data\n\nHA LightFX stores layouts, lights, profiles, and groups in Home Assistant storage under the integration's storage key. Data persists across Home Assistant restarts.\n\nStored data includes:\n\n- Layout names and icons.\n- Light entity IDs and x/y/z/zone positions.\n- Effect profiles.\n- Layout groups.\n\n## Development\n\nRepository structure:\n\n```text\ncustom_components/ha_lightfx/\n├── __init__.py             # Integration setup, service registration, WebSocket API, frontend serving\n├── config_flow.py          # Initial setup and visual configuration editor\n├── const.py                # Constants, service names, effects, storage version\n├── lightfx_engine.py       # Effect engine and persistence model\n├── manifest.json           # Home Assistant manifest\n├── services.yaml           # Service definitions shown in Developer Tools\n├── strings.json            # Config-flow UI strings\n├── translations/\n│   └── en.json             # English translations\n├── brand/\n│   ├── icon.png\n│   ├── icon@2x.png\n│   ├── logo.png\n│   └── logo@2x.png\n└── www/\n    └── ha-lightfx-card.js  # Bundled, browser-loadable Lovelace custom card\n\nfrontend/\n└── ha-lightfx-card.js      # Source for the card/editor before bundling\n```\n\nThe committed `custom_components/ha_lightfx/www/ha-lightfx-card.js` file is the browser-loadable bundle used by Home Assistant. Edit `frontend/ha-lightfx-card.js`, then rebuild the bundle:\n\n```bash\nnpm install\nnpm run build:card\n```\n\nUseful validation commands:\n\n```bash\npython3 -m py_compile custom_components/ha_lightfx/*.py\npython3 -m json.tool custom_components/ha_lightfx/manifest.json \u003e/dev/null\npython3 -m json.tool hacs.json \u003e/dev/null\npython3 -m json.tool custom_components/ha_lightfx/strings.json \u003e/dev/null\npython3 -m json.tool custom_components/ha_lightfx/translations/en.json \u003e/dev/null\nruby -e 'require \"yaml\"; YAML.load_file(\"custom_components/ha_lightfx/services.yaml\")'\nnode --check frontend/ha-lightfx-card.js\nnode --check custom_components/ha_lightfx/www/ha-lightfx-card.js\n```\n\n## Release Notes: 1.0.7\n\nVersion 1.0.7 improves the add-light form:\n\n- Entity selection is now a dropdown picker filtered to `light` domain, instead of a bare text field.\n\n## Release Notes: 1.0.6\n\nVersion 1.0.6 fixes an entity serialization bug in the config flow:\n\n- Switches `cv.entity_id` to `cv.string` in the add-light schema so `voluptuous_serialize` can render the form field in the HA frontend.\n\n## Release Notes: 1.0.5\n\nVersion 1.0.5 fixes config flow errors and auto-registers the Lovelace card:\n\n- Auto-registers the Lovelace dashboard card resource on integration setup — no manual resource URL entry needed.\n- Fixes \"extra keys not allowed @ _action\" when adding or editing lights in the config flow editor.\n\n## Release Notes: 1.0.4\n\nVersion 1.0.4 fixes two bugs found during live install testing:\n\n- Fixed `Store` import in `__init__.py` — `hass.helpers.storage.Store()` is not valid in modern HA. Uses `Store(hass, ...)` import pattern.\n- Fixed `OptionsFlow.__init__` config entry property collision — `config_entry` is a read-only base-class property.\n\n## Release Notes: 1.0.3\n\nVersion 1.0.3 adds and hardens the Lovelace visual card editor:\n\n- Adds a dashboard visual editor via `getConfigElement()` and `ha-form`.\n- Bundles the Lit-based card source for browser loading through Home Assistant.\n- Adds configurable card options for title, layout selector, zone legend, dragging, refresh button, and stop confirmation.\n- Refreshes card layout state after mutating service calls.\n- Keeps dragged light dot, label, and glow positions aligned.\n- Requests card updates when Home Assistant state changes.\n- Adds explicit HACS integration category metadata.\n- Cleans up unused options-flow abort copy.\n\nVersion 1.0.2 included the sequential multi-model review fix set:\n\n- Bundled frontend card served from the integration path.\n- Required brand assets for Home Assistant/HACS.\n- README, manifest, and HACS metadata alignment.\n- Safer options-flow context handling.\n- Service cleanup on unload.\n- Stale layout handling in layout groups.\n- Profile/layout name validation improvements.\n- RGB color list length validation.\n- Storage version alignment.\n- Optional `create_layout` response with generated `layout_id`.\n- Preview failure warning logging.\n\n## AI Used in Development\n\nThis project used AI-assisted development for code review, bug fixing, documentation, and release tasks. Multi-model sequential reviews were run across the codebase to catch issues before release. All AI-generated changes were reviewed by a human before merging.\n\n## License\n\nMIT\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frusty4444%2Fha-lightfx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frusty4444%2Fha-lightfx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frusty4444%2Fha-lightfx/lists"}