# Smart warning for refrigerator room

By: Robert Jonsson (rj222pi)
A simple project using a temperature sensor with the LoPy4 & Pycom to collect data throughout each day. Wi-Fi is used to send gathered data and sometimes webhooks to trigger "high temp" notifications to a phone app.
Time to complete: ~10-20 hours.
## Objective
The project idea came from my father, he had problems regarding a refrigerated room in his workplace. Every so often during hot summer days the compressor that cools the room dies. So my father has to spend 40min driving back and forth between home and work. Some days even multiple times each day just to check on the compressor. It would be better if the extra trip could be avoided and the saved time could be used for other things.
I thought the problem was a great example of real life events that could benefit from IoT devices and it felt perfect as a course project. The gathered data is sent to [Ubidots](https://ubidots.com/) for neat dashboard presentations and [IFTTT](https://ifttt.com/home) is used to handle notifications in case the temperature would rise too high inside the fridge.
Not only will this solution bring "peace of mind" but it will also help with monitoring the temperature, using ubidots to easily present the data history.
## Material
### What is needed:
* Lopy4 with Pycom Expansion Board V3.1 (or v3.0).
I bought [this bundle](https://www.electrokit.com/produkt/lnu-1dt305-tillampad-iot-lopy4-and-sensors-bundle/) for 949kr from elektrokit, since it was the simplest to do. It contains everything needed (which is also linked below) and a few extra items. I've opted to use elektrokit for all my orders, but all of the items could be bought from anywhere else as well i.e amazon or maybe you can google to find your own local shop.
*I did not end up using the antenna in my setup. But it's in [Alternatives](#Alternatives).*

* [Micro USB cabel](https://www.electrokit.com/produkt/usb-kabel-a-hane-micro-b-5p-hane-1m/)= 39kr
Most of us own this already and it's needed to connect the expansion board to the computer or to power it through a wall plug adapter.

* "[Temperature sensor MCP9700](https://www.electrokit.com/produkt/mcp9700-e-to-to-92-temperaturgivare/)" = 8kr
An analog temperature sensor that's included in the kit I bought.

* [Breadboard](https://www.electrokit.com/produkt/kopplingsdack-400-anslutningar/)= 59kr
[Jumper wire](https://www.electrokit.com/produkt/labsladd-1-pin-hane-hane-150mm-10-pack/)= 33kr.
Breadboard isn't a must but is recommended for easy connection between the boards and sensors, no need for soldering. The jumper wire is used for connecting the board and sensors through the breadboard.

### Alternatives
* [Cheaper micro controller](https://www.amazon.se/gp/product/B08MB9K8D1/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1) ~223kr
Smaller device with Wi-Fi and JST connections.
>I will try to set this up using the same or similiar code as for my pycom since the pycom is a bit over the top for what I want to achieve and I'd rather save it for another project.*

* [LoRa/Sigfox antenna](https://www.digikey.se/product-detail/en/pycom-ltd/SIGFOX%2FLORA%2520ANTENNA%2520KIT/1871-1005-ND/7721843?gclid=CjwKCAjwjJmIBhA4EiwAQdCbxpTXDPcoqjMBVZVkveYlr5EYfjXQfJhWo2E_7UsdDqd6M6TztzdPoRoCr44QAvD_BwE) ~143kr
A good alternative in case you don't have Wi-Fi connection available, just be sure to check your coverage first on any of the maps: [LoRaTTN](h[ttps://](https://www.thethingsnetwork.org/map))/[LoRaHelium](https://explorer.helium.com/coverage#2.9/57.36/31.54)/[Sigfox](https://www.sigfox.com/en/coverage).

* [Battery holder 3xAAA with JST](https://www.electrokit.com/produkt/batterihallare-3xaaa-med-strombrytare-och-jst-kontakt/)=29kr.
>I bought this to later power the device instead of the micro USB ([Voltage notes](#Connecting-hardware)).

* [3D Printed Pycom & Breadboard case](https://github.com/HedvigBring/Pycom-Breadboard-Case) 0-40kr
This is not a must, but it's nice to have. I could print my own so the cost was next to nothing. You can always check if anyone can print it for you.
## Hardware & Computer Setup
* Connect the LoPy4 to the expansion board
>In this orientation:

* Install [Node.js](https://nodejs.org/en/) on your computer, it will be needed for the pymakr plugin.
For Linux Ubuntu/Debian "sudo apt install nodejs".
* Now choose and install your IDE, you can pick whichever you want ([Vscode](https://code.visualstudio.com/download)/[Atom](https://atom.io/)). I went with Vscode because I already had that installed .
* In the IDE go to "extensions" and type "pymakr" and install the plugin. Pymakr will make it easy to run and upload code to the device.
>What it looks like for Vscode

Installation is successfull if the bottom of the IDE looks something like this:

* Connect the device. It should auto-connect but if it doesn't follow this guide for [Vscode](https://docs.pycom.io/gettingstarted/software/vscode/#:~:text=Connecting%20via%20Serial%20USB) or [Atom](https://docs.pycom.io/gettingstarted/software/atom/#:~:text=Connecting%20via%20Serial%20USB).
I followed [this simple guide](https://hackmd.io/@lnu-iot/rk4qNlajd#:~:text=issue%20here%3A%20link-,3.%20Make%20LED%20blink,-You%E2%80%99ve%20already%20installed) which goes through how to set up a project in Vscode and create libraries, you can then try the code to make the LED on the LoPy4 blink. This code is a good test to make sure everything is working correctly and that it's possible to upload code to the device. You can also check [this libraries guide](https://hackmd.io/@lnu-iot/BJnuGmJh_#:~:text=How%20to%20download%20libraries) for a more in-depth tutorial on how to download and import them.
## Connecting hardware
So now it's time to connect the sensors. I'm using the "MCP9700", it's an analog sensor and if you're going to use any other temperature sensor make sure to read the datasheet so you connect it properly. You don't want to damage any electronics with faulty wiring. Pick the wires color as you will but be consistant about it e.g always use red for 3.3v and maybe black or white for GND, but it's up to you.
The micro USB will be used as the power source, but in a near future this solution will be replaced by the battery pack. *I've gone with the 3xAAA specific battery pack because it stays in the safe range of 3.3V - 4.5V during use and this won't damage the board.*
* If the cables are connected following the right picture below, with the sensor in the middle of the board with the **sensors flat side towards you**.
* Connect the device **3.3v** to the red line on the breadboard
* Connect another wire from the red line into the middle of the breadboard lining up with the sensors left pin.
* Connect the **GND** to the blue line on the breadboard.
* Connect another wire from the blue line into the middle of the breadboard lining up under the sensors right pin.
* Connect the green cable to the device port **P16** (any pin with ADC capabilities will work like P13-P16) and then connect it to the middle of the breadboard lining up to the sensors middle pin.
**My wiring scheme:**
:white_circle: **: GND**
:red_circle: **: 3.3v**
:green_apple: **: P16 (Data)**
>Fritzing :large_blue_circle: = :white_circle: - Fritzing picture borrowed from [course tutorial](https://hackmd.io/@lnu-iot/BJnuGmJh_#:~:text=to%20interface%20them.-,How%20to%20connect%20a%20sensor%20physically,-The%20basic%20sensors).

## Platform

> Current temp (left) & temp during the day (right) - changed to every 30min for display
I've decided to use [Ubidots](https://ubidots.com/stem/) as my platform, it seemed most beginner friendly and I think it will be easier for my dad to play around with if he wants to. I also really liked the dashboards you can use here to represent the data. Another option would be [Pybytes](https://pycom.io/products/software/pybytes-3/) since it can create dashboards as well. Both platforms also have the ability to create alarms/notifications e.g through sms or email.
But for notifcations I opted to use [IFTTT](https://ifttt.com/home) instead because it can use webhooks to create/send notifications in the "IFTTT" app. Which works better for my father because he doesn't want notifications through his email.
## The code & data transmission
All code files can be found [here](https://github.com/Cazerminis/lnuproject).
### IFTTT
To create your own notifcations in the IFTTT app you first need to download the app on your phone, search for "IFTTT" in your designated app store. Then go to the [IFTTT website](https://www.ifttt.com) and create an account, login on the website and on your app. You should now be able to press "create" in the top right corner.
* In the "If this" option press "Add".
* Then search for **"webhooks"**, press it and select **"Recieve a web request"** *(You can name this event whatever you want, this will be the "trigger word" that will used later. Mine is "hightemp").*
* Press "**create trigger**".
* In the "Then That", press "Add".
* Search for "**Notifications**", press it and select "**Send notification from the IFTTT app**".
* Here you can customize the look of the notification. I went with:
> "Hight temp in the fridge!
> Value1 Degrees
> At: OccuredAt"
You can write free text or press "**Add ingridient**" to add things like **"Value1"** which is the value from the sensor, **"OccuredAt"** is the time of the trigger ([IFTTT code](#IFTTT-code)).
* Press continue and what title you want for the applet, then select "Finish".
In the webhooks [documentation](https://maker.ifttt.com) You can test if it's working correctly by entering your trigger word in the event field, remove the "{}". If you want to you can also add values to the optional JSON body. Then press the "Test it" button.

It should look something like this on your phone if it's working correctly, you can then proceed with the [IFTTT code](#IFTTT-code).

### Sensor readings
So the sensor is now connected and all the wiring is correct. Time to create the code to gather data from the sensor, send the data to the platform and if needed contact IFTTT to create notifications. *If you use another sensor here make sure to read it's datasheet so you know how to gather the data.*
I've used the code from [Tutorial 2](https://hackmd.io/@lnu-iot/BJnuGmJh_#:~:text=Basic%20Analog%20sensors-,Analog,-sensors%20are%20devices) to **gather sensor data**, but you should also read it for better understanding on how to connect and gather data from the sensors.
### Wi-fi connection & data transmission
I followed [this](https://help.ubidots.com/en/articles/961994-connect-any-pycom-board-to-ubidots-using-wi-fi-over-http#:~:text=boot.py%22%20file.-,3.-,-Next%2C%20copy%20and) **ubidots guide** for **connecting** the **device to Wi-Fi** and **send data to ubidots** using http. *I'm not showing the gather/send functions here since they are just copied from the guide.*
I also used this course [Tutorial 3](https://hackmd.io/@lnu-iot/r1bGPUOhu#:~:text=time.sleep(5)-,Connect%20to%20Wi-Fi,-If%20you%20use) for another angle in connecting to **Wi-Fi** and to **hide keys/tokens** for different services i.e Wi-Fi, ubidots or pybytes.
To hide your keys, create a new file in your project and name it "keys.py" and enter your Wi-Fi credentials. Once you've created an ubidots account, follow this [ubidots token guide](https://help.ubidots.com/en/articles/590078-find-your-token-from-your-ubidots-account) to get your token.
*keys.py:*
```python=
WIFI_NAME = "Wi-Fi ssid"
WIFI_PASS = "Wi-Fi password"
Ubidots = "ubidots token"
```
You can now import the keys file into main and use the variable names instead of "hard coding" the credentials.
*main.py:*
```python=
import keys
from network import WLAN
wlan = WLAN(mode=WLAN.STA)
wlan.antenna(WLAN.INT_ANT)
wlan.connect(ssid=keys.WIFI_NAME, auth=(WLAN.WPA2, keys.WIFI_PASS))
while not wlan.isconnected ():
machine.idle()
print("Connected to Wi-Fi\n")
```
###### IFTTT code
I can highly recommend [this blogpost](https://blog.miguelgrinberg.com/post/micropython-and-the-internet-of-things-part-iv-wi-fi-and-the-cloud) which goes through http requests, webhooks and IFTTT very well, at least I found it easier to understand what was going on after reading this.
```python=
import = urequests
```
I'm using a forever loop that gathers data from the sensor and then sends the data to the other functions. The "post_var" function is for sending data to Ubidots and "send_warning" is the function for creating the IFTTT notifcation. The "DELAY" variable is set to 60 seconds, which means that the device reads and sends data to ubidots every minute.
```python=62
while True:
millivolts = apin.voltage()
celsius = (millivolts - 500.0) / 10.0
post_var("pycom",celsius)
send_warning(celsius)
time.sleep (DELAY)
```
The device also checks every 60 seconds if the temperature rises above the threshold or not. If it does it will make a post request with the trigger "hightemp" in the url together with my specific webhooks key. To find your webhooks key make sure to read the documentation tab in [webhooks](https://ifttt.com/maker_webhooks) and your key will be at the top together with some more information.
```python=49
#Send IFTTT notification on phone
def send_warning(grader):
try:
tempUrl="https://maker.ifttt.com/trigger/hightemp/with/key/mywebhookskey"
if(grader>9):
print("high temp")
res = urequests.post(url=tempUrl, json={"value1": grader})
return res.json(),c
else:
pass
except:
pass
```
# Presenting data
To build a new dashboard to present your data, press the top left corner **"Dashboard"**.

* Press the **orange circle** with a **"+".**
* Now you can choose a name for the dashboard, the time range for how old data should be displayed (*I choose for the last 7 days*) and much more options.
* Press the **green circle** in the **bottom right corner** when done.
* Press "**Add new widget**".
* Choose a widget you think fits (I took thermometer).
* At the top right click "**add variables**", select your pycom device and add your data "grader".
* Choose the settings you want like aggregation method or range value, press the **green button** with a "+" **at the bottom**.
* Your widget should now be displayed.
In the end I also added one more widget (line chart) to display the temperature throughout the day.

Since I'm using Ubidots STEM the data is only stored for 1 month, but it's possible to download the data or start a subscription for business which would keep the data for 24 months.
# Final thoughts
I think the project has been a lot of fun and I think the lectures have been good at giving insight to what our IoT devices can be used for in the world.
There are some things that I would change for the project. One is that I will try to replace my LoPy4/Pycom device with the [alternative device](#Alternatives) in the future. Since I don't need such an advanced device as the LoPy4/Pycom for what I need to do, so the alternative will be a cheaper option. Then I can do something else with the LoPy4/Pycom.
Another improvement would be to switch from powering the device with USB to power it with the battery pack, which will hopefully make it easier to store my device inside a [food container](https://www.ikea.com/se/sv/p/ikea-365-matlada-fyrkantigt-plast-60452174/) to place inside the fridge. This would mean I don't have to solder on longer wires on the sensor to store the device outside the fridge (moisture testing inside the containers is already going on). Once the battery pack is added I will also try to upload new code that will work with IFTTT to warn if the battery has <20% and then if it's <5% battery life left. Just so my dad knows that it's soon time to switch the batteries.
I also want to create a new webhook to IFTTT through Ubidots, so if Ubidots haven't recieved data from the device in 10 minutes it will send a webhook to IFTTT which will create a notification about it. This would be good to know if:
a) The batteries are dead.
b) That something else is wrong - is Wi-Fi down?
For option b) it would be good to have redundancy for the data transmission, adding the lora/sigfox antenna as backup for the Wi-Fi. This is not an alternative for me since I'm not in coverage, but it's an option.
Other than these changes I feel like the project has been going well and I'm satisfied with the end result. It's going to be fun to see if there's anything else I can come up with in the future, since I get the LoPy/Pycom device to spare.
