Metadata-Version: 2.5
Name: pyosd-audio
Version: 0.2.0
Summary: Python library for controlling OSD Audio devices, starting with the PAM1270 multi-zone amplifier
Project-URL: Homepage, https://gitlab.com/libs6952135/pyosd
Project-URL: Documentation, https://libs6952135.gitlab.io/pyosd/
Project-URL: Repository, https://gitlab.com/libs6952135/pyosd.git
Author-email: mvheimburg <heimburg@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: amplifier,home-automation,multi-zone,osd,osd-audio,pam1270,rs232
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Home Automation
Classifier: Topic :: System :: Hardware
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: pyserial>=3.5
Description-Content-Type: text/markdown

# pyosd

[![docs](https://img.shields.io/badge/docs-gitlab%20pages-blue)](https://libs6952135.gitlab.io/pyosd/)

Control OSD Audio devices from Python. The first supported device is the
**PAM1270** — a 12-channel / 6-zone commercial multi-zone amplifier controlled
over RS232, directly or through an IP-to-serial gateway.

> **Unofficial.** pyosd is an independent project, not affiliated with or endorsed by
> OSD Audio. "OSD Audio" and "PAM1270" are used only to name the hardware it talks to.

```python
from pyosd import PAM1270, InputSource, Volume

with PAM1270.from_serial("/dev/ttyUSB0") as amp:
    amp.zones[3].power = True
    amp.zones[3].input_source = InputSource.LINE
    amp.zones[3].volume = Volume.from_db(-25.0)

    print(amp.zones[3].state)
```

## Install

The package is not on PyPI yet — releases go to this project's private GitLab
package registry. Authenticate with a deploy token (username = the deploy token
username) or a personal access token (username = the token's *name*):

```bash
uv add pyosd-audio --index "https://<user>:<token>@gitlab.com/api/v4/projects/libs6952135%2Fpyosd/packages/pypi/simple"
```

Or pin it in the consuming project's `pyproject.toml` and keep the credentials
in the environment:

```toml
[[tool.uv.index]]
name = "pyosd"
url = "https://gitlab.com/api/v4/projects/libs6952135%2Fpyosd/packages/pypi/simple"
```

```bash
export UV_INDEX_PYOSD_USERNAME=<user> UV_INDEX_PYOSD_PASSWORD=<token>
uv add pyosd-audio
```

From another project's CI, the built-in job token works: username
`gitlab-ci-token`, password `$CI_JOB_TOKEN`.

Fully type annotated and `py.typed`; no stubs needed.

## Why it is shaped this way

- **A domain layer** (`pyosd.domain`) that knows about zones, volumes, tone and
  balance — validated value objects that own the non-linear step-to-decibel
  conversions, with no I/O and no device specifics.
- **A device client** (`pyosd.devices.pam1270`) that presents that model as an
  ergonomic wrapper, encodes the wire protocol in pure functions, and keeps a
  cache fed by the amplifier's unsolicited status broadcasts.
- **Transports** (`pyosd.transport`) for serial, TCP, and an in-memory fake.

Because the amplifier reports changes made by the IR remote and voltage
triggers, the client demultiplexes broadcasts from query answers rather than
assuming the next line answers the last write.

## Testing without hardware

`PAM1270Simulator` implements the protocol as observed on real hardware, so the whole stack runs
in-process:

```python
from pyosd import PAM1270, FakeTransport, PAM1270Simulator

amp = PAM1270(FakeTransport(PAM1270Simulator())).open()
amp.zones[1].volume = 25
assert amp.zones[1].volume.step == 25
```

## Development

```bash
uv sync
uv run pytest
uv run ruff check . && uv run ruff format .
uv run ty check
uv run mkdocs serve
```

## Releasing

Bump `version` in `pyproject.toml` and merge to `main`. CI tags `v<version>` for you, publishes the
build to this project's GitLab package registry, and cuts a GitLab release. Publishing to
TestPyPI/PyPI is wired up but stays manual until the package goes public.

## Documentation

<https://libs6952135.gitlab.io/pyosd/> — usage guide, the full PAM1270 RS232
protocol reference, and the API reference.

## License

MIT — see [LICENSE](LICENSE).
