Allow Zabbix monitoring to switch office lights

 · Systeemkabouter

As my wife is not a big fan of the colored Hue light bulbs, I removed a couple of them from the living room. One of the bulbs is now delivering pink, blue or red light in the bedroom of our youngest. The other bulb was moved to my home office. And thus the need for monitoring integration was born. This is nowhere near a new idea, but I have never taken the time to set something like this up. So it seemed a nice X-mas downtime project.

I had already experimented with the python Phue library to control the lights in our home. And I created a custom Zabbix -> signal integration in the past. So it should be fairly easy to combine the two in something nice.

The setup is as follows:

[zabbix host] -> [VPN] -> [raspberri pi at home] -> [Hue controller]

I thought about creating an API on the PI, but thinking about it, just using a password less ssh setup seemed just as good. So that is what I ended op doing.

The script controlling the light just does a number of loops, switching the light briefly to red and white. There is also a testversion of this script that I run from cron to check the system still works. This script changes the light from blue to green and back a couple of times.

Hue script:

#!/usr/bin/python3

from phue import Bridge
import time

def rgb_to_xy(red, green, blue):
    """ conversion of RGB colors to CIE1931 XY colors
    Formulas implemented from: https://gist.github.com/popcorn245/30afa0f98eea1c2fd34d
    Args:
        red (float): a number between 0.0 and 1.0 representing red in the RGB space
        green (float): a number between 0.0 and 1.0 representing green in the RGB space
        blue (float): a number between 0.0 and 1.0 representing blue in the RGB space
    Returns:
        xy (list): x and y
    """

    # gamma correction
    red = pow((red + 0.055) / (1.0 + 0.055), 2.4) if red > 0.04045 else (red / 12.92)
    green = pow((green + 0.055) / (1.0 + 0.055), 2.4) if green > 0.04045 else (green / 12.92)
    blue =  pow((blue + 0.055) / (1.0 + 0.055), 2.4) if blue > 0.04045 else (blue / 12.92)

    # convert rgb to xyz
    x = red * 0.649926 + green * 0.103455 + blue * 0.197109
    y = red * 0.234327 + green * 0.743075 + blue * 0.022598
    z = green * 0.053077 + blue * 1.035763

    # convert xyz to xy
    x = x / (x + y + z)
    y = y / (x + y + z)

    # TODO check color gamut if known

    return [x, y]

b = Bridge('192.168.XX.YY')

# If the app is not registered and the button is not pressed, press the button and call connect() (this only needs to be run a single time
b.connect()

green = rgb_to_xy(0.0, 1.0, 0.0)
red = rgb_to_xy(1.0, 0.0, 0.0)
white = rgb_to_xy(1.0,1.0,1.0)
blue = rgb_to_xy(0.0,0.0,1.0)
yellow = rgb_to_xy(1.0,1.0,0.0)

# 5 is the identifier of my office light
b.set_light(5, 'on', True)

counter=0

while counter < 15:

  counter +=1
  b.set_light(5, 'xy', red)
  time.sleep(1.5)
  b.set_light(5, 'xy', white)
  time.sleep(1.5)

The zabbix alertscript is like really trivial. Passing the alert text as morse code seemed over the top.

root@monitor:/usr/lib/zabbix/alertscripts# more set_office_alert.sh
#!/bin/bash

ssh 10.20.XX.YY /home/zabbix/bin/office_alert.py

Testing the alertscript from zabbix resulted in this:

Now we wait for a critical alert to actually trigger this :-).