WebThings on Armbian: Using the ODROID-XU4 for the Internet of Things

Mozilla WebThings is a platform for controlling home devices. A primary purpose is to give users the ability to set up and control a “smart home” on their own without relying on third party services. This article will tell you why and how to set it up on ODROID-XU4.


For years, cloud -operated devices have had limitations. Problems with interoperability and reliability are beyond the scope of this article, but one that needs to be addressed is privacy. I personally consider that taking or revealing (any) user’s data without their explicit permission is a problem that everyone should consider. Even if you don’t see yourself as having anything to hide, it is doubtful you’d want to share your credit card numbers, so it’s important to be thoughtful and considerate before adopting a service or connecting devices because your privacy policy will also affect other family members or even your guests. We have seen some progress when it comes to strengthening privacy in the last couple of years thanks to certain regulations. Europe started with GDPR, which outlined some important regulatory guidelines when it comes to software that handles personal data. One important one specifically, article 25, requires “Privacy by Design” in technical systems. This means they must be designed to maintain users’ privacy from the ground up.

Figure 1 - GPDR
Figure 1 - GPDR


It is reasonable to predict that the connected devices market will change sooner or later. For now, you can stay ahead and try FLOSS projects which did not wait for regulations to enable privacy. Since the dawn of the Mozilla IoT platform development, the project was explicitly designed to avoid your data going to someone else’s cloud.

Figure 2 - NoCloud
Figure 2 - NoCloud

The key principle is pretty simple: all home devices are connected only to the home network, so data just stays local, nothing is going out. Without going into too many details, there are many IoT standards today, and probably none will be appropriate to match every use case. That said, a common technology can abstract many overlaps. This is the mission of W3C, the organization known for the standardization of the world wide web (HTML, HTTP, and XML). W3C’s “Web of Things” working group (WoT) is committed to address some IoT problems using existing web technologies and fill the missing gap. While some describe WoT as the “HTML for IoT”, think that WoT protocols are mostly for machines instead of humans, technically we are talking about REST APIs and JSON Schema for semantics.


The WebThings framework is based on simplified WoT proposed recommendations. Today, the implementation is composed of:

WebThings API for devices that speak REST on HTTP. WebThings gateway can control devices from a nice web application. WebThings gateway’s add-on adapter(s) to translate non-WebThings devices or services to WebThings API.

Figure 3 - ThingsGateway
Figure 3 - ThingsGateway


In this article, I will cover how an ODROID-XU4 can be a valid single-board computer for hosting WebThings gateway software which was originally developed for reference target Raspberry Pi 3.

Figure 4 - ODROID-XU4
Figure 4 - ODROID-XU4

Following these instructions should also work for other ODROIDs with minor adaptations. If you need to pick one, I suggest you consider the ODROID-H2, because it should be a bit simpler to develop on x86_64 CPU architecture. Setup is not straightforward so you’ll need a GNU/Linux host computer, SD-card, Serial Port and Ethernet link.

Setup Armbian

The Mozilla reference image is based on Raspbian, a Debian port for Raspberry Pi, this image won’t work on non-Pi devices. Hopefully the Armbian project has just released images to boot the latest Debian-10 on various ARM boards. Either the Debian or Ubuntu flavor of Armbian will work on ODROID-XU4, but let’s download the minimal image and then dump it to an SD card.

On a GNU/Linux system, I used an USB SD adapter and these command lines:

$ lsblk # Will list your disks make sure to use the right one
$ disk='/dev/disk/by-id/usb-Generic-_USB3.0_CRW_-0_000000021716-0:0' #
$ file "$disk" # TODO

$ release="Armbian_20.02.1_ODROIDxu4_buster_current_5.4.19_minimal"
$ url="https://dl.armbian.com/odroidxu4/archive/${release}.7z"

$ sudo sync
$ sudo apt-get install curl 7zip-full time # Install those tools on Debian or adapt
$ time curl -O "$url" # 3sec 155313070c
$ time 7z e -so "$release.7z" "$release.img" | sudo dd bs=4MB of="$disk"
#| 562036736 bytes (562 MB, 536 MiB) copied, 142.735 s, 3.9 MB/s


Insert the SD image on ODROID-XU4. If you have the serial port configured you should be able to view the boot log:

$ screen /dev/ttyUSB0 115200

#| U-Boot 2017.05-armbian (Feb 17 2020 - 07:52:44 +0100) for ODROID-XU4
#| CPU: Exynos5422 @ 800 MHz
#| Model: ODROID XU4 based on EXYNOS5422
#| Board: ODROID XU4 based on EXYNOS5422
#| Type: xu4
#| DRAM: 2 GiB
#| MMC Device 0 ( SD ): 7.4 GiB
#| mmc_init: -5, time 4
#| *** Warning - bad CRC, using default environment
#| In: serial
#| Out: serial
#| Err: serial
#| Net: No ethernet found.
#| Press quickly 'Enter' twice to stop autoboot: 0
#| (...)
A couple of minutes later, you should be able to log in as root with the default password “1234”. Then system will ask setup default user:
#| Armbian 20.02.1 Buster ttySAC2
#| odroidxu4 login: root
#| Password: 1234
#| You are required to change your password immediately (root enforced)
#| Changing password for root.
#| (current) UNIX password:
#| Enter new UNIX password:
#| Retype new UNIX password:
#| ___ _ _ _ __ ___ _ _ _
#| / _ \ __| |_ __ ___ (_) __| | \ \/ / | | | || |
#| | | | |/ _` | '__/ _ \| |/ _` | \ /| | | | || |_
#| | |_| | (_| | | | (_) | | (_| | / \| |_| |__ _|
#| \___/ \__,_|_| \___/|_|\__,_| /_/\_\\___/ |_|
#| Welcome to Armbian buster with Linux 5.4.19-odroidxu4
#| System load: 2.23 0.79 0.28 Up time: 1 min
#| Memory usage: 6 % of 1993MB IP:
#| CPU temp: 32°C
#| Usage of /: 29% of 7.1G
#| New to Armbian? Check the documentation first: https://docs.armbian.com
#| Thank you for choosing Armbian! Support: www.armbian.com
#| Creating a new user account. Press  to abort
#| Desktop environment will not be enabled if you abort the new user creation
#| Please provide a username (eg. your forename): user
#| Trying to add user user
#| Adding user `user' ...
#| Adding new group `user' (1000) ...
#| Adding new user `user' (1000) with group `user' ...
#| Creating home directory `/home/user' ...
#| Copying files from `/etc/skel' ...
#| Enter new UNIX password:
#| Retype new UNIX password:
#| passwd: password updated successfully
#| Changing the user information for user
#| Enter the new value, or press ENTER for the default
#| Full Name []: User
#| Room Number []:
#| Work Phone []:
#| Home Phone []:
#| Other []:
#| Is the information correct? [Y/n] y
#| Dear User, your account user has been created and is sudo enabled.
#| Please use this account for your daily work from now on.
Once done, let’s inspect the system, and install a multi-cast DNS service that will help to connect remotely using SSH:
root@odroidxu4:~# cat /etc/os-release
#| PRETTY_NAME="Debian GNU/Linux 10 (buster)"
#| NAME="Debian GNU/Linux"
#| VERSION_ID="10"
#| VERSION="10 (buster)"
#| (...)

root@odroidxu4:~# df
#| Filesystem 1K-blocks Used Available Use% Mounted on
#| udev 950928 0 950928 0% /dev
#| tmpfs 204128 6592 197536 4% /run
#| /dev/mmcblk1p1 7505192 498264 6915480 7% /
#| tmpfs 1020628 0 1020628 0% /dev/shm
#| tmpfs 5120 0 5120 0% /run/lock
#| tmpfs 1020628 0 1020628 0% /sys/fs/cgroup
#| tmpfs 1020628 0 1020628 0% /tmp
#| /dev/zram0 49584 632 45368 2% /var/log
#| tmpfs 204124 0 204124 0% /run/user/0

root@odroidxu4:~# sudo apt-get update
root@odroidxu4:~# sudo apt-get install avahi-daemon
root@odroidxu4:~# reboot
Once rebooted, let’s login using SSH with hostname.local address instead of IP that may be different for each of us:
$ ssh root@odroidxu4.local

Extra storage

Optionally you can skip or use this trick to preserve SD-card’s life span. I just plugged a pair of USB sticks (of 4GB each) in the two USB3 ports of ODROID. This extra USB mass storage will be used for swap memory and docker. once mounted as follow:

$ sudo=$(which sudo)

$ dev="/dev/disk/by-id/usb-Generic_Mass-Storage-0:0" # TODO
$ file "$dev"
$ fdisk -l $dev || lsblk # Update previous line

$ dev='/dev/sda' # TODO update
$ label="docker"
$ yes | ${sudo} mkfs.ext4 -L "$label" "$dev" # TODO: verify $disk variable

$ dev=/dev/sdb # TODO: update if needed
$ label="swap"
$ fdisk -l $dev
$ yes | $sudo mkswap -L "$label" "$dev"
$ free
#| total used free shared buff/cache available
#| Mem: 2041260 107724 1759992 6592 173544 1865772
#| Swap: 1020628 0 1020628
$ sudo swapoff -a
$ free
#| total used free shared buff/cache available
#| Mem: 2041260 106224 1761472 6592 173564 1867272
#| Swap: 0 0 0

$ sudo swapon "/dev/disk/by-label/swap"
$ free
#| total used free shared buff/cache available
#| Mem: 2041260 107912 1759716 6592 173632 1865584
#| Swap: 3943420 0 3943420
Install docker to use the other USB disk:
$ sudo apt-get install docker.io time git lsb-release file
#| Need to get 55.9 MB of archives.
#| After this operation, 255 MB of additional disk space will be used.
#| Do you want to continue? [Y/n] Y
#| (...)

$ dev="/dev/disk/by-label/docker"
$ mnt="/var/lib/docker"
$ df -h "$mnt"
# /dev/mmcblk1p1 7.2G 1.2G 6.0G 17% /
$ sudo systemctl stop docker
$ sudo sync
$ sudo mkdir -p "$mnt"
$ sudo mount "$dev" "$mnt"
$ df -h "$mnt" # /dev/sda 3.7G 16M 3.5G 1% /var/lib/docker
$ sudo systemctl restart docker
$ sudo docker version # 18.09.7

Build binaries

There are various ways to use Mozilla WebThings platform. The simplest one would be to use the deb package built for Raspbian but ARMv6 version won’t be optimized for our ARMv7 CPU. So let’s try to build it again on the device using docker to make sure the whole process is replicable. It was for latest release 0.11.0, so I published “webthings-gateway_0.11.0-1_armhf-debian-buster.deb” package at https://bintray.com/rzr/deb/webthings-gateway#files. Feel free to install this one or rebuild on the device using the following steps:

$ sudo apt-get install docker.io time git lsb-release file
$ sudo apt-get install time screen
$ url=https://github.com/mozilla-iot/gateway-deb.git
$ git clone --depth 1 --recursive "${url}"
$ cd gateway-deb
$ sudo time bash ./build-docker.sh

$ sudo docker image ls
#|   c0edf15b50a7 About an hour ago 122MB
#| gatewaydeb_default latest 32e5bdf8321c 8 hours ago 843MB
#|   51a23a2e7130 9 hours ago 1.04GB
#| Debian 10 3eee7456d779 3 weeks ago 92.8MB

$ du -hsc ./dist/*
#| 21M ./dist/WebThings-gateway_0.11.0-1_armhf-debian-buster.deb

$ sudo chmod -Rv 700 ./dist/WebThings-gateway_*.deb
$ sudo apt install -y ./dist/WebThings-gateway_*.deb
#| Need to get 0 B/40.5 MB of archives.
#| After this operation, 180 MB of additional disk space will be used.
#| Do you want to continue? [Y/n] Y
#| (...)

$ sudo reboot


Now the most difficult part is done (no more command lines!) Let’s wear the user hat and connect to the dashboard by pointing your browser at http://odroidxu4.local:8080/. The welcome page should appear as follows:

| Mozilla IoT
| Welcome
| Choose a secure web address for your gateway:
| [subdomain].mozilla-iot.org
| [Email]
| [Create]
| [Skip]
The gateway can be registered on mozilla.org for remote management, this is optional, so let’s skip subdomain as we won’t use the gateway from the Internet for our first experiment. The next page will ask to create (local) credentials:
| Welcome
| Create your first user account:
| user: [user]
| email: [user@localhost]
| password: [password]
| password: [password]
| [Next]
And now we’re ready to add some WebThings, and you can start filling out your dashboard with Virtual Resources. First hit the “burger menu” icon on the top left, go to settings page, and then go to the “add-ons” page at https://odroidxu4.local/settings/add-ons/ and enable a “Virtual Things” adapter:
| Mozilla IoT Virtual Things Adapter
| by Mozilla IoT
Once enabled It should be listed on the adapters page at https://odroidxu4.local/settings/adapters. You can then go back to the 1st “Things page” (it’s the first entry in the menu). We can start adding “things” by pressing the bottom “+” button at https://odroidxu4.local/things, then press “Done” at the bottom:
| Virtual On/Off Color Light
| Color Light
| Save
From this point, you can decide to control a virtual lamp from the UI, and even establish some basic rules (second entry in menu) with more virtual resources.

Figure 5 - Virtual Things
Figure 5 - Virtual Things

Join the community

We just validated that our setup is working using mock devices, so the next step is to look at other add-ons. Today there are above 100, which is a great showcase of community contributions. A typical use of an add-on adapter is to connect a device that speaks another protocol, and the add-on is just translated to WebThings abstractions. The gateway can support Zigbee, ZWave devices you’ll find on the market. That said, some add-ons might not work flawlessly on our ODROID-XU4 setup, so please report issues with related projects to @rzr on GitHub and I’ll be glad to share hints or fixes.

It goes even beyond that. Any stuff that has an API can be managed using the WebThings platform. As an example, I made the Activity Pub adapter that allows posting a public message to mastodon social network when some conditions are met. Automation is possible using the rule engine where users can link sensors to actuators to establish “smart behaviors”. Remote control is possible from a progressive web app served by the gateway itself. In my opinion, this is much simpler and trustworthy than when you are forced to install an app from a store on personal phones to get access to the devices you bought.

Mozilla’s WebThings project is a good demonstration of how a service could look the same to users but is operated totally differently than what you’ll find today on the IoT market. Your feedback is welcome, so that WebThings can be improved.


Be the first to comment

Leave a Reply