Skip to content

Latest commit

 

History

85 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bentolab

Version License: Apache 2.0 CI Dependabot Updates

Unofficial. This is a community-maintained library. It is not affiliated with, endorsed by, or supported by Bento Bioworks Ltd. See Disclaimer and NOTICE.

Python control library for Bento Lab PCR workstations (Bento Bioworks, London). Communicates over Bluetooth LE using the Nordic UART Service protocol, reverse-engineered from the official Bento Bio app.

Bento Lab Pro V1.4 in use — PCR profile on the display, centrifuge rotor and gel box visible

My Bento Lab Pro V1.4 (unit BL13489) mid-run — the device this library was reverse-engineered against.

Target Devices

Unit Hardware Serial Connectivity Status
1 Pro V1.4 BL13489 Bluetooth LE Primary, fully supported
2 Pro V1.31 BL13125 Wi-Fi Protocol TBD

Setup

# One-command setup (requires uv)
make setup_dev

# Or manually:
uv venv --python 3.13
uv pip install -r requirements.txt
```text

## Library Usage

```python
from bentolab import BentoLabBLE, PCRProfile, ThermalStep, CycleStep

async def main():
    lab = BentoLabBLE()
    await lab.connect()

    # Build a profile from the standard 3-step PCR pattern
    profile = PCRProfile.simple(num_cycles=35)

    # Or compose it explicitly:
    custom = PCRProfile(
        name="HF-Pgl3-EGFP-Puro-linear",
        initial_denaturation=ThermalStep(95.0, 300),
        cycles=[
            CycleStep(
                denaturation=ThermalStep(98.0, 10),
                annealing=ThermalStep(60.0, 30),
                extension=ThermalStep(72.0, 150),
                repeat_count=35,
            )
        ],
        final_extension=ThermalStep(72.0, 300),
        lid_temperature=110.0,
    )

    # Run with live progress updates
    async for state in lab.run_profile(custom):
        print(f"{state.state.value}  block={state.block_temperature}C  "
              f"progress={state.progress}%")
```text

## Command-line interface

`bentolab` ships a Typer CLI that subsumes the one-off scripts in `tools/`.
Profiles live as YAML in the platform user-data directory; runs are recorded
as NDJSON in the same tree (or override with `BENTOLAB_DATA_DIR`).

```bash
bentolab scan                           # discover devices
bentolab status                         # one snapshot
bentolab monitor                        # live tail of status broadcasts
bentolab profile new my-profile         # opens $EDITOR on a YAML template
bentolab profile list
bentolab profile import path/to/x.yaml
bentolab run my-profile                 # uploads + starts + tails until done
bentolab stop                           # abort the current run
bentolab logs list
bentolab logs show <run-id>
```text

Profile YAML:

```yaml
name: HF-Pgl3-EGFP-Puro-linear
lid_temperature: 110
initial_denaturation: { temperature: 95, duration: 300 }
cycles:
  - repeat: 35
    denaturation: { temperature: 98, duration: 10 }
    annealing:    { temperature: 60, duration: 30 }
    extension:    { temperature: 72, duration: 150 }
final_extension:  { temperature: 72, duration: 300 }
hold_temperature: 4
notes: ""
```text

Every subcommand accepts `--json` for machine-readable output. Exit codes:
`0` ok, `2` user error, `3` device error, `4` aborted.

## Tools (low-level / RE debug)

| Tool | Purpose |
|------|---------|
| `tools/ble_scanner.py` | Discover BLE devices, enumerate GATT profiles |
| `tools/ble_monitor.py` | Subscribe to all BLE notifications passively |
| `tools/ble_commander.py` | Interactive BLE command REPL with fuzzing |
| `tools/wifi_scanner.py` | mDNS/nmap discovery for Wi-Fi unit |
| `tools/wifi_monitor.py` | Passive TCP traffic capture |
| `tools/session_logger.py` | Compatibility shim — re-exports `bentolab._logging.SessionLogger` |

For day-to-day operation use the `bentolab` CLI above; the scripts in
`tools/` are kept for protocol-decoding work.

## Quick Start

```bash
# Scan for BLE devices
python tools/ble_scanner.py --scan-time 10

# Connect and enumerate GATT profile
python tools/ble_scanner.py --connect --device-name "Bento"

# Interactive exploration
python tools/ble_commander.py
```text

## Documentation

- [BLE GATT Profile](docs/ble-gatt-profile.md)
- [Protocol Commands](docs/protocol-commands.md)
- [Firmware Analysis](docs/firmware-analysis.md)
- [Wi-Fi Protocol](docs/wifi-protocol.md)

## License

[Apache License 2.0](LICENSE) — see also [NOTICE](NOTICE) for attribution and
the trademark / interoperability disclaimers that ship with every redistribution.

## Disclaimer

Not affiliated with, endorsed by, or sponsored by Bento Bioworks Ltd.
"Bento Lab" is a trademark of Bento Bioworks. Protocol information in this
repository was determined through interoperability analysis of BLE
communication with devices owned by the author, consistent with DMCA §1201(f)
(US) and Article 6 of the EU Software Directive 2009/24/EC.
<!-- branch protection verification Mon Aug  3 05:16:43 AM CEST 2026 -->

About

Python BLE/Wi-Fi control library for Bento Lab PCR workstations — reverse-engineered protocol, async client, FastAPI HTTP wrapper, and Typer CLI.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages