Metadata-Version: 2.4
Name: pykoreader
Version: 0.2.0
Summary: KOReader telemetry snapshot model and Home Assistant command protocol (parsing, command builders, coalescing command queue).
Project-URL: Homepage, https://github.com/hudsonbrendon/pykoreader
Project-URL: Repository, https://github.com/hudsonbrendon/pykoreader
Project-URL: Home Assistant integration, https://github.com/hudsonbrendon/ha-koreader
Author-email: Hudson Brendon <contato.hudsonbrendon@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: home-assistant,kindle,koreader,telemetry
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.11
Provides-Extra: test
Requires-Dist: pytest; extra == 'test'
Description-Content-Type: text/markdown

# pykoreader

[![CI](https://github.com/hudsonbrendon/pykoreader/actions/workflows/ci.yml/badge.svg)](https://github.com/hudsonbrendon/pykoreader/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/pykoreader)](https://pypi.org/project/pykoreader/)

Pure-Python model of the **KOReader** telemetry snapshot and the Home Assistant
command protocol: snapshot parsing, command builders, and a coalescing,
capped command queue. No Home Assistant or network dependencies.

Used by the **[ha-koreader](https://github.com/hudsonbrendon/ha-koreader)** Home
Assistant integration, but usable standalone.

## Install

```bash
pip install pykoreader
```

## Usage

```python
from pykoreader import Snapshot, CommandQueue, parse_payload, commands

# Parse an incoming webhook body (a decoded JSON object) into a typed snapshot.
snap = parse_payload({"battery_level": 80, "reading": True, "book_title": "Foundation"})
print(snap.battery_level, snap.book_title)   # 80 Foundation

# Build and queue commands for the device's next check-in.
queue = CommandQueue()
queue.add(commands.set_frontlight(40))
queue.add(commands.set_frontlight(60))       # idempotent: replaces the previous one
queue.add(commands.show_message("Time to sleep", timeout=10))
print(queue.drain())                         # returns pending commands and clears
```

## API

- `Snapshot` / `Snapshot.from_payload(mapping)` — typed telemetry fields; unknown keys kept in `.extra`.
- `parse_payload(raw)` — validate a decoded body is an object and return a `Snapshot` (raises `ValueError` otherwise).
- `commands` — builders: `set_frontlight`, `set_warmth`, `set_frontlight_power`, `set_wifi`, `page_turn`, `goto_page`, `goto_chapter`, `toggle_bookmark`, `set_dark_mode`, `suspend`, `restart`, `refresh`, `sync_now`, `show_message`; plus type constants and `COALESCE_TYPES`.
- `CommandQueue` — `add(command)`, `drain()`, `pending`, `len()`. Coalesces idempotent types (last-write-wins), caps at `MAX_QUEUED_COMMANDS`.

## License

MIT
