Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
.gitignore Initial commit Jan 7, 2017
CO2Meter.py fixed many pylint warnings Apr 9, 2017
LICENSE Initial commit Jan 7, 2017
README.md fixed typo in readme Apr 9, 2017
example.py added example script Jan 10, 2017
setup.py bump version to 2.1 Apr 10, 2017



Python Module to use co2meters like the 'AirCO2ntrol Mini' from TFA Dostmann with USB ID 04d9:a052. There are also other modules using the same interface.

This module supports Python 2.7 and 3.x.


Reverse Engineering of the protocol and initial code done by Henryk Plötz.

Read all about it at hackaday

Code derived from this article


With pip:

pip install git+https://github.com/heinemml/CO2Meter

Without pip:

python setup.py install

Remark: you don't need to install, you can also just copy the CO2Meter.py into your project.

If you don't want to run your script as root make sure you have sufficient rights to access the device file.

This udev rule can be used to set permissions.

ACTION=="remove", GOTO="co2mini_end"

SUBSYSTEMS=="usb", KERNEL=="hidraw*", ATTRS{idVendor}=="04d9", ATTRS{idProduct}=="a052", GROUP="plugdev", MODE="0660", SYMLINK+="co2mini%n", GOTO="co2mini_end"


save it as /etc/udev/rules.d/90-co2mini.rules and add the script user to the group plugdev.

This rules make the device also available as co2mini0 (increase trailing number for each additional device).


from CO2Meter import *
import time
sensor = CO2Meter("/dev/hidraw0")
while True:

The device writes out one value at a time. So we need to parse some data until we have co2 and temperature. Thus the get_data() method will initially return none or only on value (whichever comes first). When you just need one measurement you should wait some seconds or iterate until you get a full reading. If you just need co2 a call to get_co2 might speed things up.


You can pass a callback to the constructor. It will be called when any of the values is updated. The parameters passed are sensor and value. sensor contains one of these constants:

CO2METER_CO2 = 0x50

Error handling

In Case the device can't be read anymore (e.g. it was unplugged) the worker thread will end in the background. Afterwards calls to any of the get_* functions will throw an IOError. You will need to handle any resetup, making sure that the device is there etc yourself.