Metadata-Version: 2.5
Name: python-mobius
Version: 0.4.2
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 reverse-engineered Python client for the BLE protocol used by "Mobius
Ready" aquarium equipment — EcoTech Marine (VorTech pumps, Radion lights),
AquaIllumination (Prime, Hydra), Neptune Systems, and NYOS.

Built on [`bleak`](https://github.com/hbldh/bleak) for cross-platform BLE.

**Not affiliated with or endorsed by any of these companies.** This is an
independent reimplementation of the wire protocol for interoperability with
hardware you own, derived from public community reverse-engineering work
and analysis of the publicly-distributed Mobius Android app. See
[`documentation/`](./documentation) for the full protocol writeup, with
every field marked as either directly confirmed or explicitly flagged as
inferred/experimental.

## Status

Alpha. Core protocol (framing, CRC, attribute get/set, scenes), pump
telemetry, pump schedules, light schedules, and device discovery/grouping
are implemented and verified against real hardware (two VorTech MP40QD
pumps, two Radion XR15 G6 Pro lights). See
[`documentation/10-known-gaps-and-open-questions.md`](./documentation/10-known-gaps-and-open-questions.md)
for what isn't covered yet (dosers, environmental sensors, Thread/CoAP
device relay).

## Install

```bash
pip install python-mobius
# or, for more robust BLE connection retries (recommended):
pip install python-mobius[retry]
```

## 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"  {device.address}  {info.model.name}  {info.serial}")

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

asyncio.run(main())
```

Or from the command line:

```bash
mobius-scan --adapter hci0
```

## What you can do

- **Discover devices** and group them by tank/mesh (`pan_id`), reading
  model/serial straight from BLE advertisements — no connection required.
- **Read pump telemetry**: current speed, estimated flow (GPH), operation
  state, error state.
- **Read pump schedules**: which mode (constant speed, tidal swell, pulse,
  etc.) is active at any given time, exactly as programmed.
- **Read light schedules**: per-channel intensity at any given time,
  replicating the app's own client-side interpolation (there's no "current
  intensity" attribute — lights only expose the programmed curve).
- **Control scenes**: start feed mode, resume the normal schedule, or any
  other configured scene.
- **Low-level protocol access** (`build_frame`, `get_attribute`,
  `set_attribute`, ...) if you want to go beyond what's wrapped in
  `MobiusDevice`.

## Supported device types

| PrimitiveType | Support | Notes |
|---|---|---|
| `VisualV1` (Radion, Prime, Hydra, etc.) | ✅ Verified | Lights |
| `VorTechV1`, `PumpV1`, `VectraV1`, `AlpacaV1`, `TurtleV1` | ✅ Verified | Pumps |
| `CoffeeV1` (NYOS Quantum) | ⚠️ Experimental | Same wire structure as pumps per the protocol, untested against real hardware |
| `DoseV1`, `HotSauceV1` | ❌ Unsupported | Different primitive format; identity info only |

`MobiusDevice.get_device_summary()` always tells you which tier applies via
its `"support"` field — see [`documentation/04-device-identity.md`](./documentation/04-device-identity.md).

## Development

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

Tests are validated against real captured packets and real device
manufacturer-data/serials where possible — see `tests/`.

## License

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

## Acknowledgments

The protocol reverse-engineering and implementation in this library were
carried out with substantial assistance from Claude (Anthropic), used to
analyze a decompiled copy of the official Mobius Android app and
cross-reference it against prior public community research (notably the
Reef2Reef "Controlling Mobius enabled VorTech pump using 0-10V and BLE"
thread and the `danmrossi/MobiusControl` project), then to design, write,
and test the Python implementation itself. See
[`documentation/00-overview.md`](./documentation/00-overview.md) for the
full methodology and confirmation-strength notes on every protocol
detail.
