Skip to main content

Storz & Bickel BLE Python Library

A Python library for controlling Storz & Bickel vaporizers (Volcano Hybrid, Venty/Veazy, and Crafty/Crafty+) via Bluetooth Low Energy (BLE).

Features

  • Device Support: Volcano Hybrid, Venty, Veazy (qvap path), and Crafty/Crafty+
  • Async/Await: Built with modern Python async/await patterns
  • Type Safe: Full type hints and Pydantic models for data validation
  • Home Assistant Ready: Follows Home Assistant best practices
  • Controls: temperature/heater/pump, boost/superboost, and a full settings surface — brightness, auto-off, vibration, ECO charging, display-on-cooling, Venty heater mode, and the Crafty charge-LED & permanent-Bluetooth toggles
  • Diagnostics: local run_analysis() returning a structured report — status, detected error flags, and raw registers (no cloud upload)
  • Workflows: Volcano presets (balloon, flow1flow3) and custom run_workflow(steps) timed heat+pump sequences

Installation

Using pip

pip install storzandbickel-ble

Using uv

uv pip install storzandbickel-ble

Quick Start

Basic Usage

import asyncio
from storzandbickel_ble import StorzBickelClient


async def main():
    # Create client
    client = StorzBickelClient()

    # Scan for devices
    devices = await client.scan(timeout=10.0)
    print(f"Found {len(devices)} devices")

    # Connect to first device
    if devices:
        device = await client.connect_device(devices[0])

        # Set target temperature
        await device.set_target_temperature(185.0)

        # Turn heater on
        await device.turn_heater_on()

        # Read current state
        print(f"Current temperature: {device.state.current_temperature}°C")
        print(f"Target temperature: {device.state.target_temperature}°C")

        # Disconnect
        await device.disconnect()


asyncio.run(main())

Home Assistant-Oriented Quickstart

The library patterns map cleanly to HA coordinator/entity flows:

  • discover/connect once
  • keep notifications enabled as the primary state path
  • call update_state() for startup reconciliation or recovery
  • use explicit exceptions and availability_transition_count for clean availability handling

Device-Specific Examples

Crafty/Crafty+

import asyncio
from storzandbickel_ble import StorzBickelClient
from storzandbickel_ble.models import DeviceType


async def main():
    client = StorzBickelClient()

    # Scan for Crafty devices
    devices = await client.scan(timeout=10.0, device_type=DeviceType.CRAFTY)

    if devices:
        # Connect to first Crafty device
        crafty = await client.connect_device(devices[0])

        # Update state to get current values
        await crafty.update_state()

        # Check temperatures
        print(f"Current temperature: {crafty.state.current_temperature}°C")
        print(f"Target temperature: {crafty.state.target_temperature}°C")

        # Set target temperature
        await crafty.set_target_temperature(185.0)
        print(f"Set target temperature to 185°C")

        # Verify the change
        await crafty.update_state()
        print(f"New target temperature: {crafty.state.target_temperature}°C")

        await crafty.disconnect()


asyncio.run(main())

For additional per-device examples (Venty, Veazy, Volcano), see docs/usage.rst.

Workflow and Analysis APIs

import asyncio
from storzandbickel_ble import StorzBickelClient


async def main():
    client = StorzBickelClient()
    volcano = await client.connect_by_name("S&B VOLCANO")

    # Volcano workflow presets: balloon, flow1, flow2, flow3
    await volcano.run_workflow_preset("flow1")

    # ...or a custom workflow: a list of (target_temp, hold_seconds, pump_seconds)
    await volcano.run_workflow(
        [
            (185.0, 10.0, 8.0),
            (200.0, 0.0, 12.0),
        ]
    )

    # Local diagnostics report (no cloud upload)
    report = await volcano.run_analysis()
    print(report["ok"], report["warnings"], report["errors"])
    print(report["findings"])  # which error-mask bits are set, per register
    print(report["diagnostics"])  # raw registers / history, as hex

    await volcano.disconnect()


asyncio.run(main())

Per-bit error meanings are decoded on Storz & Bickel's servers, not in the client, so findings reports which error bits are set; only locally-known cases (e.g. the Crafty akku charger/cable error) carry a meaning. The Venty/Veazy detailed analysis is a cloud-only blob, so their report returns the decoded settings/state plus a note rather than a full report.

Device Support Matrix

Device Temperature Heater Battery Pump Boost/Superboost Vibration Brightness Workflow Presets Local Analysis
Volcano Hybrid
Venty
Veazy
Crafty/Crafty+

Supported Functions by Family

Function Volcano Venty Veazy Crafty
Discovery and connect
Real-time notification state
Temperature target control
Heater control
Pump control
Brightness and vibration settings
Boost / superboost (offsets / modes)
Heater mode (normal/boost/superboost)
ECO charging (optimization / limit)
Display-on-cooling / vibration-on-ready
Charge-LED / permanent-Bluetooth
Find device
Charging / setpoint-reached state ✅*
Local diagnostics (run_analysis)
Workflow presets
Custom workflows (run_workflow)

*Crafty exposes setpoint_reached but not a charging bit (it signals charging via its LED only).

Data Update Model

  • Notification-driven updates are enabled on connect for supported characteristics.
  • update_state() performs explicit reads/commands and is useful for an immediate refresh.
  • Home Assistant integrations can treat notifications as the primary state stream and call update_state() for recovery or reconciliation.

Concurrency and Command Semantics

  • Device-level BLE I/O is serialized internally to avoid overlapping reads/writes.
  • Commands that require responses (for example, qvap command exchange) raise CommandTimeoutError when the response does not arrive in time.
  • availability_transition_count tracks connect/disconnect transitions to help downstream integrations avoid noisy up/down logging.

Diagnostics Snapshot API

Each device exposes a sanitized diagnostics payload via:

snapshot = device.get_diagnostics_snapshot()

Snapshot payloads intentionally omit serial numbers from state to reduce sensitive data exposure in logs and diagnostics exports.

Known Limitations

  • Firmware update workflows are not implemented in this library.
  • Vendor cloud upload paths are intentionally out of scope.
  • Detailed device-error decoding is server-side at Storz & Bickel: run_analysis() reports which error bits are set plus raw registers, not the per-bit cause. The Venty/Veazy analysis blob is cloud-only.
  • The Venty/Veazy boost timeout is a fixed 90 s on/off setting (set_boost_timeout_disabled), not a configurable duration.
  • BLE behavior can vary by adapter, OS, and stack implementation.

Troubleshooting

  • Ensure your BLE adapter is enabled and supports Bluetooth Low Energy.
  • If a device is not discovered, retry scanning and confirm it is advertising.
  • For flaky connections, disconnect and reconnect before issuing control commands.
  • If command operations timeout, retry with a higher timeout and reduced command burst frequency.
  • Use get_diagnostics_snapshot() when reporting issues to provide a sanitized runtime context.

Documentation

Full documentation is available at Read the Docs.

Requirements

  • Python 3.14+
  • Bluetooth adapter with BLE support
  • Linux, macOS, or Windows

Dependencies

  • bleak>=0.21.0 - BLE communication
  • pydantic>=2.0.0 - Data validation

Development

Setup

# Clone repository
git clone https://github.com/yourusername/storzandbickel-ble.git
cd storzandbickel-ble

# Install with uv
uv pip install -e ".[dev]"

# Or with pip
pip install -e ".[dev]"

Running Tests

uv run pytest

Linting

uv run ruff check .
uv run ruff format .

Type Checking

uv run mypy src

Docker

Build

docker build -t storzandbickel-ble .

Run

docker run --rm storzandbickel-ble

Development

docker-compose up dev

License

MIT License - see LICENSE file for details

Disclaimer

This library is based on reverse engineering and is not officially supported by Storz & Bickel. Use at your own risk. The authors are not responsible for any damage to devices.

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

References

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

storzandbickel_ble-0.1.21.tar.gz (118.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

storzandbickel_ble-0.1.21-py3-none-any.whl (37.8 kB view details)

Uploaded Python 3

File details

Details for the file storzandbickel_ble-0.1.21.tar.gz.

File metadata

  • Download URL: storzandbickel_ble-0.1.21.tar.gz
  • Upload date:
  • Size: 118.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.2

File hashes

Hashes for storzandbickel_ble-0.1.21.tar.gz
Algorithm Hash digest
SHA256 caa48b7c8447b06a388b2c1eb5c798124841d713eb4638793d1fc00410eaac7e
MD5 73efe96860ce9aee9bb82b0141b3db6e
BLAKE2b-256 00928be1602da76884a0cb2374fd733139e99c5a61186dc8db32a307ae1a4e15

See more details on using hashes here.

File details

Details for the file storzandbickel_ble-0.1.21-py3-none-any.whl.

File metadata

File hashes

Hashes for storzandbickel_ble-0.1.21-py3-none-any.whl
Algorithm Hash digest
SHA256 4288454069e6b5e2471da5c04d545288ce5342b0d4e4229c835738d6e9a2d847
MD5 031d1de924b22b0e7f3d220641118bfe
BLAKE2b-256 46283f2d99a2cee47dc0e161a98ca4280a800b0253d5ee6cb919094bd236ee85

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.21 This release

2 files

0.1.20

2 files

0.1.19

2 files

0.1.18

2 files

0.1.17

2 files

0.1.16

2 files

0.1.15

2 files

0.1.14

2 files

0.1.13

2 files

0.1.12

2 files

0.1.11

2 files

0.1.10

2 files

0.1.9

2 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page