Metadata-Version: 2.5
Name: python-mobius
Version: 0.10.0
Summary: Reverse-engineered Python client for the Mobius BLE protocol (EcoTech Marine VorTech/Radion, AquaIllumination, Neptune Systems, NYOS)
Project-URL: Homepage, https://code.r3pek.org/r3pek/python-mobius
Project-URL: Documentation, https://code.r3pek.org/r3pek/python-mobius/src/branch/main/documentation
Project-URL: Issues, https://code.r3pek.org/r3pek/python-mobius/issues
Author: r3pek
License: GPL-2.0-only
License-File: LICENSE
Keywords: aquarium,ble,bleak,bluetooth,ecotech,fsci,mobius,radion,reef,vortech
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Home Automation
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Hardware
Requires-Python: >=3.9
Requires-Dist: bleak>=0.21
Provides-Extra: dev
Requires-Dist: bleak-retry-connector>=3.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Provides-Extra: retry
Requires-Dist: bleak-retry-connector>=3.0; extra == 'retry'
Description-Content-Type: text/markdown

# python-mobius

A Python client for the Bluetooth protocol of "Mobius" aquarium devices:
EcoTech Marine (VorTech and Vectra pumps, Radion lights),
AquaIllumination (Prime, Hydra, Orbit, Axis), Neptune Systems and NYOS.
Built on [`bleak`](https://github.com/hbldh/bleak).

**Not affiliated with or endorsed by any of these companies.** This is an
independent implementation of the protocol for interoperability with
hardware you own, based on reverse engineering of the Mobius app and
public community research. The protocol is documented in
[`documentation/`](./documentation/00-overview.md), in enough detail to
implement it in another language.

## Features

- **Discovery without connecting**: model, serial number and tank (pan_id)
  from BLE advertisements.
- **Lights**: channels, schedules, and the current intensity computed the
  way the app does it (schedule intensity, lunar phases, acclimation,
  hyperdrive).
- **Pumps**: speed, flow, motor power and other sensor values; schedules
  and the active mode; battery backup settings and whether the pump runs
  on battery.
- **Schedules**: read and write, as editable JSON or as the app's `.mob`
  template files; light schedule groups are handled.
- **Scenes**: list, start (whole tank) and cancel.
- **Settings and commands**: advanced features (Local Control, LED auto
  dim, fan speed, fan shutdown), lunar phases, schedule intensity, time
  sync, reboot, restart all.
- **One connection per tank**: every other device of the tank is reached
  through it over the Thread mesh (`RelayedMobiusDevice`).
- **Batched polling**: everything a poll needs in one request.
- **Diagnostics**: attribute dumps, firmware and hardware information,
  Thread and clock diagnostics.
- **`mobius-scan`** command line tool.

## Supported devices

| PrimitiveType | Devices | Support |
|---|---|---|
| `VisualV1` | Radion, Prime, Hydra | Tested |
| `VorTechV1`, `TurtleV1` | VorTech, Axis | Tested |
| `PumpV1`, `VectraV1`, `AlpacaV1` | Nero, Vectra, Orbit | Same format as the tested pumps; not tested |
| `CoffeeV1` | NYOS Quantum | Experimental: decoded with the pump format, not tested |
| `DoseV1`, `HotSauceV1` | Dosers, sensors | Identity only |

See [known gaps](./documentation/10-known-gaps-and-open-questions.md) for
what isn't covered or tested.

## Install

```bash
pip install python-mobius
# recommended: more reliable connections
pip install "python-mobius[retry]"
```

Python 3.9 or newer.

## Quick start

```python
import asyncio
from mobius import scan_for_mobius_devices_with_info, group_by_pan_id, MobiusDevice

async def main():
    found = await scan_for_mobius_devices_with_info()
    for pan_id, members in group_by_pan_id(found).items():
        print(f"tank {pan_id:#06x}:")
        for device, info in members:
            print(f"  {info.serial}  {info.model.name if info.model else info.model_raw}")

    device, info = found[0]
    async with MobiusDevice(device, serial=info.serial) as d:
        print(await d.get_device_summary())

asyncio.run(main())
```

Reaching the rest of the tank through one connection:

```python
from mobius import RelayedMobiusDevice

async with MobiusDevice(serial="00000000000002") as gateway:
    for peer in await gateway.discover_mesh_peers_auto():
        print(await RelayedMobiusDevice(gateway, peer).get_device_info())
```

Command line:

```bash
mobius-scan                                  # list devices by tank
mobius-scan --by-serial SERIAL --dump-schedule
mobius-scan --by-serial SERIAL --relay-target OTHER_SERIAL
mobius-scan --help
```

The full API and every CLI option are described in
[documentation/16-python-library.md](./documentation/16-python-library.md).

## Development

```bash
git clone https://code.r3pek.org/r3pek/python-mobius
cd python-mobius
pip install -e ".[dev]"
pytest
```

Tests use captured packets and advertisements from real devices where
possible.

## Related

[ha-mobius](https://code.r3pek.org/r3pek/ha-mobius) is a Home Assistant
integration built on this library.

## License

GPLv2, see [`LICENSE`](./LICENSE).

## Acknowledgments

The Reef2Reef thread "Controlling Mobius enabled VorTech pump using 0-10V
and BLE" and the `danmrossi/MobiusControl` project, whose work this
builds on. The reverse engineering and implementation were done with
substantial help from Claude (Anthropic).
