Python Code

First, we're going to import the libraries used by our code to read sensor values, use CircuitPython on our Pi, and read/write to Adafruit IO using the REST client.

Download: file
# Import standard python modules
import time

# import Adafruit Blinka
import board
import busio

# import sensor libraries
import adafruit_sgp30
import adafruit_veml6070
import adafruit_bme280

# import Adafruit IO REST client
from Adafruit_IO import Client, Feed, RequestError

Next, we'll set up our code with our Adafruit IO username and secret key. If you need these values, navigate to your Adafruit IO profile. We'll also create an instance of the REST client with these values.

Download: file
# Set to your Adafruit IO key.
# Remember, your key is a secret,
# so make sure not to publish it when you publish this code!
ADAFRUIT_IO_KEY = 'YOUR_AIO_KEY'

# Set to your Adafruit IO username.
# (go to https://accounts.adafruit.com to find your username)
ADAFRUIT_IO_USERNAME = 'YOUR_AIO_USERNAME'

# Create an instance of the REST client
aio = Client(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)

The code next assigns feeds, or creates and assigns them. Then, we create an I2C busio object and create objects for the VEML6070, BME280, and SGP30 sensors.

Download: file
# Create busio I2C
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000)
# Create VEML6070 object.
uv = adafruit_veml6070.VEML6070(i2c)
# Create BME280 object.
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c)
bme280.sea_level_pressure = 1013.25
# Create SGP30 object using I2C.
sgp30 = adafruit_sgp30.Adafruit_SGP30(i2c)
sgp30.iaq_init()
sgp30.set_iaq_baseline(0x8973, 0x8aae)

in the while True loop, we read data from the SGP30, VEML6070, and the BME280. The VEML6070 samples ten times before arriving at a final data.

Download: file
    # Read SGP30.
    eCO2_data = sgp30.eCO2
    tvoc_data = sgp30.TVOC

    # Read VEML6070, sample ten times.
    for j in range(10):
      uv_data = uv.read

    # Read BME280.
    temp_data = bme280.temperature
    # convert temperature (C->F)
    temp_data = int(temp_data) * 1.8 + 32
    humid_data = bme280.humidity
    pressure_data = bme280.pressure
    alt_data = bme280.altitude

Then, we send our data to Adafruit IO. Since we'll be sending a lot of data to our feeds, we added a pause between sending each sensor's data to its corresponding Adafruit IO Feeds. 

Download: file
 # Send SGP30 Data to Adafruit IO.
    print('eCO2:', eCO2_data)
    aio.send(eCO2_feed.key, eCO2_data)
    print('tvoc:', tvoc_data)
    aio.send(tvoc_feed.key, tvoc_data)
    time.sleep(SENSOR_DELAY)

Finally, we wait for LOOP_DELAY minutes. If you want to report data more quickly or slowly, adjust the LOOP_DELAY variable at the start of the code.

Make sure you have your Adafruit IO Username and Key set up and that your Pi is connected to the internet. Then, enter the following in your terminal to run the code:

python3 environmental_monitor.py

You should see the following output in your terminal:

Download: file
Reading sensors...
sending data to adafruit io...
eCO2: 400
tvoc: 0
UV Level:  3
Temperature: 75.2 C
Humidity: 54.8 %
Pressure: 1008.1 hPa
Altitude = 42.68 meters

Your dashboard should populate with values. Note that it will take the SGP30 at least ten reads before it obtains a baseline measurement. 

Code

"""
'environmental_monitor.py'
===============================================================================
Example of sending I2C sensor data
from multiple sensors to Adafruit IO.

Tutorial Link: https://learn.adafruit.com/adafruit-io-air-quality-monitor

Adafruit invests time and resources providing this open source code.
Please support Adafruit and open source hardware by purchasing
products from Adafruit!

Author(s): Brent Rubell for Adafruit Industries
Copyright (c) 2018 Adafruit Industries
Licensed under the MIT license.
All text above must be included in any redistribution.

Dependencies:
    - Adafruit_Blinka (CircuitPython, on Pi.)
        (https://github.com/adafruit/Adafruit_Blinka)
    - Adafruit_CircuitPython_SGP30.
        (https://github.com/adafruit/Adafruit_CircuitPython_SGP30)
    - Adafruit_CircuitPython_VEML6070.
        (https://github.com/adafruit/Adafruit_CircuitPython_VEML6070)
    - Adafruit_CircuitPython_BME280.
        (https://github.com/adafruit/Adafruit_CircuitPython_BME280)
"""

# Import standard python modules
import time

# import Adafruit Blinka
import board
import busio

# import CircuitPython sensor libraries
import adafruit_sgp30
import adafruit_veml6070
import adafruit_bme280

# import Adafruit IO REST client
from Adafruit_IO import Client, Feed, RequestError

# loop timeout, in seconds.
LOOP_DELAY = 10

# Set to your Adafruit IO key.
# Remember, your key is a secret,
# so make sure not to publish it when you publish this code!
ADAFRUIT_IO_KEY = 'YOUR_AIO_KEY'

# Set to your Adafruit IO username.
# (go to https://accounts.adafruit.com to find your username)
ADAFRUIT_IO_USERNAME = 'YOUR_AIO_USERNAME'

# Create an instance of the REST client
aio = Client(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)

try: # if we already have the feeds, assign them.
    tvoc_feed = aio.feeds('tvoc')
    eCO2_feed = aio.feeds('eco2')
    uv_feed = aio.feeds('uv')
    temperature_feed = aio.feeds('temperature')
    humidity_feed = aio.feeds('humidity')
    pressure_feed = aio.feeds('pressure')
    altitude_feed = aio.feeds('altitude')
except RequestError: # if we don't, create and assign them.
    tvoc_feed = aio.create_feed(Feed(name='tvoc'))
    eCO2_feed = aio.create_feed(Feed(name='eco2'))
    uv_feed = aio.create_feed(Feed(name='uv'))
    temperature_feed = aio.create_feed(Feed(name='temperature'))
    humidity_feed = aio.create_feed(Feed(name='humidity'))
    pressure_feed = aio.create_feed(Feed(name='pressure'))
    altitude_feed = aio.create_feed(Feed(name='altitude'))

# Create busio I2C
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000)
# Create VEML6070 object.
uv = adafruit_veml6070.VEML6070(i2c)
# Create BME280 object.
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c)
bme280.sea_level_pressure = 1013.25
# Create SGP30 object using I2C.
sgp30 = adafruit_sgp30.Adafruit_SGP30(i2c)
sgp30.iaq_init()
sgp30.set_iaq_baseline(0x8973, 0x8aae)

# Sample VEML6070
def sample_VEML():
    for j in range(10):
      uv_raw = uv.read
    return uv_raw

while True:
    print('Reading sensors...')
    # Read SGP30.
    eCO2_data = sgp30.eCO2
    tvoc_data = sgp30.TVOC

    # Read VEML6070.
    uv_data = sample_VEML()

    # Read BME280.
    temp_data = bme280.temperature
    # convert temperature (C->F)
    temp_data = int(temp_data) * 1.8 + 32
    humid_data = bme280.humidity
    pressure_data = bme280.pressure
    alt_data = bme280.altitude

    print('sending data to adafruit io...')
    # Send SGP30 Data to Adafruit IO.
    print('eCO2:', eCO2_data)
    aio.send(eCO2_feed.key, eCO2_data)
    print('tvoc:', tvoc_data)
    aio.send(tvoc_feed.key, tvoc_data)
    time.sleep(2)
    # Send VEML6070 Data to Adafruit IO.
    print('UV Level: ', uv_data)
    aio.send(uv_feed.key, uv_data)
    time.sleep(2)
    # Send BME280 Data to Adafruit IO.
    print('Temperature: %0.1f C' % temp_data)
    aio.send(temperature_feed.key, temp_data)
    print("Humidity: %0.1f %%" % humid_data)
    aio.send(humidity_feed.key, int(humid_data))
    time.sleep(2)
    print("Pressure: %0.1f hPa" % pressure_data)
    aio.send(pressure_feed.key, int(pressure_data))
    print("Altitude = %0.2f meters" % alt_data)
    aio.send(altitude_feed.key, int(alt_data))
    # avoid timeout from adafruit io
    time.sleep(LOOP_DELAY * 60)
This guide was first published on Aug 16, 2018. It was last updated on Aug 16, 2018. This page (Python Code) was last updated on Aug 23, 2019.