From bdadd2061c36af743b6c02173e76248353ca8c12 Mon Sep 17 00:00:00 2001
From: Fabio Manganiello <blacklight86@gmail.com>
Date: Thu, 1 Aug 2019 22:40:41 +0200
Subject: [PATCH] Added EnviropHAT support

---
 docs/source/conf.py                         |  1 +
 platypush/backend/sensor/envirophat.py      | 36 +++++++++++
 platypush/plugins/gpio/sensor/envirophat.py | 71 +++++++++++++++++++++
 requirements.txt                            |  3 +
 setup.py                                    |  1 +
 5 files changed, 112 insertions(+)
 create mode 100644 platypush/backend/sensor/envirophat.py
 create mode 100644 platypush/plugins/gpio/sensor/envirophat.py

diff --git a/docs/source/conf.py b/docs/source/conf.py
index a1dca25bc..fabe8f48b 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -220,6 +220,7 @@ autodoc_mock_imports = ['googlesamples.assistant.grpc.audio_helpers',
                         'serial',
                         'pyHS100',
                         'grpc',
+                        'envirophat',
                         ]
 
 sys.path.insert(0, os.path.abspath('../..'))
diff --git a/platypush/backend/sensor/envirophat.py b/platypush/backend/sensor/envirophat.py
new file mode 100644
index 000000000..5e98b4483
--- /dev/null
+++ b/platypush/backend/sensor/envirophat.py
@@ -0,0 +1,36 @@
+from platypush.backend.sensor import SensorBackend
+from platypush.context import get_plugin
+
+
+class SensorEnvirophatBackend(SensorBackend):
+    """
+    Backend to poll analog sensor values from an MCP3008 chipset
+    (https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters/mcp3008)
+
+    Requires:
+
+        * ``adafruit-mcp3008`` (``pip install adafruit-mcp3008``)
+        * The :mod:`platypush.plugins.gpio.sensor.mcp3008` plugin configured
+    """
+
+    def __init__(self, temperature=True, pressure=True, altitude=True, luminosity=True,
+                 analog=True, accelerometer=True, magnetometer=True, qnh=1020, **kwargs):
+        super().__init__(self, **kwargs)
+
+        self.qnh = qnh
+        self.enabled_sensors = {
+            'temperature': temperature,
+            'pressure': pressure,
+            'altitude': altitude,
+            'luminosity': luminosity,
+            'analog': analog,
+            'accelerometer': accelerometer,
+            'magnetometer': magnetometer,
+        }
+
+    def get_measurement(self):
+        plugin = get_plugin('gpio.sensor.envirophat')
+        return plugin.get_data(qnh=self.qnh).output
+
+
+# vim:sw=4:ts=4:et:
diff --git a/platypush/plugins/gpio/sensor/envirophat.py b/platypush/plugins/gpio/sensor/envirophat.py
new file mode 100644
index 000000000..0e8b3f40b
--- /dev/null
+++ b/platypush/plugins/gpio/sensor/envirophat.py
@@ -0,0 +1,71 @@
+import envirophat
+
+from platypush.plugins import action
+from platypush.plugins.gpio.sensor import GpioSensorPlugin
+
+
+class GpioSensorEnvirophatPlugin(GpioSensorPlugin):
+    """
+    Plugin to interact with a `Pimoroni enviropHAT <https://shop.pimoroni.com/products/enviro-phat>`_ device.
+    You can use an enviropHAT device to read e.g. temperature, pressure, altitude, accelerometer, magnetometer and
+    luminosity data, plus control the status of its RGB LEDs.
+
+    Requires:
+
+        * ``envirophat`` (``pip install envirophat``)
+    """
+
+    @action
+    def get_measurement(self, qnh=1020.0):
+        """
+        :param: qnh: Local value for atmospheric pressure adjusted to sea level (default: 1020)
+        :type qnh: float
+
+        :returns: dict. Example::
+
+            output = {
+                "temperature": 21.0,   # Celsius
+                "pressure": 101555.08, # pascals
+                "altitude": 10,        # meters
+                "luminosity": 426,     # lumens
+
+                # Measurements from the custom analog channels
+                "analog": [0.513, 0.519, 0.531, 0.528],
+
+                "accelerometer": {
+                    "x": -0.000915,
+                    "y": 0.0760,
+                    "z": 1.026733
+                },
+                "magnetometer": {
+                    "x": -2297,
+                    "y": 1226,
+                    "z": -7023
+                },
+            }
+
+        """
+
+        ret = {}
+        weather = envirophat.weather
+        light = envirophat.light
+        accelerometer = envirophat.motion.accelerometer()
+        magnetometer = envirophat.motion.magnetometer()
+        leds = envirophat.leds
+        analog = envirophat.analog
+
+        weather.update()
+
+        ret['temperature'] = weather.temperature()
+        ret['pressure'] = weather.pressure()
+        ret['altitude'] = weather.altitude(qnh=qnh)
+        ret['luminosity'] = light.light()
+        ret['accelerometer'] = {getattr(accelerometer, v) for v in ['x', 'y', 'z']}
+        ret['magnetometer'] = {getattr(magnetometer, v) for v in ['x', 'y', 'z']}
+        ret['analog'] = list(analog.read_all())
+        ret['leds'] = leds.is_on()
+
+        return ret
+
+
+# vim:sw=4:ts=4:et:
diff --git a/requirements.txt b/requirements.txt
index ab7336f02..b3fd8cdd1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -147,3 +147,6 @@ pyScss
 # nfcpy >= 1.0
 # ndef
 
+# Support for enviropHAT
+# envirophat
+
diff --git a/setup.py b/setup.py
index e0c290550..09146fd34 100755
--- a/setup.py
+++ b/setup.py
@@ -171,6 +171,7 @@ setup(
         'Support for mpv player plugin': ['python-mpv'],
         'Support for compiling SASS/SCSS styles to CSS': ['pyScss'],
         'Support for NFC tags': ['nfcpy>=1.0', 'ndef'],
+        'Support for enviropHAT': ['envirophat'],
         # 'Support for Leap Motion backend': ['git+ssh://git@github.com:BlackLight/leap-sdk-python3.git'],
         # 'Support for Flic buttons': ['git+https://@github.com/50ButtonsEach/fliclib-linux-hci.git']
         # 'Support for media subtitles': ['git+https://github.com/agonzalezro/python-opensubtitles#egg=python-opensubtitles']