Can I do it with my code to autostart:
$ crontab -e
@reboot cd /home/pi/bme680_test && ./python Example_bme680.py
?
no, use @reboot python /home/pi/bme680_test/Example_bme680.py &
as your crontab entry
Thanks. Can You help me where to paste that pm2.5 [sds011] code in my code from bme680?
aqi.py
#!/usr/bin/python -u
# coding=utf-8
# "DATASHEET": http://cl.ly/ekot
# https://gist.github.com/kadamski/92653913a53baf9dd1a8
from __future__ import print_function
import serial, struct, sys, time, json, subprocess
DEBUG = 0
CMD_MODE = 2
CMD_QUERY_DATA = 4
CMD_DEVICE_ID = 5
CMD_SLEEP = 6
CMD_FIRMWARE = 7
CMD_WORKING_PERIOD = 8
MODE_ACTIVE = 0
MODE_QUERY = 1
PERIOD_CONTINUOUS = 0
JSON_FILE = '/var/www/html/aqi.json'
MQTT_HOST = ''
MQTT_TOPIC = '/weather/particulatematter'
ser = serial.Serial()
ser.port = "/dev/ttyUSB0"
ser.baudrate = 9600
ser.open()
ser.flushInput()
byte, data = 0, ""
def dump(d, prefix=''):
print(prefix + ' '.join(x.encode('hex') for x in d))
def construct_command(cmd, data=[]):
assert len(data) <= 12
data += [0,]*(12-len(data))
checksum = (sum(data)+cmd-2)%256
ret = "\xaa\xb4" + chr(cmd)
ret += ''.join(chr(x) for x in data)
ret += "\xff\xff" + chr(checksum) + "\xab"
if DEBUG:
dump(ret, '> ')
return ret
def process_data(d):
r = struct.unpack('<HHxxBB', d[2:])
pm25 = r[0]/10.0
pm10 = r[1]/10.0
checksum = sum(ord(v) for v in d[2:8])%256
return [pm25, pm10]
#print("PM 2.5: {} Ī¼g/m^3 PM 10: {} Ī¼g/m^3 CRC={}".format(pm25, pm10, "OK" if (checksum==r[2] and r[3]==0xab) else "NOK"))
def process_version(d):
r = struct.unpack('<BBBHBB', d[3:])
checksum = sum(ord(v) for v in d[2:8])%256
print("Y: {}, M: {}, D: {}, ID: {}, CRC={}".format(r[0], r[1], r[2], hex(r[3]), "OK" if (checksum==r[4] and r[5]==0xab) else "NOK"))
def read_response():
byte = 0
while byte != "\xaa":
byte = ser.read(size=1)
d = ser.read(size=9)
if DEBUG:
dump(d, '< ')
return byte + d
def cmd_set_mode(mode=MODE_QUERY):
ser.write(construct_command(CMD_MODE, [0x1, mode]))
read_response()
def cmd_query_data():
ser.write(construct_command(CMD_QUERY_DATA))
d = read_response()
values = []
if d[1] == "\xc0":
values = process_data(d)
return values
def cmd_set_sleep(sleep):
mode = 0 if sleep else 1
ser.write(construct_command(CMD_SLEEP, [0x1, mode]))
read_response()
def cmd_set_working_period(period):
ser.write(construct_command(CMD_WORKING_PERIOD, [0x1, period]))
read_response()
def cmd_firmware_ver():
ser.write(construct_command(CMD_FIRMWARE))
d = read_response()
process_version(d)
def cmd_set_id(id):
id_h = (id>>8) % 256
id_l = id % 256
ser.write(construct_command(CMD_DEVICE_ID, [0]*10+[id_l, id_h]))
read_response()
def pub_mqtt(jsonrow):
cmd = ['mosquitto_pub', '-h', MQTT_HOST, '-t', MQTT_TOPIC, '-s']
print('Publishing using:', cmd)
with subprocess.Popen(cmd, shell=False, bufsize=0, stdin=subprocess.PIPE).stdin as f:
json.dump(jsonrow, f)
if __name__ == "__main__":
cmd_set_sleep(0)
cmd_firmware_ver()
cmd_set_working_period(PERIOD_CONTINUOUS)
cmd_set_mode(MODE_QUERY);
while True:
cmd_set_sleep(0)
for t in range(15):
values = cmd_query_data();
if values is not None and len(values) == 2:
print("PM2.5: ", values[0], ", PM10: ", values[1])
time.sleep(2)
# open stored data
try:
with open(JSON_FILE) as json_data:
data = json.load(json_data)
except IOError as e:
data = []
# check if length is more than 100 and delete first element
if len(data) > 100:
data.pop(0)
# append new values
jsonrow = {'pm25': values[0], 'pm10': values[1], 'time': time.strftime("%d.%m.%Y %H:%M:%S")}
data.append(jsonrow)
# save it
with open(JSON_FILE, 'w') as outfile:
json.dump(data, outfile)
if MQTT_HOST != '':
pub_mqtt(jsonrow)
print("Going to sleep for 1 min...")
cmd_set_sleep(1)
time.sleep(60)
I try Your way and my in cronetab and itās offline when I reboot
After the line import serial, struct, sys, time, json, subprocess
put time.sleep(30) #Sleep to allow wireless to connect before starting MQTT
Even if you donāt use wireless itās a good idea to sleep for a little to allow the Pi to get an IP address. If you donāt want to wait 30 secs you can try something lower. Even 10 seconds should be plenty if you have a pi 3 or newer.
try this simple code:
import time
def hexShow(argv):
result = ''
hLen = len(argv)
for i in range(hLen):
hvol = argv[i]
hhex = '%02x'%hvol
result += hhex+' '
print ('hexShow:',result)
t = serial.Serial('/dev/ttyAMA0',9600)
t.setTimeout(1.5)
while True:
t.flushInput()
time.sleep(0.5)
retstr = t.read(10)
hexShow(retstr)
if len(retstr)==10:
if(retstr[0]==0xaa and retstr[1]==0xc0):
checksum=0
for i in range(6):
checksum=checksum+int(retstr[2+i])
if checksum%256 == retstr[8]:
pm25=int(retstr[2])+int(retstr[3])*256
pm10=int(retstr[4])+int(retstr[5])*256
print ("pm2.5:%.1f pm10 %.1f"%(pm25/10.0,pm10/10.0))
Replace the code at the top with this:
#!/usr/bin/python -u
# coding=utf-8
# "DATASHEET": http://cl.ly/ekot
# https://gist.github.com/kadamski/92653913a53baf9dd1a8
from __future__ import print_function
import serial, struct, sys, time, json, subprocess
time.sleep(30) #Sleep to allow wireless to connect before starting MQTT
DEBUG = 0
CMD_MODE = 2
CMD_QUERY_DATA = 4
CMD_DEVICE_ID = 5
Basically you just want to add the time.sleep part.
to get pm2.5 sensor data.
I donāt know of coding but Your code is too short for me
@shramik_salgaonkar
pi@raspberrypi:~ $ python pm_sensor.py
Traceback (most recent call last):
File "pm_sensor.py", line 11, in <module>
t = serial.Serial('/dev/ttyAMA0',9600)
NameError: name 'serial' is not defined
@adam I donāt understand what for is that time.sleep(30) #Sleep to allow wireless to connect before starting MQTT
and how it help me to see that sensor in dashboard?
Did it work when you put it in?
I have that two files:
aqi.py
- start on boot my sensor and show data in local server in browser:
#!/usr/bin/python -u
# coding=utf-8
# "DATASHEET": http://cl.ly/ekot
# https://gist.github.com/kadamski/92653913a53baf9dd1a8
from __future__ import print_function
import serial, struct, sys, time, json, subprocess
DEBUG = 0
CMD_MODE = 2
CMD_QUERY_DATA = 4
CMD_DEVICE_ID = 5
CMD_SLEEP = 6
CMD_FIRMWARE = 7
CMD_WORKING_PERIOD = 8
MODE_ACTIVE = 0
MODE_QUERY = 1
PERIOD_CONTINUOUS = 0
JSON_FILE = '/var/www/html/aqi.json'
MQTT_HOST = ''
MQTT_TOPIC = '/weather/particulatematter'
ser = serial.Serial()
ser.port = "/dev/ttyUSB0"
ser.baudrate = 9600
ser.open()
ser.flushInput()
byte, data = 0, ""
def dump(d, prefix=''):
print(prefix + ' '.join(x.encode('hex') for x in d))
def construct_command(cmd, data=[]):
assert len(data) <= 12
data += [0,]*(12-len(data))
checksum = (sum(data)+cmd-2)%256
ret = "\xaa\xb4" + chr(cmd)
ret += ''.join(chr(x) for x in data)
ret += "\xff\xff" + chr(checksum) + "\xab"
if DEBUG:
dump(ret, '> ')
return ret
def process_data(d):
r = struct.unpack('<HHxxBB', d[2:])
pm25 = r[0]/10.0
pm10 = r[1]/10.0
checksum = sum(ord(v) for v in d[2:8])%256
return [pm25, pm10]
#print("PM 2.5: {} Ī¼g/m^3 PM 10: {} Ī¼g/m^3 CRC={}".format(pm25, pm10, "OK" if (checksum==r[2] and r[3]==0xab) else "NOK"))
def process_version(d):
r = struct.unpack('<BBBHBB', d[3:])
checksum = sum(ord(v) for v in d[2:8])%256
print("Y: {}, M: {}, D: {}, ID: {}, CRC={}".format(r[0], r[1], r[2], hex(r[3]), "OK" if (checksum==r[4] and r[5]==0xab) else "NOK"))
def read_response():
byte = 0
while byte != "\xaa":
byte = ser.read(size=1)
d = ser.read(size=9)
if DEBUG:
dump(d, '< ')
return byte + d
def cmd_set_mode(mode=MODE_QUERY):
ser.write(construct_command(CMD_MODE, [0x1, mode]))
read_response()
def cmd_query_data():
ser.write(construct_command(CMD_QUERY_DATA))
d = read_response()
values = []
if d[1] == "\xc0":
values = process_data(d)
return values
def cmd_set_sleep(sleep):
mode = 0 if sleep else 1
ser.write(construct_command(CMD_SLEEP, [0x1, mode]))
read_response()
def cmd_set_working_period(period):
ser.write(construct_command(CMD_WORKING_PERIOD, [0x1, period]))
read_response()
def cmd_firmware_ver():
ser.write(construct_command(CMD_FIRMWARE))
d = read_response()
process_version(d)
def cmd_set_id(id):
id_h = (id>>8) % 256
id_l = id % 256
ser.write(construct_command(CMD_DEVICE_ID, [0]*10+[id_l, id_h]))
read_response()
def pub_mqtt(jsonrow):
cmd = ['mosquitto_pub', '-h', MQTT_HOST, '-t', MQTT_TOPIC, '-s']
print('Publishing using:', cmd)
with subprocess.Popen(cmd, shell=False, bufsize=0, stdin=subprocess.PIPE).stdin as f:
json.dump(jsonrow, f)
if __name__ == "__main__":
cmd_set_sleep(0)
cmd_firmware_ver()
cmd_set_working_period(PERIOD_CONTINUOUS)
cmd_set_mode(MODE_QUERY);
while True:
cmd_set_sleep(0)
for t in range(15):
values = cmd_query_data();
if values is not None and len(values) == 2:
print("PM2.5: ", values[0], ", PM10: ", values[1])
time.sleep(2)
# open stored data
try:
with open(JSON_FILE) as json_data:
data = json.load(json_data)
except IOError as e:
data = []
# check if length is more than 100 and delete first element
if len(data) > 100:
data.pop(0)
# append new values
jsonrow = {'pm25': values[0], 'pm10': values[1], 'time': time.strftime("%d.%m.%Y %H:%M:%S")}
data.append(jsonrow)
# save it
with open(JSON_FILE, 'w') as outfile:
json.dump(data, outfile)
if MQTT_HOST != '':
pub_mqtt(jsonrow)
print("Going to sleep for 1 min...")
cmd_set_sleep(1)
time.sleep(60)
and
Example_bme680.py
- show bme680 sendos data in Cayenne dashboard when I do python Example_bme680.py.
#!/usr/bin/env python
import cayenne.client
import time
import bme680
import logging
print("""read-all.py - Displays temperature, pressure, humidity, and gas.
Press Ctrl+C to exit!
""")
try:
sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY)
except IOError:
sensor = bme680.BME680(bme680.I2C_ADDR_SECONDARY)
# These calibration data can safely be commented
# out, if desired.
print('Calibration data:')
for name in dir(sensor.calibration_data):
if not name.startswith('_'):
value = getattr(sensor.calibration_data, name)
if isinstance(value, int):
print('{}: {}'.format(name, value))
# These oversampling settings can be tweaked to
# change the balance between accuracy and noise in
# the data.
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)
# Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
MQTT_USERNAME = "06487d60-1537-11ea-84bb-8f71124cfdfb"
MQTT_PASSWORD = "23309cdee31964b2ae4caed9417b689c9bebece2"
MQTT_CLIENT_ID = "f9f06b50-1602-11ea-8221-599f77add412"
client = cayenne.client.CayenneMQTTClient()
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, loglevel=logging.INFO, port=8883)
# For a secure connection use port 8883 when calling client.begin:
# client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, port=8883, loglevel=logging.INFO)
i=0
timestamp = 0
print('\n\nInitial reading:')
for name in dir(sensor.data):
value = getattr(sensor.data, name)
if not name.startswith('_'):
print('{}: {}'.format(name, value))
sensor.set_gas_heater_temperature(320)
sensor.set_gas_heater_duration(150)
sensor.select_gas_heater_profile(0)
# Up to 10 heater profiles can be configured, each
# with their own temperature and duration.
# sensor.set_gas_heater_profile(200, 150, nb_profile=1)
# sensor.select_gas_heater_profile(1)
print('\n\nPolling:')
try:
while True:
client.loop()
if sensor.get_sensor_data():
output = '{0:.2f} C,{1:.2f} hPa,{2:.2f} %RH'.format(
sensor.data.temperature,
sensor.data.pressure,
sensor.data.humidity)
if sensor.data.heat_stable:
print('{0},{1} Ohms'.format(
output,
sensor.data.gas_resistance))
else:
print(output)
if (time.time() > timestamp + 10):
client.celsiusWrite(1, sensor.data.temperature)
client.hectoPascalWrite(2, sensor.data.pressure)
client.virtualWrite(3, sensor.data.humidity,"rel_hum","p")
client.virtualWrite(4, sensor.data.gas_resistance, "co","ohms")
timestamp = time.time()
time.sleep(1)
except KeyboardInterrupt:
pass
while True:
client.loop()
if (time.time() > timestamp + 10):
client.celsiusWrite(1, i)
client.luxWrite(2, i*10)
client.hectoPascalWrite(3, i+800)
timestamp = time.time()
i = i+1
Please can You help me combine those two files to make my pm sensor [SDS011] be visible in Cayenne Dashboard?
do you have a link to this sensor?
@shramik_salgaonkar As I say I make everything with that TUTORIAL
@adam when I put that line to my aqi.py file my PM sensor donāt show me data on my local server
OK, I donāt want to waste Your time and I will stay with my local server for that SDS011 sensor. Just help me to add my Example_bme680.py file wright to cronetab.
Share the complete code you have that is working now and Iāll add the line to it.
#!/usr/bin/env python
import cayenne.client
import time
import bme680
import logging
from __future__ import print_function
import serial
import struct
import sys
import time
import json
import subprocess
DEBUG = 0
CMD_MODE = 2
CMD_QUERY_DATA = 4
CMD_DEVICE_ID = 5
CMD_SLEEP = 6
CMD_FIRMWARE = 7
CMD_WORKING_PERIOD = 8
MODE_ACTIVE = 0
MODE_QUERY = 1
PERIOD_CONTINUOUS = 0
ser = serial.Serial()
ser.port = "/dev/ttyUSB0"
ser.baudrate = 9600
ser.open()
ser.flushInput()
byte, data = 0, ""
def dump(d, prefix=''):
print(prefix + ' '.join(x.encode('hex') for x in d))
def construct_command(cmd, data=[]):
assert len(data) <= 12
data += [0, ]*(12-len(data))
checksum = (sum(data)+cmd-2) % 256
ret = "\xaa\xb4" + chr(cmd)
ret += ''.join(chr(x) for x in data)
ret += "\xff\xff" + chr(checksum) + "\xab"
if DEBUG:
dump(ret, '> ')
return ret
def process_data(d):
r = struct.unpack('<HHxxBB', d[2:])
pm25 = r[0]/10.0
pm10 = r[1]/10.0
checksum = sum(ord(v) for v in d[2:8]) % 256
return [pm25, pm10]
#print("PM 2.5: {} Ī¼g/m^3 PM 10: {} Ī¼g/m^3 CRC={}".format(pm25, pm10, "OK" if (checksum==r[2] and r[3]==0xab) else "NOK"))
def process_version(d):
r = struct.unpack('<BBBHBB', d[3:])
checksum = sum(ord(v) for v in d[2:8]) % 256
print("Y: {}, M: {}, D: {}, ID: {}, CRC={}".format(r[0], r[1], r[2], hex(
r[3]), "OK" if (checksum == r[4] and r[5] == 0xab) else "NOK"))
def read_response():
byte = 0
while byte != "\xaa":
byte = ser.read(size=1)
d = ser.read(size=9)
if DEBUG:
dump(d, '< ')
return byte + d
def cmd_set_mode(mode=MODE_QUERY):
ser.write(construct_command(CMD_MODE, [0x1, mode]))
read_response()
def cmd_query_data():
ser.write(construct_command(CMD_QUERY_DATA))
d = read_response()
values = []
if d[1] == "\xc0":
values = process_data(d)
return values
def cmd_set_sleep(sleep):
mode = 0 if sleep else 1
ser.write(construct_command(CMD_SLEEP, [0x1, mode]))
read_response()
def cmd_set_working_period(period):
ser.write(construct_command(CMD_WORKING_PERIOD, [0x1, period]))
read_response()
def cmd_firmware_ver():
ser.write(construct_command(CMD_FIRMWARE))
d = read_response()
process_version(d)
def cmd_set_id(id):
id_h = (id >> 8) % 256
id_l = id % 256
ser.write(construct_command(CMD_DEVICE_ID, [0]*10+[id_l, id_h]))
read_response()
print("""read-all.py - Displays temperature, pressure, humidity, and gas.Press Ctrl+C to exit!""")
try:
sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY)
except IOError:
sensor = bme680.BME680(bme680.I2C_ADDR_SECONDARY)
# These calibration data can safely be commented
# out, if desired.
print('Calibration data:')
for name in dir(sensor.calibration_data):
if not name.startswith('_'):
value = getattr(sensor.calibration_data, name)
if isinstance(value, int):
print('{}: {}'.format(name, value))
# These oversampling settings can be tweaked to
# change the balance between accuracy and noise in
# the data.
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)
# Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
MQTT_USERNAME = "06487d60-1537-11ea-84bb-8f71124cfdfb"
MQTT_PASSWORD = "23309cdee31964b2ae4caed9417b689c9bebece2"
MQTT_CLIENT_ID = "f9f06b50-1602-11ea-8221-599f77add412"
client = cayenne.client.CayenneMQTTClient()
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID,
loglevel=logging.INFO, port=8883)
# For a secure connection use port 8883 when calling client.begin:
# client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, port=8883, loglevel=logging.INFO)
i = 0
timestamp = 0
print('\n\nInitial reading:')
for name in dir(sensor.data):
value = getattr(sensor.data, name)
if not name.startswith('_'):
print('{}: {}'.format(name, value))
sensor.set_gas_heater_temperature(320)
sensor.set_gas_heater_duration(150)
sensor.select_gas_heater_profile(0)
# Up to 10 heater profiles can be configured, each
# with their own temperature and duration.
# sensor.set_gas_heater_profile(200, 150, nb_profile=1)
# sensor.select_gas_heater_profile(1)
cmd_set_sleep(0)
cmd_firmware_ver()
cmd_set_working_period(PERIOD_CONTINUOUS)
cmd_set_mode(MODE_QUERY)
print('\n\nPolling:')
try:
while True:
client.loop()
# cmd_set_sleep(0)
for t in range(15):
values = cmd_query_data()
if values is not None and len(values) == 2:
print("PM2.5: ", values[0], ", PM10: ", values[1])
time.sleep(2)
if sensor.get_sensor_data():
output = '{0:.2f} C,{1:.2f} hPa,{2:.2f} %RH'.format(
sensor.data.temperature,
sensor.data.pressure,
sensor.data.humidity)
if sensor.data.heat_stable:
print('{0},{1} Ohms'.format(
output,
sensor.data.gas_resistance))
else:
print(output)
if (time.time() > timestamp + 10):
client.celsiusWrite(1, sensor.data.temperature)
client.hectoPascalWrite(2, sensor.data.pressure)
client.virtualWrite(3, sensor.data.humidity, "rel_hum", "p")
client.virtualWrite(4, sensor.data.gas_resistance, "co", "ohms")
client.virtualWrite(5, values[0], "pm", "mg")
client.virtualWrite(6, values[1], "pm", "mg")
timestamp = time.time()
time.sleep(1)
except KeyboardInterrupt:
pass
@adam I share my codes above:
aqi.py
is for SDS011 sensor and Example_bme680.py
is for BME680 sensor. Both are working but bme680 donāt start on boot and stop working when I close my ssh terminal on laptop.