{"id":51061907,"url":"https://github.com/thekoma/dlight-homeassistant","last_synced_at":"2026-06-23T03:01:30.153Z","repository":{"id":360788776,"uuid":"1251709302","full_name":"thekoma/dlight-homeassistant","owner":"thekoma","description":"Native Home Assistant integration for the Google dLight experimental desk lamp — local TCP control, zeroconf discovery, HACS-installable","archived":false,"fork":false,"pushed_at":"2026-05-27T21:43:27.000Z","size":58,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-27T23:09:47.661Z","etag":null,"topics":["dlight","google","hacs","home-assistant","light"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thekoma.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-27T20:57:24.000Z","updated_at":"2026-05-27T21:43:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/thekoma/dlight-homeassistant","commit_stats":null,"previous_names":["thekoma/dlight-homeassistant"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/thekoma/dlight-homeassistant","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thekoma%2Fdlight-homeassistant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thekoma%2Fdlight-homeassistant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thekoma%2Fdlight-homeassistant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thekoma%2Fdlight-homeassistant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thekoma","download_url":"https://codeload.github.com/thekoma/dlight-homeassistant/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thekoma%2Fdlight-homeassistant/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34673437,"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-23T02:00:07.161Z","response_time":65,"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":["dlight","google","hacs","home-assistant","light"],"created_at":"2026-06-23T03:01:26.468Z","updated_at":"2026-06-23T03:01:30.147Z","avatar_url":"https://github.com/thekoma.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"custom_components/dlight/brand/icon.png\" width=\"148\" alt=\"Google dLight\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eGoogle dLight for Home Assistant\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  Native Home Assistant integration for the Google \u003cstrong\u003edLight\u003c/strong\u003e experimental desk lamp.\u003cbr\u003e\n  Control power, brightness and color temperature \u003cstrong\u003elocally\u003c/strong\u003e, over the lamp's own TCP protocol —\n  no MQTT bridge, no extra container.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://my.home-assistant.io/redirect/hacs_repository/?owner=thekoma\u0026repository=dlight-homeassistant\u0026category=integration\"\u003e\u003cimg src=\"https://my.home-assistant.io/badges/hacs_repository.svg\" alt=\"Open inside HACS\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/hacs/integration\"\u003e\u003cimg src=\"https://img.shields.io/badge/HACS-Custom-41BDF5.svg\" alt=\"HACS Custom\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/thekoma/dlight-homeassistant/actions/workflows/validate.yml\"\u003e\u003cimg src=\"https://github.com/thekoma/dlight-homeassistant/actions/workflows/validate.yml/badge.svg\" alt=\"Validate\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/thekoma/dlight-homeassistant/actions/workflows/test.yml\"\u003e\u003cimg src=\"https://github.com/thekoma/dlight-homeassistant/actions/workflows/test.yml/badge.svg\" alt=\"Tests\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/thekoma/dlight-homeassistant/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/thekoma/dlight-homeassistant?display_name=tag\u0026color=41BDF5\" alt=\"Latest release\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/thekoma/dlight-homeassistant?color=41BDF5\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## Overview\n\nThe **Google dLight** is an experimental smart desk lamp that speaks a local\nTCP/JSON protocol on your LAN. By reverse-engineering a lamp I own, this\nintegration talks to it **directly from Home Assistant** — the lamp shows up as a\nnormal `light` entity with on/off, brightness and color temperature, discovered\nautomatically over mDNS.\n\nThere is no cloud, no MQTT broker and no side-car container to run or babysit:\nthe protocol client lives inside the integration and runs in Home Assistant's\nevent loop.\n\n## Features\n\n- **Local \u0026 cloud-free** — direct TCP control on your LAN, nothing leaves the network.\n- **Zeroconf auto-discovery** — the lamp is found automatically via mDNS (`_ged7._tcp`); manual setup (IP + device ID) is available as a fallback.\n- **Full light control** — power, brightness, and color temperature (**2600 K – 6000 K**).\n- **Reflects physical changes** — adjustments made on the lamp's touch ring are picked up by polling.\n- **Gentle on the hardware** — all I/O is serialized and polling is conservative (default 30 s, configurable), because the lamp only sustains a single connection at a time.\n- **Optimistic updates** — commands feel instant in the UI without hammering the lamp with extra polls.\n- **HACS-ready** — one-click install, bundled brand icon, CI-validated (hassfest + HACS).\n- **Localized** — translated into 29 languages, covering the countries where Google has offices.\n\n## Supported device\n\n| | |\n|---|---|\n| **Product** | Google dLight (experimental desk lamp) |\n| **Model** | `GLAMP001` |\n| **Tested firmware** | `3.0.4` |\n| **Transport** | TCP port `3333` (local) |\n| **Discovery** | mDNS service `_ged7._tcp.local.`, instance `GLAMP_\u003cdeviceId\u003e` |\n| **Color temperature** | 2600 K (warmest) – 6000 K (coolest) |\n| **Brightness** | 1–100 on the device, mapped to Home Assistant's 1–255 |\n\n## How it works\n\n```\n        mDNS  _ged7._tcp                         TCP :3333  (JSON, length-prefixed)\nHome Assistant ───────────────►  custom_components/dlight  ───────────────────────►  dLight lamp\n  light entity ◄───────────────  client + coordinator      ◄───────────────────────  (GLAMP001)\n                 discovery / state            (single serialized connection)\n```\n\n- **`client.py`** — a dependency-free async TCP client implementing the lamp protocol. A per-lamp `asyncio.Lock` guarantees only one connection is open at a time.\n- **`coordinator.py`** — a `DataUpdateCoordinator` that polls the lamp's state on a configurable interval and exposes it to the entity.\n- **`light.py`** — the `light` entity: maps the lamp's state to Home Assistant and translates service calls into commands, with optimistic state updates.\n- **`config_flow.py`** — zeroconf discovery + manual setup, plus an options flow for the poll interval.\n\n## Requirements\n\n- **Home Assistant 2024.12** or newer. (The bundled brand icon is served automatically on **2026.3+** via the brands proxy; on older versions the integration still works, just with the default icon.)\n- The lamp powered on and reachable from your Home Assistant host (same LAN / mDNS reachable, TCP `3333` open).\n\n## Installation\n\n### HACS (recommended)\n\n[![Open inside HACS](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=thekoma\u0026repository=dlight-homeassistant\u0026category=integration)\n\n1. Click the badge above (or in HACS: **⋮ → Custom repositories**, add\n   `https://github.com/thekoma/dlight-homeassistant`, category **Integration**).\n2. Install **Google dLight**.\n3. **Restart** Home Assistant.\n\n### Manual\n\n1. Copy `custom_components/dlight/` into your Home Assistant `config/custom_components/` directory.\n2. Restart Home Assistant.\n\n## Configuration\n\nNo YAML required — everything is done from the UI.\n\n### Automatic discovery\n\nWhen the lamp is on the network, Home Assistant discovers it and shows a\nnotification under **Settings → Devices \u0026 Services**. Click **Configure** and\nconfirm.\n\n### Manual setup\n\nIf discovery doesn't find it (e.g. different VLAN / mDNS blocked):\n\n1. **Settings → Devices \u0026 Services → Add Integration → Google dLight**.\n2. Enter the lamp's **host/IP** and its **device ID** (the `\u003cdeviceId\u003e` part of\n   its `GLAMP_\u003cdeviceId\u003e` mDNS name).\n\n### Options\n\nOpen the integration's **Configure** dialog to set the **polling interval**\n(seconds, default `30`, minimum `5`). Increase it if you want to be extra gentle\non the lamp; decrease it for snappier reflection of physical-control changes.\n\n## What you get\n\nA single `light` entity (and a matching device) exposing:\n\n| Capability | Details |\n|---|---|\n| Power | `on` / `off` |\n| Brightness | full range, mapped from the lamp's 1–100 scale |\n| Color temperature | `color_temp` mode, **2600–6000 K** |\n| Availability | entity goes `unavailable` if the lamp can't be reached, and recovers automatically |\n\nThe device page shows the model (`GLAMP001`), firmware/hardware versions and the\nlamp's MAC address.\n\n## Design notes\n\nA few things make this integration reliable with the dLight:\n\n1. **In-process, no side-car.** The protocol client runs inside Home Assistant —\n   there's no separate service or container to deploy and monitor.\n2. **Gentle on the hardware.** Reverse-engineering the device showed it accepts\n   **one connection at a time**, and a single state query takes **~1.2 s** on\n   current firmware. Polling it too aggressively makes it unstable, so this\n   integration polls conservatively (30 s by default), serializes every request\n   behind one lock, and uses optimistic updates so the UI stays responsive\n   without extra round-trips.\n3. **Correct color-temperature range.** Verified on-device: the lamp spans\n   **2600–6000 K**.\n\n## Under the hood\n\nThe lamp speaks a small TCP/JSON protocol on port `3333`: the client sends a\ncompact JSON command terminated by a newline, and the lamp replies with a 4-byte\nbig-endian length prefix followed by a JSON body. It advertises itself over mDNS\nas `_ged7._tcp.local.` with the instance name `GLAMP_\u003cdeviceId\u003e` and a TXT record\ncarrying its MAC, model and firmware. All of this was worked out by\nreverse-engineering the device.\n\n## Troubleshooting\n\n- **Lamp not discovered** — add it manually (host + device ID). Make sure Home\n  Assistant and the lamp share a subnet or that mDNS is forwarded between VLANs.\n- **Entity `unavailable`** — check the lamp's IP (DHCP may have reassigned it;\n  re-discovery updates the stored host) and that TCP `3333` is reachable. Note\n  the lamp may answer ICMP slowly/variably — use a port check rather than ping.\n- **Occasional instability** — raise the polling interval in **Options**.\n- **Default (puzzle-piece) icon** — the bundled icon is served via the HA 2026.3+\n  brands proxy; on older Home Assistant versions the default icon is shown.\n\n## Development\n\n```bash\ngit clone https://github.com/thekoma/dlight-homeassistant\ncd dlight-homeassistant\npython -m venv .venv \u0026\u0026 source .venv/bin/activate\npip install -r requirements_test.txt\npytest                 # 25 tests (client / coordinator / light / config flow)\n```\n\nCI runs `pytest`, Home Assistant **hassfest**, and **HACS** validation on every\npush.\n\n### Project layout\n\n```\ncustom_components/dlight/\n├── __init__.py        # config entry setup/unload\n├── manifest.json\n├── const.py\n├── client.py          # async TCP protocol client (no external deps)\n├── coordinator.py     # DataUpdateCoordinator (polling)\n├── light.py           # the light entity\n├── config_flow.py     # zeroconf + manual setup + options\n├── strings.json / translations/\n└── brand/             # icon.png, icon@2x.png (served via the brands proxy)\nicons/                 # icon.svg (gradient) + icon-stylized.svg (flat) sources\ntests/                 # pytest-homeassistant-custom-component suite\n```\n\n## License\n\nReleased under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthekoma%2Fdlight-homeassistant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthekoma%2Fdlight-homeassistant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthekoma%2Fdlight-homeassistant/lists"}