I used OrangePi Zero to build a low-cost, self-updating temperature sensor. It uses Wifi for connectivity. Connection parameters are stored as plaintext files on FAT32 /boot partition.
Temperature sensors are standard 1Wire DS18B20 sensors (serial connection). Multiple sensors can be daisy-chained and connected to single box
- OrangePi Zero
- USB power adapter
- Case (optional)
- Class 10 4GB (or more) SD card
- OneWire DS18B20 temperature sensor
- USB-to-serial adapter (
lsusb
reports QinHeng Electronics HL-340 USB-Serial adapter)
Armbian has a really powerfull set of build tools, and they also support OPZ out of the box. Vagrant build process is well documented and keeps all the mess within builder VM.
I selected next
kernel with default configuration, and I selected Debian
Stretch as base image. In config-default.conf
, I specified a separate 100M
FAT boot partition, which allows me to read SD card on Windows/Linux/Mac
machines (FAT partition needs to be the first primary partition on SD card for
Windows to read it).
I also have a custom script called customize-image.sh
, which should be placed
in userpatches
folder before building the image. This script is called in
chroot environment at the very end of build process. In it, I set up WiFi
network on startup by reading wireless network configuration - SSID and
passphrase - from a file called wpa.txt
on boot partition. I also disable
NetworkManager, set up hostname according to /boot/id.txt
and disable
first-time password change for root user and login user creation (Ansible will
manage that).
At this point you can burn the image to the card and boot OPZ. You might want
to edit /boot/wpa.txt
as OPZ will try to connect to WiFi on boot.
Now that I can ssh to the box, I can use Ansible to provision the system.
You need to install additional roles from Galaxy with:
ansible-galaxy install -r requirements.yml
Three roles are used:
- nickjj/ansible-docker role is used to install and configure Docker
users
role is used to create login user and setup authorized keys and sudo (default root password is changed after provisioning)services
role starts services viadocker-compose
Invoke ansible-playbook
to start provisioning:
ansible-playbook --vault-id @prompt -i inventories/hosts.ini playbook.yml
Note that you will need to have fingerprint of the box in your
~/.ssh/known_hosts
file in order for Ansible to use default root password
(stored in group vars). You can fingerprint the box with:
ssh-keyscan -H <box_ip> ~/.ssh/known_hosts
I use three containers, managed by docker-compose.yml
.
- Statsd container that is used to aggregate metrics locally and send metrics to Graphite server
- Python script that runs in a container, reads temperature and sends readings
to Statsd via UDP. Since this container needs
/sys
and/dev
access, it needs to be started with--privileged
flag - Watchtower container that monitors Docker repository for new versions of images of running containers, downloads them and restarts running container instances (including itself)
All three Docker containers are started with --restart=always
, meaning that
containers will be restarted on any error, clean termination and even on reboot,
if they are not already running.
Graphite is used as metrics aggregation engine, and Grafana is used to display them in a nice dashboard.
Front (single USB port and Ethernet port can be seen)
Rear (microSD slot on the bottom and mini USB for power)
Top
- Add Grafana screenshot
- Use statsite instead of Statsd for sending metrics - it is based on Statsd and actively maintained
- Use OpenVPN to connect sensor boxes to home VPN and be able to SSH to them, no matter where they are deployed