Python library for controlling Storz & Bickel devices via Bluetooth Low Energy (BLE)
Project description
Storz & Bickel BLE Python Library
A Python library for controlling Storz & Bickel vaporizers (Volcano Hybrid, Venty, and Crafty/Crafty+) via Bluetooth Low Energy (BLE).
Features
- Full Device Support: Control Volcano Hybrid, Venty, and Crafty/Crafty+ devices
- 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
- Comprehensive: Supports all device features including temperature control, status monitoring, and configuration
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())
Testing with Real Device
To test with a real Crafty+ device, use the example script:
uv run python examples/test_crafty.py
This will:
- Scan for your device
- Connect automatically
- Display current state
- Test various controls
- Monitor temperature updates in real-time
See examples/README.md for more details.
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())
Venty
import asyncio
from storzandbickel_ble import StorzBickelClient
from storzandbickel_ble.models import DeviceType
async def main():
client = StorzBickelClient()
# Scan for Venty devices
devices = await client.scan(timeout=10.0, device_type=DeviceType.VENTY)
if devices:
# Connect to first Venty device
venty = await client.connect_device(devices[0])
# Update state to get current values
await venty.update_state()
# Check temperatures
print(f"Current temperature: {venty.state.current_temperature}°C")
print(f"Target temperature: {venty.state.target_temperature}°C")
# Set target temperature
await venty.set_target_temperature(190.0)
print(f"Set target temperature to 190°C")
# Verify the change
await venty.update_state()
print(f"New target temperature: {venty.state.target_temperature}°C")
await venty.disconnect()
asyncio.run(main())
Volcano Hybrid
import asyncio
from storzandbickel_ble import StorzBickelClient
from storzandbickel_ble.models import DeviceType
async def main():
client = StorzBickelClient()
# Scan for Volcano devices
devices = await client.scan(timeout=10.0, device_type=DeviceType.VOLCANO)
if devices:
# Connect to first Volcano device
volcano = await client.connect_device(devices[0])
# Update state to get current values
await volcano.update_state()
# Check temperatures
print(f"Current temperature: {volcano.state.current_temperature}°C")
print(f"Target temperature: {volcano.state.target_temperature}°C")
# Set target temperature
await volcano.set_target_temperature(200.0)
print(f"Set target temperature to 200°C")
# Verify the change
await volcano.update_state()
print(f"New target temperature: {volcano.state.target_temperature}°C")
await volcano.disconnect()
asyncio.run(main())
Device Support Matrix
| Device | Temperature Control | Heater Control | Battery | Air Pump | Boost Mode | Vibration |
|---|---|---|---|---|---|---|
| Volcano Hybrid | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ |
| Venty | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ |
| Crafty/Crafty+ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
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 communicationpydantic>=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
pytest
Linting
ruff check .
ruff format .
Type Checking
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
- Protocol documentation: See
s&b_procol.md - BLE GATT specification: https://www.bluetooth.com/specifications/specs/core-specification/
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file storzandbickel_ble-0.1.2.tar.gz.
File metadata
- Download URL: storzandbickel_ble-0.1.2.tar.gz
- Upload date:
- Size: 117.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3de01935b03cd174f82684a3ad5308246a661d7dabb038140ff080c901e90c48
|
|
| MD5 |
062f6fc49f8f6675591855324c11f899
|
|
| BLAKE2b-256 |
eb188f3e2a702986be5af451e3e31184d58fc412df709d9e4e93125ce0745907
|
File details
Details for the file storzandbickel_ble-0.1.2-py3-none-any.whl.
File metadata
- Download URL: storzandbickel_ble-0.1.2-py3-none-any.whl
- Upload date:
- Size: 28.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59db8ab09ad5dbb17d43874b3cb211bc1e3a22f1916d222e4be8772b4719f869
|
|
| MD5 |
e1961b8c20dcd23d72c243b03e46cb43
|
|
| BLAKE2b-256 |
8094bbeee516dea47d9508a89ab8e2e1b89f3306f60fbf858842c4c2c2c75f54
|