From ea4e293338962fd1a34305feeb35a7c138968932 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Tue, 27 Feb 2024 23:16:36 +0100 Subject: [PATCH] [#352] Migrated `backend.sensor.leap` to `leap` plugin. Closes: #352 --- docs/source/backends.rst | 1 - docs/source/platypush/backend/sensor.leap.rst | 7 -- docs/source/platypush/plugins/leap.rst | 5 ++ docs/source/plugins.rst | 1 + platypush/backend/sensor/leap/manifest.yaml | 15 ---- .../sensor => plugins}/leap/__init__.py | 87 ++++++++----------- platypush/plugins/leap/manifest.yaml | 11 +++ 7 files changed, 52 insertions(+), 75 deletions(-) delete mode 100644 docs/source/platypush/backend/sensor.leap.rst create mode 100644 docs/source/platypush/plugins/leap.rst delete mode 100644 platypush/backend/sensor/leap/manifest.yaml rename platypush/{backend/sensor => plugins}/leap/__init__.py (79%) create mode 100644 platypush/plugins/leap/manifest.yaml diff --git a/docs/source/backends.rst b/docs/source/backends.rst index e7aad8389..8288711e2 100644 --- a/docs/source/backends.rst +++ b/docs/source/backends.rst @@ -16,7 +16,6 @@ Backends platypush/backend/nodered.rst platypush/backend/redis.rst platypush/backend/sensor.ir.zeroborg.rst - platypush/backend/sensor.leap.rst platypush/backend/stt.deepspeech.rst platypush/backend/stt.picovoice.hotword.rst platypush/backend/stt.picovoice.speech.rst diff --git a/docs/source/platypush/backend/sensor.leap.rst b/docs/source/platypush/backend/sensor.leap.rst deleted file mode 100644 index 337233211..000000000 --- a/docs/source/platypush/backend/sensor.leap.rst +++ /dev/null @@ -1,7 +0,0 @@ -``sensor.leap`` -================================= - -.. automodule:: platypush.backend.sensor.leap - :members: - - diff --git a/docs/source/platypush/plugins/leap.rst b/docs/source/platypush/plugins/leap.rst new file mode 100644 index 000000000..4ad5ff3b2 --- /dev/null +++ b/docs/source/platypush/plugins/leap.rst @@ -0,0 +1,5 @@ +``leap`` +======== + +.. automodule:: platypush.plugins.leap + :members: diff --git a/docs/source/plugins.rst b/docs/source/plugins.rst index a021e64d0..4cde2fb97 100644 --- a/docs/source/plugins.rst +++ b/docs/source/plugins.rst @@ -59,6 +59,7 @@ Plugins platypush/plugins/lastfm.rst platypush/plugins/lcd.gpio.rst platypush/plugins/lcd.i2c.rst + platypush/plugins/leap.rst platypush/plugins/light.hue.rst platypush/plugins/linode.rst platypush/plugins/log.http.rst diff --git a/platypush/backend/sensor/leap/manifest.yaml b/platypush/backend/sensor/leap/manifest.yaml deleted file mode 100644 index 1dfa51981..000000000 --- a/platypush/backend/sensor/leap/manifest.yaml +++ /dev/null @@ -1,15 +0,0 @@ -manifest: - events: - platypush.message.event.sensor.leap.LeapConnectEvent: when a Leap Motion device - is connected - platypush.message.event.sensor.leap.LeapDisconnectEvent: when a Leap Motion device - disconnects - platypush.message.event.sensor.leap.LeapFrameEvent: when a new frame is received - platypush.message.event.sensor.leap.LeapFrameStartEvent: when a new sequence of - frame starts - platypush.message.event.sensor.leap.LeapFrameStopEvent: when a sequence of frame - stops - install: - pip: [] - package: platypush.backend.sensor.leap - type: backend diff --git a/platypush/backend/sensor/leap/__init__.py b/platypush/plugins/leap/__init__.py similarity index 79% rename from platypush/backend/sensor/leap/__init__.py rename to platypush/plugins/leap/__init__.py index 9b2fff0f4..1ee90adae 100644 --- a/platypush/backend/sensor/leap/__init__.py +++ b/platypush/plugins/leap/__init__.py @@ -1,12 +1,10 @@ -import time - from threading import Timer from multiprocessing import Process +from typing import Iterable, Optional import Leap -from platypush.backend import Backend -from platypush.context import get_backend +from platypush.context import get_bus from platypush.message.event.sensor.leap import ( LeapFrameEvent, LeapFrameStartEvent, @@ -14,12 +12,14 @@ from platypush.message.event.sensor.leap import ( LeapConnectEvent, LeapDisconnectEvent, ) +from platypush.plugins import RunnablePlugin -class SensorLeapBackend(Backend): +class LeapPlugin(RunnablePlugin): """ - Backend for events generated using a Leap Motion device to track hands and - gestures, https://www.leapmotion.com/ + Integration to handle events from a `Leap Motion + `_ device to track hands and + gestures. Note that the default SDK is not compatible with Python 3. Follow the instructions on https://github.com/BlackLight/leap-sdk-python3 to build the @@ -41,10 +41,9 @@ class SensorLeapBackend(Backend): def __init__( self, - position_ranges=None, - position_tolerance=0.0, # Position variation tolerance in % - frames_throttle_secs=None, - *args, + position_ranges: Optional[Iterable[Iterable[float]]] = None, + position_tolerance: float = 0.0, + poll_interval: Optional[float] = 0.1, **kwargs ): """ @@ -58,22 +57,15 @@ class SensorLeapBackend(Backend): [25.0, 600.0], # y axis [-300.0, 300.0], # z axis ] - - :type position_ranges: list[list[float]] - :param position_tolerance: % of change between a frame and the next to really consider the next frame as a new one (default: 0). - :type position_tolerance: float - - :param frames_throttle_secs: If set, the frame events will be throttled - and pushed to the main queue at the specified rate. Good to set if - you want to connect Leap Motion events to actions that have a lower - throughput (the Leap Motion can send a lot of frames per second). - Default: None (no throttling) - :type frames_throttle_secs: float + :param poll_interval: How often the plugin should generate and push + events (default: at most one event each 0.1 seconds). Note that a + Leap Motion generates events with a very high throughput, so you + may want to set a higher value if you want to throttle the events + and avoid flooding the bus. """ - - super().__init__(*args, **kwargs) + super().__init__(poll_interval=poll_interval, **kwargs) if position_ranges is None: position_ranges = [ @@ -84,16 +76,13 @@ class SensorLeapBackend(Backend): self.position_ranges = position_ranges self.position_tolerance = position_tolerance - self.frames_throttle_secs = frames_throttle_secs - - def run(self): - super().run() + def main(self): def _listener_process(): listener = LeapListener( position_ranges=self.position_ranges, position_tolerance=self.position_tolerance, - frames_throttle_secs=self.frames_throttle_secs, + frames_throttle_secs=self.poll_interval, logger=self.logger, ) @@ -106,27 +95,30 @@ class SensorLeapBackend(Backend): ) controller.add_listener(listener) - self.logger.info('Leap Motion backend initialized') + self.logger.info('Leap Motion device initialized') - while not self.should_stop(): - time.sleep(0.1) + try: + self.wait_stop() + except KeyboardInterrupt: + self.logger.info('Terminating Leap Motion listener') - time.sleep(1) - self._listener_proc = Process(target=_listener_process) - self._listener_proc.start() - self._listener_proc.join() + while not self.should_stop(): + self.wait_stop(1) + self._listener_proc = Process(target=_listener_process) + self._listener_proc.start() + self._listener_proc.join() + self._listener_proc = None class LeapFuture(Timer): def __init__(self, seconds, listener, event): self.listener = listener self.event = event - super().__init__(seconds, self._callback_wrapper()) def _callback_wrapper(self): def _callback(): - self.listener._send_event(self.event) + self.listener._send_event(self.event) # pylint: disable=protected-access return _callback @@ -145,16 +137,7 @@ class LeapListener(Leap.Listener): self.running_future = None def _send_event(self, event): - backend = get_backend('redis') - if not backend: - self.logger.warning( - 'Redis backend not configured, I cannot propagate the following event: {}'.format( - event - ) - ) - return - - backend.send_message(event) + get_bus().post(event) def send_event(self, event): if self.frames_throttle_secs: @@ -166,21 +149,21 @@ class LeapListener(Leap.Listener): else: self._send_event(event) - def on_init(self, controller): + def on_init(self, *_, **__): self.prev_frame = None self.logger.info('Leap controller listener initialized') - def on_connect(self, controller): + def on_connect(self, *_, **__): self.logger.info('Leap controller connected') self.prev_frame = None self.send_event(LeapConnectEvent()) - def on_disconnect(self, controller): + def on_disconnect(self, *_, **__): self.logger.info('Leap controller disconnected') self.prev_frame = None self.send_event(LeapDisconnectEvent()) - def on_exit(self, controller): + def on_exit(self, *_, **__): self.logger.info('Leap listener terminated') def on_frame(self, controller): diff --git a/platypush/plugins/leap/manifest.yaml b/platypush/plugins/leap/manifest.yaml new file mode 100644 index 000000000..b7c3b12fc --- /dev/null +++ b/platypush/plugins/leap/manifest.yaml @@ -0,0 +1,11 @@ +manifest: + events: + - platypush.message.event.sensor.leap.LeapConnectEvent + - platypush.message.event.sensor.leap.LeapDisconnectEvent + - platypush.message.event.sensor.leap.LeapFrameEvent + - platypush.message.event.sensor.leap.LeapFrameStartEvent + - platypush.message.event.sensor.leap.LeapFrameStopEvent + install: + pip: [] + package: platypush.plugins.leap + type: plugin