Enviro + is a new extension board for raspberry pi with many different types of sensor built in.It can be used for gathering all kinds of environmental data from its surroundings.
You can learn all about it here https://shop.pimoroni.com/products/enviro-plus
What we are going to build
Today we are going to make a super high tech solution for securing our homes by detecting light and proximity.My idea for this came from the fact that the entrance to my home is quite dark there during the day and any changes in light could be an indicator that that door has been opened and the changes in proximity could further hint that someone or something 🐻 has come near or passed by the device.
The data will be sent to a firebase db and will be monitored from a React frontend.
You can see the finished example live here https://tender-lamarr-33eddc.netlify.com
Note: This is obviously a very rudimentary solution and should in no way actually be used for your home security.
Another Note: This project assumes you already have a raspberry pi setup with Raspbian lite installed and an internet connection.
Getting Started
To get started log into your Raspberry Pi and run the install script provided by Pimoroni.
This is the recommended and easiest way to install the dependences but there are various other ways outlined in their readme https://github.com/pimoroni/enviroplus-python
curl -sSL https://get.pimoroni.com/enviroplus | bash
Once installed you will still need to manually add a few more dependencies
sudo apt install python-pip pip install configparser pip3 install RPi.GPIO pip3 install spidev
Running the code
Now that you have all the dependencies installed it is time to write some code.Download the starter project from here https://github.com/makeupsomething/entrance-monitor and then checkout the feature / step-1 branch and run the example.
git clone https://github.com/makeupsomething/entrance-monitor.git cd entrance-monitor git checkout feature / step-1 python3 entrance-monitor / index.py
The app should start and you should be able to see the light and proximity values on the lcd screen.Try covering the light sensor and see the values change.
Let’s take a look at some of the code to see what is going on here.
Set up the canvas and font
# / New canvas to draw on./ img = Image.new ('RGB', (WIDTH, HEIGHT), color = (0, 0, 0)) draw = ImageDraw.Draw (img) path = os.path.dirname (os.path.realpath (__ file__)) # / Set up canvas and font / font_size = 15 font = ImageFont.truetype ("entrance-monitor / fonts / Asap / Asap-Bold.ttf", font_size) text_colour = (255, 255, 255) back_colour = (170, 0, 170) message = ""
Here we create a new Image using the Pillow library.We then set up the font and text defaults.Try editing the text or background color and restarting the app.The display on the enviro + can handle any RGB color value!
try: while True: lux = ltr559.get_lux () prox = ltr559.get_proximity () message = "" "Light: {: 05.02f} Lux Proximity: {: 05.02f} "" ".format (lux, prox) # / Calculate text position / size_x, size_y = draw.textsize (message, font) x = (WIDTH-size_x) / 2 y = (HEIGHT / 2)-(size_y / 2) draw.rectangle ((0, 0, 255, 80), back_colour) draw.text ((x, y), message, font = font, fill = text_colour) disp.display (img) time.sleep (1.0) except KeyboardInterrupt: pass
Here is where the main work is being done.
We use the ltr559 library for getting the lux and proximity values from the light sensor.We then format them into a string and assign it to the empty message we set earlier.
Then based on the length of the string calculate the size and then try to position it in the center of the screen.
Finally we draw a rectangle and add the text to it using the Pillow library and finally add the finished image to the display.
We then sleep for one second before looping through it again.
Firebase
Firebase is a mobile and web application development platform owned by Google.
Create firebase project
If you do not have a firebase account you will need to create one, you can login using your google account. It is free to create an account and you do not need to provide any payment details to get started.
Once logged in click the Add Project button.
Give the project a name and click Continue. Select Not right now for adding google analytics to your project and finally click Create project.
It may take a few minutes to provision the servers.
Setup database and rules
Firebase has two database solutions.
- Cloud Firestore
- Realtime Database
For most cases Cloud Firestore is the recommended database to use, but as it is not supported by the python library we are using, we will be using the Realtime Database. As our use case is quite simple it will not make any difference.
Go in the sidebar of the firebase console click database.
The first option you see will be to enable Cloud Firestore, but we will not use that for this project. Scroll a little further down the page and click enable the realtime database.
You will get a popup to configure your database rules, select start in test mode and then click enable. This means that our database will have no authentication, this is a really bad idea on a production app but since this is just for test purposes it is ok for now.
*Note:* Again, having your database in test mode is a really bad idea and should never be done on a production app!!
Next you will need to get your project api key and project id.
Click on the gear icon on in the sidebar and select Project settings, your project id and api key should be listed there. Make a note of them as we will need them soon.
Install pyrebase and connect to firebase
Back on our raspberry pi we can now start to integrate our project with firebase.
We are using pyrebase4, a fork of the original pyrebase library for interacting with firebase from python.
Install pyrebase4
pip3 install pyrebase4
and then inside the project folder checkout the step-2 branch
git checkout feature/step-2
If you try to run this now you will get an error, this is because we need to add some data to connect to our firebase project. The project looks for environment variables API_KEY and PROJECT_ID so let’s set them up.
This is the firebase api key and project id that you should have made a note of earlier.
export API_KEY="apiKey" export PROJECT_ID="projectId"
Then try to run the code like before
python3 entrance-monitor/index.py
You will not see any difference on the device or terminal output but if you check the database in the firebase console you should start to see the data updating, try covering the light sensor to see the data update more quickly.
Let’s take a look at the code
Configure Firebase
We setup and connect the firebase instance like so
config = { "apiKey": os.getenv('API_KEY'), "authDomain": os.getenv('PROJECT_NAME')+".firebaseapp.com", "databaseURL": "https://"+os.getenv('PROJECT_NAME')+".firebaseio.com", "storageBucket": os.getenv('PROJECT_NAME')+"appspot.com", } firebase = pyrebase.initialize_app(config) db = firebase.database()
Sending data to database
Then to send data to our database we simply add to our loop
data = {"light": lux, "proximity": prox, "createdAt": str(datetime.datetime.now())} db.child("data").push(data)
Firebase realtime database accepts data in a JSON format, so we create an object that contains the lux and proximity and also a timestamp. We then push it to a child collection called data.
But this will be sending data every second, our data will get out of control on firebase and actually pretty quickly exceed our daily write limit on the free plan. We really only want to send data when we detect dramatic changes in light or proximity, apart from that we can send regular status updates at a reasonable interval, let’s say every 60 seconds.
First we need to keep track of the previous lux and proximity values so we can detect if the next value is dramatically different. We will also keep a count, we will use this for keeping track of how long has passed since we last posted data to the database. If it exceeds 60 (seconds) then send the current value.
We declare them outside the while loop
prev_lux = 0 prev_prox = 0 count = 0
Then inside the while loop we need to check if the current values for lux and proximity are larger than the previous value. If they are, then update the database straight away. If not, then set the new previous value and increase the count value
if(abs(prev_lux - lux) > 20 or abs(prev_prox - prev_prox) > 20 or count >= 60): data = {“light”: lux, “proximity”: prox, “createdAt”: str(datetime.datetime.now())} db.child(“data”).push(data) count = 0 prev_lux = lux prev_prox = prox count = count + 1
Now it is time to start visualizing the data.
React frontend
React
React is a JavaScript library for building user interfaces. It is maintained by Facebook and a community of individual developers and companies.
Getting the project
Fork the repo and download.
I won’t go into too much detail here about how the frontend works as it is out of the scope of the tutorial. This this serves to show that we can get the data in realtime from the device to firebase to the frontend in (almost) realtime.
To run the project we will need to add our firebase api key and project id to the project. These are the same api key and project id you used in the python project.
Create a file called .env at the root of the project and then add the following
REACT_APP_API_KEY=apiKey REACT_APP_PROJECT_ID=projectId
Now install the dependencies and run the project like
npm install npm run start
Make sure the app on your raspberry pi is still running or restart it and then go to https://localhost:3000 to see the live output.
]]>