Skip to main content

Homey ESPHomeDriver

PyPI version PyPI downloads Python CI License: MIT Ruff Status Homey

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.

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.

Metadata

Release files for homey-esphomedriver 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for homey-esphomedriver 0.4.1
File Size Uploaded Provenance Actions
homey_esphomedriver-0.4.1.tar.gz 181.5 kB With provenance Details for homey_esphomedriver-0.4.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for homey-esphomedriver 0.4.1
File Interpreter ABI Platform Actions
homey_esphomedriver-0.4.1-py3-none-any.whl Python 3 none any Details for homey_esphomedriver-0.4.1-py3-none-any.whl

Total release size: 419.0 kB

Release files / homey_esphomedriver-0.4.1.tar.gz

Download URL homey_esphomedriver-0.4.1.tar.gz
Size 181.5 kB
Tags Source
SHA-256 checksum
How to use checksums
55bdc549f414b9334d4d78490f9ef41d02b19911e7e831c01b52a79b7655b159
BLAKE2b-256 checksum
How to use checksums
8f644e79aa207055150df0ae6c91704abbb8dfed3406114054f47ca4884454bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log

Release files / homey_esphomedriver-0.4.1-py3-none-any.whl

Download URL homey_esphomedriver-0.4.1-py3-none-any.whl
Size 237.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
39b86250e2d7d2ca8ff1d02342b0139e28a15733e597efbc93939821889eae6b
BLAKE2b-256 checksum
How to use checksums
8a9d7fe00f0d87ffb5b22ef8042acb5a0a51e1a11ca0eedcaf9b63b8498199ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log

Security for homey-esphomedriver 0.4.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for homey_esphomedriver-0.4.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page