# Monitor your room temperature, humidity, brightness and sound level - prototype.
#### Author: Seif Bourogaa - sb224ay
In this project we are going to build a system that allows us to track and monitor the temperature, humitidy, brightness and sound-level in a room. We will be storing the data on a database locally using Raspberry Pi, allowing you to have full control of all the data.

Estimated time: **~6 hours**
Estimated price: **~100$**
## Objective
There's a couple of reasons behind this project:
1. First and foremost I wanted to learn more about IoT, IoT-protocols and how to set up IoT devices.
2. Find a way to measure temperature and brightness at home.
3. Automatically monitor my alarm to gather data on when I work so I can send it to my employer so he can confirm it and let me get paid.
4. Use the data gathered to eventually be able to control my AC system and my room lightening
## Material
Bellow I will list all the material used. Since this was a prototype, some components can be replaced with cheaper alternatives, but I will address that towards the end.
1. **Microcontroller**, I have used a Fipy from PyCom to create this prototype. It is rather expensive microcontroller but it has a powerful CPU, capable of using five different networks: WiFi, BLE, LTE, LoRa and Sigfox and has a 1KM WiFi range. It is MicroPython enabled and that is also the programming language I will be using in this tutorial. However, any other Wifi-capable Microcontroller should do fine.
Price: [60$](https://pycom.io/product/fipy/)
2. **Expansion Board** I am also using a PyCom expansion board to make all the wiring easier.
Price: [18$](https://pycom.io/product/expansion-board-3-0/)
3. **Temperature sensor** I will be using a DHT11 sensor, which measures temperature and humidity.
Price: [5$](https://www.kjell.com/se/produkter/el-verktyg/arduino/tillbehor/temperatur-och-luftfuktighetssensor-for-arduino-p87877)
4. **Light Dependant Resistor** I am using a LDR to measure the brightness in the room.
Price: [5$](https://www.kjell.com/se/produkter/el-verktyg/arduino/moduler/luxorparts-ljussensor-for-arduino-p87894)
5. **Small Microphone Module** I will be using a microphone module to detect the sound of my alarm going off.
Price: [10$](https://www.kjell.com/se/produkter/el-verktyg/arduino/moduler/ljudsensormodul-for-arduino-p87071)
6. **Resistors.** You will need at least 1 4.7kΩ resistor and 1 1kΩ resistor. You'll find these in any electronics store and they are very cheap!
This is all you need if you just want to take measuremeants and put them on some server. However, if you want it all in-house, like I will be doing in this tutorial, then it is highly recommended you get:
### Material (Optional)
6. [ **Raspberry Pi**](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/), I am using a Raspberry Pi 4 Model B with 8GB of RAM but any Raspberry Pi 4 model should be good enough.
7. [ A case](https://www.raspberrypi.org/products/raspberry-pi-4-case/) for your Raspberry Pi 4.
8. Rasperry Pi 4 [Power Supply](https://www.raspberrypi.org/products/type-c-power-supply/)
**Note:** Depending on how much effort and style you want to put on this, the price range can vary a lot. Since this was a prototype I did not choose always chose the optional components.
## Computer Setup
Bellow I will describe the steps I took to get my Microcontroller upp and running and how I uploaded code to the Microcontroller. **Please note** that all steps described here are done on Manjaro Linux and is thus not guaranteed to work on Windows or some other Linux distributions.
### Flashing Firmware
#### Flashing the expansion board
First, it is recommended that we update the firmware on the expansion board without the Fipy microcontroller attached to it. To do so, we simply connect it with the USB to the computer, [download the latest firmware](https://docs.pycom.io/pytrackpysense/installation/firmware/) and run the following in your konsole:
sudo dfu-util -D expansion31_0.0.11.dfu
If the firmware was updated succesfully, you should get an output similiar to this one:

#### Flashing the Microcontroller
Once we have updated the firmware on the expansion board, we can connect the Microcontroller to the expansion board. It should be attached like this:

Next we need to update the firmware on the Fipy. [First, we need to get the firmware updating tool](https://software.pycom.io/downloads/linux-1.16.5.html). Once that is downloaded connect your Fipy and the attached expansion board to the computer and run the firmware updating tool. It should look like this:

Click continue until you reach this window:

Here, flash the Fipy with *"pybytes"* firmware and make sure *"Force update Pybytes registreation"* and Enable Pybytes/SmartConfig support" and *"Show Advanced Settings" *is **not** checked.
If everything was succesfull, you should be greeted with this screen:

Congratulations! You are now ready to start coding! But first...
### Choose your IDE
To program my device I have chosen to use Atom. Why? Because there is this very neat PyCom plugin called "pyMakr" that allows you to install the code on your device right from Atom.
To install Atom IDE on your computer, run the following command:
sudo pacman -S atom
Once you have Atom installed, you will have to install the pyMakr plugin on Atom to enable this feature. Simply go to setting, go to the install tab and search for "pyMakr". Once it has been installed, you should be able to find it under the Packages tab, like this:

### Uploading code
Uploading code with Atom using the pyMakr plugin is easy. Create a folder where you store your code and simply press the "Upload Project to device" button shown bellow.

## Putting everything together
Here is all the components you will need. Now we simply have to connect everything, since this was a prototype I have only done this with normal jumper cables.

This is what the circuit diagram looks like:

Here, the Red lines represent Voltage in (Vin), Black lines represent Ground (GND) and blueish lines represent the data lines from the sensors to the Fipy. Please note that on the DHT-11 sensor, you need a **4.7KΩ resistor** between the data line and Vin, represented by the yellow line in the diagram. Likewise, you need a **1KΩ resistor** between the data line and GND on the LDR sensor, once again represented by the yellow line.
## Platform
On this protoype I am using a local platform, it is free and it allows us to have full control over our own data. To do this, I am using a Raspberry Pi 4 Model B running [Manjaro ARM KDE Plasma](https://manjaro.org/download/#ARM).
Before running the Raspberry Pi as a remote home-server that you can access, host a database on, send data to etc, there are a couple of things you need to do.
### Enabling SSH
In order for us to connect to our Raspberry Pi remotely we need to enable SSH. This is easily done running the following commands in the konsole:
sudo pacman -S openssh
sudo systemctl enable sshd.service
sudo systemctl start sshd.service
Now we should be able to restart our Rasperry Pi, relocate it to whereever we want it to be and access it remotely:

### Install MQTT Broker
Now that we have remote access to the Raspberry Pi we intend to use as a home server, we need to be able to send data to it from our device.
In order to do so, I have chosen to use MQTT. However, in order to send data using MQTT we need an MQTT broker. There are many public ones available, but I have chosen to create my own one to have full control of the data.
The MQTT broker we will be using in this tutorial is Mosquitto MQTT. It is installed by running the following commands:
sudo pacman -S mosquitto
sudo systemctl enable mosquitto
sudo systemctl start mosquitto
It should now be up and running. We can check the status with:
sudo systemctl status mosquitto

### Install Docker
To gather, store and display the data I will be using Telegraf, InfluxDB and Grafana (or TIG-stack) and I will be running each of these on individual containers that are linked to each other. To do this, I will be using docker.
Install docker by running the following command in the konsole:
sudo pacman -S docker.

Now we need to install the TIG-stack images. We do this by running the following commands in the konsole:
docker pull telegraf
docker pull influxdb
docker pull grafana/grafana
### Mount external harddrive
I will store all the data on an external harddrive attached to the Raspberry Pi, to avoid damaging the microSD card in the long run.
First, we need to specify a mount point. I want the data, on the external harddrive, to be found under /mnt/devserver. In order to do so, execute the following commands:
sudo blkid
This should get us the location of the harddrive, in my case it is under /dev/sda3. Now we need to create a target folder to be the mount point for the external harddrive, this is done by executing the following command:
sudo mkdir /mnt/devserver
Now we mount the external harddrive on that mountpoint:
sudo mount /dev/sda3 /mnt/devserver
In order to automatically mount the harddrive at startup we need to modify the /etc/fstab file. First, we need to get the UUID:
sudo blkid

Here we can see that the UUID is 662e8342-22a7-48d3-8be2-a46acc1c4322
Now we need to add that line to the /etc/fstab file:
sudo nano /etc/fstab

Now we can reboot the Raspberry Pi without having to manually mount the external harddrive every time.
### Create directory for data
Now, we need to create a directory to store the data we are collecting, I will create the storage point on the external harddrive.
cd /mnt/devserver
sudo mkdir IoTStack
Now we need to add two files to that directory, called:
docker-compose.yml
telegraf.conf
You will find these on the Github page. However, you will need to edit telegraf.conf file to include your own MQTT broker settings.
### Firing up the TIG-stack
If you have followed all these steps, we should now be able to fire up our TIG-stack and collect data from our device. Run the following command in the Konsole:
docker-compose up -d

All our data is now being collected and a new folder, called "data" should have appeared in that directory, where it is stored.

## The Code and Configuration files
The code as well as the two above configuration files can be found on [Github](https://github.com/Loqotia/IoTStack).You will also need to edit the JSON file to include your WiFi data, such as SSID and Password, as well as your MQTT username and password. Last, but not least, you need to insert the correct MQTT IP and Topic in the main file.
## Transmitting the data
The data flow is the following:

1. The Fipy takes sensor-readings every 10 minutes and sends it through WiFi to the Raspberry Pi, using the MQTT Protocol. These packets are known as "publish" packets and they are going to the MQTT-broker we installed on the Raspberry Pi above.
2. The Fipy is constantly checking the readings from the sound sensor, but it only ever sends it if it reaches a certain treshold at a certain time - between 03-05AM.
3. Telegraf subscribes to the desired topics specified in the configuration file, in this case loqotia/bedroom, and grabs the packages from the broker.
4. Once the Telegraf client has recieved the data it is sent to the InfluxDB that stores the data along side the time and date the data was reiceved.
5. Grafana, which is used to visualize the data, is querying InfluxDB for new data every 10 minutes and adds it to the relevant graphs and charts.
Wifi is great for sending data, since it is very fast. But it has its limitations. Wifi has short range and very high power consumption. However, this is not a problem in this project. As these are intended to be used at home where they are well within range of the WiFi network as well as having plenty of electricity to consume.
If energy consumption is a problem for you, consider adding Deep Sleep between data readings, change connection from WiFi to something with less energy consumption, like Bluetooth Low Energy (BLE) or LoRa.
Another limitation with this is the way the data is sent. The data is formatted as JSON, which is very easy to work with and ontop of that Telegraf is configured to work with JSON-format. The bigger issue could be integrity, as the data is sent plain without any encoding, this could easily be configured though. For me, it is not much of an issue, since I am not sending very sensitive data.
## Presenting the data
The data is saved to the database as soon as a new topic is published, which is every 10 minutes and stored for as long as we want - or until we run out of space on the harddrive.:P
Every 10 minutes is quite often and if you intend to run this using battery power than the frequency of the readings could be reduced to increase the uptime of one battery charge.
### Database
The database I am running is InfluxDB, which is a Open Source database optimized for fast, high-availability storage and retrieval of time series data. It is also very easy to work with and is integrated flawlessly and simple with Telegraf and Grafana. However, any SQL database could be used if you are willing to take the time to configure it.
### Automation of the data
Since I am not interested in the sound readings all the time, the data is only stored in the database if the sound-level reach a certain threshold at a certain time, thus allowing me to know how many days I have worked this/last month and grab the data from the database to know what date that was.
### Visualization
The data is visualized with Grafana, which is very easy to work with and configure to display the exact data we want.

Here, I have configured grafana to display the temperature, humidity and brightness over the last 12 hours as well as the last recorded temperature, humidity and brightness.
## Finalizing the design
Since this was only a prototype, this will not be the final design. There are a few things I am going to change before I start deploying these at home.
1. Although the Fipy is great for prototyping, it is very expensive. I will replace the Fipy with ESP8266 microcontrollers, which are far cheaper.
2. I need to 3D print a case for my ESP8266 microcontroller and the sensors. As of right now, it is a mess:

3. Design and order a PCB to make everything fit in a neat case.
4. I will also need to 3D print a case for my Raspberry Pi, since I have a cooling tower attached to it and a mSATA SSD expansion board on the way. However, since the mSATA SSD expansion board has not arrived yet, I can't start designing one. My home server is currently looking like this, not very pretty:

I will be updating this as I continue with it, by the end of August. I just recently moved and I am working full time as well as studying full time so let's just say the project and the Raspberry Pi ain't the only things needing some love right now.