From b78e3172358e36905186788c4bf84f6ab0c2e301 Mon Sep 17 00:00:00 2001 From: Frank Morton Date: Sun, 25 Nov 2018 16:46:10 -0500 Subject: [PATCH 1/4] improve read_pulses/blocking reliability --- adafruit_irremote.py | 63 +++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/adafruit_irremote.py b/adafruit_irremote.py index d5fc6d8..e2b6a14 100644 --- a/adafruit_irremote.py +++ b/adafruit_irremote.py @@ -73,6 +73,7 @@ # pylint: disable=no-self-use import array +import time __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_IRRemote.git" @@ -192,30 +193,56 @@ def decode_bits(self, pulses, debug=False): output[i // 8] |= 1 return output - def read_pulses(self, input_pulses, max_pulse=10000, blocking=True): - """Read out a burst of pulses until a pulse is longer than ``max_pulse``. + def read_pulses_non_blocking(self, input_pulses, max_pulse=10000, pulse_window=0.10): + """Read out a burst of pulses without blocking until pulses stop for a specified + period (pulse_window), pruning pulses after a pulse longer than ``max_pulse``. - :param ~pulseio.PulseIn input_pulses: Object to read pulses from - :param int max_pulse: Pulse duration to end a burst - :param bool blocking: If True, will block until pulses found. - If False, will return None if no pulses. - Defaults to True for backwards compatibility + :param ~pulseio.PulseIn input_pulses: Object to read pulses from + :param int max_pulse: Pulse duration to end a burst + :param float pulse_window: pulses are collected for this period of time """ - if not input_pulses and not blocking: - return None - received = [] + received = None + recent_count = 0 + pruning = False while True: - while not input_pulses: - pass - while input_pulses: + try: pulse = input_pulses.popleft() + recent_count += 1 if pulse > max_pulse: - if not received: + if received is None: continue - else: - return received - received.append(pulse) - return received + pruning = True + if not pruning: + if received is None: + received = [] + received.append(pulse) + except IndexError: + if recent_count == 0: + return received + recent_count = 0 + time.sleep(pulse_window) + + # pylint: disable-msg=too-many-arguments + def read_pulses(self, input_pulses, max_pulse=10000, blocking=True, + pulse_window=0.10, blocking_delay=0.10): + """Read out a burst of pulses until pulses stop for a specified + period (pulse_window), pruning pulses after a pulse longer than ``max_pulse``. + + :param ~pulseio.PulseIn input_pulses: Object to read pulses from + :param int max_pulse: Pulse duration to end a burst + :param bool blocking: If True, will block until pulses found. + If False, will return None if no pulses. + Defaults to True for backwards compatibility + :param float pulse_window: pulses are collected for this period of time + :param float blocking_delay: delay between pulse checks when blocking + """ + while True: + pulses = self.read_pulses_non_blocking(input_pulses, max_pulse, pulse_window) + if blocking and pulses is None: + time.sleep(blocking_delay) + continue + return pulses + # pylint: enable-msg=too-many-arguments class GenericTransmit: """Generic infrared transmit class that handles encoding.""" From 85bf01931430452c5b6dddfcedeae9a8539fe4b4 Mon Sep 17 00:00:00 2001 From: fmorton Date: Fri, 30 Nov 2018 11:08:54 -0500 Subject: [PATCH 2/4] make read_pulses_non_blocking private --- adafruit_irremote.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_irremote.py b/adafruit_irremote.py index e2b6a14..5f9126e 100644 --- a/adafruit_irremote.py +++ b/adafruit_irremote.py @@ -193,7 +193,7 @@ def decode_bits(self, pulses, debug=False): output[i // 8] |= 1 return output - def read_pulses_non_blocking(self, input_pulses, max_pulse=10000, pulse_window=0.10): + def _read_pulses_non_blocking(self, input_pulses, max_pulse=10000, pulse_window=0.10): """Read out a burst of pulses without blocking until pulses stop for a specified period (pulse_window), pruning pulses after a pulse longer than ``max_pulse``. @@ -237,7 +237,7 @@ def read_pulses(self, input_pulses, max_pulse=10000, blocking=True, :param float blocking_delay: delay between pulse checks when blocking """ while True: - pulses = self.read_pulses_non_blocking(input_pulses, max_pulse, pulse_window) + pulses = self._read_pulses_non_blocking(input_pulses, max_pulse, pulse_window) if blocking and pulses is None: time.sleep(blocking_delay) continue From 77b83b1bbdd47db17fb5ad17ea6003f3812bdca7 Mon Sep 17 00:00:00 2001 From: fmorton Date: Fri, 30 Nov 2018 12:20:16 -0500 Subject: [PATCH 3/4] check input_pulses length in read_pulses instead of try/except --- adafruit_irremote.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/adafruit_irremote.py b/adafruit_irremote.py index 5f9126e..8d1e6cb 100644 --- a/adafruit_irremote.py +++ b/adafruit_irremote.py @@ -205,7 +205,7 @@ def _read_pulses_non_blocking(self, input_pulses, max_pulse=10000, pulse_window= recent_count = 0 pruning = False while True: - try: + while input_pulses: pulse = input_pulses.popleft() recent_count += 1 if pulse > max_pulse: @@ -216,11 +216,11 @@ def _read_pulses_non_blocking(self, input_pulses, max_pulse=10000, pulse_window= if received is None: received = [] received.append(pulse) - except IndexError: - if recent_count == 0: - return received - recent_count = 0 - time.sleep(pulse_window) + + if recent_count == 0: + return received + recent_count = 0 + time.sleep(pulse_window) # pylint: disable-msg=too-many-arguments def read_pulses(self, input_pulses, max_pulse=10000, blocking=True, From 78d1610783cc5f0bd642b05282006c06971b4be8 Mon Sep 17 00:00:00 2001 From: fmorton Date: Mon, 3 Dec 2018 09:50:38 -0500 Subject: [PATCH 4/4] fix read_pulses for pylint by having one positional arg --- adafruit_irremote.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/adafruit_irremote.py b/adafruit_irremote.py index 8d1e6cb..4009556 100644 --- a/adafruit_irremote.py +++ b/adafruit_irremote.py @@ -222,8 +222,7 @@ def _read_pulses_non_blocking(self, input_pulses, max_pulse=10000, pulse_window= recent_count = 0 time.sleep(pulse_window) - # pylint: disable-msg=too-many-arguments - def read_pulses(self, input_pulses, max_pulse=10000, blocking=True, + def read_pulses(self, input_pulses, *, max_pulse=10000, blocking=True, pulse_window=0.10, blocking_delay=0.10): """Read out a burst of pulses until pulses stop for a specified period (pulse_window), pruning pulses after a pulse longer than ``max_pulse``. @@ -242,7 +241,6 @@ def read_pulses(self, input_pulses, max_pulse=10000, blocking=True, time.sleep(blocking_delay) continue return pulses - # pylint: enable-msg=too-many-arguments class GenericTransmit: """Generic infrared transmit class that handles encoding."""