Metadata-Version: 2.4
Name: broute-j11
Version: 0.1.0
Summary: Python library for RATOC RS-WSUHA-J11 B-route smart meter adapters
Author: jethac
License-Expression: MIT
Project-URL: Homepage, https://github.com/jethac/broute-j11
Project-URL: Repository, https://github.com/jethac/broute-j11
Project-URL: Issues, https://github.com/jethac/broute-j11/issues
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyserial>=3.5
Provides-Extra: dev
Requires-Dist: build>=1.2.2; extra == "dev"
Requires-Dist: mypy>=1.17; extra == "dev"
Requires-Dist: PyYAML>=6.0.2; extra == "dev"
Requires-Dist: pytest>=8.4; extra == "dev"
Requires-Dist: pytest-asyncio>=0.26; extra == "dev"
Requires-Dist: pytest-cov>=6.2; extra == "dev"
Requires-Dist: ruff>=0.12; extra == "dev"
Requires-Dist: twine>=6.1; extra == "dev"
Requires-Dist: types-PyYAML>=6.0.12; extra == "dev"
Requires-Dist: types-pyserial>=3.5; extra == "dev"
Dynamic: license-file

# broute-j11

`broute-j11` is an MIT-licensed Python library for communicating with Japanese
B-route smart electricity meters through binary-UART J11 adapters. It is
intended to provide reusable framing, command, ECHONET Lite, serial transport,
and asynchronous session layers without depending on Home Assistant.

Version 0.1.0 provides the binary framing, command, ECHONET Lite, serial
transport, and self-healing asynchronous session layers.

## Quick start

Load credentials from a secret store or the environment and pass them to a
session. No I/O happens until the session is connected.

```python
import asyncio
import os

from broute_j11 import J11Session, SerialTransport, SessionConfig


async def main() -> None:
    transport = SerialTransport("/dev/ttyUSB0")
    config = SessionConfig(
        auth_id=os.environ["BROUTE_AUTH_ID"],
        password=os.environ["BROUTE_PASSWORD"],
    )

    async with J11Session(transport, config) as session:
        reading = await session.async_read_meter()
        print(reading.instantaneous_power)


if __name__ == "__main__":
    asyncio.run(main())
```

The package-level API also exposes network-cache, link/profile, statistics,
backoff, transport, and documented exception types. Lower-level framing,
command, and ECHONET helpers remain available from their respective modules.

The exception hierarchy is:

```text
Exception
├── ProtocolError
│   ├── FrameFormatError / ChecksumError
│   ├── CredentialFormatError / CommandFailedError
│   ├── EchonetFrameError
│   └── SessionError
│       ├── SessionClosedError / SessionTimeoutError
│       └── AuthenticationError / MeterNotFoundError / TransmissionError
└── TransportError
```

## Supported hardware

Initial protocol support is deliberately scoped to:

- RATOC Systems RS-WSUHA-J11;
- ROHM BP35C2-J11-T01; and
- other BP35C0-J11-based adapters after their USB and UART behavior is
  verified.

The similarly named RATOC RS-WSUHA-P and ROHM BP35C2 use a text-based `SK...`
command protocol and are not supported. J11 adapters use ROHM's binary UART
protocol.

## Safety and security

B-route authentication IDs and passwords are secrets. Never include real
credentials, meter identifiers, MAC addresses, PAN IDs, USB serial numbers,
captured frames, or unredacted diagnostics in source, tests, logs, exceptions,
or bug reports. Use synthetic values in fixtures and load credentials from a
secret store or the process environment at runtime.

This project communicates with a utility meter through a consumer USB radio
adapter. It does not require, authorize, or provide instructions for opening a
meter or modifying mains wiring. Do not treat readings or connection status as
an electrical-safety alarm. Installation, electrical work, and utility-meter
service must be handled by qualified parties under the rules for your location.

## Home Assistant relationship

This repository is the framework-independent protocol package. It deliberately
has no Home Assistant dependency and does not itself install a Home Assistant
integration. The package is being extracted from the separately maintained
`home-assistant-broute-j11` custom integration and is intended to support that
integration and a focused extension to Home Assistant Core's existing
`route_b_smart_meter` integration.

Home Assistant entities, config flows, diagnostics, and coordinator behavior
belong in those integration repositories rather than this package.

## Development

Python 3.11, 3.12, 3.13, and 3.14 are supported. Create and activate a virtual
environment, then install the development dependencies:

```console
python -m venv .venv
python -m pip install -e ".[dev]"
```

Run the same checks used by CI:

```console
ruff format --check .
ruff check .
mypy src scripts tests
pytest -q --cov=broute_j11 --cov-branch --cov-report=term-missing
python -m build
python -m twine check --strict dist/*
python scripts/inspect_distribution.py dist/*.whl dist/*.tar.gz
```

Tests that need protocol traffic must use synthetic frames. Hardware checks are
opt-in and must never print or persist credentials.

## License

This project is available under the [MIT License](LICENSE).
