Install Domoticz and Razberry2 on Raspbian 2017-01-11


I just installed domoticz with the following setup:

  • Razberry2
  • Raspberry Pi 3
  • Raspbian Jessie, 2017-01-11

There are a couple of things to keep in mind, for the Razberry2 to work properly, especially with the later jessie releases:

  • The serial port has to be turned ON
  • Console on the serial port has to be turned OFF
  • Bluetooth has to be disabled
  • hciuart.service can optionally be disable (to get rid of an error message during boot)

So, the minor issue is that when you use “raspi-config” to turn off the serial console, it does not only turn off the console output on the serial port. It also turns off the serial port, which is not really what we want. That is why most people get a bit confused and fiddle around until they figure out that the “enable_uart=0” entry in /boot/configure.txt should be “enable_uart=1”, and never think of why it happened to be that way.

The “console output” to serial is configured in /boot/cmdline.txt with the entry “console=serial0,115200”, which we need to get rid of, but still make sure that there is no “enable_uart=0” in /boot/config.txt.

Unless you really want to, there is no need to redistribute the GPU RAM mapping.

So, a working setup (as of 2017-01-20) is:

  • Create an SD card with 2017-01-11-raspbian-jessie.img
  • Before you unmount it from your PC, change the following files on the SD card:

/boot/cmdline.txt

cat /boot/cmdline.txt
 dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

/boot/configure.txt

 enable_uart=1
 dtoverlay=pi3-disable-bt

  • Boot the raspberry pi
  • Disable the hciuart service
 sudo systemctl stop hciuart
 sudo systemctl disable hciuart

  • Ensure you have a /dev/ttyAMA0 file
 ls -la /dev/ttyAMA0
 crw-rw---- 1 root dialout 204, 64 Jan 20 08:19 /dev/ttyAMA0
  •  Install domoticz as described above by kent
 mkdir ~/domoticz
 cd ~/domoticz
 wget https://releases.domoticz.com/releases/release/domoticz_linux_armv7l.tgz
 tar xvfz domoticz_linux_armv7l.tgz
 rm domoticz_linux_armv7l.tgz
 sudo cp domoticz.sh /etc/init.d
 sudo chmod +x /etc/init.d/domoticz.sh
 sudo update-rc.d domoticz.sh defaults
 sudo service domoticz.sh start
  • Go to “Setup”->”Hardware”
  • Add a OpenZWave USB device with the serial port: /dev/ttyAMA0

Done.

wpa_supplicant in debian /ubuntu/ raspbian – getting it to work on your raspberry pi


Hi again,

This time, I will go through a couple of things that I learned today, which has bugged me for quite some time. It also took me forever to figure it out why I could not get it to work the way I wanted to. It also was not made easier with a recent change in the network management of Raspbian Jessie. Proper wifi configuration (on the command line) on the Raspberry Pi 3 with its built in wifi is simple, but not easy. This blog entry is about the scenario whan you do all your configuration on the command line. I have no clue on how to do it through any GUI tools.

What I wanted to do, could in principle be easily solved by the first two examples below, but I really wanted to both understand what I was doing, as well as having a flexible solution where my raspberry pi would also be a bit more mobile. By setting the ssid and wpa2 passwords directly in the /etc/network/interfaces file, I would have to remember and reconfigure the wifi configuration (prefreably before I unplug the device) if I were to move a raspberry pi from my home to my office (since they have different ssid:s and network configurations).

So i will touch these topics, since they are closely related:

  • Proper use of wpa_supplicant.conf in a wifi setup
  • Why on earth the raspberry pi claims a DHCP Ip address on eth0, wlan0, etc even if you configure a static IP address

For the quick solution, there are basically two scenarios:

  • If you want wifi, and are ok with DCHP: stay with the default configuration of /etc/network/interfaces, and just add a “network” section to /etc/wpa_supplicant/wpa_supplicant.conf
  • If you want wifi and a static IP address: The key items to remember is: id_str in /etc/wpa_supplicant/wpa_supplicant.conf and wpa-roam instead of wpa-conf in /etc/network/interfaces.

In the “jessie” release of Raspbian, the /etc/network/interfaces configuration changed from using wpa-roam to using wpa-conf to fit with the change to use a system component called dhcpcd. Basically, without any reconfiguration the dhcpcd daemon will monitor the states of any network interface (also eth0) and request an IP address from your DHCP server (which most likely is your internet router at home). In the bulk of installations, this is perfectly ok, even for advanced users, and for beginners it just works out of the box. The default configuration of the /etc/network/interfaces file will now expect you to use the stansa “iface xxx inet manual” instead of “iface xxx inet dhcp”. The DHCP stansa will still work, but is sort of redundant, since dhcpcd should be taking care of your DHCP requests.

Most how-to’s on the internet, showing you how to set up a static ip address on an interface, will work as expected (almost). You will get a static ip addres configured on your interface, but in the background you will also get a second ip address through the dhcpcd daemon, which you sadly will not see with the ifconfig -a command. You will, though, see it with either “hostname -I” or ip addr show“. One side effect (which is also merely more than an annoyance) is that you get a second route to your default gateway. Since the route you configure with your static ip configuration takes precedence, you will not even notice it, but it is there (which is seen by using “netstat -nr” or “ip route show“.

Wifi configurations that come quickly to a decently round up linux admin (which would not at all use the wpa_supplicant.conf):

  • Putting the ssid and WPA2 password directly in the /etc/network/interfaces, using DHCP


allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ssid "MY_SSID"
wpa-psk "MY_SECRET_PASSWORD"

  • Using the ssid and WPA password directly in the /etc/network/interfaces, using static IP configuration


allow-hotplug wlan0
iface wlan0 inet static
wpa-ssid "MY_SSID"
wpa-psk "MY_SECRET_PASSWORD"
address 192.168.3.11
netmask 255.255.255.0
network 192.168.3.0
broadcast 192.168.3.255
gateway 192.168.3.1
dns-nameservers 192.168.3.1

Although both these ways of configuring the wifi on my raspberry pi works, they are both very static. As mentioned above, I would have to re-configure the /etc/network/interfaces file before I shut the raspberry pi down if I were to move it to another wifi network. I would like to just shut it down, move it, and start it up with a working configuration.

In the second case I would also get that “shadow” ip address:


pi@raspberrypi:~ $ hostname -I
192.168.3.11 192.168.3.133

The difference between “wpa-conf” and “wpa-roam” in the /etc/network/interfaces file, is that when you use “wpa-conf” you should not be moving your gear around that much. If you want to use DHCP, just set up your network in the /etc/wpa_supplicant/wpa_supplicant.conf or directly in your /etc/network/interfaces file. One network to rule them all. If you move your device, you should be prepared before you shut down, or be prepared for a big hassle when you arrive at your new destination. When using “wpa-roam” you should either accept that you get a shadow IP address, or disable the wlan0 interface in the dhcpcd configuration, or turn off dhcpcd once and for all.

I set up a simple test, which still turned out to be 20 scenarios to go through. Sorry for the crappy table format. The table is mostly for show. Green is where the configuration is ok, yellow is where it looks to work at first glance but there is something lurking in the background.

Test# Config file:
/etc/network/interfaces
DHCPCD enabled ->
“sudo update-rc.d dhcpd enable; sudo shutdown -r”
DHCPCD disabled ->
“sudo update-rc.d dhcpd enable; sudo shutdown -r now”
1 allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
 
works (ping 192.168.3.1)
dhclient -v … is running
works (ping 192.168.3.1)
dhclient -v … is running
2 allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf 
works (ping 192.168.3.1)
no dhcp client running after reboot
does not work, but if you start the dhclient manually, you will get an ip address
3 allow-hotplug wlan0
iface wlan0 inet static
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf 
invalid config without the “address” variable invalid config without the “address” variable
4 allow-hotplug wlan0
iface wlan0 inet static
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
address 192.168.3.11 
Works (ping 192.168.3.1)
ifconfig show only one IP address
“ip addr show” shows 2 ip addresses
“netstat -nr” show a default route (from dhcp)
Works (ping 192.168.3.1), but no default route
ifconfig show only one IP address
“ip addr show” shows 1 ip addresses
“netstat -nr” show no default route (from dhcp)
5 allow-hotplug wlan0
iface wlan0 inet static
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
address 192.168.3.11
# bad gateway address
gateway 192.168.3.99 
Works (ping 192.168.3.1), but no default route
ifconfig show only one IP address
“ip addr show” shows 2 ip addresses
“netstat -nr” show 2 default routes (from dhcp), but the bad one has precedence
when removing the bad route “sudo route del -net 0.0.0.0 gw 192.168.3.99” all works
Works (ping 192.168.3.1), but no default route
ifconfig show only one IP address
“ip addr show” shows 1 ip addresses
“netstat -nr” show no default route (from dhcp)
6 allow-hotplug wlan0
iface wlan0 inet static
wpa-conf /etc/wpa_supplicant/wpa_supplicant.confiface stg inet static
address 192.168.3.11
netmask 255.255.255.0
gateway 192.168.3.1
broadcast 192.168.3.255
dns-nameservers 192.168.3.1 
does not work, missing required variable: address does not work, missing required variable: address
7 allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.confiface stg inet static
address 192.168.3.11
netmask 255.255.255.0
gateway 192.168.3.1
broadcast 192.168.3.255
dns-nameservers 192.168.3.1 
Works (ping 192.168.3.1)
ifconfig show only one IP address
“ip addr show” shows 1 ip addresse (dhcp)
“netstat -nr” show a default route (from dhcp)
does not work, although “sudo wpa_cli status” show proper connection to the ssid
running “dhclient -v …” gives wlan0 an IP address
8 allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.confiface stg inet static
address 192.168.3.11
netmask 255.255.255.0
gateway 192.168.3.1
broadcast 192.168.3.255
dns-nameservers 192.168.3.1 
Works (ping 192.168.3.1)
proper gw, dns, all
wpa_cli status” show proper connection
“ip addr show” shows 2 ip addresses
“netstat -nr” shows 2 routes to the default gateway
Works (ping 192.168.3.1)
proper gw, dns, all
wpa_cli status” show proper connection
“ip addr show” shows only 1 ip address
9 command line:
echo “denyinterfaces wlan0” | sudo tee -a /etc/hdcpcd.conf
sudo service dhcpcd restart/etc/network/interfacesconfiguration:
allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.confiface stg inet static
address 192.168.3.11
netmask 255.255.255.0
gateway 192.168.3.1
broadcast 192.168.3.255
dns-nameservers 192.168.3.1

 

Works as expected. Static IP set.
Ping 192.168.3.1 ok
proper gw, dns, all
wpa_cli status” show proper wifi connection
“ip addr show” shows 1 ip address
“hostname -I” shows 1 ip address
“netstat -nr” shows 1 default route
n/a, will work, see test 8
10 command line:
echo “denyinterfaces wlan0” | sudo tee -a /etc/hdcpcd.conf
sudo service dhcpcd restart/etc/network/interfacesconfiguration:
allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.confiface default dhcp

 

Works as expected. DHCP address.
“wpa_cli status” show proper wifi connection
dhclient -v … is running
Ping 192.168.3.1 ok
proper gw, dns, all
wpa_cli status” show proper wifi connection
“ip addr show” shows 1 ip address
“hostname -I” shows 1 ip address
“netstat -nr” shows 1 default route
n/a, will work, see test 8

You can ignore your wlan0 interface by doing the following (which will survive a reboot).


echo "denyinterfaces wlan0" | sudo tee -a /etc/dhcpcd.conf
sudo service dhcpcd restart

In the end, the choice is yours. If you are decently experienced and you disable dhcpcd, you will not lose much at all. I would even recommend it.

  • Disable dhcpcd


sudo update-rc.d dhcpcd disable
sudo service dhcpcd stop
# sudo shutdown -r now

  • /etc/wpa_supplicant/wpa_supplicant.conf


country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
ssid=”AT_HOME”
psk=”SUPERSECRET”
id_str=”HOME_SSID”
priority=15
}

network={
ssid=”OFFICE_SSID”
psk=”SUPERSECRET”
id_str=”OFFICE”
priority=14
}

 

  • /etc/network/interfaces


auto lo
iface lo inet loopback

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf

iface default inet dhcp

iface HOME inet static
address 192.168.2.11
netmask 255.255.255.0
gateway 192.168.2.1
broadcast 192.168.2.255
dns-nameservers 192.168.2.1

iface OFFICE inet static
address 192.168.3.11
netmask 255.255.255.0
gateway 192.168.3.1
broadcast 192.168.3.255
dns-nameservers 192.168.3.1

Useful commands:

  • wpa_cli status
  • sudo iw wlan0 scan | grep -i ssid
  • hostname -I
  • iwconfig wlan0
  • ip addr show
  • ip route show

References:

  • https://wiki.debian.org/WPA
  • http://manual.aptosid.com/en/inet-setup-en.htm
  • https://www.raspberrypi.org/forums/viewtopic.php?t=110606

Web server load balancing on (in the end) Raspberry Pi for less than 100 bucks


So…

The other day I got very interested in web server load balancing.

Again.

One of these things that most people would just never care about, but as always… I got obsessed with it.

Again.

Not so much because the technology is particularly complex (it is), or that you need to have so much knowledge of low level IP protocol to understand it well (you do). It was more that someone at work told me that I didn’t understand it. Such remarks alone have made smarter people than me insane; some of them brought elephants over the alps.

But, in an ancient workplace of mine, some 10-12 years ago, I ran into this topic for the first time. I was working at a company called Inserve, and a good old friend Rober Carlsson introduced me to the topic. Shortly after we started working together with a company called RadWare, selling their take on the issue. I can still remember how fascinated I was of their, at the time, so simple way of implementing so called “triangulation”, where a load balancer would get a TCP packet, change the MAC address in the headers and put it back on the network, so that a back end web-server would fetch it and send the reply directly over the router to the client.

I am getting way too detailed for this post already.

The other day, as I sad, I realized that I was a bit out of the loop. I had not researched the topic in quite a while. And all those company- and product- names I was using fluently a few years ago, was a bit faint. Extreme networks, F5, RadWare.

At work, we are using fairly old F5 boxes. They work well, and there are a couple of features I really enjoy. Setting up a load balanced web server environment is fairly straight forward.

  • Set up a virtual host
  • Set up a pool
  • Add back end members to the pool

Done.

And you can add rules to the pool (monitors), which are ran against all back end members. I if all monitors return OK, the targeted back end server deserves to stay in the configuration.

This is a very neat way of making sure that only correctly configured back end servers are serving web pages to the public.

A simple test can be to check if port 80 is responding. A more complex test would connect, request a web page, and parse the content for some keywords. This way, one can easily setup a web page that would represent an end to end view of the stack. I.e embedding a function in the web page, that connects to the back end database, checking for a certain value in the database. If all goes well, the web page would eventually show “Database connection OK”. A monitor could parse this output for this string, and voila, the test proves that both the web server and it’s database connectivity is ok.

I love such features.

But, and there is always a but. A major corporation can afford the big players. A clustered F5 system is expensive. The “brand new BMW” kind of expensive. They have really good products, don’t take me wrong, but it is not for the startup where a free lunch consists of half a sandwich.

So, I started looking around a bit and got fascinated by two products that I looked at a bit more:

  • http://Loadbalancer.org
  • http://zenloadbalancer.org

The first one is decently priced, but commercial. The second one, zenloadbalancer.org, is free as in beer.

I started looking into the zenloadbalancer.org product, and downloaded their ISO image (the product is based on Debian). There was a good video available on Youtube, so I got started in no time at all.

The magic in this sauce, is the web-frontend that the guys at ZenLoadbalancer delivers. The load balancing itself is based on the open source project Pen, which is fairly heavy to get into. But with the help from the web gui, I had a working solution up and running in an hour or so.

Basically, my configuration was:

  1. A forward of port 8080 on my firewall to port 80 on my internal IP 192.168.2.49, which would be the virtual IP on my load balancer
  2. the virtual IP on eth0:1 on my load balancer
  3. the two web servers, 192.168.2.21 and 192.168.2.22, which are the two apache web servers I had configured on the “inside”.
I configured a monitor to check my back end web servers (more about this in a separate post). It worked. Not that I had expected anything else.
But then I had a chat with another friend, Karl Gilén, who I hooked up with a couple of Raspberry Pi:s. We started talking about a “Raspberry Pi only” clustered web farm. With a load balancer, a couple of web servers, perhaps also the mysql database on Raspberry Pi. Well, all is possible since it is all in the Debian distro. But now it had to be done.
I got started thinking of how I could reproduce the load balancing on the Raspberry Pi, and after just a few seconds it came to me. “Just rip it off off the zenloadbalancer box!”.
Connecting to the zenloadbalancer, i did the following:

[ccne lines=”-1″]
root@kmg-zenlb-0001:~# ps -ef | grep pen
root 1045 1 0 13:52 ? 00:00:00 /usr/local/zenloadbalancer/app/pen/bin/pen -S 10 -c 2049 -x 257 -F /usr/local/zenloadbalancer/config/Kalle_pen.cfg -C 127.0.0.1:10448 192.168.2.49:80
root 1055 1 0 13:52 ? 00:00:00 /usr/local/zenloadbalancer/app/pen/bin/pen -S 10 -c 2049 -x 257 -F /usr/local/zenloadbalancer/config/1200kcaltcp_pen.cfg -C 127.0.0.1:12162 192.168.2.48:80
root 27021 12111 0 17:30 pts/0 00:00:00 grep pen
root@kmg-zenlb-0001:~# cat /usr/local/zenloadbalancer/config/Kalle_pen.cfg
# Generated by pen 2012-09-21 13:43:20
# pen -S 10 -c 2049 -x 257 -F ‘/usr/local/zenloadbalancer/config/Kalle_pen.cfg’ -C 127.0.0.1:10448 192.168.2.49:80
no acl 0
no acl 1
no acl 2
no acl 3
no acl 4
no acl 5
no acl 6
no acl 7
no acl 8
no acl 9
acl 9 deny 0.0.0.0 0.0.0.0
no ascii
blacklist 30
no block
client_acl 0
control_acl 0
debug 0
no delayed_forward
no hash
no http
no log
no roundrobin
server 0 acl 0 address 192.168.2.21 port 80 max 0 hard 0
server 1 acl 0 address 192.168.2.22 port 80 max 0 hard 0
server 2 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 3 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 4 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 5 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 6 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 7 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 8 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 9 acl 0 address 0.0.0.0 port 0 max 0 hard 0
no stubborn
timeout 5
tracking 0
no web_stats
no weight
no prio
root@kmg-zenlb-0001:~# ifconfig -a
eth0 Link encap:Ethernet HWaddr 00:0c:29:62:9c:e1
inet addr:192.168.2.47 Bcast:192.168.2.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe62:9ce1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:50817 errors:0 dropped:0 overruns:0 frame:0
TX packets:44155 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:32617453 (31.1 MiB) TX bytes:3929003 (3.7 MiB)

eth0:1 Link encap:Ethernet HWaddr 00:0c:29:62:9c:e1
inet addr:192.168.2.49 Bcast:192.168.2.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
[/ccne]

This could not be hard to reproduce on the raspberry pi, no? I brought down the IP address 192.168.2.49 on the zenloadbalancer box and just did the following on my Raspberry Pi.

[ccne lines=”-1″]
pi@raspberrypi /tmp $ sudo apt-get install pen
pi@raspberrypi /tmp $ vi /tmp/kalle.cfg
pi@raspberrypi /tmp $ cat /tmp/kalle.cfg
# Generated by pen 2012-09-21 13:43:20
# pen -S 10 -c 2049 -x 257 -F ‘/usr/local/zenloadbalancer/config/Kalle_pen.cfg’ -C 127.0.0.1:10448 192.168.2.49:80
no acl 0
no acl 1
no acl 2
no acl 3
no acl 4
no acl 5
no acl 6
no acl 7
no acl 8
no acl 9
acl 9 deny 0.0.0.0 0.0.0.0
no ascii
blacklist 30
no block
client_acl 0
control_acl 0
debug 0
no delayed_forward
no hash
no http
no log
no roundrobin
server 0 acl 0 address 192.168.2.21 port 80 max 0 hard 0
server 1 acl 0 address 192.168.2.22 port 80 max 0 hard 0
server 2 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 3 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 4 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 5 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 6 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 7 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 8 acl 0 address 0.0.0.0 port 0 max 0 hard 0
server 9 acl 0 address 0.0.0.0 port 0 max 0 hard 0
no stubborn
timeout 5
tracking 0
no web_stats
no weight
no prio
pi@raspberrypi /tmp $ sudo ifconfig eth0:1 192.168.2.49 netmask 255.255.255.0
pi@raspberrypi /tmp $ sudo pen -S 10 -c 2049 -x 257 -F /tmp/kalle.cfg -C 127.0.0.1:10448 192.168.2.49:80
[/ccne]

And… It works! I now run my site 1200kcal.com on port 8080 load balanced on a Raspberry Pi. If you are lucky, it is still running (I don’t aim to run this config for very long).

Ask around for how much your fellow web admins paid for their web load balancing (a lot), and compare it to my 35 chf Raspberry Pi, with a 10 chf power supply. My load balancer maxes out quite easily, though. =)

 

Integrating a traffic light with OP5 through a Raspberry Pi



The last couple of months, I have been amazed about the Raspberry Pi. I won’t go into great detail on this wonderful device, other than the obvious.

  • It is cheap
  • It comes with Ethernet, HDMI
  • It runs Debian Linux
  • It has GPIO, general purpose input output, pins on the board

So, the device itself is just screaming for some interesting projects, interfacing with stuff that normally are not integrated with your IT stack. I’ve tried it out in a few different ways already, and I’ve bought a handful of devices. One of them has a fixed position, connected to my TV, running XBMC.

Well, let’s go back a few years in time. Quite many years, will say. Back to the days when I had just started growing a beard, and was just that naïve that only youngsters freshly out of high-school can be. I headed off to university and one of the first day of the introduction week we went to the student pub. There I saw one of the coolest things since the invention of sliced bread, a pedestrian crossing light.

Normally, such thing would not leave that much of an impression with me, but this one was special. Our own student pub was one of three student pubs in the same basement corridor. But there was only one WC. In principle, this was not a problem early in the evening, but as the night went on, the line to the WC was an annoyance. In our pub, the one with the crossing light, we were less stressed about it than people in the other pubs, since our crossing light was connected to the lock of the WC door. Whenever the lock was locked, our crossing light was red; hence when the door was unlocked it was green.

When we relocated the pub, we ended up in a location where the WC situation was much better. I had personally made sure that we brought the crossing light with us, but I could never come up with as good of a use for it. This was a long time ago, but the bright idea (pun intended) stuck with me over the years.

When I implemented Nagios/OP5 at my new workplace, I started playing with the thought that I wanted some way of raising the attention of the monitoring with my guys. The classical “big screen on the wall” was of course one of the first things that crossed our minds. This was easy, and people notice it – goal achieved. But I wanted something else, something more… catchy.

Just by a coincident, I got in contact with a guy who is responsible for replacing old bulb-based traffic lights with new LED-based traffic lights. He gave me a handful of 3-light (red, yellow, green) pedestrian crossing lights, and now I was able to get going with my latest project.

A Nagios/OP5 installation that shows service states on a traffic light.

Note that you are on your own when connecting the things together. If you are not completely sure of what you are doing, then don’t. I’ve been doing things like this for a while, so I trust myself. But I do not take any responsibility what so ever for any mistakes you do yourself. This project involves 220V, which can be lethal. Don’t blame me if things go bo-boo. End of disclaimer.

 

This is the conceptual view:

All in all, I’ve got a Nagios/OP5 installation in a virtual machine. In this example, one of my services is configured with an event handler, pointing to a command configured in checkcommands.cfg. I decided that the communication between my monitoring system and the Raspberry Pi would go over nrpe, which is anyways the standard Nagios Agent. Adding a couple of scripts on the server to take care of events, and the client side, to control the GPIO, was fairly simple.

Let us go through the whole chain on both hosts, the Nagios/OP5 system and the Raspberry Pi. I will start in a reverse order, as the Nagios configuration is simple and does not require much of explanation. Which service to chose for your traffic light is up to you. There are a couple of interesting constructs that come with OP5, that is not readily available out of the box in a Nagios installation. One of these is the “Business process view”, that allows you to perform logical operations on service states. You can also create new services from these aggregations. I will leave this part out of this blog entry, but the principle is so easy, that if you manage with the rest in this article, your should not have a hard time figuring that part out either.

In principle, I just chose one service and added an event_handler to it. That’s it. The event_handler is configured as any other command in the _checkcommands.cfg_ file. An event handler should take care of a couple of checks, so that you are sure that you really want to do something when the event hander is triggered, as it is triggered quite often. Basically, check the state (OK, WARNING, CRITICAL) and the state type (hard, soft) and make up your mind.

As mentioned before, I chose to use _check_nrpe_ to integrate Nagios with my Raspberry Pi, since it is readily available and very simple to configure. All I need to do, is to remotely run a script on the Raspberry Pi, which nrpe allows me to do after a very simple configuration. I just had to come up with a name for my remote command, add it to the nrpe configuration on the Raspberry Pi, restart nrpe, and start using check_nrpe on the Nagios/OP5 server.

On the Nagios/OP5 server, you need to get the following into your configuration files. When using OP5 there is a very simple web-gui to do this in. Othervise just fire up your favorite editor (which should be _vi_).

Here is the service in the Nagios/OP5 services.cfg for my dummy service to monitor and display on the traffic light. The magic is in the sauce, I mean event_handler:

[ccne]

# service ‘remote debug’
define service{
use default-service
host_name pi-s001
service_description remote debug
check_command check_nrpe!-H $HOSTADDRESS$ -c kmg_dummy
event_handler event_ampel
}

[/ccne]

This event handler is configured in the Nagios/OP5 configuration file checkcommands.cfg. Note the arguments I am sending to the script.

  • $SERVICESTATE$ – Nagios macro for the current state of the service
  • $SERVICESTATETYPE$ – Nagios macro for the current type (soft or hard) of the service
  • $HOSTNAME$ – Nagios macro for the service’s host
  • $SERVICEDESC$ – Nagios macro for the name of the service
  • $SERVICEATTEMPTS$ – Nagios macro for the number of attempts
[ccne]

# command ‘event_ampel’
define command{
command_name event_ampel
command_line $USER1$/kmg/event_ampel $SERVICESTATE$ $SERVICESTATETYPE$ $HOSTNAME$ $SERVICEDESC$ $SERVICEATTEMPT$
}
[/ccne]

The $SERVICEATTEMPTS$ macro together with the $SERVICESTATETYPE$ and the $SERVICESTATE$ gives you the possibility to actually try and fix a problem before Nagios/OP5 even has notified a sysadmin. In a default installation/config, Nagios will test a service so many times before it is a hard CRITICAL, which is notified to the outside world. If you write your event handler in such way, that it tests these parameters, i.e service state = CRITICAL, type = soft, service attempts = 3, then you can perform something like restarting a server, before waking up the sysadmin. My event handler is a bit simpler than that. I am just to trigger a relay, controlling a light bulb, so I skipped some of that. This is the event handler script:

[ccne lines=”-1″]

#!/usr/bin/ksh

state=$1
statetype=$2
serviceHost=$3
service=$4
serviceattempt=$5

raspberryPi=10.64.150.5

logfile=/opt/monitor/var/eventhandler.log

# Sep 25 14:53:14
date=`date +”%b %d %H:%M:%S”`

case “$state” in
OK)
command=kmg_ampel_green
;;
WARNING)
command=kmg_ampel_yellow
;;
CRITICAL)
command=kmg_ampel_red
;;
esac
/bin/echo -en “$date; restart_windows_service.sh; $serviceHost:$service; Got a $statetype $state at try $serviceattempt, sending $command to host $raspberryPi ” >> $logfile

/opt/plugins/check_nrpe -H $raspberryPi -c $command >> $logfile
echo “Set Ampel ok”
[/ccne]

If you by any chance had the Raspberry Pi setup and running already, you could test the event handler and the integration in two ways from the Nagios/OP5 host:

[ccne]
#— check that nrpe works (i.e allowed_hosts on the pi is set properly)
op5$ /opt/plugins/check_nrpe -H 10.64.150.5
#— check that the commands config on the pi works
op5$ /opt/plugins/check_nrpe -H 10.64.150.5 kmg_ampel_green
#— check that the whole stack works
op5$ ./event_ampel kmg_ampel_red
[/ccne]

So far, the Nagios configuration. We also need the relay control and the Raspberry Pi configuration. This is the hardware you need to complete this project:

  • One Raspberry Pi
  • 5V DC source (Micro USB charger)
  • 12V DC source (to drive the relays)
  • 3 x 5kOhm resistors
  • 3 x BC237C transistors
  • 3 x Relays, 12VDC activation/250AC switching
  • A few cables.
I used a 12V/DC power source to drive the relays, since I could not quickly find any 5V/DC relays. If you do find such relays, just connect the Raspberry Pi pin 2 (5V) to the driver, and you will save yourself a couple of bucks.
Install the Debian Squeeze on a SD card, enable SSH, and expand the root fs at the first boot. Then log into your box and install ksh and nagios-nrpe-server.

[ccne lines=”-1″]
sudo apt-get install ksh
sudo apt-get install nagios-nrpe-server
[/ccne]

That is basically it. You will survive without ksh, but since I am an old fart, I tend to stick to what I know from before. Ksh was there in the dawn of UNIX. In the good old days, it was the bread and butter of decent scripting. Nowadays you’ll manage with bash, and wont miss ksh a lot. More about that in a different blog post. If you don’t care for ksh, just change the references to it in my examples to bash.

Now we will configure the nrpe daemon correctly.

[ccne lines=”-1″]
pi@raspberrypi /etc/nagios $ grep allowed_hosts nrpe.cfg
allowed_hosts=127.0.0.1,192.168.2.34,194.40.128.84
pi@raspberrypi /etc/nagios $ cat nrpe.d/kmg_commands.cfg
command[kmg_ampel_red]=/app/prd/op5/bin/ampel red
command[kmg_ampel_yellow]=/app/prd/op5/bin/ampel yellow
command[kmg_ampel_green]=/app/prd/op5/bin/ampel green
command[kmg_ampel_blink]=/app/prd/op5/bin/ampel blink
command[kmg_ampel]=/app/prd/op5/bin/ampel blink
command[kmg_dummy]=/app/prd/op5/bin/dummy
pi@raspberrypi /etc/nagios $ sudo /etc/init.d/nagios-nrpe-server restart
[ ok ] Stopping nagios-nrpe: nagios-nrpe.
[ ok ] Starting nagios-nrpe: nagios-nrpe.
[/ccne]

With that taken care of, the integration between the Nagios/OP5 server and the Raspberry Pi is set up. The best way to test this is the commands in one of the examples above (check_nrpe -H 10.64.150.5). If that doesn’t work, kill the nrpe process on the Raspberry Pi with “kill” and start it again. That usually solves most problems.

Interfacing with the GPIO ports is extremely easy in the Debian/Raspbian squeeze. You just echo some commands to files in the /sys filesystem. Firstly you’ve got to enable some GPIO ports and set the direction. I’ve done this in a startup script, /etc/init.d/ampel, to which I also symbolically linked /etc/rc2.d/S99ampel so that it will automatically do this at reboot. Debian is a weird beast, though. Note that I put the startup script in rc2.d, which is the default runlevel for Debian, whereas I would have put this in rc3.d on an Ubuntu box.

Here is my /etc/init.d/ampel script:

[ccne lines=”-1″]
#!/usr/bin/ksh
# /etc/init.d/ampel
#

### BEGIN INIT INFO
# Provides: ampel
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Ampel
# Description: Ampel
### END INIT INFO
################################################################################

TS=$(date “+%Y%m%d %H:%M:%S”)
echo “$TS; $0 $1” >> /var/log/ampel.log

case $1 in
start)
echo “$TS; setup gpio” >> /var/log/ampel.log

echo “17” > /sys/class/gpio/export
echo “18” > /sys/class/gpio/export
echo “21” > /sys/class/gpio/export

echo “out” > /sys/class/gpio/gpio17/direction
echo “out” > /sys/class/gpio/gpio18/direction
echo “out” > /sys/class/gpio/gpio21/direction

#— to rid the sudo part – change the permissions

chmod 666 /sys/class/gpio/gpio17/value
chmod 666 /sys/class/gpio/gpio18/value
chmod 666 /sys/class/gpio/gpio21/value
;;
esac
[/ccne]

This makes sure that the GPIO pins are correctly set, which you can control in the file system by checking the /sys/class/gpio directory. Note that I am changing the file permissions for the “value” files. If you don’t do this, you must write to these files as root, which is easily done by using “sudo”. But since the Raspberry Pi isn’t a state of the art box when it comes to security anyways, I just decided that if you by any chance is logged in to the system, you should be able to set these values, never mind which user you are.
If you see “your” gpio pins there, you should be fine.

[ccne lines=”-1″]
pi@raspberrypi ~ $ ls -la /sys/class/gpio/
total 0
drwxr-xr-x 2 root root 0 Aug 16 16:58 .
drwxr-xr-x 26 root root 0 Aug 16 16:58 ..
–w——- 1 root root 4096 Aug 16 16:58 export
lrwxrwxrwx 1 root root 0 Aug 16 16:58 gpio17 -> ../../devices/virtual/gpio/gpio17
lrwxrwxrwx 1 root root 0 Aug 16 16:58 gpio18 -> ../../devices/virtual/gpio/gpio18
lrwxrwxrwx 1 root root 0 Aug 16 16:58 gpio21 -> ../../devices/virtual/gpio/gpio21
lrwxrwxrwx 1 root root 0 Aug 16 16:58 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
–w——- 1 root root 4096 Aug 16 16:58 unexport
[/ccne]

The nrpe configuration in /etc/nagios/nrpe.d/kmg_commands.cfg points out the /app/prd/op5/bin/ampel script, which is merely a wrapper, if there were anything clever to be done before actually switching the relays. In this example, I am not logging anything, and there is very little magic around it. It is usually wise to have such a wrapper between nrpe and whatever you want to perform on the system; for me it comes naturally to do it this way.

[ccne lines=”-1″]
#!/usr/bin/ksh

ampel_bin=/app/prd/ampel/bin
#ampel=”sudo $ampel_bin/setAmpel_a1″
ampel=”$ampel_bin/setAmpel_a1″

blink(){
$ampel all
sleep 0.2s
$ampel none
sleep 0.2s
$ampel all
sleep 0.2s
$ampel none
sleep 0.2s
}

red(){
blink
echo ” – Set ampel to: red”
$ampel red
}
yellow(){
blink
echo ” – Set ampel to: yellow”
$ampel yellow
}
green(){
blink
echo ” – Set ampel to: green”
$ampel green
}

echo “Ampel”
case $1 in
red)
red
;;
yellow)
yellow
;;
green)
green
;;
blink)
blink
;;
esac

exit 0
[/ccne]

In the end, this wrapper will execute the “$ampel” script, which is set to “/app/prd/ampel/bin/setAmpel_a1” with one parameter; red, yellow, green, or blink. This is the setAmpel_a1 script:

[ccne lines=”-1″]
#!/usr/bin/ksh

#—————————–
# Base configuration
#—————————–
this_dir=$(cd `dirname $0`; pwd)
base_dir=$(cd `dirname $0`/..;pwd)

. $base_dir/conf/gpio.conf

off=0
on=1

red(){
echo “$on” > /sys/class/gpio/gpio${a1red}/value
}

yellow(){
echo “$on” > /sys/class/gpio/gpio${a1yellow}/value

}

green(){
echo “$on” > /sys/class/gpio/gpio${a1green}/value
}

none(){
echo “$off” > /sys/class/gpio/gpio${a1red}/value
echo “$off” > /sys/class/gpio/gpio${a1yellow}/value
echo “$off” > /sys/class/gpio/gpio${a1green}/value
}

all(){
echo “$on” > /sys/class/gpio/gpio${a1red}/value
echo “$on” > /sys/class/gpio/gpio${a1yellow}/value
echo “$on” > /sys/class/gpio/gpio${a1green}/value
}

#================================
# MAIN
#================================
case $1 in
red)
none
red
;;
yellow)
none
yellow
;;
green)
none
green
;;
none)
none
;;
all)
all
;;
esac
[/ccne]

That’s all folks!