From 065b5aa40ddf796e7b772c108f317fc3dc25ae9f Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 15 Sep 2015 16:02:16 +0100 Subject: [PATCH] Draft of a queue implementation for MotionSensor This is a quick *untested* implementation of a background threaded queue for `MotionSensor`. The optional *queue_len* is the number of values to store in the queue, *sample_rate* is the number of times per second to query the motion sensor, and if *partial* is False (the default) then the `motion_detected` property won't return anything until the queue has been filled. --- gpio_components/input_devices.py | 36 +++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/gpio_components/input_devices.py b/gpio_components/input_devices.py index bbc188a..41a2e99 100644 --- a/gpio_components/input_devices.py +++ b/gpio_components/input_devices.py @@ -1,3 +1,9 @@ +from __future__ import division + +from time import sleep +from threading import Thread, Event +from collections import deque + from RPi import GPIO from w1thermsensor import W1ThermSensor @@ -36,14 +42,34 @@ class Button(InputDevice): class MotionSensor(InputDevice): - def _is_active_with_pause(self): - sleep(0.1) - return self.is_active + def __init__(self, pin=None, queue_len=20, sample_rate=10, partial=False): + super(MotionSensor, self).__init__(pin) + self._sample_rate = sample_rate + self._partial = partial + self._queue = deque(maxlen=queue_len) + self._queue_full = Event() + self._terminated = False + self._queue_thread = Thread(target=self._fill_queue) + self._queue_thread.start() + + def __del__(self): + self._terminated = True + self._queue_thread.join() + + def _fill_queue(self): + while not self._terminated and len(self._queue) < self._queue.maxlen: + self._queue.append(self.is_active) + sleep(1 / self._sample_rate) + self._queue_full.set() + while not self._terminated: + self._queue.append(self.is_active) + sleep(1 / self._sample_rate) @property def motion_detected(self): - n = 20 - return sum(self._is_active_with_pause() for i in range(n)) > n/2 + if not self._partial: + self._queue_full.wait() + return sum(self._queue) > (len(self._queue) / 2) class LightSensor(object):