Homey ESPHomeDriver
This module can be used to make the development of ESPHome apps for Homey easier.
It is essentially a map-tool from Homey-capabilities to ESPHome entities.
This module requires Homey Apps SDK v3.
Related Modules
- node-homey-zigbeedriver — Module for Zigbee drivers
- node-homey-zwavedriver — Module for Z-Wave drivers
- node-homey-rfdriver — Module for RF drivers
- node-homey-oauth2app — Module for OAuth2 apps
Installation
$ pip install homey-esphomedriver
Homey apps declare it next to aioesphomeapi in app.json / .homeycompose/app.json:
"pythonPackages": ["aioesphomeapi", "homey-esphomedriver"]
Also checkout [aioesphomeapi](https://github.com/esphome/aioesphomeapi) if you want to talk to the ESPHome Native API directly, without homey-esphomedriver.
$ pip install aioesphomeapi
Changelog
See CHANGELOG.md.
Requirements
This module requires Homey Apps SDK v3 (Python 3.14 runtime).
Usage
Your device should extend EspHomeDevice. This is the class you most likely want to extend from. Your driver should extend EspHomeDriver.
Product identity lives on the Homey driver like Zigbee productId: an esphome object in driver.compose.json. EspHomeDriver reads it from self.manifest. driver.py and device.py can re-export the stock classes when you do not need extra logic.
Driver compose
{
"name": { "en": "AQ-1" },
"class": "sensor",
"$extends": ["esphome-defaults"],
"esphome": {
"clientInfo": "Homey EverythingSmart",
"projects": ["EverythingSmart.AQ-1"],
"hiddenEntities": ["status_led"],
"deviceEntities": { "voc": "measure_tvoc" },
"deviceClassOverrides": { "aq_1": "sensor" }
}
}
| Compose key | Python BrandProfile field |
Purpose |
|---|---|---|
projects |
projects |
Exact ESPHome project.name this driver accepts |
projectPrefix |
project_prefix |
Prefix match such as Brand. |
clientInfo |
client_info |
Name shown on the node for this Homey client |
hiddenEntities |
hidden_entities |
Hide extra entities (status LED, OTA helpers) |
deviceEntities |
device_entities |
Remap an entity to a Homey capability |
deviceClassOverrides |
device_class_overrides |
Force Homey class from an entity id |
Omit projects / projectPrefix to accept every project (io.esphome). If both are set, either match is enough.
A class-level brand_profile = BrandProfile(...) on the driver still overrides compose. Use that for after_map.
Driver
# drivers/aq-1/driver.py
from homey_esphomedriver import EspHomeDriver
homey_export = EspHomeDriver
Device
# drivers/aq-1/device.py
from homey_esphomedriver import EspHomeDevice
homey_export = EspHomeDevice
Lifecycle hooks
Core owns on_init and on_uninit on EspHomeDriver and EspHomeDevice. Subclass the hooks below instead — same pattern as homey-oauth2app's onOAuth2Init. Brand app.py exports Homey's App.
| Class | Override | When |
|---|---|---|
EspHomeDriver |
on_esphome_init / on_esphome_uninit |
After Flow listeners / before teardown |
EspHomeDevice |
on_esphome_init(client) / on_esphome_uninit |
After capability wiring; client is None when host is unknown |
EspHomeDevice |
on_esphome_connected(client) |
After each login + set_available; session not READY yet — no cmds |
On a paired device, use self.client for the live EspHomeClient (may exist before the API handshake). Capability commands still require a READY session via _require_client() / available — including from on_esphome_connected.
Debug logging uses env.json DEBUG; there is no separate class flag.
# drivers/aq-1/device.py
from homey_esphomedriver import EspHomeClient, EspHomeDevice as BaseDevice
class EspHomeDevice(BaseDevice):
async def on_esphome_init(self, client: EspHomeClient | None) -> None:
await super().on_esphome_init(client)
if client is not None:
self.log(f"API session started for {client.host}")
async def on_esphome_connected(self, client: EspHomeClient) -> None:
await super().on_esphome_connected(client)
self.log(f"Logged in to {client.host}")
homey_export = EspHomeDevice
Homey Compose files
Homey Compose runs before Python, so $extends / $template only see files already in the app. When homey-esphomedriver is listed in pythonPackages, Homey CLI copies this package's templates into .homeycompose/ during preprocess (homey app run, build, validate), before compose. That is what makes "$extends": ["esphome-defaults"] and pair "$template": "enter_key" resolve.
Until that CLI is released, or when the package is unpublished, run the same copy by hand:
$ esphome-homey sync
-p / --path selects an app directory other than the current one. sync leaves app.json, app.py, driver.compose.json, and existing driver code alone unless --force.
A brand app is a normal Homey Python app:
$ homey app create
$ homey app dependencies add aioesphomeapi homey-esphomedriver
$ homey app driver create
Then set $extends and the esphome block on each driver's driver.compose.json, add store images, and publish with Homey CLI.
Documentation
See ARCHITECTURE.md for what devices get from Homey and how a brand listing is an esphome compose block on top of this core.
[esphome-homey](https://github.com/Doekse/esphome-homey)— generic Homey app (io.esphome; any ESPHome node)
License
MIT. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file homey_esphomedriver-0.4.0.tar.gz.
File metadata
- Download URL: homey_esphomedriver-0.4.0.tar.gz
- Upload date:
- Size: 180.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77c4ca76243c1e78879b6fa68f1644426072a3f3a6e093057a4c8b044bfefd46
|
|
| MD5 |
f5e67f5464587af64004a78e38e2256d
|
|
| BLAKE2b-256 |
09075fb164121f02a60ce2c3283838a7b0cd928209bc8c9c61187d90f4e43332
|
Provenance
The following attestation bundles were made for homey_esphomedriver-0.4.0.tar.gz:
Publisher:
publish-pypi.yml on Doekse/homey-esphomedriver
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
homey_esphomedriver-0.4.0.tar.gz -
Subject digest:
77c4ca76243c1e78879b6fa68f1644426072a3f3a6e093057a4c8b044bfefd46 - Sigstore transparency entry: 2567708174
- Sigstore integration time:
-
Permalink:
Doekse/homey-esphomedriver@7544e574bf1dc3e98ffb7eaf4ea594de8401f7bc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Doekse
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@7544e574bf1dc3e98ffb7eaf4ea594de8401f7bc -
Trigger Event:
push
-
Statement type:
File details
Details for the file homey_esphomedriver-0.4.0-py3-none-any.whl.
File metadata
- Download URL: homey_esphomedriver-0.4.0-py3-none-any.whl
- Upload date:
- Size: 237.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2505f9998e953ef442ab57e253bfbe644eddd5d88801477e81270aa6cacc389
|
|
| MD5 |
9283fe6d05b8ae0ee00185f16e92a272
|
|
| BLAKE2b-256 |
b8f5486133bb028098dd823adc734aad83e238434f86e6fc4c8bc5ac396e629b
|
Provenance
The following attestation bundles were made for homey_esphomedriver-0.4.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on Doekse/homey-esphomedriver
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
homey_esphomedriver-0.4.0-py3-none-any.whl -
Subject digest:
a2505f9998e953ef442ab57e253bfbe644eddd5d88801477e81270aa6cacc389 - Sigstore transparency entry: 2567708178
- Sigstore integration time:
-
Permalink:
Doekse/homey-esphomedriver@7544e574bf1dc3e98ffb7eaf4ea594de8401f7bc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Doekse
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@7544e574bf1dc3e98ffb7eaf4ea594de8401f7bc -
Trigger Event:
push
-
Statement type: