When my alarm clock goes off in the morning, the lamp on my bedside table also turns on, to help me wake up, and its color indicates outside temperature: from red for warm through yellow and green to blue and violet for “it’s freezing outside”.
Architecture
I built this mostly from off-the-shelf components, with a bit of custom script glue, based on an existing home automation infrastructure:
- my alarm clock is a Squeezebox Radio, formerly sold by Logitech, connected to the Logitech Media Server (LMS) running on a Linux VM on my home server
- a custom “daemon” script called
lms2mqtt
running on the same server connects to the LMS via Telnet, listens to notifications about status changes, such as “alarm went off”, and publishes those notifications as MQTT messages. This script is available on Github. - the openHAB home automation controller subscribes to those MQTT messages, and when it detects the “alarm has gone off” message, it triggers execution of a rule, i.e. a piece of code in the openHAB domain-specific language.
- that rule retrieves the current local temperature from OpenWeatherMap via the openHAB Weather binding, converts it to a color between red (warm) and violet (cold), and turns on the bedside lamp and sets it to that color.
- my bedside lamp is a custom build based on an Ikea Fado table lamp, where I replaced the dumb light bulb with a few RGB LED light strips controlled by a Wemos D1-Mini ESP8266 board, flashed with the open source Tasmota firmware. I could also have used an off-the-shelf “smart” light bulb, or just a “smart” table lamp.
openHAB configuration
I am still using openHAB 2.5, and even some openHAB 1 bindings, so chances are you would have to make some changes to run this under the latest openHAB 3.x.
Services
My bindings configuration file /etc/openhab2/services/addons.cfg
looks like this
binding = mqtt1,expire1,openweathermap
Things
The Weather binding is configured in /etc/openhab2/things/weather.things
:
Bridge openweathermap:weather-api:api [apikey="get-your-own-api-key", refreshInterval=15, language="de"] { Thing weather-and-forecast local [location="52.37052,9.73322", forecastHours=0] }
You need to sign up with OpenWeatherMap to get your own (free) API key, and you obviously need to adjust this for the latitude & longitude of your location.
Items
In /etc/openhab2/items/weather.items
I define an openHAB “item” for current outside temperature
Number localCurrentTemperature "Outside [%.1f°C]" <temperature> { channel="openweathermap:weather-and-forecast:api:local:current#temperature" }
In /etc/openhab2/items/local.items
I define several additional openHAB “items” used to control the whole thing. There are items linked to the MQTT messages published by my daemon script (see below). You need to change this to the MAC address of your Squeezebox, if you want to build this for your home.
//----- lms2mqtt daemon String SqRadio_Alarm_sound "alarm sound [%s]" {mqtt="<[mosquitto:lms/00\\:04\\:20\\:26\\:71\\:b8/alarm/sound:state:default]"} String SqRadio_Alarm_end "alarm end [%s]" {mqtt="<[mosquitto:lms/00\\:04\\:20\\:26\\:71\\:b8/alarm/end:state:default]"} Switch SqRadio_Alarm
The mood light running Tasmota firmware is named wemos-B and controlled via MQTT. I always use separate items for 1. controlling the physical light, 2. reading the status of the physical light, and 3. a “proxy” item that ties it all together, and can be controlled multiple ways, e.g. from a UI. This is described in more detail in a separate post.
Switch Moodlight_Proxy "Mood" (gSwP) Switch Moodlight_Cmnd (gSwC) {mqtt=">[mosquitto:cmnd/wemos-B/power:command:*:default]"} Switch Moodlight_Stat (gSwS,gSwA) {mqtt="<[mosquitto:stat/wemos-B/POWER:state:default]"} Switch Moodlight_Expire (gSwX) {expire="15m,command=OFF" } Color Moodlight_Color "wemos-B Color" {mqtt=">[mosquitto:cmnd/wemos-B/HSBCOLOR:command:*:default], <[mosquitto:stat/wemos-B/RESULT:state:JSONPATH($.HSBColor):.HSBColor.]" }
Rules
The specific rules for the weather-alarm-mood-light are in /etc/openhab2/rules/squeezebox.rules
:
rule "SqRadio alarm on" when Item SqRadio_Alarm_sound received update then SqRadio_Alarm.sendCommand(ON) end rule "SqRadio alarm off" when Item SqRadio_Alarm_end received update then SqRadio_Alarm.sendCommand(OFF) Moodlight_Proxy.sendCommand(OFF) end rule "moodlight with alarm" when Item SqRadio_Alarm changed to ON then val ht = (localCurrentTemperature.state as DecimalType).intValue var Number hue; if (ht < -5) { hue=300 } // magenta else if (ht < 0) { hue=240 } // blue else if (ht < 5) { hue=180 } // cyan else if (ht < 10) { hue=120 } // green else if (ht < 15) { hue= 60 } // yellow else if (ht < 20) { hue= 45 } // orange else { hue= 0 } // redvar hsb = new HSBType(
new DecimalType(hue.intValue),
new PercentType(50),
new PercentType(95)
)
Moodlight_Color.sendCommand(hsb.toString)
Moodlight_Proxy.sendCommand(ON)
Moodlight_Expire.sendCommand(ON) end