Home Automation

Enter Your Electronics & Design Project for a chance to win a $100 Shopping Cart!

Back to The Project14 homepage

Project14 Home
Monthly Themes
Monthly Theme Poll

 

Interfacing the Matrix Creator with MATRIX Lite Python

 

Overview

Previously I posted an overview of the Home Automation project I am creating using the MATRIX Creator, Raspberry Pi 3 A+ and OpenHAB 2 and part of the configuration involves collecting sensor data from the MATRIX Creator to present in the OpenHAB UI. Here, I will describe how I am using the MATRIX Lite Python interfaces to collect this data from the Creator.

 

Related posts:

OpenHAB 2 with Matrix Creator and RasPi 3 A+: Intro

OpenHAB 2 with Matrix Creator and RasPi 3 A+: OpenHAB 2 Exec Binding

OpenHAB 2 with Matrix Creator and RasPi 3 A+: OpenHAB 2 MQTT Binding

OpenHAB 2 with Matrix Creator and RasPi 3 A+: Everloop and demo

OpenHAB 2 with Matrix Creator and RasPi 3 A+: GPIO and Postmortem

 

MATRIX Creator Set-up

 

The MATRIX Labs website has very good instruction on how to set-up and configuration the MATRIX Creator and the first place to start is the Overview page.

https://matrix-io.github.io/matrix-documentation/matrix-creator/overview/

 

There is plenty of info at the site and elsewhere on element14 to get started with the MATRIX Creator so I will not cover getting the Raspberry Pi OS installed and configured.

 

A Raspberry Pi 3 A+ running the '2018-11-13-raspbian-stretch-full' image was used to host the MATRIX Creator for this project.

 

To get started, the matrix-creator-init was installed to initialize the MATRIX Creator code on the Raspberry Pi

https://github.com/matrix-io/matrix-creator-init

 

# Add repo and key
curl https://apt.matrix.one/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.matrix.one/raspbian $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/matrixlabs.list

# Update packages and install
sudo apt-get update
sudo apt-get upgrade

# Installation
sudo apt install matrixio-creator-init

 

After the Raspberry Pi is up and running and the MATRIX Creator is installed, the next step is to select which MATRIX Ecosystem to select.

https://matrix-io.github.io/matrix-documentation/#programming-layers

 

In this example, the MATRIX Hardware Abstraction Layer (HAL) and MATRIX Lite Python was used to interface with the MATRIX Creator

 

First, install the MATRIX HAL software.

https://matrix-io.github.io/matrix-documentation/matrix-hal/overview/

 

There are 2 different options to install the MATRIX HAL software:

   1. From Package - This is the easiest option

      https://matrix-io.github.io/matrix-documentation/matrix-hal/getting-started/installation-package/

 

   2. From Source -  This requires downloading the code and building and installing the software manually.

       It might be a good idea to perform this step just to ensure the latest HAL software is used

       https://matrix-io.github.io/matrix-documentation/matrix-hal/getting-started/installation-source/

 

To install from package, perform the following.

Add the MATRIX source repo to the package manager on the Pi.

curl https://apt.matrix.one/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.matrix.one/raspbian $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/matrixlabs.list

 

Ensure the packages on the system are updated

sudo apt-get update
sudo apt-get upgrade

 

Install MATRIX HAL packages

sudo apt-get install matrixio-creator-init libmatrixio-creator-hal libmatrixio-creator-hal-dev

 

Reboot the system

sudo reboot

 

Check the system to ensure the software was installed.

ls /usr/lib/libmatrix_creator_hal.so 
/usr/lib/libmatrix_creator_hal.so

 

ls -d /usr/include/matrix_hal/
/usr/include/matrix_hal/

 

The following link shows how to test the MATRIX HAL code.

https://matrix-io.github.io/matrix-documentation/matrix-hal/getting-started/programs/

 

Second, install MATRIX Lite Python.

The MATRIX Lite software includes both a Javascript and a Python option to interface the MATRIX Creator. In  this example , only the MATRIX Lite Python code was used.

 

The MATRIX Lite Python code can be obtained from the MATRIX GiHub repo

https://github.com/matrix-io/matrix-lite-py

 

Install the dependencies

sudo apt-get install swig
sudo apt-get install python3-pip

 

Create a location on the Raspberry Pi for the code and then use the git tool to down load the code.

git clone --recurse-submodules https://github.com/matrix-io/matrix-lite-py
Cloning into 'matrix-lite-py'...
remote: Enumerating objects: 184, done.
remote: Counting objects: 100% (184/184), done.
remote: Compressing objects: 100% (124/124), done.
remote: Total 184 (delta 75), reused 155 (delta 50), pack-reused 0
Receiving objects: 100% (184/184), 25.83 KiB | 0 bytes/s, done.
Resolving deltas: 100% (75/75), done.
Submodule 'matrix-hal-swig' (https://github.com/matrix-io/matrix-hal-swig) registered for path 'matrix-hal-swig'
Cloning into '/home/pi/development/matrix-test/matrix-lite-py/matrix-hal-swig'...
remote: Enumerating objects: 52, done.        
remote: Counting objects: 100% (52/52), done.        
remote: Compressing objects: 100% (37/37), done.        
remote: Total 52 (delta 18), reused 42 (delta 11), pack-reused 0        
Submodule path 'matrix-hal-swig': checked out '6fc66b98160144f14db072f8ece92f2a138078ba'

 

Once downloaded, there should be a matrix-lite-py folder present.

ls -lt
total 4
drwxr-xr-x 5 pi pi 4096 Mar  1 23:11 matrix-lite-py

 

Change directory into the matrix-lite-py folder and run make to build the code

cd matrix-lite-py
make
# build destination
mkdir -p build;
# generate HAL wrapper
swig -python -c++ -outdir build matrix-hal-swig/matrix.i;
# generate Python library
gcc -O2 -fPIC -c -std=gnu++11 -fno-threadsafe-statics matrix-hal-swig/matrix.cpp matrix-hal-swig/drivers/*.cpp matrix-hal-swig/drivers/sensors/*.cpp
mv *.o build
# handy to use: python-config --cflags
gcc -O2 -fPIC -c -o build/matrix_wrap.o -std=gnu++11 -fno-threadsafe-statics matrix-hal-swig/matrix_wrap.cxx -I/usr/include/python3.5m
gcc -lmatrix_creator_hal -shared -std=gnu++11 -fno-threadsafe-statics build/*.o -o build/_matrix.so
# remove generated HAL wrapper
rm matrix-hal-swig/matrix_wrap.cxx;

 

 

Run the swigExamples.py script to test that the matrix-lite-py has been installed correctly.

NOTE: This does require Python 3.0.

 python3 swigExamples.py INFO: [/dev/spidev0.0] was opened
['SwigPyIterator', 'SwigPyIterator_swigregister', '__builtin__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_matrix', '_newclass', '_object', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic', 'cvar', 'everloop', 'everloopImage', 'everloopImage_swigregister', 'everloop_swigregister', 'gpio', 'gpio_swigregister', 'humidity', 'humidity_struct', 'humidity_struct_swigregister', 'humidity_swigregister', 'imu', 'imu_struct', 'imu_struct_swigregister', 'imu_swigregister', 'led', 'led_swigregister', 'pressure', 'pressure_struct', 'pressure_struct_swigregister', 'pressure_swigregister', 'uv', 'uv_struct', 'uv_struct_swigregister', 'uv_swigregister']

 

If successful, the Everloop LEDs should all run Blue.

A piece of paper was used to cover the MATRIX Creator to show the LEDs more clearly.

 

 

The swigExamples.py script has code in it run examples for the other sensors but are comment out.  To run these, just comment out the appropriate code to run another example.

import build.matrix as hal
from time import sleep


# Print exported objects/functions
print(dir(hal))


## LED Example ##
everloop = hal.everloop()


leds = []
for i in range(everloop.ledCount):
    led = hal.led(0,0,1,0)#led.r led.g led.b led.w
    leds.append(led)


everloop.set(leds)


## IMU Example ##
# imu = hal.imu()
# while True:
#     data = imu.read()
#     print ("Accelerometer: (xyz)",data.accel_x, data.accel_y, data.accel_z)
#     print ("Gyroscope: (xyz)",data.gyro_x, data.gyro_y, data.gyro_z)
#     print ("Magnetometer:(xyz)", data.mag_x, data.mag_y, data.mag_z)
#     print ("Yaw Pitch Roll:", data.yaw, data.pitch, data.roll)
#     sleep(0.05)


## UV Example ##
# uv = hal.uv()
# while True:
#     data = uv.read()
#     print ("UV: ", data.uv)
#     sleep(0.05)


## Humidity Example ##
# humidity = hal.humidity()
# while True:
#     data = humidity.read()
#     print("Humidity: ", data.humidity)
#     print("Temperature: ", data.temperature)
#     sleep(0.05)

 

Humidity example

INFO: [/dev/spidev0.0] was opened


Humidity:  29.045000076293945
Temperature:  29.53700065612793
Humidity:  29.045000076293945
Temperature:  29.53700065612793
Humidity:  29.045000076293945
Temperature:  29.53700065612793
Humidity:  29.045000076293945
Temperature:  29.53700065612793
Humidity:  29.045000076293945

 

 

For my project, to get the Sensor values to display in OpenHAB, I took the basic swigExamples.py script and modified it by creating a MatrixSensors class and associated methods for each sensors. Also, I added argparse to the script so that a arguments can be passed to the script to retrieve the sensor values without having to edit the script each time.  A dictionary is used to change the colors on the Everloop based on predefined values.   Eventually this will be modified so the intensity and colors can be adjusted dynamically.

I guess I need to set-up a github repo for this but this is what I have thus far.

 

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import sys
import os
import build.matrix as hal
from time import sleep


ledMatrix = {'red': {'ledr' : 1, 'ledg' : 0 , 'ledb' : 0, 'ledw' : 0},
            'green': {'ledr' : 0, 'ledg' : 1 , 'ledb' : 0, 'ledw' : 0},
            'blue': {'ledr' : 0, 'ledg' : 0 , 'ledb' : 1, 'ledw' : 0},
            'white': {'ledr' : 0, 'ledg' : 0 , 'ledb' : 0, 'ledw' : 1},
            'off': {'ledr' : 0, 'ledg' : 0 , 'ledb' : 0, 'ledw' : 0},
            }
# Print exported objects/functions
#print(dir(hal))
class MatrixSensors(object):
    """
    Setup Matrix Sensor  Python examples
    """
    def __init__(self):
        self.leds = []
        self.everloop = hal.everloop()
        self.imu = hal.imu()
        self.gpio = hal.gpio()
        self.uv = hal.uv()
        self.humidity = hal.humidity()
        self.pressure = hal.pressure()
        self.gpioIN = 15
        self.gpioOUT = 14


    ## LED Example ##
    def runEverloop(self, color):
        print ("Color: %s" % color)
        for i in range(self.everloop.ledCount):
            #led = hal.led(0,0,0,0)#led.r led.g led.b led.w
            led = hal.led(ledMatrix.get(color, {}).get('ledr'),
                          ledMatrix.get(color, {}).get('ledg'),
                          ledMatrix.get(color, {}).get('ledb'),
                          ledMatrix.get(color, {}).get('ledw'),
                          )#led.r led.g led.b led.w
            self.leds.append(led)


        self.everloop.set(self.leds)


    ## IMU Example ##
    def getIMU(self, args):
        ## IMU Example ##
        data = self.imu.read()
        result = ""
        if (args == "accel"):
            return  (data.accel_x, data.accel_y, data.accel_z)
        elif (args == "gyro"):
            return  (data.gyro_x, data.gyro_y, data.gyro_z)
        elif (args == "mag"):
            return  (data.mag_x, data.mag_y, data.mag_z)
        elif (args == "euler"):
            return  (data.yaw, data.pitch, data.roll)
        else:
            return  (0, 0, 0)


    ## UV Example ##
    def getUV(self):


        data = self.uv.read()
        return data.uv


    ## Humidity Example ##
    def getHumid(self, args):


        data = self.humidity.read()
        result = ""
        if (args == "temp"):
            result = ((9.00 / 5.00 * data.temperature)+32.00)
        elif (args == "humid"):
            result = data.humidity
        else:
            result = 0
            print ("%s not found!" % arg.pressure)


        return ('{0:.2f}'.format(result))


    ## Pressure Example ##
    def getPressure(self, args):
        data = self.pressure.read()
        result = ""
        if (args == "temp"):
            result = ((9.00 / 5.00 * data.temperature)+32.00)
        elif (args == "alt"):
            result = data.altitude
        elif (args == "pressure"):
            result = data.pressure
        else:
            result = 0


        return ('{0:.2f}'.format(result))


    def runGPIO(self):
        ## GPIO ##
        print(dir(self.gpio))


        self.initGPIO()


        while True:
            os.system("clear")
            pinState = self.gpio.getValue(self.gpioIN)
            print("GPIO State: %d" % pinState)
            self.gpio.setDigital(self.gpioOUT,pinState)
            sleep(0.05)


    def initGPIO(self):
        # turn pin 1 on
        self.gpio.setMode(self.gpioOUT,1)
        self.gpio.setFunction(self.gpioOUT,0)
        self.gpio.setDigital(self.gpioOUT,1)


        # read pin 0
        self.gpio.setMode(self.gpioIN,0)
        self.gpio.setFunction(self.gpioIN,0)


def main(args):
    matrixSen = MatrixSensors()
    if args.eLoop:
        matrixSen.runEverloop(args.eLoop)
    elif args.gpio:
        matrixSen.runGPIO()
    elif args.imu:
        imu_x, imu_y, imu_z = matrixSen.getIMU(args.imu)
        if (args.imu == "euler"):
            print("yaw:%f pitch:%f roll:%f" % (imu_x, imu_y, imu_z))
        else:
            print("x:%f y:%f z:%f" % (imu_x, imu_y, imu_z))
    elif args.humid:
        envCond = matrixSen.getHumid(args.humid)
        print (envCond)
    elif args.pressure:
        press = matrixSen.getPressure(args.pressure)
        print (press)
    elif args.uv:
        print(matrixSen.getUV())
    else:
        print("ERROR: option not recognized!")
        raise Exception('Options not found')


if __name__ == "__main__":
    import argparse


    parser = argparse.ArgumentParser(description="matrix-lite script")
    parser.add_argument("-g", "--gpio", dest="gpio",
                        action="store_true", default=False,
                        help="run gpio") 
    parser.add_argument("-e", "--eloop", dest="eLoop",
                        action="store", help="run eloop")
    parser.add_argument("-i", "--imu", dest="imu",
                        action="store", help="run IMU; -u or --imu")
    parser.add_argument("-p", "--press", dest="pressure",
                        action="store", help=" -p or --press; \"temp\", \"alt\", \"pressure\"")
    parser.add_argument("-u", "--uv", dest="uv",
                        action="store_true", default=False,
                        help="run UV") 
    parser.add_argument("-hu", "--humid", dest="humid",
                        action="store", help="run Humidity")


    args = parser.parse_args()
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit()


    try:
        main(args)
        #user_input = input()
    except KeyboardInterrupt:
        sys.exit(0) 

 

Running this looks like this.

Pressure sensor example:

/usr/bin/python3 matrixSensors.py -p "temp"
INFO: [/dev/spidev0.0] was opened
96.12

 

/usr/bin/python3 matrixSensors.py -p "alt"
INFO: [/dev/spidev0.0] was opened
34.19

 

/usr/bin/python3 matrixSensors.py -p "pressure"
INFO: [/dev/spidev0.0] was opened
100917.75

 

Humidity Sensor example:

/usr/bin/python3 matrixSensors.py -hu "humid"
INFO: [/dev/spidev0.0] was opened
29.05

 

/usr/bin/python3 matrixSensors.py -hu "temp"
INFO: [/dev/spidev0.0] was opened
84.80

 

NOTE: The temperature is in Fahrenheit and the temp is a bit high due to the proximity of the sensors to the Raspberry Pi. The recommendation is to separate the MATRIX Creator and the Raspberry Pi so the heat from the Pi does not interfere with the sensors.

 

IMU Example

/usr/bin/python3 matrixSensors.py --imu "gyro"
INFO: [/dev/spidev0.0] was opened
x:0.844000 y:3.140000 z:0.942000

 

/usr/bin/python3 matrixSensors.py --imu "accel"
INFO: [/dev/spidev0.0] was opened
x:0.002000 y:0.012000 z:0.982000

 

/usr/bin/python3 matrixSensors.py --imu "mag"
INFO: [/dev/spidev0.0] was opened
x:-0.190000 y:0.293000 z:0.000000

 

 /usr/bin/python3 matrixSensors.py --imu "euler"
INFO: [/dev/spidev0.0] was opened
yaw:56.446461 pitch:-0.525565 roll:0.934405

 

GPIO Example - Push Button connected to Pin 15 and a LED connected to Pin 14.

/usr/bin/python3 matrixSensors.py -g

GPIO TEST
GPIO State: 1

 

Everloop Example

/usr/bin/python3 matrixSensors.py -e "green"
INFO: [/dev/spidev0.0] was opened
Color: green

 

 

/usr/bin/python3 matrixSensors.py -e "red"
INFO: [/dev/spidev0.0] was opened
Color: red

 

 

That is all I have at this point for the Python interfaces.