- Python 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| documentation | ||
| src/mobius | ||
| tests | ||
| .gitignore | ||
| CHANGELOG.md | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
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 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/ 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
for what isn't covered yet (dosers, environmental sensors, Thread/CoAP
device relay).
Install
pip install python-mobius
# or, for more robust BLE connection retries (recommended):
pip install python-mobius[retry]
Quick start
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:
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 inMobiusDevice.
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.
Development
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.
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 (JADX) 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 for the
full methodology and confirmation-strength notes on every protocol
detail.