AmbiLamp: Lamp Code
Sensor Script

Now that you have created the web app and assembled the hardware, you are ready to connect them! The next three lessons are about communicating between your physical sensors and the database that the web app uses.

The Python requests library makes it easy to submit HTTP requests to a web API. In your terminal, ssh'd into the Pi (note, we are working on the Pi right now!), execute

$ sudo pip install requests
to obtain this library.

The code block below shows a skeleton script for using requests. Study and understand it, because you're about to fill it in to make post and get requests to your own API!

import requests
# import the DHT and MCP libraries

# construct the DHT22

# construct the ldr

# the address we will make the request to

# initialize an empty dictionary
packet = {}

# get the temperature and humidity from DHT object

# get the brightness from the ldr object

# fill the packet with data in the format expected by the web API
packet['temperature'] = round(temperature, 3)

# just a debug, comment it out when you know the script works

# submit the post request.
r =,json=packet)

Note that we set the json of the request to the data packet, and recall that the API route simply uses req.body to insert into the database. If we wrote the API differently, say, in a route that expects form data instead of raw JSON, we would send the packet in the expected format. You can learn more about using requests from their documentation.

Challenge: Post Data

Your first challenge is to fill in the skeleton above so that the script

Reads the current temperature, humidity, and brightness from the sensors
Inserts the data into the database so that the web app can use it

Run the script by executing

$ sudo python

Like we mentioned in the sensor testing article, you will want to code in the iot_ambilamp/code folder. This way you have access to all the libraries to interface with and drive the hardware on the IoT AmbiLamp PCB.

When writing this script, you can use the test scripts we provided in the last lesson to determine how to get data from the sensors. You can also look at the documentation for these libraries, which shows the functions available to you and example usage. We've also made an API reference for the web app, which tells you what the packet you submit to the post request should look like. Remember that the mongoose schema inserts the timestamp automatically, so you don't have to include that.

You can check that the script is working by looking at your mLab database, and by making a get request through the web app (a.k.a. visit, but using your app's name, of course).

Regarding the API reference: it was created for the API we made while creating the project. If there are any differences in your API - for example, the field "timeInHotZone" was "timeInHot" in the tutorial videos - you need to submit the fields that will be recognized by your API. You can always look at the schemas in your models folder to check what fields you have.

When you've confirmed that one data entry is posted to the web app every time you run the script, you can move on to the next challenge. Bonus, check out the details page - you should see the data being used by the web app!

Take a moment to commit this script to git. Right now. You don't want to lose this working code if you mess up during the next challenge.

Challenge: Update Statistics

This part is a bit trickier. Every time we take a new data reading, we need to update the statistics document so that our homepage dashboard is accurate. To do this, we need to

Get the settings document, so we know what each of the thresholds are
Get the statistics document, so we know what the current averages and counts are
Make a dictionary matching the format of the statistics document
Increment the timeTotal field
If the current temperature is in the hot zone, increment the timeInHot field. There should be equivalent checks for whether it is in the cold, humid, and dry zones
Update the running averages. We've put the equation for a running average in the hints below
If appropriate, increment the timeOn field

Again, use the API reference and your own knowledge of the API you wrote to make the requests needed for this challenge. As some additional hints:

When you make a get request, the object returned by the requests library isn't immediately in the format you can use (that is, you want the JSON, and it doesn't give you that directly). Poke around the library's documentation to figure out how to get the JSON from the return of any call to requests.get(url).

The equation for a running average is

You probably want to make a quick call to the delete route for statistics, now that you're about to update them with actual data. Right now there's fake stuff sitting there, and you don't want calculations done with a mix of real and fake.

Now, every time you run the script, you should see a new data entry appear in the data collection, and see an edit to the statistics collection. You can always make get requests from your web app ( to check that what you send from the Python script is being successfully saved.

When this works, go ahead and move on to the next lesson!

Commit again. We've made a functional change to our codebase - you should always commit before moving on to new functional changes.