This post goes over integrating hardwired contact sensors into a Home Assistant supervised instant running on the Armbian operating system on Odroid N2+ hardware. Available in the US here. NOTE: I no longer use Armbian, but this fully function Debian 11 distro. The distro has a built in command, menu-config, that provides for the supervised install of HA.
We bought our house years ago. The house had an existing minimal alarm system the previous owner had installed. Part of buying the house required us to take over the alarm system contract, which we did. We over paid for the alarm system and 3rd party monitoring for years. The system had hard wired contact sensors on the doors, a motion sensor and a glass break sensor. While the system provided my wife a small sense of comfort when we traveled, I always felt the system was a joke because of the limited features. There we’re multiple ways you could gain access to the house with no threat of detection.
About a year ago I discovered Home Assistant. I started playing around with it looking at different contact and motion detection sensors. I tried out Wyze and then switched over to the Aqara line of sensors. I’m very happy with the Aqara sensors. They are easy to integrate directly into Home Assistant with one of many Zigbee USB dongles. I utilize the HUSBZB-1. While the wireless sensors are easy to use, I really prefer the aesthetics of hidden hardwired sensors. That was the one thing our existing alarm system did right. They used hardwired sensors on all the doors.
The hardwired sensors are really just switches that are either open or closed, based on the position of the door. So power either flows or it doesn’t. The arm based board utilized as controllers for Home Assistant all come with a number of GPIO pins. In the simplest terms the GPIO pins can provide or receive a voltage and then report a change in that voltage. So if you use a GPIO pin that is providing voltage, connect it to the contact sensor and then the contact sensor back to a ground GPIO pin you have a complete circuit. The contact sensors in my house are Normally Open (NO) that means they are on, letting voltage flow when the door is closed. Normally Closed (NC) sensors would be off when the door is closed, stopping the flow of voltage. Regardless of your sensor type, NO or NC, the result is the same. Opening and closing the door changes the voltage measured at the GPIO pin. So wiring is easy you just need to find a GPIO pin that is providing voltage and wire it to ground with the sensor in line.
While there may be a way to do this utilizing the Home Assistant Operating System (HAOS), I don’t know that path. HAOS isolates the user from accessing the operating system. That’s fine if you’re just using items that come out of the box. It’s very limiting if you want to take full advantage of your hardware and operating system capabilities.
Most people seem to pick the Raspberry Pi 4 for their controller because of it’s cheap price, but I believe the Odroid N2+ is currently the best platform for Home Assistant. The N2+ provides about 2X CPU performance over the Raspberry Pi 4 for an additional $30. The N2+ also has the option to use eMMC storage instead of a micro SD card. The eMMC write speed comes in at 125MB/s, while a class 10 micro SD has a write speed of 10MB/s. There are faster micro SD card. The fastest I’ve seen has a write speed of 90MB/s. So eMMC is the way to go for performance. While you probably would not notice this in your operational system, the performance improvements are very visible when you’re working on your initial setup. Time is money and I know I’ve saved hundreds of dollars in time because I selected the N2+.
If you’re not going to go with HAOS then you need a operating system distribution for your hardware. At this point in time I recommend Armbian, primarily because the Armbian team looks to support multiple Arm boards. Having a common platform is great because you can try out different hardware if you like and the operating system configuration is exactly the same. You don’t have to figure out how to do something uniquely for each hardware platform. The current armbian release for the Odroid N2+ is here. I used the CLI version as there is no need for a DESKTOP with HA. The only issue with using this distribution for HA is that it’s one Debian version back from what HAOS uses. That said it has all the current version of software packages that HA utilzes so there is no operational issue with using the previous version of Debian with HA.
So the basic install process for the Armbian release is the same as installation of HAOS. That is, you grab the operating system image, decompress it and burn it on your storage media. Once you’ve installed the image you plug it into your system and boot the system. For the Armbian image you’ll have a couple of additional steps. You log into the default account “root” with the password “1234” . On first login you’re asked to change the password and set up the main account you’ll log into. While you could can just contine to log in as the root use it’s good security practice to set up a different account and to disable the root account. Once your logged into the command prompt you make sure the system is up to date
sudo apt-get update
sudo apt-get upgrade
Reboot the system just in case there was an operating system update
sudo shutdown -r now
Log back in to the command line and install docker:
sudo bash
apt-get install ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg]\
https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io
Install and enable apparmor
apt install apparmor
echo "extraargs=apparmor=1 security=apparmor" >> /boot/armbianEnv.txt
update-initramfs -u
shutdown -r now
Log back in and add the last few packages required by
sudo bash
apt install jq libglib2.0-bin
apt install udisks2
I’m pretty sure that previous line installing udisk2 didn’t work for me so I had to do this to get udisk2 installed:
apt --fix-broken install
apt install udisks2
Install HA os-agent:
wget \
https://github.com/home-assistant/os-agent/releases/download/1.2.2/os-agent_1.2.2_linux_aarch64.deb
dpkg -i os-agent_1.2.2_linux_aarch64.deb
Install HA supervised, make sure you select the odroid-n2 hardware during these steps when asked:
wget https://github.com/home-assistant/supervised-installer/releases/latest/download/homeassistant-supervised.deb
dpkg -i homeassistant-supervised.deb
shutdown -r now
At this point you should be able to access you’re home-assistant GUI. If you have a previous install that you did a backup of you can now create a HA account, login and reinstall the backup.
The last thing we need to do is install the packages that support GPIO pin access:
sudo bash
apt-get install gpiod python3-libgpiod
You need to add a file that make the pins available to all users:
echo 'KERNEL=="gpiochip0", MODE="0666"' > /etc/udev/rules.d/99-perm.rules
echo 'KERNEL=="gpiochip1", MODE="0666"' > /etc/udev/rules.d/99-perm.rules
shutdown -r now
At this point you just need to pick your pins and wire things up. Here is a picture
of the GPIO pins and their associated pin numbers.
The GPIO software make the pins available using a different set of numbers. As
such you need to do the translation to make these pins available in any software that reads the state of the pins.
The following is the mapping for the pins with an indication of the voltage on the pins. I used pins that had a positive voltage because I then connected them to ground. Pins 29, 31 and 33 are underlined as they are the three used in the bash script below:
62 = 7 -
63 = 27 +
64 = 28 +
65 = 16 +
66 = 18 +
67 = 22 +
69 = 13 +
70 = 33 +
71 = 35 -
72 = 15 +
73 = 19 +
74 = 21 +
75 = 24 +
76 = 23 +
77 = 8 ?
78 = 10 ?
79 = 29 +
80 = 31 +
81 = 12 +
82 = 3 +
83 = 5 +
84 = 36 -
You can check this mapping using the command:
gpioinfo periphs-banks
For monitoring and integrating this into Home Assistant were going to use a bash script. The script uses netcat as a way to verify Home Assistant is up before it starts sending messages to HA. It uses the mosquitto client to interface with the mosquitto broker that comes with home assistant. So we have to install two final packages
apt-get install netcat mosquitto-clients
You need to create the file watchpins_mqtt.bash. I recommend that you create it in the default home assistant directory structure so it’ll be include in any backup you do of home assistant from within home assistant. Create a directory in the home assistant directory structure:
mkdir /usr/share/hassio/homeassistant/os-support-apps/
Then use nano or vi to create the file watchpins_mqtt.bash in the os-support-apps directory with this content. Make sure to replace and with the user name and password you establish within your HA mosquitto broker:
#!/bin/bash
# you need to update <USER> and <PASS WORD> below with the user and password for you mqtt server
# wait for HA to come up by checking web port before sending any messages
notdone=1
while [ $notdone -eq 1 ]; do
netcat -w 3 -z localhost 8123
if [ $? -eq 0 ]; then
echo port open
notdone=0
else
echo port closed
fi
sleep 10
done
# give a little time to make sure things are really up
sleep 20
#post fact senosrs are available and in a closed state
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/front_door/availability -m online
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/back_door/availability -m online
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/basement_door/availability -m online
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/front_door -m '{"state":"OFF"}'
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/back_door -m '{"state":"OFF"}'
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/basement_door -m '{"state":"OFF"}'
# keep track of current sensor state, assume everything is closed
declare -g curfd="0"
declare -g curbkd="0"
declare -g curbsd="0"
#echo curfd = $curfd, curbd = $curbkd, curbsd = $curbsd
#Loop forever
while true
do
# Read in gpio pin values for three doors
while read fd bkd bsd; do
#echo fd = $fd curfd = $curfd bkd = $bkd curbkd = $curbkd bsd = $bsd curbsd = $curbsd
# report any change in state of doors
if [ $curfd != $fd ];then
if [ $fd = 1 ];then
echo "`date` Sending front_door open "
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/front_door -m '{"state":"ON"}'
else
echo "`date` Sending front_door closed"
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/front_door -m '{"state":"OFF"}'
fi
curfd=$fd
fi
if [ $curbkd != $bkd ];then
if [ $bkd = 1 ];then
echo "`date` Sending back_door open"
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/back_door -m '{"state":"ON"}'
else
echo "`date` Sending back_door closed"
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/back_door -m '{"state":"OFF"}'
fi
curbkd=$bkd
fi
if [ $curbsd != $bsd ];then
if [ $bsd = 1 ];then
echo "`date` Sending basement_door open"
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/basement_door -m '{"state":"ON"}'
else
echo "`date` Sending basement_door closed"
mosquitto_pub -u <USER> -P <PASS WORD> -h 127.0.0.1 -t home-assistant/contact/basement_door -m '{"state":"OFF"}'
fi
curbsd=$bsd
fi
done <<<$(gpioget gpiochip0 79 80 70)
#Only check state every half second
sleep .5
done
This script currently handles 3 hardwired contact sensors. Adding more sensors requires you adding them to the “while read…” and “done <<< lines…” and then doing a little cutting and pasting, but it should be pretty straight forward. The script has fd (front door), bk (back door) and bsd (basement door).
To start the script on reboot you can add the following line, just above the exit 0 line, in the file /etc/rc.local:
/usr/share/hassio/homeassistant/os-support-apps/watchpins/watchpins_mqtt.bash > /dev/null &
The script looks to talk with the mosquitto broker that you can install as an add on directly in HA. Setting up the add on also requires you to do a basic configuration for MQTT under integrations. When you set up the Mosquitto broker should have a configuration that looks something like this, with the username and password you want to use. You update the bash script above with the same username and password.
logins:
- username: USERNAME
password: PASSWORD
customize:
active: false
folder: mosquitto
certfile: fullchain.pem
keyfile: privkey.pem
require_certificate: false
The last step is to actually create the binary sensor in your home assistant configuration.yaml. So use either nano or vi to edit /usr/share/hassio/homeassistant/configuration.yaml and add this:
binary_sensor:
- platform: mqtt
name: "front_door_mqtt"
state_topic: "home-assistant/contact/front_door"
payload_on: "ON"
availability:
- topic: "home-assistant/contact/front_door/availability"
payload_available: "online"
payload_not_available: "offline"
qos: 0
device_class: door
value_template: "{{ value_json.state }}"
- platform: mqtt
name: "back_door_mqtt"
state_topic: "home-assistant/contact/back_door"
payload_on: "ON"
availability:
- topic: "home-assistant/contact/back_door/availability"
payload_available: "online"
payload_not_available: "offline"
qos: 0
device_class: door
value_template: "{{ value_json.state }}"
- platform: mqtt
name: "basement_door_mqtt"
state_topic: "home-assistant/contact/basement_door"
payload_on: "ON"
availability:
- topic: "home-assistant/contact/basement_door/availability"
payload_available: "online"
payload_not_available: "offline"
qos: 0
device_class: door
value_template: "{{ value_json.state }}"
If you only only have one or two sensor then just add entries to configuration.yaml for one or two entries. You need to restart home assistant which you can do via:
ha core restart
You should now see the binary senors as new entities in home assistant.
Hopefully this is helpful.