Python driver for Senseair Sunrise, Sunlight and S12 CO2 sensors (I2C and Modbus RTU)
Project description
senseair-sunrise
Python driver for Senseair Sunrise / Sunlight and S12 CO2 sensors over I2C and Modbus RTU (UART), on Linux (incl. Raspberry Pi), Windows and macOS.
A Pythonic port of the Senseair Arduino library.
| Sensor | I2C class | Modbus class |
|---|---|---|
| Sunrise / Sunlight | SunriseI2C |
SunriseModbus |
| S12 | S12I2C |
S12Modbus |
All four share the measurement / configuration / calibration API inherited from SunriseBase.
Methods raise a SunriseError subclass on failure and return dataclasses. A successful
read_measurement() still requires checking Measurement.error_status against the ErrorStatus
flags to confirm the reading is valid.
Installation
pip install senseair-sunrise # core (Modbus RTU works everywhere)
pip install "senseair-sunrise[rpi]" # + smbus2/gpiozero for Raspberry Pi native I2C/GPIO
pip install "senseair-sunrise[ftdi]" # + pyftdi for an FT232H/FT2232H USB-I2C bridge
To install from a local checkout of this repository (e.g. before it is published), use a path instead of the package name — the same extras apply:
pip install -e . # editable install from a clone of this repo
pip install -e ".[rpi]" # editable + Raspberry Pi I2C/GPIO extras
pip install /path/to/python-sunrise # non-editable, from a local path
Modbus RTU needs only pyserial. I2C and the EN/nRDY pins go through pluggable backends, so the
same sensor classes run on a Raspberry Pi or, via an FTDI USB bridge, on Windows/macOS.
On a Raspberry Pi, the EN/nRDY pins can be driven through two interchangeable backends (both
implement the Pin protocol):
-
GpiodPin(libgpiod) — the install-friendly default forexamples/rpi_pins.py. It talks to the kernel's GPIO character device directly, with no separate pin factory to install:sudo apt install python3-libgpiod # prebuilt, no compiler python examples/rpi_pins.py --gpio-backend gpiod --en-pin 17 --nrdy-pin 27
GpiodPinworks with both libgpiod v1 (Raspberry Pi OS Bookworm's apt package) and v2. Pins are integer BCM line offsets on agpiochip; on a Raspberry Pi 5 the 40-pin header may live on a chip other than/dev/gpiochip0, so pass--gpiochipif line requests fail. -
GpiozeroPin(gpiozero) — also needs a separate pin-factory backend. Installlgpiofrom apt, which ships a prebuilt module:sudo apt install python3-lgpio
Prefer apt over
pip install lgpio: the PyPI source build needsswigand a C toolchain, and prebuilt wheels are not always available for newer Python versions. Without any backend,gpiozerofalls back to its experimental sysfs pin factory, which fails on current kernels. (To see an apt-installed module from a virtualenv, create it with--system-site-packages.)
Usage
Continuous mode over Modbus RTU:
import time
from senseair_sunrise import SunriseModbus, describe_error_status
sensor = SunriseModbus("/dev/ttyUSB0") # default address 0x68
sensor.enable()
while True:
meas = sensor.read_measurement()
print(f"{meas.co2_ppm} ppm {meas.temperature_c:.2f} C")
for flag in describe_error_status(meas.error_status):
print(" -", flag)
time.sleep(16)
Over I2C on a Raspberry Pi (or an FTDI USB bridge on Windows/macOS):
from senseair_sunrise import SunriseI2C, SMBus2Bus # FtdiI2CBus for an FTDI bridge
sensor = SunriseI2C(SMBus2Bus(1)) # /dev/i2c-1
sensor.enable()
print(sensor.read_measurement().co2_ppm)
Driving the enable / nRDY pins (recommended for single mode) uses the pluggable Pin backends
(GpiozeroPin, FtdiPin), passed as enable_pin= / nrdy_pin=. Over an FTDI bridge, get the GPIO
controller from the bus with FtdiI2CBus.get_gpio() and wrap individual bits in FtdiPin.
I2C bus speed and latency
The sensors support an I2C clock of up to 100 kHz (constants.I2C_CLOCK_HZ; the S12 also
supports 400 kHz Fast Mode, but this library targets 100 kHz). The two backends configure the bus
differently:
FtdiI2CBus(url, frequency=...)defaults to a conservative 20 kHz due to the FTDI MPSSE engine limitations, the actual bitrate for write operations over I2C is very slow (see pyftdi for details). The FTDI latency timer is set toSUNRISE_I2C_IDLE_TIMEOUT_MS // 3(~5 ms) so the host services the bus before the sensor sleeps after 15 ms of idle.SMBus2Busruns at whatever clock the kernel/OS configures (e.g.dtparam=i2c_arm_baudrate=in/boot/config.txton a Raspberry Pi). It cannot be set or read from Python, so make sure the OS configures it at or below 100 kHz.
Examples
Runnable scripts live in examples/ — sunrise_continuous.py, sunrise_single.py,
sunrise_change_address.py, sunrise_scale_factor.py, s12_continuous.py, s12_single.py, and
calibrate.py. Each takes --protocol modbus|i2c plus --port / --bus / --ftdi; the
continuous/single scripts also expose --set-continuous / --set-single, --samples and
--period for measurement settings. Two more cover I2C wiring setups: multi_sensor.py reads
several sensors sharing one bus (distinct addresses), ftdi_pins.py drives the EN/nRDY pins
through an FTDI bridge's GPIO, and rpi_pins.py does the same from a Raspberry Pi's native GPIO
and I2C port (--gpio-backend gpiozero or gpiod). Run any script with --help for details.
Development
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
pytest # hardware-free unit tests
ruff check .
mypy src
License
BSD-3-Clause. See LICENSE.
Project details
Release history Release notifications | RSS feed
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 senseair_sunrise-0.1.0.tar.gz.
File metadata
- Download URL: senseair_sunrise-0.1.0.tar.gz
- Upload date:
- Size: 36.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce82ded014e8b1b35315f113d7beb38c4270cf7315929157394983f9c0254808
|
|
| MD5 |
ef5ed7157199f3810e37f9f116bca2c2
|
|
| BLAKE2b-256 |
0fe1517c2647a34700185b86dbf2584a92d6484496ae2e809cd647069cbf5103
|
File details
Details for the file senseair_sunrise-0.1.0-py3-none-any.whl.
File metadata
- Download URL: senseair_sunrise-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77878b765d2e98e0510c40225c88382df5a6e8dd0cbfdb81d7c914a50712a750
|
|
| MD5 |
e7ec160e84a9455516f96473e1ac275a
|
|
| BLAKE2b-256 |
84308af632c3fcc0d15983a4e1385f6c8a59b29d47355701788c79d63344ca9e
|