# Tutorial on how to build an IoT-device to monitor humidity and temperature in a humidor.
**Author**
Magdalena Zetterström (mz222fv)
Målet med projektet är att övervaka luftfuktigheten samt temperaturen i en humidor. Skulle luftfuktigheten vara för hög eller låg skickas en notis för att uppmärksamma användaren om det.
Tidsestimationen för projektet är 16 timmars arbete.
## Objective
Humidoren som ska övervakas står i dagsläget inne i ett skåp som sällan öppnas. I humidoren förvaras cigarrer och cigarrer bör förvaras i en luftfuktighet mellan 68%-72% för att må som bäst.
Att ha en enhet som automatiskt registrerar den aktuella luftfuktigheten och även varnar när den avviker för mycket från gränsvärdet, gör att det blir lättare att hålla rätt luftfuktighet för cigarrerna. Risken att glömma av att själv kontrollera luftfuktigheten minskar och på detta viset behöver bara skåpet öppnas om luftfuktigheten är fel.
## Material
I det här projektet har jag valt att använda mig av Pycom LoPy4 tillsammans med Pycom expantionboard 3.0. Enheten går att använda med LoraWAN, WiFi, Sigfox och BLE. Den är dessutom strömsnål som passar det här ändamålet.
Sensorn som jag använt är en DHT-11 vilken är en kombinerad sensor som mäter både temperatur och luftfuktighet. För att koppla ihop sensorn med LoPy4:an använde jag labbsladdar med hane/hona kontakt som jag kopplade in i expansionboarden.
För att kunna spänningsätta enheten användes en batterihållare för 3xAA batterier.

## Computer setup
Mitt första steg skulle varit att uppdatera mjukvaran i expansionboarden men jag lyckades aldrig med det. Efter sökande och kontakt med Pycom framkom det att endel macanvändare kunde ha problem med att uppdatera mjukvaran, men att expansionboarden troligtvis redan har den senaste mjukvaran. Därför hoppade jag över detta steget.
Jag ställde in LoPy4:an för att testa LoraWAN, detta gjordes genom att ladda upp en main.py-fil till enheten via Atom med ”Pymakr 2.1.5”-paketet installerat. Koden för main.py hittade jag på https://docs.pycom.io/ där det fanns exempelkod att tillgå.
Sedan konfigurerade jag om LoPy4:an för att köra mot vårt WiFi hemma. Denna konfiguration gjordes via http://pybytes.pycom.io.
För att ladda in min slutliga kod använde jag mig av Atom där jag hade modifierat min main.py enligt den funktionalitet jag ville att den skulle utföra.
## Putting everything together
Batterihållarens pluspol kopplade jag till expansionboardens VIN-port genom att löda ihop batterikontaktens sladd med en halv labbsladd så hankontakten blev kvar, minuspolen kopplade jag ihop med sensorns jord (svart linje på bilden) för att sedan sätta den i expansionboardens jord.
Plusbenet på sensorn (röd linje på bilden) kopplades till 3.3V i expansionboarden. Sensorns sista ben (gul linje) är den som skickar signalen och den kopplade jag in på P3 på expansionboarden.
Att jag enbart använt mig av labbsladdar i min koppling gör att det upplevs lite provisoriskt och det finns en risk att en sladd lossnar så det här bygget ska ses som en prototyp mer än en färdig produkt.

## Platform
Till en början använde jag mig av http://pybytes.pycom.io för att kunna ställa in WiFi och LoraWAN men när jag väl skulle läsa ut sensorvärden valde jag att gå över till Ubidots.
På Ubidots kan man lägga till sin enhet och där se utlästa sensorvärden på ett enkelt sätt. Till detta ändamålet räcker deras gratisplan eftersom det inte kommer genereras så mycket data som skickas och inte heller särskilt ofta så det finns ingen anledning att betala för mer.
## The code
Det är denna kod är den som ligger i main.py i enheten. Den kopplar upp enheten mot WiFi, läser ut sensorvärdena och skickar det sedan i json-format till Ubidots. I main.py använder jag mig av bibliotek vilka är de första som som listas i koden nedan. Koden är skriven med micropython som är språket som LoPy4:an använder sig av.
```python=
from network import WLAN
import urequests as requests
import machine
import time
import pycom
from machine import Pin
from dth import DTH
#stopping heartbeat
pycom.heartbeat(False)
pycom.rgbled(0x000008) # blue
#config from which pin to read from
th = DTH(Pin('P3', mode=Pin.OPEN_DRAIN),0)
# created function for reading sensor data
def getSensorData():
print("******** Reading sensor **********")
result = th.read()
pycom.rgbled(0xFFA500) #orange
#try until we get a valid result
while not result.is_valid():
time.sleep(.5)
result = th.read()
pycom.rgbled(0x7f0000) #red
print("******** Result not valid **********")
pycom.rgbled(0x001000) # green
print("******** Sensor reading OK! **********")
return result
#token for Ubidots
TOKEN = "<TOKEN>" #Put here your TOKEN
DELAY = 3600 # Delay in seconds
#WLAN settings
wlan = WLAN(mode=WLAN.STA)
wlan.antenna(WLAN.INT_ANT)
# Assign WiFi credentials
wlan.connect("<SSID>", auth=(WLAN.WPA2, "<PASSWORD>"), timeout=5000)
#connect to WiFi
while not wlan.isconnected ():
machine.idle()
print("Connected to Wifi\n")
# Builds the json to send the request
def build_json(variable1, value1, variable2, value2):
try:
data = {variable1: {"value": value1}, variable2: {"value": value2}}
return data
except:
return None
# Sends the request
def post_var(device, value1, value2):
try:
url = "https://industrial.api.ubidots.com/"
url = url + "api/v1.6/devices/" + device
headers = {"X-Auth-Token": TOKEN, "Content-Type": "application/json"}
data = build_json("humidity", value1, "temperature", value2)
if data is not None:
print(data)
req = requests.post(url=url, headers=headers, json=data)
return req.json()
else:
pass
except:
pass
#running loop for ever and new reading every hour
while True:
sensorData = getSensorData()
humidity = sensorData.humidity
temperature = sensorData.temperature
post_var("pycom", humidity, temperature)
time.sleep(DELAY)
```
## Transmitting the data / connectivity
I main.py filen på min Pycom enhet skapas ett temporärt Json-objekt upp där jag lägger till key Value för datan som hämtas från DHT11-sensorn.
Sedan görs en POST av datan till Ubidots REST-API. I Headern för requestet så specificeras vilken ContentType det ska vara dvs ”application/json” samt en individuell token. Json användes för att det är ett utbrett sätt att skicka data samt att det fungerade sömlöst mot Ubidots.
En gång i timmen skickas datan från enheten till Ubidots genom WiFi. För att kunna göra detta följde jag en guide på Ubidots hemsida (https://help.ubidots.com/en/articles/961994-connect-any-pycom-board-to-ubidots-using-wi-fi-over-http). Om datan skulle skickas oftare skulle det gå åt för stor mängd data och gratisversionen av Ubidots skulle inte räcka. Men det finns ingen anledning att skicka data oftare eftersom luftfuktigheten inte varierar så mycket på kort tid.
Att jag valt att använda mig av WiFi var framförallt att det inte finns något LoRa nätverk i närheten av mig. Men samtidigt fungerar det bra med WiFi eftersom humidoren bara kommer vara i hemmet.
## Presenting the data
I Ubidots lägger man till sin enhet och efter den har kontakt går det enkelt att skapa en dashboard efter tycke och smak. Först väljs den data som ska presenteras och får då flera valmöjligheter på hur datan ska presenteras. Jag valde att visa både temperaturen och fuktigheten på tre olika grafiska sätt samt att ha en graf över historiska mätvärden.
Datan sparas i Ubidots till jag själv raderar den och jag har ställt in min IoT-enhet att skicka data en gång i timmen för att inte överskrida den tillåtna datamängden per dag.
Vill man få notiser är det också enkelt att ställa in events i Ubidots. Jag har valt att det ska skickas ett e-mail när fuktigheten är för låg respektive för hög och det fungerar alldeles utmärkt.

## Finalizing the design
Nu ligger enheten löst i humidoren vilket inte är idealiskt. Labbsladdarna upplevs också väldigt temporära så om jag vill fortsätta använda mig av enheten borde jag bygga en låda för den. Men rent funktionellt fungerar den som tänkt nu. Jag får varning om fuktigheten avviker och jag slipper kontrollera humidoren själv. Så jag är väldigt nöjd med slutresultatet och presentationen av datan.


