# :rotating_light: A basic IoT Homeguard system
*By M. Moggia mm223wz*
**This tutorial goes through how to build a cheap, bare bone, and stand-alone IoT Homeguard system with a temperature/humidity sensor as proof of concept.**
:stopwatch: *Estimated time to complete the project is 2-4 hours.*
:cat: Code available [@github](https://github.com/MM223wz/HomeGuard)
## :bulb: Project objectives
I want to protect my apartment from fire and break-ins. Also I wanna be able to keep an eye on what's going on at home regarding temperature, humidity, air quality, noise level and more. The device should be stand-alone, cheap, connected to internet, and modular – it should be quite easy to add more sensors and functionality later on. Hopefully this project will serve as a starter, a proof of concept, and give insights how to construct your own Homeguard system.
## :euro: Material
*Swedish VAT 25% included.*
Device | Purpose | Source | ~Cost
---|---|---|---
LoPy 4 | Microcontroller | [pycom.io](https://pycom.io/product/lopy4/) | €50
Expansion Board 3.1 | Power, status, holder | [pycom.io](https://pycom.io/product/expansion-board-3-0/) | €22
USB micro data cable | Set up, program, power | [amazon.se](https://amazon.se/) | €1.5
DHT11 | Temperature & humidity sensor | [amazon.se](https://amazon.se/) | €8
Dupont cables | Attach sensor | [amazon.se](https://amazon.se/) | €6.5
**TOTAL COST** | | | **€88**
:bangbang: :gb: *NB! Because of Brexit you may also need to pay customs duty if you buy the Pycom devices directly from UK.*
:computer: You will also need a computer to set up and program the microcontroller.
### Images
- LoPy microcontroller

- Expansion Board

- Dupont cables *(female - male)*

- USB micro data cable

- DHT11 sensor *(breakout version)*

## :desktop_computer: Setup
To set up the microcontroller and program it you need a computer. I'm using a Mac Mini M1 computer, but you can also use a Windows/Linux machine.
### :wrench: Hardware
First we need to insert the LoPy microcontroller to the Expansion board and connect them to our computer with the USB cable. *Detailed instructions can be found at [docs.pycom.io/gettingstarted](https://docs.pycom.io/gettingstarted/).*
***NB!** Make sure your USB cable is capable of also **transfer data** – not only power.*

*Image: The LoPy inserted into the Expansionboard and the USB cable attached.*
It's also a good idea to upgrade the firmware for the Pycom LoPy 4 microcontroller. Use a custom program (special update tool) for that – follow the instructions at [docs.pycom.io/updatefirmware](https://docs.pycom.io/updatefirmware/).
:bug: *NB! When making this tutorial the firmware upgrade didn't work for me on my M1 Mac or when I used "pygate". I had to use my old MacBook Pro with an Intel processor and the "legacy" mode instead. These are the settings I used:*


### :keyboard: IDE
As IDE (Integrated Developer Environment) we will use [Atom](https://atom.io) since it's open source and free. Download the program and install it on your computer.
Open up Atom and install the plugin **pymakr** – detailed instructions can be found at [docs.pycom.io/gettingstarted/software/atom](https://docs.pycom.io/gettingstarted/software/atom/).
### :file_folder: Code files
Create an empty folder on your computer and name it "HomeGuard". Inside that folder create an empty folder called "pycom" and inside that another called "lib". In Atom choose **File** -> **Add Project Folder...** from the main menus and select the HomeGuard folder.

*Your new empty project.*
Make sure your Pycom devices are connected to your computer by the USB cable and that the Pymakr window is visible at the lower part of your IDE (in Atom):

*To open/close the Pymakr window click on the "Pymakr" logo in the lower right inside Atom.*
:gear: Click "Settings" to the right in the Pymakr window, choose "Global settings". Use defaults except for "Sync Folder" which you set to `pycom`. Then close the settings window.
In Atom, in the Project column, right click on the "pycom" folder and select "New File". Name it "boot.py". Repeat, but this time you name the file "main.py".
Add the following placeholder code and save the files:
boot.py
```python=
# Runs at boot
```
main.py
```python=
# HomeGuard Main code
import pycom
pycom.heartbeat(False)
pycom.rgbled(0xff00)
```
:arrow_forward: Make sure main.py is the active file in Atom and then click the "Play" button in the Pymakr-window (right arrow). Now your LoPy should show a bright green light:

## :dart: Putting everything together
Since this is a proof of concept we are only using one sensor (DHT11) and minimal wiring. *Later on you could use a breadboard so it's easier to add more sensors.*

*Image: Breadboard.*
Disconnect the USB cable (at the computer) so the Pycom devices are turned off.
Use your Dupont cables and make these connections:
DHT11 | Pycom Expansionboard | Wire color
---|---|---
1st pin | P23 | Blue
2nd pin | 3V3 | Red
3rd pin | GND | Black

## :snake: Platform
As the platform for the data we are going to use [Kaa](https://www.kaaiot.com/). Kaa is a cloud based IoT platform that's very adaptable – and best of all it has a **free tier for up to five units**.
:cloud: Create an account at Kaa, log in to the Kaa Cloud and do the following steps.
*A detailed tutorial can be found at [docs.kaaiot.io](https://docs.kaaiot.io/KAA/docs/current/Tutorials/getting-started/connecting-your-first-device/).*
1. Add an **Application** with the Display Name "HomeGuard" (Use the :heavy_plus_sign: button at the upper right).
2. Go to Device Management -> Applications and create a new **Version** (Click the :heavy_plus_sign: button). Add an arbitrary alphanumeric string to the Application Name (for example "uhx786") and the Display Name "Beta1".
3. Create a "digital twin" - an **Endpoint** - at Device Management -> Devices (Yeah, another :heavy_plus_sign: button). Leave Endpoint token empty and let it be autogenerated. **Note the token name and save it somewhere.**
4. Turn on the **EPTS auto-extraction** feature. Go to the Device management -> Applications -> expand your application -> select "epts" and enable the "Autoextract" checkbox. Also change the "Format" under Timestamp extraction to "autodetect".
## :cat: The code
The following code files are needed for the project:
:file_folder: Path/file | :dart: Purpose/source
---|---
`pycom` | Project folder with all files that will be uploaded to the LoPy microcontroller:
`pycom/boot.py` | Runs when the microcontroller boots up, *see below*.
`pycom/main.py` | Contains the main code for the project, *see below*.
`pycom/lib` | Folder with the library files:
`pycom/lib/dht.py` | For the DHT-11 temperature sensor, [@github](https://github.com/MM223wz/HomeGuard/blob/798055a7fe1004eca8825f8336a51d709ec77d4e/pycom/lib/dht.py)
`pycom/lib/kaa_client.py` | Handles communication with Kaa Cloud, [@github](https://github.com/MM223wz/HomeGuard/blob/798055a7fe1004eca8825f8336a51d709ec77d4e/pycom/lib/kaa_client.py)
`pycom/lib/_keys.py` | Keys and variables data, *see below*.
`pycom/lib/mqtt.py` | For the MQTT protocol, [pycom@github](https://github.com/pycom/pycom-libraries/blob/master/examples/mqtt/mqtt.py)
Create the `_keys.py` file in the lib folder, and insert your data *(leave the MQTT-variables though)*:
```python=
# HomeGuard variables, tokens, and keys
WIFI_SSID = 'Your Wifi Name'
WIFI_PASS = 'Your Wifi Password'
MQTT_CLIENT = 'mqtt.cloud.kaaiot.com'
MQTT_PORT = 1883
KAA_APP_VERSION_NAME = 'Kaa Appversion Name'
KAA_ENDPOINT_ID = 'Kaa Endpoint ID'
KAA_ENDPOINT_TOKEN = 'Kaa Endpoint Token'
```
Download or copy/paste the code for the remaining library files from [Github](https://github.com/MM223wz/HomeGuard) and save them in your lib-folder: `dht.py`, `kaa_client.py`, and `mqtt.py`.
Edit your `boot.py`:
```python=
# Runs at boot
import machine
import uos as os
import _keys as keys
import utime as time
from network import WLAN
uart = machine.UART(0, baudrate=115200)
os.dupterm(uart)
# Connect to Wifi
wlan = WLAN(mode=WLAN.STA)
nets = wlan.scan()
for net in nets:
if net.ssid == keys.WIFI_SSID:
print('Wifi network found.')
wlan.connect(net.ssid, auth=(net.sec, keys.WIFI_PASS), timeout=5000)
while not wlan.isconnected():
machine.idle() # save power while waiting
print('Wifi connection succeeded.')
break
# Sync RTC - Real Time Clock
rtc = machine.RTC()
rtc.ntp_sync("pool.ntp.org")
while not rtc.synced():
machine.idle()
# Adjust your local timezone, by default, NTP time will be GMT
time.timezone(1*60**2) # GMT+1: 1*60*60
print('RTC synced with NTP time: {}'.format(time.localtime()))
machine.main('main.py')
```
Edit `main.py`:
```python=
# HomeGuard Main code
import pycom
import utime as time
import _keys as keys
import machine
from mqtt import MQTTClient
from kaa_client import DataCollectionClient
from dht import DHT
# Adjust to your needs
READ_SENSOR_DATA_INTERVAL = 5 # in seconds
# Turn on blinking blue
pycom.heartbeat(True)
# Connect to Kaa Cloud
client = MQTTClient(machine.unique_id(), keys.MQTT_CLIENT, port=keys.MQTT_PORT)
data_collection_client = DataCollectionClient(client)
data_collection_client.connect_to_server()
# Set up DHT-11 sensor
sensor = DHT('P23', 0)
# Main program loop
while True:
time.sleep(READ_SENSOR_DATA_INTERVAL)
result = sensor.read()
if result.is_valid():
msg_data = data_collection_client.compose_data(temperature=result.temperature, humidity=result.humidity)
data_collection_client.client.publish(topic=data_collection_client.data_collection_topic, msg=msg_data)
print('--> Sent message on topic "{}":\n{}'.format(data_collection_client.data_collection_topic, msg_data))
```
When all code files are stored, plug in the USB cable connected to the Pycom expansionboard/microcontroller again, open up Atom, and connect to the device in the Pymakr window.
:outbox_tray: Upload and run the code by clicking on the "Upload project to device" button.
:cloud: If everything is working you should now see sensor data both in the Pymakr window and also uploaded to the Kaa Cloud.
## :postbox: Transmitting the data
The sensor data is checked and uploaded to the cloud every 5 seconds. This is very often, and only useful for debugging. Change it to something more reasonable, like every 10 minutes:
Edit `main.py`:
```python=10
# Adjust to your needs
READ_SENSOR_DATA_INTERVAL = 600 # in seconds
```
At the moment only Wifi is used when sending data – at least one other wireless connection should be added for redundancy.
The transport protocol used for the data is [MQTT](https://mqtt.org) - which is very lightweight and efficient – perfect for IoT.
## :chart_with_upwards_trend: Presenting the data
At the Kaa Cloud there are lot of ways to set up how the data should be presented. The default view (Device Management -> Devices -> Device) is a good start:

:snake: The Kaa Cloud Platform is a collection of microservices that handles data:

There are many possibilities to store the collected data permanently, for example in a cloud based database. For more information see [docs.kaaiot.io/KAA/docs/current/Architecture-overview](https://docs.kaaiot.io/KAA/docs/current/Architecture-overview/).
## :rocket: Final result
The final result looks like this:

To be useful in practice it should be moved to a box.
My final thoughts of this project is that it was fun – and also very exciting because the possibilities are endless. There are so many ways to extend it, make it better, smarter, and more useful. Here are just a few at the top of my head:
- Send out notifications when certain levels are reached (alarms)
- Add more sensors; air quality, movement, sound level, vibrations, doors & windows (magnetic sensors)
- Connect lights, speaker, buzzer for showing status and alerting
- Make it redundant and more resilient with battery power and using more wireless networks
- Create a tailored case with a 3D-printer