def test_read_fail(): _mock() import pms5003 sensor = pms5003.PMS5003(serial=MockSerialFail()) with pytest.raises(pms5003.ReadTimeoutError): data = sensor.read() del data
def test_read(): _mock() import pms5003 sensor = pms5003.PMS5003() sensor._serial = MockSerial() data = sensor.read() data.pm_ug_per_m3(2.5)
def test_active_mode_to_passive_to_active(): """Test new simulator object with instantiation in default active mode and then a switch to passive mode and then back to active. """ _mock() import pms5003 serial = PMS5003Simulator() sensor = pms5003.PMS5003(serial=serial) data1 = sensor.read() data1.pm_ug_per_m3(2.5) # This should block until new data is generated by simulator data2 = sensor.read() data2.pm_ug_per_m3(2.5) sensor.cmd_mode_passive() assert serial.written_data == PASSIVE_REQ data3 = sensor.read() data3.pm_ug_per_m3(2.5) time.sleep(0.5) data4 = sensor.read() data4.pm_ug_per_m3(2.5) sensor.cmd_mode_active() assert serial.written_data == PASSIVE_REQ + READ_REQ + READ_REQ + ACTIVE_REQ data5 = sensor.read() data5.pm_ug_per_m3(2.5)
def test_checksum_pass(): _mock() import pms5003 serial = MockSerialArbitrary() serial.simulate_rx(GOODFRAME1) sensor = pms5003.PMS5003(serial=serial) data = sensor.read() assert data.pm_ug_per_m3(2.5) == 4
def test_checksum_fail(): _mock() import pms5003 serial = MockSerialArbitrary() serial.simulate_rx(GOODFRAME1) sensor = pms5003.PMS5003(serial=serial, retries=0) data = sensor.read() assert data.pm_ug_per_m3(2.5) == 4 serial.simulate_rx(BADFRAME1) with pytest.raises(pms5003.ChecksumMismatchError): data = sensor.read()
def test_checksum_fail_withretries(): """This simulates a good data frame, a bad data frame, then silence.""" _mock() import pms5003 serial = MockSerialArbitrary() serial.simulate_rx(GOODFRAME1) sensor = pms5003.PMS5003(serial=serial, retries=5) data1 = sensor.read() assert data1.pm_ug_per_m3(2.5) == 4 serial.simulate_rx(BADFRAME1) with pytest.raises(pms5003.ChecksumMismatchError): data2 = sensor.read()
def test_passive_mode_read(): """Test the new passive mode using new simulator object where responses are requested by polling. """ _mock() import pms5003 serial = PMS5003Simulator() sensor = pms5003.PMS5003(serial=serial, mode='passive') assert serial.written_data == PASSIVE_REQ data1 = sensor.read() data1.pm_ug_per_m3(2.5) time.sleep(0.5) data2 = sensor.read() data2.pm_ug_per_m3(2.5)
def test_checksum_retries_ok(): """This simulates a good data frame, a bad data frame, then a good data frame.""" _mock() import pms5003 serial = MockSerialArbitrary() serial.simulate_rx(GOODFRAME1) sensor = pms5003.PMS5003(serial=serial, retries=5) data1 = sensor.read() assert data1.pm_ug_per_m3(2.5) == 4 serial.simulate_rx(BADFRAME1) serial.simulate_rx(GOODFRAME2) # This should read the bad frame, then retry and get the the good one data2 = sensor.read() assert data2.pm_ug_per_m3(2.5) == 9 assert sensor.data_available() is False
def test_buffer_full_truncation(): """Simulates the serial object's buffer being full causing the truncation of the third data frame.""" _mock() import pms5003 serial = MockSerialArbitrary(rx_buf_size=80) serial.simulate_rx(GOODFRAME1) sensor = pms5003.PMS5003(serial=serial) serial.simulate_rx(GOODFRAME2) serial.simulate_rx(GOODFRAME1) data = sensor.read() assert data.pm_ug_per_m3(2.5) == 4 data = sensor.read() assert data.pm_ug_per_m3(2.5) == 9 with pytest.raises(pms5003.SerialTimeoutError): data = sensor.read()
def test_buffer_full_lucky(): """Simulates the serial object's buffer being exactly full which by good fortunate prevents truncation of subsequent data frame.""" _mock() import pms5003 serial = MockSerialArbitrary(rx_buf_size=64) serial.simulate_rx(GOODFRAME1) # 32 bytes, fits sensor = pms5003.PMS5003(serial=serial) serial.simulate_rx(GOODFRAME2) # 32 bytes, fits serial.simulate_rx(GOODFRAME1) # 32 bytes, discarded completely data = sensor.read() assert data.pm_ug_per_m3(2.5) == 4 data = sensor.read() assert data.pm_ug_per_m3(2.5) == 9 with pytest.raises(pms5003.SerialTimeoutError): data = sensor.read()
def test_odd_zero_burst(): """Test an odd length burst of NUL characters appearing between data frames. This tests the correctness of the code which parses the first two bytes of frame header. """ _mock() import pms5003 serial = PMS5003Simulator() sensor = pms5003.PMS5003(serial=serial) data1 = sensor.read() data1.pm_ug_per_m3(2.5) # Odd length (five) is important here serial.simulate_rx(b"\x00\x00\x00\x00\x00") # This should block until new data is generated by simulator data2 = sensor.read() data2.pm_ug_per_m3(2.5)
def test_active_mode_read(): """Test active mode using new simulator object. """ _mock() import pms5003 serial = PMS5003Simulator() sensor = pms5003.PMS5003(serial=serial) # The constructor waits for data but does not read it therefore this # will always be True after the object is created successfully assert sensor.data_available() is True data1 = sensor.read() data1.pm_ug_per_m3(2.5) # This should block until new data is generated by simulator data2 = sensor.read() data2.pm_ug_per_m3(2.5)
def test_active_mode_to_passive(): """Test new simulator object with instantiation in default active mode and then a switch to passive mode. """ _mock() import pms5003 serial = PMS5003Simulator() sensor = pms5003.PMS5003(serial=serial) data1 = sensor.read() data1.pm_ug_per_m3(2.5) # This should block until new data is generated by simulator data2 = sensor.read() data2.pm_ug_per_m3(2.5) sensor.cmd_mode_passive() data3 = sensor.read() data3.pm_ug_per_m3(2.5)
def test_buffer_full_badframelen_long1(): """Simulates the serial object's buffer being full, truncating a frame and then a good frame being appended to that stub to make a whole bad frame.""" _mock() import pms5003 serial = MockSerialArbitrary(rx_buf_size=34) serial.simulate_rx(GOODFRAME1) sensor = pms5003.PMS5003(serial=serial, retries=0) serial.simulate_rx(GOODFRAME1) data = sensor.read() assert data.pm_ug_per_m3(2.5) == 4 # Now add a real frame to the truncated leftovers in # the buffer to cause a bogus frame length field with # value 16973 serial.simulate_rx(GOODFRAME1) with pytest.raises(pms5003.FrameLengthError): data = sensor.read()
def test_active_mode_to_passive_unlucky(): """Test new simulator object with instantiation in default active mode and then a switch to passive mode but with unfortunate timing where a data frame sneaks in before the response to passive mode command. """ _mock() import pms5003 serial = PMS5003Simulator() sensor = pms5003.PMS5003(serial=serial) data1 = sensor.read() data1.pm_ug_per_m3(2.5) # This should block until new data is generated by simulator data2 = sensor.read() data2.pm_ug_per_m3(2.5) serial.data_frames -= 1 # hacky way to sneak an inopportune data frame in sensor.cmd_mode_passive() assert serial.written_data == PASSIVE_REQ data3 = sensor.read() data3.pm_ug_per_m3(2.5)
def test_buffer_full_badframelen_short(): """Simulates the serial object's buffer being full, truncating a frame and then a good frame being appended to the stub resulting in a short frame length field.""" _mock() import pms5003 serial = MockSerialArbitrary(rx_buf_size=34) serial.simulate_rx(GOODFRAME1) sensor = pms5003.PMS5003(serial=serial, retries=0) serial.simulate_rx(GOODFRAME1) data = sensor.read() data.pm_ug_per_m3(2.5) # Now add part of a real frame to truncated leftovers in the buffer # this will be rare but could happen if library is reading from full # buffer in the middle of PMS5003 sending data # this has a very high probability of the checksum failing serial.simulate_rx(GOODFRAME1[10:]) serial.simulate_rx(GOODFRAME1) with pytest.raises(pms5003.FrameLengthError): data = sensor.read()
async def run_pm_continuous(self): log.info('PM:30s warm-up') self.pm_pwr_pin.value(1) await asyncio.sleep(30) # 30s warm-up period as specified in datasheet self.uart = UART(1, tx=32, rx=33, baudrate=9600) self.pm = pms5003.PMS5003(self.uart, self.lock, event = self.event_new_pm_data) while True: await asyncio.sleep(1) log.debug('PM:set Passive mode') await self.pm.setPassiveMode() log.debug('PM:trigger read sensor') await asyncio.sleep(1) await self.pm.read() log.debug('PM:waiting for event') await self.event_new_pm_data log.debug('PM:got event') repo.add('pm10', self.pm.pm10_env) repo.add('pm25', self.pm.pm25_env) repo.add('pm100', self.pm.pm100_env) log.debug('PM:PM2.5 = %d', repo.get('pm25').current) self.event_new_pm_data.clear() await asyncio.sleep(0)
import time from signal import signal, SIGINT import matplotlib.pyplot as plt import datetime import pms5003 plt.ioff() # turn "interactive" mode off # so that plots do not automatically display on screen # we just want them written to files. sensor = pms5003.PMS5003() def handler(signal_received, frame): sensor.uart.close() sensor.flush_fast() # sensor.write2file() sensor.smartwrite() print('Exiting PMS5003 infinite loop; thank you and come again') exit() signal(SIGINT, handler) while True: for counter in range(5): sensor.gather(20) sensor.flush_fast() print('solo_pms5003: fast cycle complete', datetime.datetime.now()) sensor.slowbuffer.plot(y=sensor.columns[6:]) plt.savefig(sensor.data_folder+'/pms5003.png') for fignum in plt.get_fignums():
def test_double_setup(): _mock() import pms5003 sensor = pms5003.PMS5003() sensor.setup()
"temperature (C)", "pressure (hPa)", "rel. humidity (%RH)", "gas resistance (counts)", "PM > 0.3um (/0.1L air)", "PM > 0.5um (/0.1L air)", "PM > 1.0um (/0.1L air)", "PM > 2.5um (/0.1L air)", "PM > 5.0um (/0.1L air)", "PM > 10um (/0.1L air)", ] # configure the PMS5003 particulate sensor pms = pms5003.PMS5003( device='/dev/ttyAMA0', baudrate=9600, pin_enable=22, pin_reset=27 ) pms.setup() # configure the bme680 temp/humidity/pressure sensor bme = bme680.BME680(bme680.I2C_ADDR_PRIMARY) bme.set_humidity_oversample(bme680.OS_2X) bme.set_pressure_oversample(bme680.OS_4X) bme.set_temperature_oversample(bme680.OS_8X) bme.set_temp_offset(-4) # this is a guess at what the offset should be bme.set_filter(bme680.FILTER_SIZE_3) bme.set_gas_status(bme680.ENABLE_GAS_MEAS) bme.set_gas_heater_temperature(320) bme.set_gas_heater_duration(150)
"gas_reducing", "gas_oxidising", "gas_NH3", "PM1_0", "PM2_5", "PM10_0", ), ) # time between measurements DELTA_S = 30.0 if can_take_readings: BUS = smbus2.SMBus(1) BME280 = bme280.BME280(i2c_dev=BUS) PMS5003 = pms5003.PMS5003() def take_readings(): reading_number = 0 # first reading is always junk reading = take_reading(reading_number=reading_number) reading_number += 1 with contextlib.closing( mariadb.connect(default_file=str(SETTINGS_PATH))) as db: cursor = db.cursor()
def test_setup(): _mock() import pms5003 sensor = pms5003.PMS5003(serial=MockSerial()) del sensor
def test_setup(): _mock() import pms5003 sensor = pms5003.PMS5003() del sensor
def test_double_setup(): _mock() import pms5003 serial = MockSerial() sensor = pms5003.PMS5003(serial=serial) sensor.setup(serial)