This commit is contained in:
commit
3c7e72f12c
1 changed files with 324 additions and 0 deletions
324
gistfile1.txt
Normal file
324
gistfile1.txt
Normal file
|
|
@ -0,0 +1,324 @@
|
||||||
|
#
|
||||||
|
# based on three things:
|
||||||
|
# 1 - CCS811_RPi class usage example
|
||||||
|
# by Petr Lukas V1
|
||||||
|
# 2 - I2C_LCD_driver
|
||||||
|
# Compiled, mashed and generally mutilated 2014-2015 by Denis Pleic
|
||||||
|
# 3 - BME680
|
||||||
|
# Pimoroni Library, installed via pip https://shop.pimoroni.com/products/bme680
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
import requests
|
||||||
|
import time
|
||||||
|
import uuid
|
||||||
|
import bme680
|
||||||
|
from CCS811_RPi import CCS811_RPi
|
||||||
|
import I2C_LCD_driver
|
||||||
|
import paho.mqtt.client as paho
|
||||||
|
|
||||||
|
broker="cosmicpidata.mooo.com"
|
||||||
|
port=1883
|
||||||
|
mqtt_ok=0
|
||||||
|
|
||||||
|
url = "http://www.google.com"
|
||||||
|
timeout = 600
|
||||||
|
|
||||||
|
|
||||||
|
def on_publish(client,userdata,result):
|
||||||
|
print("Data published to MQTT server")
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_connect(client,userdata,flags,rc):
|
||||||
|
if rc==0:
|
||||||
|
print("connected ok")
|
||||||
|
else:
|
||||||
|
print("mqtt connection failed")
|
||||||
|
|
||||||
|
def on_disconnect(client,userdata,rc):
|
||||||
|
print("disconnecting reason " + str(rc))
|
||||||
|
|
||||||
|
mqttidentstring = str(uuid.getnode())
|
||||||
|
client1= paho.Client(mqttidentstring)
|
||||||
|
client1.on_publish = on_publish
|
||||||
|
client1.username_pw_set(username="cosmicpi",password="MuonsFROMSp8ce")
|
||||||
|
client1.on_connect=on_connect #binding call
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
request = requests.get(url,timeout=timeout)
|
||||||
|
print("internet ok")
|
||||||
|
mqtt_ok=1
|
||||||
|
except (requests.ConnectionError, requests.Timeout) as exception:
|
||||||
|
print("internet fail")
|
||||||
|
mqtt_ok=0
|
||||||
|
|
||||||
|
|
||||||
|
mylcd = I2C_LCD_driver.lcd()
|
||||||
|
mylcd.lcd_display_string("Warming up...", 1)
|
||||||
|
#import urllib2 # comment this line if you don't need ThinkSpeak connection
|
||||||
|
#import SDL_Pi_HDC1000 # comment this line if you don't use HDC sensor
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY)
|
||||||
|
except IOError:
|
||||||
|
sensor = bme680.BME680(bme680.I2C_ADDR_SECONDARY)
|
||||||
|
|
||||||
|
now = datetime.now() # current date and time
|
||||||
|
date_time = now.strftime("%m/%d/%Y")
|
||||||
|
date1=(date_time)
|
||||||
|
date_time = now.strftime("%H:%M")
|
||||||
|
date2=(date_time)
|
||||||
|
mylcd.lcd_display_string("Date: "+date1,1)
|
||||||
|
mylcd.lcd_display_string("Time: "+date2,2)
|
||||||
|
|
||||||
|
time.sleep(5)
|
||||||
|
ccs811 = CCS811_RPi()
|
||||||
|
|
||||||
|
# Do you want to preset sensor baseline? If yes set the value here, otherwise set False
|
||||||
|
INITIALBASELINE = False
|
||||||
|
# Do you want to use integrated temperature meter to compensate temp/RH (CJMCU-8118 board)?
|
||||||
|
# If not pre-set sensor compensation temperature is 25 C and RH is 50 %
|
||||||
|
# You can compensate manually by method ccs811.setCompensation(temperature,humidity)
|
||||||
|
|
||||||
|
'''
|
||||||
|
MEAS MODE REGISTER AND DRIVE MODE CONFIGURATION
|
||||||
|
0b0 Idle (Measurements are disabled in this mode)
|
||||||
|
0b10000 Constant power mode, IAQ measurement every second
|
||||||
|
0b100000 Pulse heating mode IAQ measurement every 10 seconds
|
||||||
|
0b110000 Low power pulse heating mode IAQ measurement every 60
|
||||||
|
0b1000000 Constant power mode, sensor measurement every 250ms
|
||||||
|
'''
|
||||||
|
# Set MEAS_MODE (measurement interval)
|
||||||
|
configuration = 0b100000
|
||||||
|
|
||||||
|
# Set read interval for retriveving last measurement data from the sensor
|
||||||
|
pause = 60
|
||||||
|
|
||||||
|
print('Checking hardware ID...')
|
||||||
|
hwid = ccs811.checkHWID()
|
||||||
|
if(hwid == hex(129)):
|
||||||
|
print('Hardware ID is correct')
|
||||||
|
else: print('Incorrect hardware ID ',hwid, ', should be 0x81')
|
||||||
|
|
||||||
|
#bme680 setup
|
||||||
|
sensor.set_humidity_oversample(bme680.OS_2X)
|
||||||
|
sensor.set_pressure_oversample(bme680.OS_4X)
|
||||||
|
sensor.set_temperature_oversample(bme680.OS_8X)
|
||||||
|
sensor.set_filter(bme680.FILTER_SIZE_3)
|
||||||
|
sensor.set_gas_status(bme680.ENABLE_GAS_MEAS)
|
||||||
|
|
||||||
|
sensor.set_gas_heater_temperature(320)
|
||||||
|
sensor.set_gas_heater_duration(150)
|
||||||
|
sensor.select_gas_heater_profile(0)
|
||||||
|
|
||||||
|
#run burn-in
|
||||||
|
start_time = time.time()
|
||||||
|
curr_time = time.time()
|
||||||
|
burn_in_time = 300
|
||||||
|
|
||||||
|
burn_in_data = []
|
||||||
|
|
||||||
|
# Collect gas resistance burn-in values, then use the average
|
||||||
|
# of the last 50 values to set the upper limit for calculating
|
||||||
|
# gas_baseline.
|
||||||
|
print('Collecting gas resistance burn-in data for 5 mins\n')
|
||||||
|
while curr_time - start_time < burn_in_time:
|
||||||
|
curr_time = time.time()
|
||||||
|
if sensor.get_sensor_data() and sensor.data.heat_stable:
|
||||||
|
gas = sensor.data.gas_resistance
|
||||||
|
burn_in_data.append(gas)
|
||||||
|
print('Gas: {0} Ohms'.format(gas))
|
||||||
|
outputwarm ='{0:.2f} Ohms'.format(gas)
|
||||||
|
mylcd.lcd_display_string(outputwarm, 2)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
gas_baseline = sum(burn_in_data[-50:]) / 50.0
|
||||||
|
# Set the humidity baseline to 40%, an optimal indoor humidity.
|
||||||
|
hum_baseline = 40.0
|
||||||
|
|
||||||
|
# This sets the balance between humidity and gas reading in the
|
||||||
|
# calculation of air_quality_score (25:75, humidity:gas)
|
||||||
|
hum_weighting = 0.25
|
||||||
|
|
||||||
|
print('Gas baseline: {0} Ohms, humidity baseline: {1:.2f} %RH\n'.format(
|
||||||
|
gas_baseline,
|
||||||
|
hum_baseline))
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
if sensor.get_sensor_data():
|
||||||
|
sensor.set_gas_heater_temperature(300)
|
||||||
|
sensor.set_gas_heater_duration(100)
|
||||||
|
sensor.select_gas_heater_profile(0)
|
||||||
|
|
||||||
|
|
||||||
|
hum = sensor.data.humidity
|
||||||
|
temp = sensor.data.temperature
|
||||||
|
press = sensor.data.pressure
|
||||||
|
|
||||||
|
|
||||||
|
#print 'MEAS_MODE:',ccs811.readMeasMode()
|
||||||
|
ccs811.configureSensor(configuration)
|
||||||
|
print('MEAS_MODE:',ccs811.readMeasMode())
|
||||||
|
print('STATUS: ',bin(ccs811.readStatus()))
|
||||||
|
print('---------------------------------')
|
||||||
|
|
||||||
|
# Use these lines if you need to pre-set and check sensor baseline value
|
||||||
|
if(INITIALBASELINE > 0):
|
||||||
|
ccs811.setBaseline(INITIALBASELINE)
|
||||||
|
print(ccs811.readBaseline())
|
||||||
|
|
||||||
|
print("MQTT connection")
|
||||||
|
if mqtt_ok==1:
|
||||||
|
client1.connect(broker,port)
|
||||||
|
client1.loop_start()
|
||||||
|
#return 0
|
||||||
|
|
||||||
|
while(1):
|
||||||
|
humidity = hum
|
||||||
|
temperature = temp
|
||||||
|
ccs811.setCompensation(temperature,humidity)
|
||||||
|
statusbyte = ccs811.readStatus()
|
||||||
|
print('STATUS: ', bin(statusbyte))
|
||||||
|
|
||||||
|
error = ccs811.checkError(statusbyte)
|
||||||
|
if(error):
|
||||||
|
print('ERROR:',ccs811.checkError(statusbyte))
|
||||||
|
|
||||||
|
if(not ccs811.checkDataReady(statusbyte)):
|
||||||
|
#print('No new samples are ready')
|
||||||
|
#print('---------------------------------')
|
||||||
|
time.sleep(pause)
|
||||||
|
continue;
|
||||||
|
result = ccs811.readAlg();
|
||||||
|
if(not result):
|
||||||
|
#print 'Invalid result received'
|
||||||
|
time.sleep(pause)
|
||||||
|
continue;
|
||||||
|
baseline = ccs811.readBaseline()
|
||||||
|
outputCO2 = ('eCO2: {}'.format(result['eCO2']) + ' ppm')
|
||||||
|
outputVOC = ('TVOC: {}'.format(result['TVOC']) + ' ppb')
|
||||||
|
#print ('TVOC: ',result['TVOC'], 'ppb')
|
||||||
|
#print ('Status register: ',bin(result['status']))
|
||||||
|
#print ('Last error ID: ',result['errorid'])
|
||||||
|
#print ('RAW data: ',result['raw'])
|
||||||
|
#print ('Baseline: ',baseline)
|
||||||
|
#print ('---------------------------------')
|
||||||
|
#if sensor.get_sensor_data():
|
||||||
|
|
||||||
|
#if sensor.data.heat_stable:
|
||||||
|
|
||||||
|
if sensor.get_sensor_data() and sensor.data.heat_stable:
|
||||||
|
gas = sensor.data.gas_resistance
|
||||||
|
gas_offset = gas_baseline - gas
|
||||||
|
|
||||||
|
hum = sensor.data.humidity
|
||||||
|
hum_offset = hum - hum_baseline
|
||||||
|
|
||||||
|
# Calculate hum_score as the distance from the hum_baseline.
|
||||||
|
if hum_offset > 0:
|
||||||
|
hum_score = (100 - hum_baseline - hum_offset)
|
||||||
|
hum_score /= (100 - hum_baseline)
|
||||||
|
hum_score *= (hum_weighting * 100)
|
||||||
|
|
||||||
|
else:
|
||||||
|
hum_score = (hum_baseline + hum_offset)
|
||||||
|
hum_score /= hum_baseline
|
||||||
|
hum_score *= (hum_weighting * 100)
|
||||||
|
|
||||||
|
# Calculate gas_score as the distance from the gas_baseline.
|
||||||
|
if gas_offset > 0:
|
||||||
|
gas_score = (gas / gas_baseline)
|
||||||
|
gas_score *= (100 - (hum_weighting * 100))
|
||||||
|
|
||||||
|
else:
|
||||||
|
gas_score = 100 - (hum_weighting * 100)
|
||||||
|
|
||||||
|
# Calculate air_quality_score.
|
||||||
|
air_quality_score = hum_score + gas_score
|
||||||
|
outputT = '{0:.2f}C'.format(sensor.data.temperature)
|
||||||
|
outputP = '{0:.2f}hPa'.format(sensor.data.pressure)
|
||||||
|
outputH = '{0:.1f}%RH'.format(sensor.data.humidity)
|
||||||
|
outputG = '{0:.0f} Ohms'.format(sensor.data.gas_resistance)
|
||||||
|
outputIAQ = 'IAQ:{0:.1f}'.format(air_quality_score)
|
||||||
|
#print("IAQ {0:.2f} %".format(air_quality_score))
|
||||||
|
|
||||||
|
data = []
|
||||||
|
data.append("{measurement},id={DeviceID} Temp={temp},Press={press},Hum={hum},Gas={gas},IAQ={iaq},eCO2={eco2},TVOC={tvoc} {timestamp}"
|
||||||
|
.format(measurement='IAQ0.1',
|
||||||
|
DeviceID=uuid.getnode(),
|
||||||
|
temp=sensor.data.temperature,
|
||||||
|
press=sensor.data.pressure,
|
||||||
|
hum=sensor.data.humidity,
|
||||||
|
gas=sensor.data.gas_resistance,
|
||||||
|
iaq=air_quality_score,
|
||||||
|
eco2=result['eCO2'],
|
||||||
|
tvoc=result['TVOC'],
|
||||||
|
timestamp=int(time.time())))
|
||||||
|
print(data)
|
||||||
|
if mqtt_ok==1:
|
||||||
|
ret = client1.publish("iaq/0.1",str(data))
|
||||||
|
|
||||||
|
#outputs to lcd
|
||||||
|
#date and time
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
now = datetime.now() # current date and time
|
||||||
|
date_time = now.strftime("%m/%d/%Y")
|
||||||
|
date1=(date_time)
|
||||||
|
date_time = now.strftime("%H:%M")
|
||||||
|
date2=(date_time)
|
||||||
|
mylcd.lcd_display_string(date1+" "+ date2,1)
|
||||||
|
mylcd.lcd_display_string(outputG,2)
|
||||||
|
time.sleep(6)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
#TPH and IAQ
|
||||||
|
mylcd.lcd_display_string(outputT,1)
|
||||||
|
mylcd.lcd_display_string(outputIAQ,2)
|
||||||
|
time.sleep(6)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
mylcd.lcd_display_string(outputIAQ,1)
|
||||||
|
mylcd.lcd_display_string(outputCO2,2)
|
||||||
|
time.sleep(6)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
mylcd.lcd_display_string(outputCO2,1)
|
||||||
|
mylcd.lcd_display_string(outputVOC,2)
|
||||||
|
time.sleep(6)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
mylcd.lcd_display_string(outputVOC,1)
|
||||||
|
mylcd.lcd_display_string(outputP,2)
|
||||||
|
time.sleep(5)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
mylcd.lcd_display_string(outputP,1)
|
||||||
|
mylcd.lcd_display_string(outputH,2)
|
||||||
|
time.sleep(5)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
now = datetime.now() # current date and time
|
||||||
|
date_time = now.strftime("%m/%d/%Y")
|
||||||
|
date1=(date_time)
|
||||||
|
date_time = now.strftime("%H:%M")
|
||||||
|
date2=(date_time)
|
||||||
|
mylcd.lcd_display_string(date1+" "+ date2,1)
|
||||||
|
mylcd.lcd_display_string(outputG,2)
|
||||||
|
time.sleep(4)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
#TPH and IAQ
|
||||||
|
mylcd.lcd_display_string(outputT,1)
|
||||||
|
mylcd.lcd_display_string(outputIAQ,2)
|
||||||
|
time.sleep(4)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
mylcd.lcd_display_string(outputIAQ,1)
|
||||||
|
mylcd.lcd_display_string(outputCO2,2)
|
||||||
|
time.sleep(4)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
mylcd.lcd_display_string(outputCO2,1)
|
||||||
|
mylcd.lcd_display_string(outputVOC,2)
|
||||||
|
time.sleep(4)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
mylcd.lcd_display_string(outputVOC,1)
|
||||||
|
mylcd.lcd_display_string(outputP,2)
|
||||||
|
time.sleep(4)
|
||||||
|
mylcd.lcd_clear()
|
||||||
|
mylcd.lcd_display_string(outputP,1)
|
||||||
|
mylcd.lcd_display_string(outputH,2)
|
||||||
|
time.sleep(4)
|
||||||
Loading…
Reference in a new issue