So I was a recent Kickstarter backer for the Onion Omega2 Internet of Things (IoT) device. My package finally came and I wanted to see what I can do with it. My package included the Omega2, expansion dock, and OLED display so I figured it would be cool to write an application that displayed to the screen.
A problem I always had with the Raspberry Pi, my other favorite IoT device, is that I never knew the IP address or system information because I was always using it as a headless unit. With that in mind, I decided to write an application that displayed this information to the Onion Omega2 OLED screen at boot.
We’re going to see how to write a basic script to show system information using Python and the OLED extension library.
If you’re not familiar with the Omega2, it is a small IoT device with built in WiFi that has a price of only $5.00. However, it has very little storage space and very little memory. Based on this information, we’re going to create what is shown in the image below.
We’re going to display the network IP address of the unit and constantly display the current memory usage. This memory tracking will refresh constantly.
To be successful with this Internet of Things project there are a few hardware and software requirements.
The hardware can all be purchased for pretty cheap from the Onion Omega2 website, but the software installation can be a bit tricky.
After connecting to the Omega2 via SSH, execute the following commands:
opkg update
opkg install python-light pyOledExp
This should leave us with just enough space for a nice application. Installing the full version of Python will require some external storage which you may or may not have.
Because of the Onion Omega2, I was introduced to Python development for the first time. My first choice would have been Golang, but I had some issues getting a MIPS32 build going.
Create a /root/status.py file on your device and include the following code:
from OmegaExpansion import oledExp
import os
import time
oledExp.driverInit()
ipv4 = os.popen('ip addr show apcli0').read().split("inet ")[1].split("/")[0]
mem_total = os.popen('free -h | grep Mem | awk \'{printf "%.2f %s", $2/1024, "MB"}\'').read()
while True:
mem_used = os.popen('free -h | grep Mem | awk \'{printf "%.2f %s", $3/1024, "MB"}\'').read()
oledExp.setCursor(0,0)
oledExp.write("IP")
oledExp.setCursor(1,0)
oledExp.write(ipv4)
oledExp.setCursor(3,0)
oledExp.write("MEMORY")
oledExp.setCursor(4,0)
oledExp.write(mem_used + " / " + mem_total)
time.sleep(3)
Let’s break down what is happening in the above script.
The first thing we are doing is importing the OLED module and other Python dependencies that we’ll be using within our project.
Before we can use our OLED display we have to initialize it. This initialization only needs to happen one time at which point things can be rendered or cleared from the screen.
This is where things can get a little nutty:
# http://stackoverflow.com/a/38394394/498479
ipv4 = os.popen('ip addr show apcli0').read().split("inet ")[1].split("/")[0]
You can see in the above that we are trying to get the IPv4 address from the WiFi module named apcli0
. I didn’t come up with this line of code, but instead got it from Stack Overflow, due to my novice understanding of Python. What is happening is we are executing a system command and parsing it out until we end up with the inet
value.
Based on our knowledge of the os.popen
command we can come up with something like this:
mem_total = os.popen('free -h | grep Mem | awk \'{printf "%.2f %s", $2/1024, "MB"}\'').read()
The above line will do nearly the same thing, but parsing is happening via the shell command rather than through Python. We’re saying we want to get the total memory in kilobytes and convert it to megabytes for displaying on the screen.
Finally we have our loop which will continuously refresh the OLED display forever:
while True:
mem_used = os.popen('free -h | grep Mem | awk \'{printf "%.2f %s", $3/1024, "MB"}\'').read()
oledExp.setCursor(0,0)
oledExp.write("IP")
oledExp.setCursor(1,0)
oledExp.write(ipv4)
oledExp.setCursor(3,0)
oledExp.write("MEMORY")
oledExp.setCursor(4,0)
oledExp.write(mem_used + " / " + mem_total)
time.sleep(3)
The total memory on the device doesn’t change, but the memory used does. Every loop iteration we get the new memory and display all the variables on the screen. To prevent just a constant flicker, we sleep the loop for three seconds every iteration.
You should be able to test your script by executing the following:
python /root/status.py
That is all good, but we really want this information to display when the device starts. We’ll need to create a boot command to make this happen.
It is not difficult to start our script at boot. We’re pretty much just going to paste our execute command somewhere. While connected to the Omega2 via SSH, open the /etc/rc.local file in a text editor. This file should contain the following:
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
python /root/status.py &
exit 0
Notice that our execute line now contains an ampersand at the end. Because we have an infinite loop in our script, we need to send it to the background, otherwise our Omega2 will never finish the boot process. The ampersand allows us to do this.
Reboot your device and see what happens.
You just saw how to write a Python script that displayed system information on the Onion Omega2 OLED expansion screen. This could be very useful if you need to monitor for changes on the system or maybe you get more expansions that can monitor other things. Because the Omega2 uses OpenWRT, you have to think a little differently when you develop.