Skip to content

Commit

Permalink
Add max_retries flag for SensorReader.__call__
Browse files Browse the repository at this point in the history
In response to [^1].

[^1]: #33 (comment)
  • Loading branch information
benthorner authored and avaldebe committed Dec 6, 2022
1 parent 820d267 commit 90e904d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/pms/core/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def __init__(
interval: Optional[int] = None,
samples: Optional[int] = None,
timeout: Optional[float] = None,
max_retries: Optional[int] = None,
) -> None:
"""Configure serial port"""
self.sensor = sensor if isinstance(sensor, Sensor) else Sensor[sensor]
Expand All @@ -101,6 +102,7 @@ def __init__(
self.serial.port = port
self.serial.baudrate = self.sensor.baud
self.serial.timeout = timeout or 5 # max time to wake up sensor
self.max_retries = max_retries
self.interval = interval
self.samples = samples
logger.debug(
Expand Down Expand Up @@ -169,16 +171,23 @@ def __call__(self, *, raw: Optional[bool] = None):
"""Passive mode reading at regular intervals"""

sample = 0
failures = 0
while self.serial.is_open:
try:
buffer = self._cmd("passive_read")

try:
obs = self.sensor.decode(buffer)
except SensorNotReady as e:
failures += 1
if self.max_retries is not None and failures > self.max_retries:
raise
logger.debug(e)
time.sleep(5)
except SensorWarning as e:
failures += 1
if self.max_retries is not None and failures > self.max_retries:
raise
logger.debug(e)
self.serial.reset_input_buffer()
else:
Expand Down
27 changes: 27 additions & 0 deletions tests/core/test_reader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest

import pms
from pms.core import reader
from pms.core.sensor import Sensor
from tests.conftest import captured_data
Expand Down Expand Up @@ -139,13 +140,15 @@ def factory(
samples=0, # exit immediately
interval=None,
sensor="PMSx003", # match with stubs
max_retries=None,
):
sensor_reader = reader.SensorReader(
port=mock_sensor.port,
samples=samples,
interval=interval,
sensor=sensor,
timeout=0.01, # low to avoid hanging on failure
max_retries=max_retries,
)

# https://github.com/pyserial/pyserial/issues/625
Expand Down Expand Up @@ -229,6 +232,18 @@ def test_sensor_reader_warm_up(
assert len(obs) == 1


def test_sensor_reader_warm_up_exhaust_retries(
mock_sensor,
sensor_reader_factory,
mock_sensor_warm_up,
):
sensor_reader = sensor_reader_factory(max_retries=0)

with sensor_reader as r:
with pytest.raises(pms.SensorWarmingUp):
list(r())


def test_sensor_reader_temp_failure(
mock_sensor,
sensor_reader_factory,
Expand All @@ -246,6 +261,18 @@ def test_sensor_reader_temp_failure(
assert mock_sensor.stubs["passive_read"].calls == 2


def test_sensor_reader_temp_failure_exhaust_retries(
mock_sensor,
sensor_reader_factory,
mock_sensor_temp_failure,
):
sensor_reader = sensor_reader_factory(max_retries=0)

with sensor_reader as r:
with pytest.raises(pms.SensorWarning):
list(r())


def test_sensor_reader_sensor_mismatch(mock_sensor, sensor_reader_factory):
sensor_reader = sensor_reader_factory()

Expand Down

0 comments on commit 90e904d

Please sign in to comment.