The first thing we're going to need is a small server on which we can store all the data we're collecting from our home sensors.
For this I'll use an old Raspberry Pi (1st generation) that I've got left lying around. It may not be very powerful, but I do already own it, and it uses very little energy. While it might be more than ten years old, the Raspberry Pi team is very good about supporting old hardware, so I can still use the most recent version of the Raspberry Pi OS. I'm sure any other spare, or cheap, computer that is lying around, would be fine as well.
While trying to keep things simple, one thing that is worth doing is using a repeatable testing and development environment, in which you can experiment, and once it's correct, deploy it. For this I'll be using the combination of Ansible and Vagrant; for anyone not familiar, Ansible is a light weight Python based automation system, that allows you to create and run 'playbooks', a YAML file, that will repeatably apply a series of commands to one, or many, computers. Vagrant is a way of simply managing virtual machines (VMs), 'boxes' in Vagrant speak, and in combination you can repeatedly create and test your deployment by running playbooks against Vagrant boxes. Check the respective docs on how to get both up and running on your computer.
There are a few advantages of this, even if you're only going to be working on one machine:
- You will have a complete list of everything you need to do to set up your machine/system, and won't forget to make a note of any little in-between steps
- If something goes wrong, you don't have to spend a long time undoing what you did; figure out the mistake, create a new VM and run the playbook again
- My laptop creates a much faster machine than the old Raspberry Pi, meaning installing and running commands takes less time, than if I had to wait for the rather under-powered Pi; which means quicker iteration.
- If anything goes wrong with the server, it's easy to re-create it; write a new SD card, run the playbook, then drink a cup of tea. Then it'll be back as a new clean working server, without further manual intervention (you will probably have an extra step to restore data - which you are backing up, right?)
To learn this approach I can recommend Jeff Geerling's Ansible for Devops eBook, which is how I learnt most of the important parts of using Ansible. It's well written and structured, with lots of practical examples to follow along yourself, in which you end up seeing the solution to many of the problems you'll encounter.
You could of course do this using other tools; Containers are fashionable at the moment, or other automation tools like Chef or Puppet could also work, even if in this case I think the latter is a bit overkill for such a small project, and the former makes more sense if you've got a more powerful machine and you're effectively running multiple servers on one. My old Pi isn't going to cope with that.
For development the Vagrantfile contains the configuration I used, and if something worked there it was ok to deploy it on the Raspberry Pi. I couldn't find a dedicated Vagrant box for Raspberry Pi OS, but using the current debian/bullseye64 box worked ok. I reduced the allocated RAM of the VM to 1GB, in an attempt to perhaps simulate the limits of the Pi, but didn't encounter any. The Pi is much slower than my laptop, I suspect mostly because of the differnce between the SSD on the laptop, and a SD card on the Pi.
The last step was to add a user called 'pi' to the VM. This made it easier to replicate the later roll-out onto the actual 'production'1 server, including adding the relevant SSH key to the user, instead of just using the default vagrant user and supplied SSH key. The first playbook in the vagrantfile is run by the vagrant user, but after that it's all the same as it is on the real server.
All the Ansible roles, and vagrantfile, I used are available in a public repository, so you can use the files yourself if you like, but beware that they are supplied under the 'it works on my machine' standard of quality.
Once you have Ansible, Vagrant and whichever VM provider you use installed on your computer, you should be able to go into the /Vagrant folder and run
vagrant up to launch the box and have your development VM running.
Your mother and I have had a chat, and we think it's about time we had "the talk" - server security.
It should almost go without saying that you should take some basic precautions regarding server security, how much is ultimately only something you can decide, but should be based on how it's being used. For this situation we're very low down on the level of risk, as:
- The server is not visible on the public net, and has no ports forwarded to it. There should be nothing connecting to it that we haven't added to our private home network
- It contains no valuable data, and doesn't have access to any (e.g the NAS). I don't consider a history of room temperatures, or power usage, dangerous, there's little you can do with it other than scold us for keeping our rooms too warm
But, it is still something running on the same network as our other private devices, so we should take basic precautions, which are:
- Ensure access only with SSH keys - no passwords access
- No remote root login
- Keep the system up to date
These steps are covered in the Ansible role 'basic-debian-setup', which updates the SSH configuration to ensure the above, as well as adding two quality of life improvements by adding chrony to ensure the system time is always in sync, and tmux to give us persistent, or multiple terminal sessions.
In addition it installs and configures the Unattended Upgrades package, and configures it to run weekly at a specific time, as well as logrotate to make sure our machines doesn't eventually fill up with logfiles.
Set Up The Pi Server
The first step is to install the operating system on the SD card. For this the Rasperry Pi Imager is now probably the easiest solution. It also allows you to specify things like an SSH key, hostname, users and WiFi password before writing the image, something that used to be a pain in the past. Pro-tip: when it's asking for the authorised keys for the Pi, it expects you to copy the actual key into that box, not the path to a key file, which is what I did the first time. I'm also using Raspberry Pi OS 'lite', that is without a graphical environment - I'll only ever be connecting to it via SSH.
Once the server is up and running create an entry in your
.ssh/config file, and an Ansible inventory file for your Pi. Then test logging in via SSH and running the Ansible ping command ad-hoc against it to check that you can connect.
Basic Setup Playbooks
At this point it should be possible to run the first two roles listed in 'home-sensor-network-setup.yml' against it, those being:
(Just comment out any later roles with a
#, those require more configuration, explained in later posts.)
The first makes one Pi specific change, and that is to change the memory split so that the GPU gets the minimum amount possible, which we won't need, as this is running without a display. We do this, and reboot the machine before doing anything else, in the vain hope it will speed things up. In my experience the first update of all packages takes a very long time on this old Pi, so be patient. If you're following along and not using a Raspberry Pi as your server, then you shouldn't need to run the first role.
Now with the server up and running, we can actually start using it for something…to be continued.
Overview: Home Sensor Overview