sensor.pmw3901#

Description#

Plugin to interact with an PMW3901 optical flow and motion sensor.

Configuration#

sensor.pmw3901:
  # [Optional]
  # Rotation angle for the captured optical flow. Possible options: 0, 90, 180, 270 (default: 0)
  # rotation: 0

  # [Optional]
  # SPI slot where the sensor is connected if you're using a Breakout Garden interface.
  # Possible options: 'front', 'back' (default: 'front')
  # spi_slot: front

  # [Optional]
  # SPI port (default: 0)
  # spi_port: 0

  # [Optional]
  # How often the `RunnablePlugin.loop <https://docs.platypush.tech/platypush/plugins/.html#platypush.plugins.RunnablePlugin.loop>`_ function should be
  # executed (default: 15 seconds). *NOTE*: For back-compatibility
  # reasons, the `poll_seconds` argument is also supported, but it's
  # deprecated.
  # poll_interval: 0.01

  # [Optional]
  # A number, numeric pair or mapping of ``str`` to
  # number/numeric pair representing the thresholds for the sensor.
  #
  # Examples:
  #
  #     .. code-block:: yaml
  #
  #         # Any value below 25 from any sensor will trigger a
  #         # SensorDataBelowThresholdEvent, if the previous value was
  #         # equal or above, and any value above 25 will trigger a
  #         # SensorDataAboveThresholdEvent, if the previous value was
  #         # equal or below
  #         thresholds: 25.0
  #
  #         # Same as above, but the threshold is only applied to
  #         # ``temperature`` readings
  #         thresholds:
  #             temperature: 25.0
  #
  #         # Any value below 20 from any sensor will trigger a
  #         # SensorDataBelowThresholdEvent, if the previous value was
  #         # equal or above, and any value above 25 will trigger a
  #         # SensorDataAboveThresholdEvent, if the previous value was
  #         # equal or below (hysteresis configuration with double
  #         # threshold)
  #         thresholds:
  #             - 20.0
  #             - 25.0
  #
  #         # Same as above, but the threshold is only applied to
  #         # ``temperature`` readings
  #         thresholds:
  #             temperature:
  #                 - 20.0
  #                 - 25.0
  # thresholds:   # type=Union[float, int, Tuple[Union[float, int], Union[float, int]], Mapping[str, Union[float, int, Tuple[Union[float, int], Union[float, int]]]], NoneType]

  # [Optional]
  # If set, then the sensor change events will be
  # triggered only if the difference between the new value and the
  # previous value is higher than the specified tolerance. For example,
  # if the sensor data is mapped to a dictionary::
  #
  #     {
  #         "temperature": 0.01,  # Tolerance on the 2nd decimal digit
  #         "humidity": 0.1       # Tolerance on the 1st decimal digit
  #     }
  #
  # Or, if it's a raw scalar number::
  #
  #     0.1  # Tolerance on the 1st decimal digit
  #
  # Or, if it's a list of values::
  #
  #     [
  #         0.01,   # Tolerance on the 2nd decimal digit for the first value
  #         0.1     # Tolerance on the 1st decimal digit for the second value
  #     ]
  # tolerance: 0  # type=Union[float, int, Mapping[str, Union[float, int]], Iterable[Union[float, int]]]

  # [Optional]
  # If `SensorPlugin.get_measurement <https://docs.platypush.tech/platypush/plugins/sensor.html#platypush.plugins.sensor.SensorPlugin.get_measurement>`_ returns a key-value
  # mapping, and ``enabled_sensors`` is set, then only the reported
  # sensor keys will be returned.
  # enabled_sensors:   # type=Optional[Iterable[str]]

  # [Optional]
  # How long we should wait for any running
  # threads/processes to stop before exiting (default: 5 seconds).
  # stop_timeout: 5  # type=Optional[float]

  # [Optional]
  # If set to True then the plugin will not monitor
  # for new events. This is useful if you want to run a plugin in
  # stateless mode and only leverage its actions, without triggering any
  # events. Defaults to False.
  # disable_monitor: False  # type=bool

Dependencies#

pip

pip install pmw3901

Triggered events#

Actions#

Module reference#

class platypush.plugins.sensor.pmw3901.Rotation(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]#

Bases: IntEnum

Enumerates the possible rotations of the sensor.

__init__(*args, **kwds)#
as_integer_ratio()#

Return a pair of integers, whose ratio is equal to the original int.

The ratio is in lowest terms and has a positive denominator.

>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
bit_count()#

Number of ones in the binary representation of the absolute value of self.

Also known as the population count.

>>> bin(13)
'0b1101'
>>> (13).bit_count()
3
bit_length()#

Number of bits necessary to represent self in binary.

>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
conjugate()#

Returns self, the complex conjugate of any int.

denominator#

the denominator of a rational number in lowest terms

from_bytes(byteorder='big', *, signed=False)#

Return the integer represented by the given array of bytes.

bytes

Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.

signed

Indicates whether two’s complement is used to represent the integer.

imag#

the imaginary part of a complex number

is_integer()#

Returns True. Exists for duck type compatibility with float.is_integer.

numerator#

the numerator of a rational number in lowest terms

real#

the real part of a complex number

to_bytes(length=1, byteorder='big', *, signed=False)#

Return an array of bytes representing an integer.

length

Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.

signed

Determines whether two’s complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.

class platypush.plugins.sensor.pmw3901.SPISlot(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]#

Bases: Enum

Enumeration for the possible SPI slot positions of the sensor on the Breakout Garden (front or back).

class platypush.plugins.sensor.pmw3901.SensorPmw3901Plugin(*_, **__)[source]#

Bases: SensorPlugin

Plugin to interact with an PMW3901 optical flow and motion sensor.

__init__(rotation=0, spi_slot='front', spi_port=0, poll_interval=0.01, **kwargs)[source]#
Parameters:
  • rotation (int) – Rotation angle for the captured optical flow. Possible options: 0, 90, 180, 270 (default: 0)

  • spi_slot (int) – SPI slot where the sensor is connected if you’re using a Breakout Garden interface. Possible options: ‘front’, ‘back’ (default: ‘front’)

  • spi_port – SPI port (default: 0)

get_data(*args, **kwargs)#

(Deprecated) alias for get_measurement()

get_measurement(*_, **__)[source]#
Returns:

dict. Example:

output = {
    "motion_x": 3,   # Detected motion vector X-coord
    "motion_y": 4,   # Detected motion vector Y-coord
    "motion_mod": 5  # Detected motion vector module
    "motion_events_per_sec": 7  # Number of motion events detected in the last second
}
main()#

Implementation of the main loop of the plugin.

publish_entities(entities: float | int | Mapping[str, float | int] | Iterable[float | int], *args, **kwargs) Collection[Entity]#

Publishes a list of entities. The downstream consumers include:

It also accepts an optional callback that will be called when each of the entities in the set is flushed to the database.

You usually don’t need to override this class (but you may want to extend transform_entities() instead if your extension doesn’t natively handle Entity objects).

start()#

Start the plugin.

status(*_, **__) float | int | Mapping[str, float | int] | Iterable[float | int] | None#

Returns the latest read values and publishes the platypush.message.event.entities.EntityUpdateEvent events if required.

stop()#

Stop the plugin.

transform_entities(entities: Dict[str, float | int]) List[Device][source]#

This method takes a list of entities in any (plugin-specific) format and converts them into a standardized collection of Entity objects. Since this method is called by publish_entities() before entity updates are published, you may usually want to extend it to pre-process the entities managed by your extension into the standard format before they are stored and published to all the consumers.

wait_stop(timeout=None)#

Wait until a stop event is received.