Skip to main content

pyzephyrconnect

Python client for Zephyr / Gemtek range hoods.

These hoods expose no local API. All communication is a cloud round-trip through AWS IoT Core device shadows. See PROTOCOL.md for how the protocol was reverse-engineered.

Install

pip install pyzephyrconnect

Read state

import aiohttp
from pyzephyrconnect import ZephyrClient

async with aiohttp.ClientSession() as session:
    client = ZephyrClient.from_credentials("you@example.com", "password", session)
    try:
        for hood in await client.async_setup():
            print(hood.capabilities.model, hood.capabilities.max_fan_speed)
            await hood.async_start()
            print(hood.state)
    finally:
        await client.async_stop()

Persisting tokens

The library never persists credentials - storage is yours. Supply tokens from a previous session and a callback to save new ones, and a restart skips the SRP login entirely:

from pyzephyrconnect import ZephyrClient, ZephyrTokens, ZephyrDataError

try:
    tokens = ZephyrTokens.from_dict(saved) if saved else None
except ZephyrDataError:
    # from_dict validates rather than coercing, so a corrupted or partial
    # record raises here instead of failing much later as a SECRET_HASH
    # Cognito rejects. Discard it - a full SRP login rebuilds it.
    tokens = None

client = ZephyrClient.from_credentials(
    username, password, session,
    tokens=tokens,
    token_updater=lambda t: save(t.as_dict()),
)

To keep the password out of the library completely, subclass AbstractAuth and implement async_get_tokens().

MQTT client ID

AWS IoT treats two live connections sharing a client ID as one session and evicts one for the other, so every connection is identified by the account's Cognito identity plus a suffix identifying you. It defaults to -py; pass your own if anything else may talk to the same account - the vendor phone app already does:

client = ZephyrClient.from_credentials(
    username, password, session, client_id_suffix="-ha",
)

The same keyword works on CredentialsAuth, and on AbstractAuth for a custom subclass. It must be a non-empty string, and short: AWS IoT caps the whole client ID at 128 characters, and the library appends -<thingName> per hood on top of identity plus suffix.

Probe CLI

The write path actuates a physical fan and light. The CLI writes one field at a time, refuses anything outside an allowlist, and requires --confirm:

export ZEPHYR_USER=you@example.com
python -m pyzephyrconnect --watch
python -m pyzephyrconnect --set light=1 --confirm

Destructive writes need --force as well. resetgreasefilter zeroes a usage counter that cannot be reconstructed.

Status

Read and write paths both verified against a Zephyr AK7400AS. power, light, fan, setdelaytimer (seconds) and setcleanairfunction have established semantics; resetgreasefilter ships untested by design.

Filter counters are in minutes, run-time counters in hours - see PROTOCOL.md §5 before deriving anything from them.

Still unestablished: the act mode strings and the delay-timer ceiling. See PROTOCOL.md §7.

License

GPL-3.0-or-later

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyzephyrconnect-0.2.0.tar.gz (155.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyzephyrconnect-0.2.0-py3-none-any.whl (76.7 kB view details)

Uploaded Python 3

File details

Details for the file pyzephyrconnect-0.2.0.tar.gz.

File metadata

  • Download URL: pyzephyrconnect-0.2.0.tar.gz
  • Upload date:
  • Size: 155.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pyzephyrconnect-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2afe47e95570351596390735e053e06b2838153e99340ec6cebf72586fbeddec
MD5 d2f550b09368be45ffcc43369d752ee8
BLAKE2b-256 79e50a259ed8c983c3daaf78b3fdc8e3a2f63f8d8d75e2dcb9aeca982c5d2f01

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyzephyrconnect-0.2.0.tar.gz:

Publisher: release.yml on RyanMorash/pyzephyrconnect

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyzephyrconnect-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pyzephyrconnect-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 76.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pyzephyrconnect-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6f4d4ba10e6d29fc6160d9ddcae545e2368ff6a6034e162a2acd385fb7d99f85
MD5 0e49f7c495f2a0bf3f263022f0717308
BLAKE2b-256 2fad97eddc40cf02914a14741306044cd09a9724737765cb4e9115eb484ea9ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyzephyrconnect-0.2.0-py3-none-any.whl:

Publisher: release.yml on RyanMorash/pyzephyrconnect

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.0

2 files

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