# Tutorial: Home climate automation **Project in the course 1DT305 Applied IoT by John Lindblad - jl224pz** This project is the first step in the construction of a basic infrastructure that can be used to monitor and automate air quality, temperature, and humidity in a home environment. The time requirements of just setting up a device and following this tutorial are low. It can probably be done in less than a day (about 5-10 hours depending on previous experience). However, it could be worth spending time investigating and testing different cloud platforms to identify which one that fits your needs and objectives. ## Objective The objective is to collect and organize data about indoor and outdoor environment in order to create a platform for personal use and to automate things like temperature and humidity management at home. It can also give me insights about the air quality which will enable me to take actions to improve it. I chose this project idea because it can get me started quickly and can be scaled up later by adding automation of things like floor fans and air conditioning devices. Due to the limited time for this project and the fact that I did not have supplies to create such systems, I have focused this tutorial on the building of a platform that can be used for monitoring and alerts and to enable future automation of physical appliances like AC or radiator. ## Material I bought most of the material in the form of a bundled kit exclusive for this course from Electrokit. The costs below are approximates based on prices from Pycom for the LoPy and expansion board and Amazon for the rest of the supplies. | Material | Cost | Description | | -------- | -------- | -------- | | LoPy4 | ~40 USD | The main device/microcontroller | | Pycom Expansion board 3.0 | ~ 18 USD | Enables USB, battery and other connections to the device | | Breadboard | ~ 3 USD | Simplifies the creation of prototype circuits in the development phase. (Not required but highly recommended) | | Wires | ~ 5 USD | Used to connect sensors to the device | | Micro-USB cable + wall charger | ~ 10 USD | Used to connect the device to a computer or power outlet at the wall | | DHT11 sensor | ~ 5 USD | Sensor for temperature and humidity | | CCS811 | ~ 15 USD | Sensor for CO2 and VOCs | ## Computer setup I have chosen to use Atom since it is my go-to IDE in general and the pymakr add-on makes it fit well with development on a Pycom board. I was using the pymakr add-on in Atom to upload code to the device and also for testing different scripts and ideas. If not working in a physical proximity to the device and sensor, the pybytes web tool can also be used to upload code to the device. This makes Pybtes a nice tool for device management. I did not have to do any additional setup on my computer except adding the pymakr-tool to atom. If you do not have atom installed you need to download and set it up. My pycom devices already had the latest firmware installed and, thus, I did not have any troubles updating it before getting started. I also did not need to install any extra drivers or similar. ## Putting everything together The picture below illustrates the wiring for the sensors and device. Note that the sensor could be connected directly to the breadboard and that you should put the wires to the device on the same row (read up on breadboards if you have not used one before). The image here is more aimed to show the connections and a photo of my final setup will be shown later in this tutorial. ![](https://i.imgur.com/MCdye5F.jpg) The connections for the DHT11 are the following: | Device pin | Sensor pin | | -------- | -------- | | 3V3 | VCC | | GND | GND | | P23 | S (Signal) | The connections for the CCS811 are the following: | Device pin | Sensor pin | | -------- | -------- | | 3V3 | VCC | | GND | GND | | GND | WAKE | | P9 | SDA | | P10 | SCL | Besides that, you need to connect the LoPy4 to a computer via USB or Wifi in order to upload the code (or to set up Pybytes and upload the code from there later on). When this is done, you can supply the device via USB or battery. Since my sensors were mounted on cards with resistors, there is no need for electrical calculations just to get it all up and running. Both sensors also works fine with the 3.3V voltage from the LoPy4 device. The power consumption for different frequencies are estimated to be like in the table below (approximates based on datasheets from sensors and LoPy4 device): | Frequency | Approx. power consumption | Time for 1 cycle on a 4.4 Wh battery | | -------- | -------- | -------- | | 1 per second | 400 mW | 11h | | 1 per minute | 105 mW | 43h | It is obvious that my setup requires a heavier battery due to the quite short cycle times given the power consumption and the battery specs above. I have not tried the deepsleep mode on the LoPy4 yet but some rough calculations gave me an approximate of about 90% lower power consumption for the 1 per minute-example. If that is correct it would be possible to run this setup on a 4.4Wh battery for about 2.5 weeks (or 430 hours). Since I do not use a battery and aim to set this up at home, power consumption is not yet a problem and it will be handled later in the implementation phase when I add automation of Air Conditioning to the system. The primary solution to increase the time for one battery cycle is likely to be less frequent readings (> 5 minutes intervals) and the deepsleep mode. ## Platform I have chosen to use Ubidots, the functionality I have used is: * Dashboards (to visualize data) * Events (to get notifications via mail) * Built-in database I also used Pybytes in the beginning to make some dashboards but the functionality of that platform is limited. However, it is very good for device management and the online pymakr tool can be used to easily deploy code to the device even without connecting the device via the pymakr plugin or some FTP solution like FileZilla which can be used like an "explorer" for the internal memory on the LoPy. The online pymakr tool on Pybytes can be useful when updating the code from remote. Therefore, I recommend to do the basic setup of the device on Pybytes but quickly move on to Ubidots for data visualization and analysis and creation of automations in the cloud. Ubidots is a cloud-based platform which is good if you don't have any server or other cloud-environment available. I plan to use the free version of ubidots in the beginning since it provides enough functionality for what I want to do within the scope of this project. Ubidots also have a mobile app for android which makes it easy to set up and follow the dashboard when on the move. There are various possible configurations of these dashboards and some of these will be illustrated below. The free version of Ubidots also have functionality enabling automation (called 'Events'). This cold include for example sending email notification or triggering webhooks. The webhook triggers are useful for many reasons and could be integrated with e.g. IFTTT. The premium-version of Ubidots has functionality for analytics. I have not tried this personally but it could be an alternative if you do not want to set up a TIG-stack server or similar for your more advanced analytics workflows. There is no need for such functionality in this project and it is therefore not required to get this up and running and to create dashboards and some automation. Note that there are daily limits to how much data you can send through Ubidots. This should not be a problem when running the application as presented above but may cause problems during the development phase if you experiment a lot during one day by sending data more often. Other tools that i tried but did not create any complete application for was Node-RED and a TIG-stack. These are more advanced alternatives that I will implement later when adding more complicated tasks to the automation stack of my application. Implementation of these requires more time which I felt was a ineffective investment of time for this specific project but it can be useful for larger or more complex projects or if you already have experience of such technologies. ## The code The boot-file is quite brief and simple and its main function is to connect to wifi. ```python= import pycom pycom.heartbeat(False) pycom.pybytes_on_boot(False) from network import WLAN import machine wlan = WLAN(mode=WLAN.STA) wlan.antenna(WLAN.INT_ANT) # connect to wifi wlan.connect("your-ssid", auth=(WLAN.WPA2, "your-password"), timeout=5000) # put the SSID and password for your home wifi here while not wlan.isconnected(): machine.idle() print("Connected to Wifi") ``` The main-file includes the following code and it is where most of the magic happens. There are four functions in this file: one to read from each sensor, one to create a JSON-object to be sent, and one to send the HTTP POST request. The libraries used to read data from the sensors can be found among the examples in this Github-repo https://github.com/iot-lnu/applied-iot-20/tree/master/sensor-examples. ```python= from machine import I2C import time from dht import DHT from machine import Pin import CCS811 import urequests as requests import machine # reads temperature and humidity from the DHT11-sensor def dht_read(): dht = DHT(Pin('P23', mode=Pin.OPEN_DRAIN), 0) time.sleep(2) # Just to get it some slack starting up result = dht.read() # Make a reading while not result.is_valid(): # reread if the result is not valid print("Fail") time.sleep(.5) result = dht.read() #print('Temp:', result.temperature) #print('RH:', result.humidity) return result.humidity, result.temperature # reads co2 and voc from the CCS811-sensor def ccs_read(): i2c = I2C(0) # create on bus 0 i2c = I2C(0, I2C.MASTER) # create and init as a master i2c = I2C(0, pins=('P9','P10')) # PIN assignments (P9=SDA, P10=SCL) i2c.init(I2C.MASTER, baudrate=10000) # init as a master ccs = CCS811.CCS811(i2c=i2c,addr=90) time.sleep(1) # Just to get it some slack starting up ccs.data_ready() # Make a reading time.sleep(2) co2 = ccs.eCO2 voc = ccs.tVOC #print('CO2 level: ' + str(co2) + ' ppm') #print('tVOC level: ' + str(voc)) return co2, voc # Builds the json to send the request def build_json(variable1, value1, variable2, value2, variable3, value3, variable4, value4): try: data = {variable1: {"value": value1}, variable2: {"value": value2}, variable3: {"value": value3}, variable4: {"value": value4}} return data except: return None # Sends the request. Please reference the REST API reference https://ubidots.com/docs/api/ def post_var(device, co2, voc, temp, humid): 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("co2", co2, "voc", voc, "temperature", temp, "humidity", humid) if data is not None: req = requests.post(url=url, headers=headers, json=data) return req.json() else: pass except: pass TOKEN = "your-token" #Put here your TOKEN for ubidot DELAY = 1 # Delay in seconds while True: humid, temp = dht_read() co2, voc = ccs_read() print(humid, temp, co2, voc) post_var("home-air", co2, voc, temp, humid) machine.sleep(60000) ``` ## Transmitting the data / connectivity The data is sent once a minute which is probably too often for values such as temperature but it makes it easier to smooth out variations in co2 and voc. The data transmission could be made more effective in terms of battery consumption and network usage but since I have used power supply via usb connected to the wall and my home wifi, these resources are practically unconstrained. However, in other contexts, adaptations may be required. Furthermore, range is not a problem when using a home wifi to transmit the data but can be so in other cases. As described in connection to the electrical calculations above, the lack of constraints in this first version of this project makes it preferable to focus on getting up and running and optimize the power consumption and efficiency later. However, I still recommend not to send data for example 1 per second since it does not add any value in terms of amount of data. The metrics used here are not changing fast enough for such frequency to make sense, even 1 per minute is probably too often. I use wifi to transport data. I had no LoRa access at home but tried in another location but since this tutorial is aimed for home usage, I will not include the LoRa part in this tutorial. However, e.g. in a cottage without wifi, this could be a better choice. To transport the data, a webhook (HTTP) is used and the data is sent in the form of JSON-objects. See the code above for more details about how these are constructed and sent using HTTP and the Ubidots API. ## Presenting the data The data is presented in the form of dashboards visible in the Ubidots web tool (see example below). These visualizations can be adapted in various ways depending on your personal preferences and what you want to use the data for. (note that the values here are a bit weird since the air during this moment was "too clean" to give any values for VOC and CO2) ![](https://i.imgur.com/AefMZfD.jpg) As mentioned above, there is also a mobile app for android which can show the dashboard. This app is actually pretty nice and the size of the widgets is adapted to the screen in order to adjust the order and size of them to make them visible.The 4 screenshots below were retrieved when scrolling in the app. ![](https://i.imgur.com/jrqUNdd.png =270x520) ![](https://i.imgur.com/8znuuj5.png =270x520) ![](https://i.imgur.com/ge9IZN9.png =270x520) ![](https://i.imgur.com/CsNHYJf.png =270x520) I have not focused on prediction and analytics in this tutorial but the data is collected in a way that makes this possible in the future. When automating the control of devices such as ACs it could be useful to be able to predict the temperature outside (e.g. by time, air pressure, humidity, etc) in order to make the climate system more efficient. Even though predicting weather is extremely hard, it is possible to predict it in the short run in order to make the temperature control more efficient. In my application, data is sent to the Ubidots-database in the cloud once a minute. This can simply be adjusted in machine.idle() above where the argument is time in ms between readings. This data is not very valuable and in this first step I use it more for monitoring and automation rather than analytics. This means that a more sophisticated database is not needed and Ubidots is more than enough. It could also be possible that the premium-version enables even more functionality in the form of database management and that it could be useful also for more complex and data-heavy applications. An example of how an email notification for temperature (in this case if it is above 25°C) is shown below. Triggers like this are simple to create on the Ubidots platform. One drawback with the free version is that you cannot combine two variables in the same event (e.g. *if temperature > x and humidity > y*) but one workaround for this is to create separate triggers for each variable. ![](https://i.imgur.com/eGbpS0k.png =270x520) ## Finalizing the design As previously discussed, this is the first step towards a more sophisticated climate automation system but can be used standalone as a monitoring system for home climate. The next step for me will be to set up hardware to control a couple of external appliances to control temperature and humidity. These will include: * Electrical radiator to increase temperature * Humidifier/fan to increase humidity Decreasing humidity and temperature is more complex technically and the appliances needed (AC and dehumidifier) are more expensive. Therefore, this will be done later. The last image of this tutorial shows the device and sensor setup that is currently up and running in my apartment sending data to the Ubidots platform once per minute. ![](https://i.imgur.com/6k8OFmb.jpg)