Skip to content

Client async context manager for persistent MQTT connection lifecycle #16

@jlopez

Description

@jlopez

Summary

Client should become an async context manager so that the MQTT connection lifecycle is explicitly managed:

async with await Client.login(email, password) as client:
    device = client.device(0)
    await device.set_property("ac", "on")
    # connection cleaned up on exit

Motivation

Currently, Device.set_property() falls back to a short-lived MQTT connection when no subscription is active (open, publish, close). This is fine for the primary use case (Home Assistant always calls subscribe() first, so _active_mqtt is always set), but means a library consumer who calls set_property() multiple times without subscribing incurs a full connect/disconnect per call.

A proper async context manager would lazily create a persistent _active_mqtt on entry and tear it down on exit — eliminating the short-lived connection fallback entirely.

Constraint

The current CLI pattern is incompatible with this:

# CLI today: synchronous load, then asyncio.run() per command
client = Client.from_saved()
asyncio.run(client.set_property(...))

An async context manager that spans multiple asyncio.run() calls is not possible (each call creates and destroys the event loop). Adopting this pattern would require refactoring the CLI to run a single event loop per invocation, or keeping a separate sync-friendly path.

Depends on

Priority

Low — the short-lived fallback is acceptable for all current consumers. Revisit when the CLI is refactored or when a consumer with high set_property() throughput appears.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions