def get_air_quality(): # sudo usermod -a -G dialout yourusername # https://cdn.sparkfun.com/assets/parts/1/2/2/7/5/Laser_Dust_Sensor_Control_Protocol_V1.3.pdf # Start in reporting mode : query/home/pi/.local/bin sensor = SDS011("/dev/ttyUSB0", use_query_mode=True) sensor.set_work_period(work_time=0) # work_time is continuous logging.debug('waking sensor') sensor.sleep(sleep=False) # wake sensor logging.debug('waiting 30 seconds') time.sleep(30) # capture 30 seconds of data logging.debug('running sensor query') result = sensor.query() logging.debug('sleeping sensor') sensor.sleep() # sleep sensor # print(f" PMT2.5: {pm25} μg/m3 PMT10 : {pm10} μg/m3") if result is None: logging.error("Sensor returned None") return None pm25, pm10 = result data = { 'pm25': str(pm25), 'pm10': str(pm10), 'aqipm25': str(aqi.to_iaqi(aqi.POLLUTANT_PM25, str(pm25))), 'aqipm10': str(aqi.to_iaqi(aqi.POLLUTANT_PM10, str(pm10))) } return data
def get(): print('Initiating connection with SDS011...') sensor = SDS011( DEVICE_FILE, timeout=READ_TIMEOUT, unit_of_measure=SDS011.UnitsOfMeasure.MassConcentrationEuropean) print('Resetting...') sensor.reset() # Let's wake the sensor up... print('Waking up...') sensor.workstate = SDS011.WorkStates.Measuring # ...and leave it some time to get qualified readings. print('Going to sleep for %d secs...' % WARMUP_PERIOD) time.sleep(WARMUP_PERIOD) # Should be enough. Get the values and... print('Done sleeping, next: read SDS011 measurements...') values = sensor.get_values() # ... put it to sleep until next time we need its values. It has a # mechanical fan - better not keep it spinning needlessly. print('Done! Putting sensor back to sleep...') sensor.workstate = SDS011.WorkStates.Sleeping return {Sensor.sds_pm25: values[1], Sensor.sds_pm10: values[0]}
def getAirQuality(): on() time.sleep(15) sensor = SDS011(os.environ['USB_DEVICE'], use_query_mode=True) data = sensor.query() off() return data
def __init__(self, address=None): self.address = address from sds011 import SDS011 self.sensor = SDS011(self.address) # Set dutycyle to nocycle (permanent) self.sensor.dutycycle = 0
def test_sampler(self): with self.assertRaises(ValueError): sampler = Sampler(SDS011(True)) with self.assertRaises(ValueError): sampler = Sampler(SDS011(True), num_sample=100) with self.assertRaises(ValueError): sampler = Sampler(SDS011(True), num_sample=100, sleep_time=10, sample_time=100) with self.assertRaises(ValueError): sampler = Sampler(SDS011(True), sample_time=10, sleep_time=100) sampler = Sampler(SDS011(True), sample_time=1, num_sample=10) data = sampler.collect() for x in data: self.assertEqual(len(x), 10)
def __init__(self, baudrate=9600, tty="/dev/ttyUSB0", interval=60): self.air_values = { 'pm25': 0.0, 'pm10': 0.0, 'pm25_total': [], 'pm10_total': [], 'pm25_errors': 0, 'pm10_errors': 0 } self.interval = float(interval) self.sensor = SDS011(serial_port=tty, baudrate=baudrate)
def test_sampler(self): sample_time = 2 sleep_time = 0.10 start = datetime.datetime.now() sampler = Sampler(SDS011(True), sample_time=sample_time, sleep_time=sleep_time) data = sampler.collect() stop = datetime.datetime.now() dt = stop - start self.assertTrue((dt.total_seconds() - sample_time) > 0)
def mesure(): sensor = SDS011(DEV_PATH, use_query_mode=True) # print('Sleep device...') sensor.sleep(sleep=True) # Turn off fan and diode # print('Wake-up device...') sensor.sleep(sleep=False) # Turn on fan and diode # print('Mesure for 30 secs...') time.sleep(30) # Allow time for the sensor to measure properly # print('Query data...') result = sensor.query() # print('Sleep device...') sensor.sleep() # Turn off fan and diode return result if result else (0, 0)
def __init__(self): # Create an instance of your sensor self.sensor = SDS011('/dev/ttyUSB0') self.rolling_average = [None, None] self.last_values = [None, None] # Now we have some details about it logging.debug('Device ID') logging.debug(self.sensor.device_id) logging.debug('Firmware') logging.debug(self.sensor.firmware) logging.debug('Workstate') logging.debug(self.sensor.workstate) # Set dutycyle to nocycle (permanent) self.sensor.dutycycle = 0
def active_mode(): # Start in reporting mode : active sensor = SDS011("/dev/ttyUSB0") sensor.set_work_period(work_time=1) # work_time in minutes print('waking sensor') sensor.sleep(sleep=False) print('waiting 10 seconds') time.sleep(10) print('running sensor query') pm25, pm10 = sensor.query() print(f" PMT2.5: {pm25} μg/m3 PMT10 : {pm10} μg/m3") print('sleeping sensor') sensor.sleep(sleep=True) print('waiting 2 seconds') time.sleep(2) print(sensor)
def __init__(self, name, com_port="", readinterval=5): """Initialize Interfacer""" # Initialization super(EmonHubSDS011Interfacer, self).__init__(name) # Only load module if it is installed try: from sds011 import SDS011 except ModuleNotFoundError as err: self._log.error(err) self._settings.update(self._defaults) self._template_settings = {'nodename':'SDS011','readinterval':5} ### GLOBALS ### self.previous_time = time.time() self.warmup_time = 15 # seconds to spin up the SDS011 before taking a reading self.sensor_present = False self.first_reading_done = False self.sensor_waking = False self.timenow = time.time() self.count = 0 self.readinterval = readinterval * 60 # convert to seconds. ### INIT COM PORT ### try: self._log.info("INFO: Opening sensor serial port...") self.sensor = SDS011(com_port, use_query_mode=True) self.sensor.set_work_period(read=False, work_time=0) # self.sensor.set_work_period self.sensor.sleep(sleep=False) # wake the sensor just in case. time.sleep(2) first_reading = self.sensor.query() # sensor.set_report_mode self.previous_time = time.time() if first_reading is not None: self._log.info("COM port open and SDS011 active") self._log.info("testing reading PM2.5/PM10: " + str(first_reading)) self.sensor_present = True else: self._log.error("COM port opened but sensor readings unavailable.") self._log.info("Check connections or the selected COM port in settings") except: self._log.error("Couldn't open COM port")
def __init__(self, serial_port, *args, calib_duration_s=15, **kwargs): """Initialize and start SDS011 on the given port. @param serial_port: The SDS011 port, e.g. /dev/ttyUSB0. @type serial_port: str @param calib_duration_s: The amount of time in seconds to wait after the sensor has been waken up before reading its data. Defaults to 15 seconds. @type calib_duration_s: float """ self.pm25_quality = None self.pm25_density = None self.pm10_quality = None self.pm10_density = None super().__init__(*args, **kwargs) # PM2.5 air_quality_pm25 = self.add_preload_service( 'AirQualitySensor', chars=['Name', 'AirParticulateSize', 'AirParticulateDensity']) air_quality_pm25.configure_char('AirParticulateSize', value=0) air_quality_pm25.configure_char('Name', value='PM2.5') self.pm25_quality = air_quality_pm25.configure_char('AirQuality') self.pm25_density = air_quality_pm25.configure_char( 'AirParticulateDensity') # PM10 air_quality_pm10 = self.add_preload_service( 'AirQualitySensor', chars=['Name', 'AirParticulateSize', 'AirParticulateDensity']) air_quality_pm10.configure_char('AirParticulateSize', value=1) air_quality_pm10.configure_char('Name', value='PM10') self.pm10_quality = air_quality_pm10.configure_char('AirQuality') self.pm10_density = air_quality_pm10.configure_char( 'AirParticulateDensity') self.calib_duration_s = calib_duration_s self.serial_port = serial_port self.sensor = AirSensor(serial_port) self.sensor.sleep(sleep=False)
def read_config_file(self): config = configparser.ConfigParser() config.read(self.configfile) settings = config['DEFAULT'] #Auth0 Auth Settings self.auth0_request_url = settings.get('auth0_request_url') self.auth0_grant_type = settings.get('auth0_grant_type') self.auth0_client_id = settings.get('auth0_client_id') self.auth0_client_secret = settings.get('auth0_client_secret') self.auth0_audience = settings.get('auth0_audience') #Device Master Settings self.device_id = settings.get('device_id') if self.debug == True: self.measurement_frequency = 30 self.measurement_delay = 2 print('Starting in debug mode') else: self.measurement_frequency = int( settings.get('measurement_frequency')) self.measurement_delay = int(settings.get('measurement_delay')) if self.dummy_data == False: pm_sensor_path = settings.get('pm_sensor_device') self.pm_sensor = SDS011(pm_sensor_path, use_query_mode=True) i2c = busio.I2C(board.SCL, board.SDA) self.temp_sensor = adafruit_sht31d.SHT31D(i2c) self.baro_sensor = adafruit_sht31d.SHT31D(i2c) selt.temp_offset = float(settings.get('temperature_correction')) else: self.pm_sensor = None self.temp_sensor = None self.baro_sensor = None print( 'Starting in dummy data mode - remember to delete bad data from server' ) #Upload endpoint settings self.measurement_endpoint = settings.get('measurement_endpoint')
#!/usr/bin/env python3 from sds011 import SDS011 import socket import time import aqi UDP_IP = "10.0.0.20" UDP_PORT = 1027 sock = socket.socket( socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP sensor = SDS011("/dev/ttyUSB0", use_query_mode=True) while True: sensor.sleep(sleep=False) time.sleep(30) data = sensor.query() #convert to AQI from micrograms/m^3 aqi_2_5 = aqi.to_iaqi(aqi.POLLUTANT_PM25, str(data[0])) aqi_10 = aqi.to_iaqi(aqi.POLLUTANT_PM10, str(data[1])) aqi_data = (str(aqi_2_5).encode('utf-8'), str(aqi_10).encode('utf-8')) print(data) print(aqi_data) sensor.sleep() # sock.sendto(str(data.encode('utf-8')), (UDP_IP,UDP_PORT)) sock.sendto(str(aqi_data).encode('utf-8'), (UDP_IP, UDP_PORT)) time.sleep(300)
# print('Waiting for GPS.', flush=True) l76 = L76GNSS(py, timeout=30) coord = l76.coordinates() if coord[0] == None: # Could not find any fixed coordinates coord = (0.0, 0.0) # Take a meassurement of particle levels print('Waiting for particle sensor.', '(', 60 - (time.ticks_ms() / 1000), 'seconds )', flush=True) time.sleep(60 - (time.ticks_ms() / 1000)) # Give it a minute to settle sds = SDS011() particles = sds.values() # # Current time # now = rtc.now() print("{}-{}-{} {}:{} {}, {}\n".format(now[0], now[1], now[2], now[3], now[4], coord[0], coord[1])) txb = ustruct.pack("LllHH", utime.mktime(now), int(coord[0] * 11930464), int(coord[1] * 11930464), particles[0], particles[1]) if not isInteractive:
from sds011 import SDS011 # the SDS-011 driver needs various serial port values to be set as constants DEFAULT_SERIAL_PORT = "/dev/serial0" # Serial port to use if no other specified DEFAULT_BAUD_RATE = 9600 # Serial baud rate to use if no other specified DEFAULT_SERIAL_TIMEOUT = 2 # Serial timeout to use if not specified DEFAULT_READ_TIMEOUT = 1 # How long to sit looking for the correct character sequence. # set up Nova SDS-011 sensor # send an info message saying it is being initialised myClient.publishAsync( "sensors/info", '{{"sensor":"{:s}","timestamp":"{:s}","info":"initialising Nova SDS-011 sensor"}}' .format(sensor_id, get_local_timestamp()), 1) time.sleep(10) # create an instance of the SDS011 driver class, this can also fail, if so, bail out of program so it restarts try: sds = SDS011(DEFAULT_SERIAL_PORT, use_query_mode=True) print("Nova SDS-011 sensor initialised") myClient.publishAsync( "sensors/info", '{{"sensor":"{:s}","timestamp":"{:s}","info":"initialised Nova SDS-011 sensor"}}' .format(sensor_id, get_local_timestamp()), 1) time.sleep(10) except: print("Nova SDS-011 sensor failed to initialise - bailing out!") myClient.publishAsync( "sensors/info", '{{"sensor":"{:s}","timestamp":"{:s}","info":"failed to initialise Nova SDS-011 sensor"}}' .format(sensor_id, get_local_timestamp()), 1) time.sleep(30) sys.exit(1) else:
with open("config.yml", 'r') as ymlfile: config = yaml.load(ymlfile) # Logging import logging logging.basicConfig(level=logging.DEBUG) bme280 = BME280( address=0x76, t_mode=BME280_OSAMPLE_8, p_mode=BME280_OSAMPLE_8, h_mode=BME280_OSAMPLE_8, ) # Create an instance of your bme280 dusty = SDS011('/dev/ttyUSB0') # Now we have some details about it print("SDS011 initialized: device_id={} firmware={}".format(dusty.device_id,dusty.firmware)) # Set dutycyle to nocycle (permanent) dusty.dutycycle = 0 class Measurement: def __init__(self): pm25_values = [] pm10_values = [] dusty.workstate = SDS011.WorkStates.Measuring try: for a in range(8): values = dusty.get_values()
def printValues(timing, values, unit_of_measure): if unit_of_measure == SDS011.UnitsOfMeasure.MassConcentrationEuropean: unit = 'µg/m³' else: unit = 'pcs/0.01cft' print("Waited %d secs\nValues measured in %s: PM2.5 " % (timing, unit), values[1], ", PM10 ", values[0]) # simple parsing the command arguments for setting options # Create an instance of your sensor # options defaults: logging None, debug level 0, serial line timeout 2 # option unit_of_measure (default False) values in pcs/0.01sqf or mass ug/m3 sensor = SDS011(com_port, timeout=timeout, unit_of_measure=unit_of_measure) # raise KeyboardInterrupt # Now we have some details about it print("SDS011 sensor info:") print("Device ID: ", sensor.device_id) print("Device firmware: ", sensor.firmware) print("Current device cycle (0 is permanent on): ", sensor.dutycycle) print(sensor.workstate) print(sensor.reportmode) # print("\n%d measurements in permanent measuring mode" % (cycles * 2)) # print("This will make the sensor getting old. The TTL is just 8000 hours!") # print("Do you really need to use the permanent measurering mode?") # print("In sleep mode the fan will be turned off.") # # Set dutycyle to nocycle (permanent) # sensor.reset()
lat = (parser.get('airmonitor', 'lat')) long = (parser.get('airmonitor', 'long')) urllib3.disable_warnings() # Nie zmieniaj niczego poniżej tej linii!## ##################################################### ##################################################### ##################################################### ##################################################### ##################################################### ##################################################### ##################################################### ##################################################### ##################################################### # Create an instance of your sensor sensor = SDS011('/dev/ttyAMA0') # Now we have some details about it print(sensor.device_id) print(sensor.firmware) print(sensor.dutycycle) print(sensor.workstate) print(sensor.reportmode) # Set dutycyle to nocycle (permanent) sensor.reset() sensor.workstate = SDS011.WorkStates.Measuring time.sleep(30) COUNT = 0 FACTOR = 1.5 pm25_values = []
def printValues(timing, values, unit_of_measure): if unit_of_measure == SDS011.UnitsOfMeasure.MassConcentrationEuropean: unit = 'µg/m³' else: unit = 'pcs/0.01cft' print("Waited %d secs\nValues measured in %s: PM2.5 " % (timing, unit), values[1], ", PM10 ", values[0]) # print("Values measured in pcs/0.01sqf: PM2.5 %d, PM10 %d" % (Mass2Con('pm25',values[1]), Mass2Con('pm10',values[0]))) # simple parsing the command arguments for setting options # Create an instance of your sensor # options defaults: logging None, debug level 0, serial line timeout 2 # option unit_of_measure (default False) values in pcs/0.01sqf or mass ug/m3 sensor = SDS011(sys.argv[1], timeout=timeout, unit_of_measure=unit_of_measure) # raise KeyboardInterrupt # Now we have some details about it print("SDS011 sensor info:") print("Device ID: ", sensor.device_id) print("Device firmware: ", sensor.firmware) print("Current device cycle (0 is permanent on): ", sensor.dutycycle) print(sensor.workstate) print(sensor.reportmode) print("\n%d measurements in permanent measuring mode" % (cycles * 2)) print("This will make the sensor getting old. The TTL is just 8000 hours!") print("Do you really need to use the permanent measurering mode?") print("In sleep mode the fan will be turned off.") # Set dutycyle to nocycle (permanent) sensor.reset()
def do_GET(self): # message in json to send when gotten GET request message = { "response": "successful", } self.send_response(200) # for later - answers with localhost:port/agent if self.path == '/agent': message = self.headers['user-agent'] if self.path == '/data': try: humidity, temperature = get_DHT22() # unpacking tuple if humidity is not None and temperature is not None: print( "Temperature={0:0.001f}C Humidity={1:0.001f}%".format( temperature, humidity)) else: humidity, temperature = get_DHT22() print( "Temperature={0:0.001f}C Humidity={1:0.001f}%".format( temperature, humidity)) except: print( "An exception occurred with reading humidity and temperature with DHT22" ) humidity = 0 temperature = 0 # simple parsing the command arguments for setting options # Create an instance of your sensor # options defaults: logging None, debug level 0, serial line timeout 2 # option unit_of_measure (default False) values in pcs/0.01sqf or mass ug/m3 sensor = SDS011(com_port, timeout=timeout, unit_of_measure=unit_of_measure) # raise KeyboardInterrupt # Now we have some details about it print("SDS011 sensor info:") print("Device ID: ", sensor.device_id) print("Device firmware: ", sensor.firmware) print("Current device cycle (0 is permanent on): ", sensor.dutycycle) print(sensor.workstate) print(sensor.reportmode) try: # Example of switching the WorkState print("\n%d X switching between measuring and sleeping mode:" % cycles) print( "\tMeasurement state: Read the values, on no read, wait 2 seconds and try again" ) print( "\tOn read success, put the mode into sleeping mode for 5 seconds, and loop again" ) for a in range(cycles): print("%d time: push it into wake state" % a) sensor.workstate = SDS011.WorkStates.Measuring # The sensor needs to warm up! time.sleep(8) last = time.time() while True: last1 = time.time() values = sensor.get_values() pm10, pm25 = values print('pm25 and pm10: ', pm25, pm10) if values is not None: printValues(time.time() - last, values, sensor.unit_of_measure) break print( "Waited %d seconds, no values read, wait 2 seconds, and try to read again" % (time.time() - last1)) time.sleep(1) print('pm25 and pm10: ', pm25, pm10) print( '\nSetting sensor to sleep mode cuz running fan annoys me' ) sensor.workstate = SDS011.WorkStates.Sleeping time.sleep(0.3) # # end of test # print("\nSensor reset to normal") # sensor.reset() # sensor = None print('pm25 and pm10: ', pm25, pm10) # sensor.workstate = SDS011.WorkStates.Sleeping #sensor is already sleeping after last iteration except KeyboardInterrupt: sensor.reset() sensor = None sys.exit("Nova Sensor reset due to a KeyboardInterrupt") color = "#00E400" description = "Good" if pm25 >= 0 and pm25 <= 37: color = "#00E400" description = "Good air" if pm25 > 37 and pm25 <= 61: color = "#FFFF00" description = "Moderate air" if pm25 > 61 and pm25 <= 85: color = "#FF7E00" description = "Unhealthy air for Sensitive Groups" if pm25 > 85 and pm25 <= 121: color = "#ff3300" description = "Unhealthy air" if pm25 > 121 and pm25 <= 200: color = "#ff0000" description = "Very Unhealthy air" if pm25 > 200: color = "#990000" description = "Hazardous air" message = { "current": { "indexes": [{ "stationcity": "Gliwice", "color": color, "advice": "Take a breath!", "name": "AIRLY_CAQI", "description": description, "level": "LOW" }], "values": [{ "name": "PM1", "value": 0 }, { "value": pm25, "name": "PM25" }, { "value": pm10, "name": "PM10" }, { "value": 0, "name": "PRESSURE" }, { "value": humidity, "name": "HUMIDITY" }, { "value": temperature, "name": "TEMPERATURE" }] } } self.send_header('Content-type', 'text/html') self.end_headers() # self.wfile.write(bytes(message, "utf8")) json_string = bytes(json.dumps(message), 'utf-8') self.wfile.write(json_string) return
if serialNumber == "TEST": print( "Sensor is running in TEST mode and will not report values to madavi.de or" ) print( "luftdaten.info. To start reporting to these servers, provide the serial number of" ) print( "your TL-MR3020 (13 digits) in the file \"tlmr3020sn.txt\" and restart the script." ) # First create the sensor instance. # On a TL-MR3020, the sensor is mounted on /dev/ttyUSB0 # Note that this can be different on other devices. sensor = SDS011( '/dev/ttyUSB0', timeout=2, unit_of_measure=SDS011.UnitsOfMeasure.MassConcentrationEuropean) # Set the dutycycle to two minutes (luftdaten standard) sensor.dutycycle = 2 # Print some info on the device and the sensor print("TLMR-3020 S/N read from tlmr3020sn.txt: %s" % serialNumber) print("SDS011 device ID: %s" % sensor.device_id) print("SDS011 device firmware: %s" % sensor.firmware) # Create a json string with this info, and store this string in a text file for the dashboard jsondict = dict([('tlmr3020sn', str(serialNumber)), ('SDS011_deviceid', sensor.device_id), ('SDS011_firmware', sensor.firmware)]) jsonstr = json.dumps(jsondict)
def collect(self): sds011 = SDS011(self._sds011, use_query_mode=True) sds011.sleep(sleep=False) time.sleep(int(self._sleep)) sds011s = tuple(sds011.query()) sds011.sleep() pm25 = GaugeMetricFamily('airfilter_dust', 'dust of size 2,5', labels=['sensor', 'pm']) pm25.add_metric(['sds011', '2.5'], sds011s[0]) yield pm25 pm10 = GaugeMetricFamily('airfilter_dust', 'dust of size 10', labels=['sensor', 'pm']) pm10.add_metric(['sds011', '10'], sds011s[1]) yield pm10 if self._ccs811 == 'true': ccs811 = CCS811_RPi() configuration = 0b100000 ccs811.configureSensor(configuration) hdc1000 = SDL_Pi_HDC1000() hdc1000.turnHeaterOff() hdc1000.setTemperatureResolution( HDC1000_CONFIG_TEMPERATURE_RESOLUTION_14BIT) hdc1000.setHumidityResolution( HDC1000_CONFIG_HUMIDITY_RESOLUTION_14BIT) humidity = hdc1000.readHumidity() temperature = hdc1000.readTemperature() ccs811.setCompensation(temperature, humidity) humid = GaugeMetricFamily('airfilter_humidity', 'humidity reading', labels=['sensor']) humid.add_metric(['ccs811'], humidity) yield humid temp = GaugeMetricFamily('airfilter_temperature', 'temperature reading', labels=['sensor']) temp.add_metric(['ccs811'], temperature) yield temp statusbyte = ccs811.readStatus() status = GaugeMetricFamily('airfilter_statusbyte', 'statusbyte', labels=['sensor', 'statusbyte']) status.add_metric(['ccs811', bin(statusbyte)], 1) yield status error = ccs811.checkError(statusbyte) failure = GaugeMetricFamily('airfilter_error', '1 if error on sensor', labels=['sensor']) if (error): failure.add_metric(['ccs811'], 1) else: failure.add_metric(['ccs811'], 0) yield failure samples = GaugeMetricFamily('airfilter_samples', '0 if no new samples', labels=['sensor']) res = GaugeMetricFamily('airfilter_result', '1 if valid result', labels=['sensor']) eco2 = GaugeMetricFamily('airfilter_eco2', 'eco2 reading', labels=['sensor', 'unit']) tvoc = GaugeMetricFamily('airfilter_tvoc', 'tvoc reading', labels=['sensor', 'unit']) if (ccs811.checkDataReady(statusbyte)): samples.add_metric(['ccs811'], 1) yield samples result = ccs811.readAlg() if (result): res.add_metric(['ccs811'], 1) yield res eco2.add_metric(['ccs811', 'ppm'], result['eCO2']) yield eco2 tvoc.add_metric(['ccs811', 'ppb'], result['TVOC']) yield tvoc else: res.add_metric(['ccs811'], 0) yield res eco2.add_metric(['ccs811', 'ppm'], 0) yield eco2 tvoc.add_metric(['ccs811', 'ppb'], 0) yield tvoc else: samples.add_metric(['ccs811'], 0) yield samples res.add_metric(['ccs811'], 0) yield res eco2.add_metric(['ccs811', 'ppm'], 0) yield eco2 tvoc.add_metric(['ccs811', 'ppb'], 0) yield tvoc
def __init__(self): self.logger = self._init_logger() # Enable graceful shutdown of the service: signal.signal(signal.SIGTERM, self._handle_sigterm) # Take a sample every x seconds: self.sampling_rate = 5.0 self.continue_measurement = True # ---------------------------------------------------------------------- # *** Load settings from .env file # Experimental condition, e.g. 'baseline' or 'with_filter': experimental_condition = settings.EXPERIMENTAL_CONDITION # Directory where to store data (e.g. '/home/pi/air_quality/'): data_directory = settings.DATA_DIRECTORY # Path of csv file where to store measurement data: self.path_csv = os.path.join( data_directory, 'measurement_{}.csv'.format(experimental_condition)) # If the csv file does not exist yet, create it and write first line # (header): if not os.path.isfile(self.path_csv): with open(self.path_csv, mode='w') as csv_file: csv_write = csv.writer(csv_file, delimiter=',') csv_write.writerow(['timestamp', 'pm25', 'pm10']) # ---------------------------------------------------------------------- # *** Initialise sensor sensor_initialised = False while not sensor_initialised: try: # Initialise sensor: self.sensor = SDS011('/dev/ttyUSB0', use_query_mode=True) time.sleep(5) self.sensor.sleep(sleep=False) # Give sensor time to stabilise: time.sleep(30) for x in range(5): _, _ = self.sensor.query() time.sleep(1) sensor_initialised = True except Exception: msg = 'Failed to initialise sensor, will try again.' self.logger.error(msg) self.logger.info('py-air-quality continuous measurement started.')
class SDS011(Accessory): """Accessory wrapper for SDS011. """ category = CATEGORY_SENSOR SORTED_PM_QUALITY_MAP = ((200, 5), (150, 4), (100, 3), (50, 2), (0, 1)) """ Threshold-to-state tuples. These show the state for which the threshold is lower boundary. Uses something like Air Quality Index (AQI). The UI shows: 1 - Excellent 2 - Good 3 - Fair 4 - Inferior 5 - Poor """ def __init__(self, serial_port, *args, calib_duration_s=15, **kwargs): """Initialize and start SDS011 on the given port. @param serial_port: The SDS011 port, e.g. /dev/ttyUSB0. @type serial_port: str @param calib_duration_s: The amount of time in seconds to wait after the sensor has been waken up before reading its data. Defaults to 15 seconds. @type calib_duration_s: float """ self.pm25_quality = None self.pm25_density = None self.pm10_quality = None self.pm10_density = None super().__init__(*args, **kwargs) # PM2.5 air_quality_pm25 = self.add_preload_service( 'AirQualitySensor', chars=['Name', 'AirParticulateSize', 'AirParticulateDensity']) air_quality_pm25.configure_char('AirParticulateSize', value=0) air_quality_pm25.configure_char('Name', value='PM2.5') self.pm25_quality = air_quality_pm25.configure_char('AirQuality') self.pm25_density = air_quality_pm25.configure_char( 'AirParticulateDensity') # PM10 air_quality_pm10 = self.add_preload_service( 'AirQualitySensor', chars=['Name', 'AirParticulateSize', 'AirParticulateDensity']) air_quality_pm10.configure_char('AirParticulateSize', value=1) air_quality_pm10.configure_char('Name', value='PM10') self.pm10_quality = air_quality_pm10.configure_char('AirQuality') self.pm10_density = air_quality_pm10.configure_char( 'AirParticulateDensity') self.calib_duration_s = calib_duration_s self.serial_port = serial_port self.sensor = AirSensor(serial_port) self.sensor.sleep(sleep=False) def get_quality_classification(self, pm, is_pm25=False): """Get the air quality classification based on the PM density. Uses Air Quality Index (AQI), without averaging for an hour. @see: SDS011.SORTED_PM_QUALITY_MAP @rtype: int """ assert pm >= 0 return next(state for threshold, state in self.SORTED_PM_QUALITY_MAP if threshold <= pm) @Accessory.run_at_interval(SLEEP_DURATION_S) async def run(self): """Start updating the air quality readings. Wake the sensor, wait for `calib_duration_s` seconds for the sensor to calibrate, read from the sensor and finaly put it to sleep. """ logger.debug("Waking up sensor.") self.sensor.sleep(sleep=False) await asyncio.sleep(self.calib_duration_s, loop=self.driver.loop) pm25, pm10 = self.sensor.query() self.pm25_density.set_value(pm25) self.pm25_quality.set_value( self.get_quality_classification(pm25, is_pm25=True)) self.pm10_density.set_value(pm10) self.pm10_quality.set_value( self.get_quality_classification(pm10, is_pm25=False)) self.sensor.sleep() logger.debug("Read cycle done. Sleeping.")
def sds_011(port): #[0]-> pm2.5 value, [1] -> pm10 value return SDS011(port).query()
#json_path = '..\\html\\aqi.json' #csv_path = "..\\html\\aqi.csv" def initiate_json(file_path): """ Check to see if the aqi.json exists in the html directory and add it if not """ if not exists(file_path): with open(file_path, "w") as fresh_file: fresh_file.write('[]') if __name__ == '__main__': sensor = SDS011(port, baudrate=baudrate, use_query_mode=True) sensor.sleep(sleep=False) #initiate_json() initiate_json(json_path) logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', filename='aqi.log', level=logging.DEBUG) logging.info('AQI Monitor has been started!') # how many failed readings can we tolerate failure_tolerance = 3 loop_forever = True
data = str(f.read()) print("Got", data) time.sleep(time_sleep) except KeyboardInterrupt: print("error : %s ", url) return 0 # simple parsing the command arguments for setting options # Create an instance of your sensor # options defaults: logging None, debug level 0, serial line timeout 2 # option unit_of_measure (default False) values in pcs/0.01sqf or mass ug/m3 #sensor = SDS011(sys.argv[1], timeout=timeout, unit_of_measure=unit_of_measure) sensor = SDS011(ddev, timeout=timeout, unit_of_measure=unit_of_measure) # raise KeyboardInterrupt # Now we have some details about it print("SDS011 sensor info:") print("Device ID: ", sensor.device_id) print("Device firmware: ", sensor.firmware) print("Current device cycle (0 is permanent on): ", sensor.dutycycle) print(sensor.workstate) print(sensor.reportmode) print("\n%d measurements in permanent measuring mode" % (cycles * 2)) print("This will make the sensor getting old. The TTL is just 8000 hours!") print("Do you really need to use the permanent measurering mode?") print("In sleep mode the fan will be turned off.")
handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - \ %(filename)s:%(lineno)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) ''' # Create a new sensor instance ''' On Win, the path is one of the com ports. On Linux / Raspberry Pi it depends. May be one of "/dev/ttyUSB..." or "/dev/ttyAMA...". Have a look at Win or Linux documentation. ''' # Create an instance of your sensor sensor = SDS011('/dev/ttyUSB0') # Now we have some details about it print('Device ID') print(sensor.device_id) print('Firmware') print(sensor.firmware) print(sensor.dutycycle) print(sensor.workstate) print(sensor.reportmode) # Set dutycyle to nocycle (permanent) sensor.dutycycle = 0 sensor.workstate = SDS011.WorkStates.Measuring print( "Permanent measureing (and make the senor get old. Just 8000 hours working!)\n \ Do you really need permanent measurering?")
def get_usb(): try: with subprocess.Popen(['ls /dev/ttyUSB*'], shell=True, stdout=subprocess.PIPE) as f: usbs = f.stdout.read().decode('utf-8') usbs = usbs.split('\n') usbs = [usb for usb in usbs if len(usb) > 3] except Exception as e: print('No USB available') return usbs if __name__ == '__main__': usbs = get_usb() processs = list() for port in usbs: p = SDS011(port=port, push_mqtt=False, push_domo=True, interval=60) processs.append(p) # for p in processs: # p.set_active() while True: for p in processs: try: #p.run_passive() p.run_query() except Exception as e: print(f'Error: {p.name} with {e}') continue