Company Name: Pycom Ltd

Fridge sensor using connected devices through internet of things

Fridge Sensor Transmitted Over WiFi

Background

This project was created to keep track of fridges for a brewery and is why it’s called a “Fridge Sensor.” However, this asset tracker can be modified in order to be able to track any kind of asset. This sensor measures the temperature of the asset, the battery level of the device to and the GPS coordinates of its location so that the owner can remotely make sure that everything is ok with the fridge and if any work on it does need to be done, then the location can be tracked. We’ll be using the PyCom “PyTrack Expansion Board” alongside the PyCom “SiPy Development Board” in order to retrieve and send our data over the WiFi to be displayed on the Pybytes website.

What you’ll need:

Libraries

  • onewire: Used to measure the temperature from the sensor
  • pytrack: Contains the board specific functions
  • mqtt: Allows for messages and payloads to be sent over Wifi.
  • pybytes_library
  • pybytes_protocol
  • pybytes

All Pybytes libraries can be downloaded from Pybytes.

Setting up the board:

Connect the SiPy to the Pytrack expansion board, ensuring that the LED of the LoPy is facing on the same side as the micro-USB. After this, we need to solder the temperature sensor onto the Pytrack.

With this all set up we can then plug in the micro-USB and start our code.

Boot.py

The boot.py is run on the device start up and is used to initialise the Wifi connection to ensure that a connection can be made.

import machine
import os
import time
uart=machine.UART(0,115200)
os.dupterm(uart)
if machine.reset_cause()!=machine.SOFT_RESET:
 from network import WLAN
    known_nets=[(('WIFI_NETWORK','WIFI_PASSWORD'))]
    wl=WLAN()
    original_ssid=wl.ssid()
    original_auth=wl.auth()
    wl.mode(WLAN.STA)
    available_nets=wl.scan()
    nets=frozenset([e.ssid for e in available_nets])
    known_nets_names=frozenset([e[0]for e in known_nets])
    net_to_use=list(nets&known_nets_names)
 try:
        net_to_use=net_to_use[0]
        pwd=dict(known_nets)[net_to_use]
        sec=[e.sec for e in available_nets if e.ssid==net_to_use][0]
        wl.connect(net_to_use,(sec,pwd),timeout=10000)
 while not wl.isconnected():
            time.sleep(0.1)
 except:
        wl.init(mode=WLAN.AP,ssid=original_ssid,auth=original_auth,channel=6,antenna=WLAN.INT_ANT)

Main.py

Our main will have to do a number of things:

  • Initialise Pybytes
  • Read the data using the libraries and built in sensors
  • Send the data to Pybytes to be displayed

Initialising Pybytes

USERNAME = "example@email.io" 
DEVICE_ID = "AABBCCDDEEFFGGHHIIJJKKLLMMNNOO" 
SERVER = "mqtt.pybytes.pycom.io"
pybytes = Pybytes(USERNAME, DEVICE_ID, SERVER)
pybytes.connect_wifi()

First of all we need to initialise our connection with Pybytes so that our device can log into website to display our data. The DEVICE_ID is given to us once we start creating the dashboard so at the minute we’ll leave this blank or with a placeholder.

Functions

Our functions are used to call separate functions from the specific libraries mentioned above. This data is then returned to the main where it’s passed into Pybytes.

Get_temp( ): This function is used to access the temperature sensor and then return the information to the main. The likelihood is that on startup, the temperature sensor will return a null value. Therefore we add a bit of logic to ensure that no null values can be returned, therefore preventing anomalies with the data.

def get_temp():                         
    temp_value = None
 while temp_value == None:
        temp_sensor.start_convertion()  
        sleep(1)
        temp_value = temp_sensor.read_temp_async()
        sleep(1)
 return(temp_value)

Get_location( ): This function uses the Pytracks built in GPS locator. As a result our function can simply call from the library that we imported before and pass this result back to main.

def get_location():                     
    location = gps.coords()             
 return location

Location comes back to the main as tuple and so when we try to access it from main, we’ll need to remember to split the tuple for Longitude and Latitude. At this point it’s worth putting in some error handling in case the GPS fails and returns null values.

 location = get_location()
 if location != (None,None):
        latitude = location[0]
        longitude = location[1]
 else:
        latitude = 51.23
        longitude = -0.57

Read_battery( ): The voltage function uses the pytrack library to return the voltage currently being supplied.

def read_battery():                     
    voltage = py.read_battery_voltage()
 return voltage

It should be noted that in this tutorial we want to display the voltage as a percentage rather than a number. Therefore, you’ll need to know the minimum and maximum voltage that can be supplied through the board (min 3.3v, max 4.7v in this example) and do a small calculation to convert the voltage into a percentage.

voltPercent = int(((read_battery() - 3.3) / 1.7) * 100)

Sending over Pybytes: Because we initialise the connection with Pybytes and we install the libraries for it, we don’t need to send the data as a payload and so can use specific functions to send the data to Pybytes.

pybytes.send_virtual_pin_value(False, 16, int(voltPercent))
pybytes.send_virtual_pin_value(False, 15, int(temp))
pybytes.send_custom_location(12, str(latitude), str(longitude))

Overall the main.py should look something like this:

```python 
from pybytes import Pybytes
from onewire import OneWire, DS18X20
from pytrack import Pytrack
from L76GNSS import L76GNSS
from machine import Pin
from pycom import heartbeat,rgbled
from time import sleep
#INITIALISE PYBYTES
USERNAME = "example@email.io" 
DEVICE_ID = "AABBCCDDEEFFGGHHIIJJKKLLMMNNOO" 
SERVER = "mqtt.pybytes.pycom.io"
py.setup_sleep(3600)
#INITIALISE VARIABLES
ow = OneWire(Pin('P9'))
temp_sensor = DS18X20(ow)
#FUNCTIONS
def get_temp():                         
    temp_value = None
 while temp_value == None:
        temp_sensor.start_convertion()  
        sleep(1)
        temp_value = temp_sensor.read_temp_async()
        sleep(1)
 return(temp_value)
def get_location():                     
    location = gps.coords()             
 return location
def read_battery():                     
    voltage = py.read_battery_voltage()
 return voltage
def main():
    temp = int(get_temp())
    location = get_location()
 if location != (None,None):
        latitude = location[0]
        longitude = location[1]
 else:
        latitude = 51.23
        longitude = -0.57
    voltPercent = int(((read_battery() - 3.3) / 1.7) * 100)
    pybytes.send_virtual_pin_value(False, 16, int(voltPercent))
    pybytes.send_virtual_pin_value(False, 15, int(temp))
    pybytes.send_custom_location(12, str(latitude), str(longitude))
    py.go_to_sleep()
main()

Pybytes:

Pybytes is a website created by Pycom that allows you to send the data being provided by our set up and display it through a series of widgets.

Head to pybytes.pycom.io and create an account. On the left hand side bar, click Devices and then Add Device to create a new device for your project. Once this has been done, you’ll be given the device ID that was mentioned earlier in the project. Go back to your main and edit the DEVICE_ID with the code that you’ve just been given.

Once this has been done, we can create the dashboard to display the data. For our example, we’ve used two line graphs and a map to display our data.

Make sure that for both of the line graphs that you go through and edit them so that each of the graphs has a virtual pin relating to that in our code (Temperature is 15 and Battery is 16).

Once all of this is set up, you should have a working sensor that continuously displays your data on Pybytes.