[#352] Migrated backend.sensor.leap to leap plugin.

Closes: #352
This commit is contained in:
Fabio Manganiello 2024-02-27 23:16:36 +01:00
parent fc45b606ab
commit ea4e293338
7 changed files with 52 additions and 75 deletions

View file

@ -16,7 +16,6 @@ Backends
platypush/backend/nodered.rst platypush/backend/nodered.rst
platypush/backend/redis.rst platypush/backend/redis.rst
platypush/backend/sensor.ir.zeroborg.rst platypush/backend/sensor.ir.zeroborg.rst
platypush/backend/sensor.leap.rst
platypush/backend/stt.deepspeech.rst platypush/backend/stt.deepspeech.rst
platypush/backend/stt.picovoice.hotword.rst platypush/backend/stt.picovoice.hotword.rst
platypush/backend/stt.picovoice.speech.rst platypush/backend/stt.picovoice.speech.rst

View file

@ -1,7 +0,0 @@
``sensor.leap``
=================================
.. automodule:: platypush.backend.sensor.leap
:members:

View file

@ -0,0 +1,5 @@
``leap``
========
.. automodule:: platypush.plugins.leap
:members:

View file

@ -59,6 +59,7 @@ Plugins
platypush/plugins/lastfm.rst platypush/plugins/lastfm.rst
platypush/plugins/lcd.gpio.rst platypush/plugins/lcd.gpio.rst
platypush/plugins/lcd.i2c.rst platypush/plugins/lcd.i2c.rst
platypush/plugins/leap.rst
platypush/plugins/light.hue.rst platypush/plugins/light.hue.rst
platypush/plugins/linode.rst platypush/plugins/linode.rst
platypush/plugins/log.http.rst platypush/plugins/log.http.rst

View file

@ -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

View file

@ -1,12 +1,10 @@
import time
from threading import Timer from threading import Timer
from multiprocessing import Process from multiprocessing import Process
from typing import Iterable, Optional
import Leap import Leap
from platypush.backend import Backend from platypush.context import get_bus
from platypush.context import get_backend
from platypush.message.event.sensor.leap import ( from platypush.message.event.sensor.leap import (
LeapFrameEvent, LeapFrameEvent,
LeapFrameStartEvent, LeapFrameStartEvent,
@ -14,12 +12,14 @@ from platypush.message.event.sensor.leap import (
LeapConnectEvent, LeapConnectEvent,
LeapDisconnectEvent, 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 Integration to handle events from a `Leap Motion
gestures, https://www.leapmotion.com/ <https://www.leapmotion.com/>`_ device to track hands and
gestures.
Note that the default SDK is not compatible with Python 3. Follow the 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 instructions on https://github.com/BlackLight/leap-sdk-python3 to build the
@ -41,10 +41,9 @@ class SensorLeapBackend(Backend):
def __init__( def __init__(
self, self,
position_ranges=None, position_ranges: Optional[Iterable[Iterable[float]]] = None,
position_tolerance=0.0, # Position variation tolerance in % position_tolerance: float = 0.0,
frames_throttle_secs=None, poll_interval: Optional[float] = 0.1,
*args,
**kwargs **kwargs
): ):
""" """
@ -58,22 +57,15 @@ class SensorLeapBackend(Backend):
[25.0, 600.0], # y axis [25.0, 600.0], # y axis
[-300.0, 300.0], # z 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 :param position_tolerance: % of change between a frame and the next to
really consider the next frame as a new one (default: 0). really consider the next frame as a new one (default: 0).
:type position_tolerance: 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
:param frames_throttle_secs: If set, the frame events will be throttled Leap Motion generates events with a very high throughput, so you
and pushed to the main queue at the specified rate. Good to set if may want to set a higher value if you want to throttle the events
you want to connect Leap Motion events to actions that have a lower and avoid flooding the bus.
throughput (the Leap Motion can send a lot of frames per second).
Default: None (no throttling)
:type frames_throttle_secs: float
""" """
super().__init__(poll_interval=poll_interval, **kwargs)
super().__init__(*args, **kwargs)
if position_ranges is None: if position_ranges is None:
position_ranges = [ position_ranges = [
@ -84,16 +76,13 @@ class SensorLeapBackend(Backend):
self.position_ranges = position_ranges self.position_ranges = position_ranges
self.position_tolerance = position_tolerance self.position_tolerance = position_tolerance
self.frames_throttle_secs = frames_throttle_secs
def run(self):
super().run()
def main(self):
def _listener_process(): def _listener_process():
listener = LeapListener( listener = LeapListener(
position_ranges=self.position_ranges, position_ranges=self.position_ranges,
position_tolerance=self.position_tolerance, position_tolerance=self.position_tolerance,
frames_throttle_secs=self.frames_throttle_secs, frames_throttle_secs=self.poll_interval,
logger=self.logger, logger=self.logger,
) )
@ -106,27 +95,30 @@ class SensorLeapBackend(Backend):
) )
controller.add_listener(listener) controller.add_listener(listener)
self.logger.info('Leap Motion backend initialized') self.logger.info('Leap Motion device initialized')
while not self.should_stop(): try:
time.sleep(0.1) self.wait_stop()
except KeyboardInterrupt:
self.logger.info('Terminating Leap Motion listener')
time.sleep(1) while not self.should_stop():
self._listener_proc = Process(target=_listener_process) self.wait_stop(1)
self._listener_proc.start() self._listener_proc = Process(target=_listener_process)
self._listener_proc.join() self._listener_proc.start()
self._listener_proc.join()
self._listener_proc = None
class LeapFuture(Timer): class LeapFuture(Timer):
def __init__(self, seconds, listener, event): def __init__(self, seconds, listener, event):
self.listener = listener self.listener = listener
self.event = event self.event = event
super().__init__(seconds, self._callback_wrapper()) super().__init__(seconds, self._callback_wrapper())
def _callback_wrapper(self): def _callback_wrapper(self):
def _callback(): def _callback():
self.listener._send_event(self.event) self.listener._send_event(self.event) # pylint: disable=protected-access
return _callback return _callback
@ -145,16 +137,7 @@ class LeapListener(Leap.Listener):
self.running_future = None self.running_future = None
def _send_event(self, event): def _send_event(self, event):
backend = get_backend('redis') get_bus().post(event)
if not backend:
self.logger.warning(
'Redis backend not configured, I cannot propagate the following event: {}'.format(
event
)
)
return
backend.send_message(event)
def send_event(self, event): def send_event(self, event):
if self.frames_throttle_secs: if self.frames_throttle_secs:
@ -166,21 +149,21 @@ class LeapListener(Leap.Listener):
else: else:
self._send_event(event) self._send_event(event)
def on_init(self, controller): def on_init(self, *_, **__):
self.prev_frame = None self.prev_frame = None
self.logger.info('Leap controller listener initialized') self.logger.info('Leap controller listener initialized')
def on_connect(self, controller): def on_connect(self, *_, **__):
self.logger.info('Leap controller connected') self.logger.info('Leap controller connected')
self.prev_frame = None self.prev_frame = None
self.send_event(LeapConnectEvent()) self.send_event(LeapConnectEvent())
def on_disconnect(self, controller): def on_disconnect(self, *_, **__):
self.logger.info('Leap controller disconnected') self.logger.info('Leap controller disconnected')
self.prev_frame = None self.prev_frame = None
self.send_event(LeapDisconnectEvent()) self.send_event(LeapDisconnectEvent())
def on_exit(self, controller): def on_exit(self, *_, **__):
self.logger.info('Leap listener terminated') self.logger.info('Leap listener terminated')
def on_frame(self, controller): def on_frame(self, controller):

View file

@ -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