From 6bed284e8ba5de39c3e4c3bd0592a856b253bbda Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Sat, 22 Aug 2020 23:46:21 +0100 Subject: [PATCH] Added DHT temperature/humidity sensor integration [closes #113] --- docs/source/conf.py | 1 + platypush/backend/sensor/dht.py | 29 +++++++++ platypush/plugins/gpio/sensor/dht.py | 93 ++++++++++++++++++++++++++++ requirements.txt | 4 ++ setup.py | 2 + 5 files changed, 129 insertions(+) create mode 100644 platypush/backend/sensor/dht.py create mode 100644 platypush/plugins/gpio/sensor/dht.py diff --git a/docs/source/conf.py b/docs/source/conf.py index 0a64ec9360..e5857f2740 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -259,6 +259,7 @@ autodoc_mock_imports = ['googlesamples.assistant.grpc.audio_helpers', 'gi.repository', 'twilio', 'pytz', + 'Adafruit_Python_DHT', ] sys.path.insert(0, os.path.abspath('../..')) diff --git a/platypush/backend/sensor/dht.py b/platypush/backend/sensor/dht.py new file mode 100644 index 0000000000..5521005210 --- /dev/null +++ b/platypush/backend/sensor/dht.py @@ -0,0 +1,29 @@ +from platypush.backend.sensor import SensorBackend + + +class SensorDhtBackend(SensorBackend): + """ + Backend to poll a DHT11/DHT22/AM2302 temperature/humidity sensor. + + Requires: + + * ``Adafruit_Python_DHT`` (``pip install git+https://github.com/adafruit/Adafruit_Python_DHT.git``) + * The ``gpio.sensor.dht`` plugin configured and enabled. + + """ + + def __init__(self, temperature: bool = True, humidity: bool = True, **kwargs): + """ + :param temperature: Enable temperature sensor poll. + :param humidity: Enable humidity sensor poll. + """ + + enabled_sensors = { + 'humidity': humidity, + 'temperature': temperature, + } + + super().__init__(plugin='gpio.sensor.dht', enabled_sensors=enabled_sensors, **kwargs) + + +# vim:sw=4:ts=4:et: diff --git a/platypush/plugins/gpio/sensor/dht.py b/platypush/plugins/gpio/sensor/dht.py new file mode 100644 index 0000000000..ca16342678 --- /dev/null +++ b/platypush/plugins/gpio/sensor/dht.py @@ -0,0 +1,93 @@ +from typing import Optional, Dict + +from platypush.plugins import action +from platypush.plugins.gpio.sensor import GpioSensorPlugin + + +class GpioSensorDhtPlugin(GpioSensorPlugin): + """ + Plugin to interact with a DHT11/DHT22/AM2302 temperature/humidity sensor through GPIO. + + Requires: + + * ``Adafruit_Python_DHT`` (``pip install git+https://github.com/adafruit/Adafruit_Python_DHT.git``) + + """ + + def __init__(self, sensor_type: str, pin: int, retries: int = 5, + retry_seconds: int = 2, **kwargs): + """ + :param sensor_type: Type of sensor to be used (supported types: DHT11, DHT22, AM2302). + :param pin: GPIO PIN where the sensor is connected. + :param retries: Number of retries in case of failed read (default: 5). + :param retry_seconds: Number of seconds to wait between retries (default: 2). + """ + super().__init__(**kwargs) + self.sensor_type = self._get_sensor_type(sensor_type) + self.pin = pin + self.retries = retries + self.retry_seconds = retry_seconds + + @staticmethod + def _get_sensor_type(sensor_type: str) -> int: + import Adafruit_DHT + sensor_type = sensor_type.upper() + assert hasattr(Adafruit_DHT, sensor_type), \ + 'Unknown sensor type: {}. Supported types: DHT11, DHT22, AM2302'.format(sensor_type) + + return getattr(Adafruit_DHT, sensor_type) + + @action + def read(self, sensor_type: Optional[str] = None, pin: Optional[int] = None, + retries: Optional[int] = None, retry_seconds: Optional[int] = None, + **kwargs) -> Dict[str, float]: + """ + Read data from the sensor. + + :param sensor_type: Default ``sensor_type`` override. + :param pin: Default ``pin`` override. + :param retries: Default ``retries`` override. + :param retry_seconds: Default ``retry_seconds`` override. + :return: A mapping with the measured temperature and humidity. Example: + + .. code-block:: json + + { + "humidity": 30.0, + "temperature": 25.5 + } + + """ + import Adafruit_DHT + sensor_type = self._get_sensor_type(sensor_type) if sensor_type else self.sensor_type + pin = pin or self.pin + retries = retries or self.retries + retry_seconds = retry_seconds or self.retry_seconds + humidity, temperature = Adafruit_DHT.read_retry(sensor=sensor_type, + pin=pin, retries=retries, delay_seconds=retry_seconds) + + return { + 'humidity': humidity, + 'temperature': temperature, + } + + @action + def get_measurement(self) -> Dict[str, float]: + """ + Get data from the sensor. + + :return: A mapping with the measured temperature and humidity. Example: + + .. code-block:: json + + { + "humidity": 30.0, + "temperature": 25.5 + } + + """ + return self.read() + + + +# vim:sw=4:ts=4:et: diff --git a/requirements.txt b/requirements.txt index c3b64de820..b9ff637055 100644 --- a/requirements.txt +++ b/requirements.txt @@ -285,3 +285,7 @@ croniter # Support for Github # pytz + +# Support for DHT11/DHT22/AM2302 temperature/humidity sensors +# git+https://github.com/adafruit/Adafruit_Python_DHT + diff --git a/setup.py b/setup.py index 6ce3608591..84f99a73a5 100755 --- a/setup.py +++ b/setup.py @@ -326,5 +326,7 @@ setup( 'twilio': ['twilio'], # Support for Github integration 'github': ['pytz'], + # Support for DHT11/DHT22/AM2302 temperature/humidity sensors + 'dht': ['Adafruit_Python_DHT @ git+https://github.com/adafruit/Adafruit_Python_DHT'], }, )