Skip to content

Adding a new Grove Seed sensor with GrovePi

Yatharth Ranjan edited this page Feb 25, 2020 · 2 revisions

This page will discuss adding a new Grove Sensor to be used with the GrovePi hat on a Raspberry pi. The example here creates a new sensor for the Grove Temperature and Humidity Sensor.

Install GrovePi Library

This step needs to be done the first time that you are using the grove pi. If only adding new sensors please proceed to the next section. To install the GrovePi on your Raspberry Pi, please follow the official docs.

Add a schema for your sensor

This step is exactly same as when adding any other sensor and has been described here.

Create an Implementation of the sensor

We will be adding a new sensor to the sensors/grovepi.py module.

We will extend the GrovePiSensor abstract class for thread-safe access to the GrovePi. Unfortunately, the GrovePi library for Python is not thread-safe and hence we need to ensure thread safety.

Add the following code to the bottom of the sensors/grovepi.py module.

class TemperatureAndHumiditySensor(GrovePiSensor):
    # http://wiki.seeedstudio.com/Grove-TemperatureAndHumidity_Sensor/
    # Connect the Grove Temperature & Humidity Sensor (or Pro) to digital port D4
    # This example uses the blue colored sensor.
    # SIG,NC,VCC,GND

    def __init__(self, name, topic, poll_freq_ms, flush_size, flush_after_s, **kwargs):

        # We parse the port from named arguments if present otherwise use port 4 by default
        if 'port' in kwargs:
            self.sensor = int(kwargs.get('port'))
        else:
            self.sensor = 4  # The Sensor goes on digital port 4.

        # temp_humidity_sensor_type
        # Grove Base Kit comes with the blue sensor.
        self.blue = 0  # The Blue colored sensor. Grove Temp & Humidity Sensor
        self.white = 1  # The White colored sensor. Grove Temp & Humidity Sensor Pro

        # Always remember to initialise the superclasses with all the required parameters.
        super().__init__(name, topic, poll_freq_ms, flush_size, flush_after_s)

    # This is where all your logic for getting the data from the sensor will exist.
    def get_measurement(self) -> Response:
        try:
            # Query data using the grovepi library.
            [temp, humidity] = grovepi.dht(self.sensor, self.blue)
            if not math.isnan(temp) and not math.isnan(humidity):
                # Return a Response object with the data and no errors.
                return Response({'time': datetime.now().timestamp(), 'temperature': temp, 'humidity': humidity},
                                errors=None)
        except IOError as exc:
            # Return a Response object with no data and an error.
            return Response(response=None, errors=get_error_from_exc(exc))

Note: This code may already be present in the module. This is added here as an example and to show the process to be followed to add a new sensor.

The above example is very similar to the one discussed here with the exception that instead of extending the Sensor class, we are extending a subclass of the Sensor class named GrovePiSensor class which provides thread-safe implementation of the poll() method.

Note: If you want to use the grovepi library outside the get_measurement() method of you sensor implementation(for example in the __init__ block), then make sure to first acquire the Lock to ensure thread safety using -

with grovepi_lock:
       grovepi.do_something()

Create the configuration and test the sensor is working as expected

You can now add the sensor to the config.yaml file and start collecting data -

 -  name: "grovepi_temperature_and_humidity_sensor"
    # Name of your python module which contains the sensor class
    module: "sensor.grovepi"
    # Name of the class of the sensor in the module
    class: "TemperatureAndHumiditySensor"
    # topic/channel to publish the data to in pub/sub paradigm
    publishing_topic: "data-stream/sensors/grovepi-temperature-and-humidity"
    # polling frequency in milliseconds 
    poll_frequency_ms: 1000 
    # Flush size for flushing the records
    flush_size: 10
    # Flush after [value] seconds if the flush size is not reached
    flush_after_s: 1000

Now, you need to run the application and check the data as described here.

Create a data consumer for your sensor

This is step is exactly the same as described here. Please make sure to change the names and values according to your sensor implementation in the converters and the configuration.