Metadata-Version: 2.4
Name: habitron-client
Version: 1.0.4
Summary: Asynchronous, typed API client for the Habitron SmartHub
Author: Habitron GmbH
License: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Home Automation
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.14
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: types-pyyaml; extra == 'dev'
Description-Content-Type: text/markdown

# Habitron Client

An asynchronous, fully typed API client for the Habitron SmartHub, designed for
integration with Home Assistant.

## Features

- Non-blocking TCP communication via `asyncio` `StreamReader`/`StreamWriter`.
- Persistent, lock-serialised connection with automatic reconnect on errors.
- Automatic CRC16 calculation and command wrapping.
- High-level coroutines for outputs, dimmers, RGB, shutters, climate and more.
- Safe YAML parsing (`yaml.safe_load`) into validated `TypedDict` models.
- Async UDP discovery of SmartHubs on the local network.
- Typed exception hierarchy and a `py.typed` marker (PEP 561 compliant).

## Requirements

- Python 3.11+

## Installation

```bash
pip install habitron-client
```

## Usage

The client is async-only and is used as an async context manager:

```python
import asyncio

from habitron_client import HabitronClient, HabitronError


async def main() -> None:
    async with HabitronClient("192.0.2.10") as client:
        info = await client.get_smhub_info()
        print(info["software"]["version"])

        await client.set_output(mod_addr=1, nmbr=2, val=True)


asyncio.run(main())
```

### Error handling

All failures raise a typed exception:

```text
HabitronError                 (root)
├── HabitronConnectionError   (refused / EOF / socket lost)
├── HabitronTimeoutError      (no response within the deadline)
└── HabitronProtocolError
    ├── HabitronChecksumError (CRC mismatch)
    └── HabitronBusError      (SmartHub reported an error)
```

### Discovery

```python
from habitron_client import discover_smarthubs

hubs = await discover_smarthubs()
```

## Development

```bash
pip install -e ".[dev]"
ruff check .
ruff format --check .
mypy --strict src/habitron_client
pytest
```
