project

IoT Project – Temperature Sensors

Online Link

This project is available as part of my online portfolio at: https://lehi.dev/labs/project

 

Problem/Issue & Proposed Solution

Many times in my house I have a perfect/desired temperature on the main floor which happens to have the thermostat controller, but on a specified room It is always warmer beyond comfortable level. For the solution for this problem I have designed a system where I monitor each level: basement, main, upstairs. Create a website graph to see high level where each level temperature is at as well as created a slack bit and channel to let me know each level temperature as well as send commands to turn the fan on or off. Every hour it sends data for all 3 levels. If the upstairs passes a threshold then turn on the fan if it gets below a threshold then turn off the fan.The purpose of this project is to learn how to use IoT devices to solve a problem. Establish complex conditions by using sensors, these principles include:

  • Implement Restful API to facilitate data transfer from sensors
  • Implement MQTT system to make all sensors synchronized and pass and receive data amongst each other.
  • Develop a full feature UI interface displaying temperature data states from sensors for a specific time frame.
  • Implement a non web page interface to gather each level temperature
  • Use slackbot to act on certain conditions.
  • Leverage AWS cloud to assist on keeping track of each level temperature using DynamoDB for later queries and IoT core to act on certain data being received including sending text message and send commands to a slackbot.
  • Learn to plan what materials will be necessary to accomplish the system’s purpose

 

Materials

  • Personal Computer
  • 4 x Wemos D1 Mini microcontrollers (ESP8266)
  • 3 x DHT22/DHT11 shields to connect on top of ESP8266
  • 3 x 2.5A USB Power Supply with micro USB Cable
  • 1 x raspberry pi with SD micro sd card and charger
  • 1 x fan
  • 1 x Wemo Mini Smart Plug, WiFi Enabled (or any smart plug that exposes their API via http)
  • Arduino IDE
  • Fritzing
  • Soldering iron
  • Solder

References

The following resources were used in this project:

 

Requirements

  • Utilize at least 3 physical devices (one sensor and two actuators, or two sensors and one actuator) – Used 5 (4 ESP8266 along with 2 DHT22 and 1 DHT11, 1 raspberry pi)
  • Utilize at least 2 wireless communication protocols (wifi, BLE, RFID, LoRa, etc) – Used Wifi and MQTT
  • Utilize restful API – Checked
  • Utilize event hub or cloud IoT service – Used several AWS services (AWS IoT Core, DynamoDB, SNS, Lambda, API Gateway, S3)
  • Utilize a non-web page interface (voice, IFTTT, chat) – Used Slackbot on a Slack channel

 

Procedures

  1. Solder 4 ESP8266 to act as IoT computing WiFi devices and MQTT send and receive data from topics.
  2. Solder 3 DHT22/DHT11 to gather each level temperature. You could use a combination of them or just all the same.
  3. Develop code to gather temperature information for each level, subscribe to topics to receive commands and publish to topics to send data out from the sensors.
  4. Program the code in the Arduino IDE
    1. Test/Debug to make sure the logic is sound. You can debug by first making sure the baud rate is set up in setup method. Then click on serial monitor icon  .
    2. Use commands such as Serial.println(<variableToBeEvaluated>) to print out debug messages, so you can make sure what you think the code is doing is actually happening.
  5. Use 1 ESP8266 to act as a restful api, listen to a specific endpoints and publish to a topics to gather the desired data information.
    1. How to:
      1. Use the ESP8266WebServer library as to serve endpoints that will be exposed for clients to hit it.
      2. Create different endpoints for each sensor in order to expose the data extraction from the sensor.
      3. Use ArduinoJson library to work with json responses from each sensor as to return the response to the clients.
      4. Use ESP8266WiFi to connect to wifi. PubSubClient library to connect to mosquitto message broker. Add your secrets and keys to a file and put it into .gitignore so that is not sent to github and expose passwords to the world.
      5. On each endpoint publish to a topic that the sensor is listening to and then subscribe for their responses in order to get their responses.
      6. Once data is collected back from sensors then send it back to the client requestor in json format.
      7. Send data to AWS IoT Core

 

  1. Use a raspberry pi and install Mosquitto (Message broker application) to act as a message broker, sending and receiving messages to any device subscribed to a given topic.
  2. Create MQTT topics and subscribe the Temperature ESP8266 to be listening and publish to certain topics.
  3. Use/Get AWS account
  4. Setup a raspberry pi to be a ”thing” in IoT Core services, create AWS certificates, download them to raspberry pi so it can communicate with AWS IoT Core services.
    1. How to:
      1. Go to AWS web Console
      2. IoT Core > Manage > Create > Create  a single thing > follow prompts
      3. Create certificates > activate > download all certificates including root CA for AWS IoT
      4. Secure > policies > Create > Add policy to be able to interact with IoT
      5. Attach a policy to the thing
  5. Create a cron job that runs a python script at every hour and makes http requests for all 3 levels ESP8266 and send the temperature readings to AWS IoT Core services.
  6. Setup an “Act” under AWS IoT Core services action that listens for a specific level for example “upstairs” and a specific temperature like “temperature > 70 or temperature < 70” then add a trigger that sends a text message or call a lambda function, etc. You could add quite a few triggers from a message received from raspberry pi, use one that makes sense for you. The ones I decided to implement were:
    1. SNS messaging:
      1. On AWS account setup a SNS service to text message you when the service is triggered.
    2. Lambda:
      1. On AWS account setup a lambda that once triggered makes an http request POST call to a slackbot. The event that goes to the AWS lambda function would contain the level and the temperature. Then the lambda decides whether to turn the fan on if the temperature is more than 70 degrees or to turn the fan off if the temperature is less than 70 degrees.
    3. How to:
      1. Go to AWS web Console
      2. IoT Core > Act > Create > fill out the form
      3. Rule query statement (this is where you write a SQL statement that queries every message from raspberry pi) you may have a sql statement like the following:
        1. Rule to write all data in DynamoDB
          1. SELECT room, temperature, timestamp() AS timestamp, topic() AS topic FROM ‘IoTTemperatureProject’ WHERE room = ‘main’ OR room = ‘basement’ OR room =’upstairs’
            1. I then added a trigger to send the message to DynamoDB database.
        2. Another rule to turn on or off the fan:
          1. SELECT room, temperature, timestamp() AS timestamp, topic() AS topic FROM ‘IoTTemperatureProject’ WHERE room = ‘upstairs’
            1. I then added a trigger to call lambda function, that lambda will check whether to send to turn fan on or off slack message to slackbot running at home.
        3. Rule when a temperature is a specific level “upstairs” and surpass a certain temperature
          1. SELECT room, temperature, timestamp() AS timestamp, topic() AS topic FROM ‘IoTTemperatureProject’ WHERE room = ‘upstairs’ AND temperature > 70
            1. I then added a trigger to send a SNS message to my cell phone
      4. For debugging you can always do the following:
        1. Go to AWS web Console
        2. IoT Core > Test > fill out the form with the topic that it will be receiving from raspberry pi and observe whether it is receiving the messages or not and whether the message is in the format that you intended.
      5. Setup DynamoDB:
        1. Go to AWS web Console
        2. DynamoDB > Create Table > fill out form > primary key will be a combination of level and timestamp as a sort key
        3. Create
        4. Also create an IAM role that is able to write to this database, the AWS MQTT client message will need this policy in order to write to this database.
      6. Setup Lambda:
        1. Go to AWS web Console
        2. Lambda > Create Function > fill out form > import a restful api module
        3. IAM policy can be just a basic lambda execution
        4. Create methods to check whether you need to send a slack message to turn on or off the fan
        5. Post the http request to the right slackbot (on or off message)
      7. Setup SNS:
        1. Go to AWS web Console
        2. SNS > Topics > create a new topic > fill out form
        3. Now subscribe to the topic:
          1. In SNS go to “Subscriptions” > create subscription > add ARN from previous topic
          2. Protocol: SMS
          3. Endpoint: <Your cell phone number>
          4. Create subscription
          5. Then you will get a text to confirm the subscription
  7. Setting up S3 bucket to host timeframe temperature data for all 3 levels, create an api gateway that once triggered it will call a lambda function which in turn will query the DynamoDB and send the temperatures back for a given timeframe, how to:
    1. Setting up S3 and enabling static website host:
      1. Go to AWS web Console
      2. S3 > Create bucket > fill out the form
      3. Once bucket is created go to “Properties”
      4. Static website hosting
      5. Fill out form and enable website hosting
      6. The go to “Permissions” > Bucket Policy > the add a policy similar to this:
        1. {
        2.    “Version”: “2008-10-17”,
        3.    “Statement”: [
        4.        {
        5.            “Sid”: “AllowPublicRead”,
        6.            “Effect”: “Allow”,
        7.            “Principal”: {
        8.                “AWS”: “*”
        9.            },
        10.            “Action”: “s3:GetObject”,
        11.            “Resource”: “arn:aws:s3:::<your-bucket-name>/*”
        12.        }
        13.    ]
        14. }
      7. Create a html file (index.html) and on page load request data by hitting an AWS API Gateway endpoint.
    2. Setting up API Gateway:
      1. Go to AWS web Console
      2. API Gateway > Create API > fill out the form as New API
      3. Once API is created then > Actions > Create method > GET
      4. Make sure to enable CORS
      5. Add the ARN from the lambda that it will be calling
      6. Actions > Deploy API
    3. Setting up Lambda that will be called from API Gateway:
      1. Go to AWS web Console
      2. Lambda > Create Function > fill out form
      3. Create an IAM policy that will be able to query (Read) the DynamoDB
      4. Use AWS DynamoDB modules to query it and respond with the desired data for a specific timeframe
  8. Setting a slack channel and slackbot:
    1. Sign up for a slack account at https://slack.com:
      1. Create a channel
      2. Create an app
      3. Create a slack bot
      4. Keep track of the bot token
      5. Enable webhook incoming requests to post to a specific channel you have created earlier.
      6. Keep track of the webhook URL
      7. Allow a bot to post to a specific channel
    2. How to create a bot script:
      1. Import json, requests, slackclient use pip install on 3rd party libraries
      2. Use your bot token to use with slackclient library
      3. Get slack user id from bot name
      4. Connect to slack
      5. Create an infinite loop that looks for messages
      6. Filter out the message you want the bot to act on
      7. If it finds a message that contains string “fan on” then send an http request to Wemo smart plug to turn the plug on and respond to slack channel.
      8. If it finds a message that contains string “fan off” then send an http request to Wemo smart plug to turn the plug off and respond to slack channel.
      9. If it finds a message that contains string “basement” or “main” or “upstairs” query via http the ESP8266 that is serving as a RESTful API to get the data and respond to slack channel accordingly.
      10. Add retry logic on the http requests, just in case a request fails for some reason, also add timeout so that a request doesn’t wait for too long.

Upstairs level – ESP8266 serving as a Restful API and the other serving as upstairs temperature sensor.

Main Level – ESP8266 Temperature sensor

Basement level – ESP8266 Temperature sensor

Upstairs fan

Slack channel showing slackbot commands and responses

Slackbot python script messages arriving and sending commands

SNS text message when upstairs temperature is above 70

Diagrams were facilitated by open source programs such as: Google drive plugin draw.io Diagrams.

 

Estimate the total time you spent on this project and report.

  • 2 hour building the circuit and cluster of devices to work well.
  • 8 hours coding all esp8266 sensors, restful server and fixing bugs
  • 10 hours on AWS integration including DynamoDB, SNS, Lambda, AWS Iot Core, API Gateway, IAM policies
  • 4 hours working on the lab report using tools such as Google draw.io Diagrams  and fritzing.
  • 1 hours publishing a website.

 

Certification of Work

I certify that the solution presented in this lab represents my own work. In the case where I have borrowed code or ideas from another person, I have provided a link to the author’s work in the references, and included a citation in the comments of my code.

 

— Lehi Alcantara

Appendix

Appendix 1: System Diagram

IoT Project Sensors Temperature System Diagram

 

Appendix 2: Arduino And Lambda And ProjectPibot Code

 

(Available at https://github.com/ylehilds/iot-temperature-project)