---
# System prepended metadata

title: Iot Baby Temperature Monitor

---

# Iot Baby Temperature Monitor
![](https://i.imgur.com/q7Ccq4E.png "title" =400x400)
## Introduction

### Who Am I?
- Name: Mgbah Robinson Iheanacho
- Student Credentials: rm222qf

### Project Overview
A simple baby monitor that monitors temperature in a baby environment like a stroller or crib and sends data to a server.

### Time To Complete
This project has 2 parts, iot device and the backend-server which the iot device connects to.
1. The first part`(iot device)`should take approximately 10 hours depending on complexity. 
2. The second part`(backend-server)`depends on what implementation is chosen. You can choose a pre-existing platform to publish your data and this should take about 2 hours to setup. You can choose to build your own backend server and that could take about 30 hours.
 

## Objective

### Why?
So my first son was born recently and I had to buy one of these baby monitors that allows you to monitor the baby while they're asleep. I became interested in transmitting the temperatures over the internet to I could analyze and visualize the data overtime.

This project serves the purpose of reading temperature values from a baby environment like a stroller or crib and then sends the data to a server which in turn analyzes and visualizes data. 

A valuable insight this project can give is a visualization of what temperature a baby sleeps at best or inversely ie what temperature are the toughest for the baby to sleep.

## Material
- Lopy4 with headers (394.04 kr)
This device is programmed with Micropython. It works with LoRa, Sigfox, WiFi and Bluetooth and is an excellent choice for an Iot project.
![LoPy4 with headers](https://i.imgur.com/vCXNKk3.png "title" =200x) 

- Expansion Board 3.0 (180.37 kr)
This board allows you to connect important parts that are needed to make the lopy4 device work. Parts like power, battery and jumper wires.
![Expansion Board 3.0](https://i.imgur.com/MJsrStu.png =200x) 

- Breadboard(400 Connections) 59.00 kr
This allows you to connect your sensors, jumper wires etc in an easy way. It's very practical and makes connections easier.
![](https://i.imgur.com/RQn7hrg.png =200x)

- Temperature Sensor(MCP9700A) 15.00 kr
A simple temperature sensor. This is connected by a pin on the breadboard and the value is read and can be manipulated to get temperature values. 
![](https://i.imgur.com/iTShWhb.png =200x)

- Jumper wires
Simple wires for connecting sensors from the lopy device to the breadboard.
![](https://i.imgur.com/yem1HTJ.jpg =200x)


Ultimately you can buy a bundle from electrokit which contains all you'll need for this project [here](https://www.electrokit.com/produkt/lnu-1dt305-tillampad-iot-lopy4-and-sensors-bundle/).

All material listed where purchased from [electrokit](https://electrokit.com)

## Computer setup

### Chosen IDE
- Visual studio code
- PyMakr
- IntelliJ Idea(**optional** only needed if developing the custom backend solution)
- Docker(**optional** only needed if developing the custom backend solution)

### Computer/Operating System
Macbook pro/macOS Big Sur. See configuration in the image below.
![](https://i.imgur.com/TRja2ld.png =400x)


### How the code is uploaded
The easiest way code is uploaded to the device through pymakr. Pymakr allows you to right click on the project and select upload to device
![](https://i.imgur.com/6xjxUPb.png =250x)

### Steps that are needed to get up and running
- Install node js [from here](https://nodejs.org/en/)
- Install visual studio code [from here](https://code.visualstudio.com)
- Install pymakr [from here](https://marketplace.visualstudio.com/items?itemName=pycom.Pymakr)
- You might need to upgrade your firmware before your start using it. Relevant information can be found [here](https://pycom.io/wp-content/uploads/2020/04/Lesson-2-Pymakr-Set-Up-FiPy.pdf)
:information_source: you need visual studio up and running before you can install pymakr.


It's possible that you may be using a different Operating system and all the steps listed above may not cover your particular Operating system. https://pycom.io/wp-content/uploads/2020/04/Lesson-2-Pymakr-Set-Up-FiPy.pdf gives you relevant information on setting up from pycom itself.

#### Optional(Custom Backend Solution)
These instructions are only valid if you intend to develop and run the backend solution that I've built on your computer. There is a working demo available on https://iot.ebrinktech.com.

- Install jdk 16 [from here](https://docs.oracle.com/en/java/javase/16/install/index.html)
- Install maven [from here](https://maven.apache.org/install.html)
- Install git [from here](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
- Clone the repository by running `git clone https://cinch-remit@bitbucket.org/cinch-remit/iot-backend.git`

:information_source: you need to have installed git to be able to clone the repository.

## Putting everything together

### How it's connected
For this stage, you'll need 3 jumper wires(preferably 3 different colours. I picked white, green and blue), the breadboard, the sensor, your lopy4 devices and the expansion board.

### Breadboard
- Connect the temperature sensor to the breadboard on row e, pins 12 - 14. See the image below for more clarity.
- Connect the white jumper wire to the breadboard on row c pin 12.
- Connect the blue jumper wire to the breadboard on row c pin 14.
- Connect the green jumper wire to the breadboard on row b pin 13.

![](https://i.imgur.com/iMtsxuq.jpg =500x)`breadboard connections`

### Lopy4
- Connect the green jumper wire to the lopy device on P16.
- Connect the white jumper wire to the lopy device on 3V3.
- Connect the blue jumper wire to the lopy device on GND.

See the image below for clarity
![](https://i.imgur.com/KIPnXK5.png =500x)`lopy4 connections`

### Using the `iot-backend server`(Optional)
In order to be able to transmit data to the server you need to do the following
1. Register a new account at https://iot.ebrinktech.com/register
2. Complete your registration through link sent to your email
3. Have a look through the api documentation(https://iot.ebrinktech.com/swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config)
4. Start off by registering your device by sending a `POST` request to this endpoint `/v1/device/register/{deviceId}`. 
5. After device is registered, you can transmit data by sending a `PUT` request to this endpoint `/v1/reading/register/{deviceId}`. This endpoint takes the device name as a path variable.This endpoint requires json data 
```json=
{
  "value": "string",
  "typeOfReading": "string",
  "metric": "string"
}
```
6. Once data has been transmitted, you can manipulate and visualize your data as needed.

###### IMPORTANT
This connection is currently in development stage. In the future, it might be soldered and probably the sensor will be updated.


## Platform
When this project started, choosing the right platform was tough because there are so many awesome solutions out there. The most important factors were
* ease of use
* available documentation
* price/subscription costs

After considering these factors, `MQTT` using io.adafruit.com seemed like a perfect solution. Some of the functionality available on this platform are
* Inbuilt easy to use dashboards
* Straightforward and easy to use/understand documentation
* Advanced services like weather, zapier 


Halfway through it seemed like a cool challenge to build my own dashboard and notification service and so the `iot-backend server`(this is a working title) was introduced to the project. Some of the functionality the `iot-backend-server` offers are
* Register device
* Build dashboards
* Autoupdate when data is read using websockets
* Email notification
* Swagger API 
* Container support(docker & kubernetes)

Code for the `iot-backend server` can be downloaded and modified from https://cinch-remit@bitbucket.org/cinch-remit/iot-backend.git. Development will continue even after this course. Feel free to contribute :100: 

###### Hosting tips for the iot-backend server
If you're thinking about hosting the `iot-backend server`, there are a few options that are cost effective
1. Heroku: This is a perfect startup place deploying your applications and for the most part, it's free. The downside is that your app goes to sleep when it's idle. So before you start transmitting to your device, you might need to visit the url just to 'wake up' your application. More information on https://heroku.com.

2. Digital Ocean(Kubernetes): This is a cost effective way to host your applications using kubernetes. I've provided manifest files in the `container` folder found in the code but you'd have to setup an account on digitalocean.com, start up a kubernetes cluster and then apply the manifest files. Digital ocean gives you $100 free credits which are valid for 2 months. So you've got nothing to loose if you'd like to try it out. For some more advanced settings like linking to your own domain name(`ingress` && `ingress controllers`), keeping your data intact even though you restart your application(`persistent volumes` && `persistent volume claims`) or any questions about kubernetes in general feel free to contact me @rm222qf(rm222qf@student.lnu.se) or consult the https://kubernetes.io website.

## The Code
Code for the pycom device can be found here https://github.com/achomgbah/iot-device.git

```python=
# wifi connection
from network import WLAN
import machine

wlan = WLAN(mode=WLAN.STA)

def isconnected():
    return wlan.isconnected()

def connect():

    networks = wlan.scan()
    for network in networks:
        if network.ssid == 'network-name':
            print('my network found')
            wlan.connect(network.ssid, auth=(network.sec, '******'), timeout=5000)
            while not wlan.isconnected():
                machine.idle()
            print('WLAN Connection successful.!')
            break

```
The code above has 2 functions,
- `isConnected()` checks if the device is already connected to a wifi network
- `connect()` attemps to connect to a wifi network using the desired network name and password.

```python=
# main python script
import pycom
import urequests
import machine
import ubinascii

import wifi_connect
import ujson
import time

from mqtt import MQTTClient

# API Information(demo link to my custom server)
base_url = 'https://iot.ebrinktech.com'

# Register device with API
unique_id = machine.unique_id()
device_name = ubinascii.hexlify(unique_id).decode()

mqtt_host = "io.adafruit.com"
mqtt_username = '******'
mqtt_password = '******'

def sub_cb(topic, msg):
    print(msg)

def registerReading():
    print('about to register')
    wifi_connect.connect()
#MQTT
    client = MQTTClient(device_name, mqtt_host,user=mqtt_username, password=mqtt_password, port=1883)
    client.set_callback(sub_cb)
    client.connect()
    client.subscribe(topic="mytopic/name")

# HTTP
    url = base_url+'v1/device/register/'+device_name
    register_headers = {"Authorization": "Basic *********",", "content-type":"application/json"}
    res = urequests.request('POST',url,None, None, register_headers, None,False)
    print(res.text)
    print('\n')
    headers = {"Authorization": "Basic *********", "accept": "*/*", "content-type":"application/json"}

    adc = machine.ADC()
    apin = adc.channel(pin='P16')

    while True:
        millivolts = apin.voltage()
        degC = (millivolts - 500.0)/10.0
        defF = ((degC * 9.0)/5.0) + 32.0

        reading_endpoint = base_url + 'v1/reading/register/'+device_name
        data = '{"value":"' + str(degC) + '","typeOfReading":"Temperature","metric":"Celcius"}'
        reading_res = urequests.request('PUT',reading_endpoint,data, None, headers,None, False)
        print(reading_res.content)

        time.sleep(1)
        print("Sending ON")
        client.publish(topic="mytopic/name", msg=str(degC))

        time.sleep(1)

        client.check_msg()

        time.sleep(1)
```
The code above defines some variables which are important for sending data. Defining them as variables helps keep the code 'cleaner' and allows for easier editing in the future if things change.

##### Imports(External libraries used.)
- `urequests`: library used to handle https requests
- `wifi_connect`: function to connect to wifi
- `ujson`: library used to format to and from json
- `mqtt`: library used to handle all things mqtt

These external libraries can be found and downloaded [here](https://pypi.org)

##### HTTP Server variables
- `base_url` = this is the server address of the custom server which the device transmits data to.
- `unique_id` = the devices's unique encoded id 
- `device_name` = the decoded value of the unique_id
##### MQTT variables
- `mqtt_host` = the `MQTT` server address
- `mqtt_username` = login username for `MQTT` server
- `mqtt_password` = login password for the `MQTT` server

##### What does the code do?
Line 31 - 34 creates a connection to the mqtt server and subscribes to the desired topic.

Line 37 - 39 registers the device using its unique name to the custom server.

Line 44 - 45 collects information about the pin on which the sensor is connected.

Line 47 - 65 then uses the information collected from the previous lines and based on some calculations, it then gets a temperature reading. This reading is then sent to the custom server and finally to the mqtt data. Every temperature received is sent to the servers.

The api endpoints used on the custom are available on the [demo server](https://iot.ebrinktech.com/).

## Transmitting the data/connectivity
- During my development test, the device sleeps for only 1 second after transmitting data which is can be a lot if the same settings are used in a production environment. 
- The wireless protocol used is wifi. Since the project is intended to be used inhouse, it makes sense to just connect to the wifi available in the house/location where the baby stroller/crib is. 
- 2 transport protocols are used namely MQTT and Http. MQTT sends data to the mqtt server (io.adafruit.com) while http sends data to iot.ebrinktech.com.

## Presenting the data
![](https://i.imgur.com/rnlJaNk.png =600x) `iot-backend`

![](https://i.imgur.com/8IA5obM.png) `adafruit`

![](https://i.imgur.com/iDDBPZI.png) `adafruit`


- Data is saved everytime a value is read. In otherwords, the rate at which data is saved depends on the rate at which data is transmitted. During development, the device sleeps for 1 second after data is transmitted. While this might look like data is saved every second, it's valuable to note that transmitting of data between 2 transport protocols takes a longer than 1 second and that is why I refer to how long the device sleeps after each transmission.

## Finalizing the design
Overall this was a very practical project which was interesting all the way. Some of my reflections are as follows
- Spending some time to read through documentation can save a lot of debug time.
- Planning how data will be processed before the data exists can save a lot of deploy and rebuild time.
- When choosing a platform, chances are no platform offers all the functionalities you desire. Making a priority list of what functionality can be skipped or is most important can make decision making process go a lot faster.

### Future Plans
- I'd like to add better sensors(temperature, sound and something for vibration) so I can get in more reliable data and be able to do more analysis.
- Visualize data in grafana
- More features in the `iot-backend server` like showing current value, widgets for types of data and ability to send instructions to the device.
- Write unit tests for the `iot-backend server`

### Screenshots from `iot-backend server`
`login page`
![](https://i.imgur.com/IsuuFCR.png)
`logged in landing page`
![](https://i.imgur.com/2n5gmeT.png)
`device page`
![](https://i.imgur.com/YuzofEW.png)
`reading graph`
![](https://i.imgur.com/UNX4WNr.png)


### Screenshots from `io.adafruit.com`
`graph`
![](https://i.imgur.com/9RmKMaD.png)

`last read value`
![](https://i.imgur.com/hWVkxwV.png)

