Scenes in OpenHab – an astonishingly simple way to create scenes

Published by Oliver on

You are looking to create scenes in OpenHab and don’t know how? Well you are not the only one! While OpenHab is a pretty awesome home automation platform the concept of scenes is just not properly supported. Most solutions are overly complicated but here is a simply solution for simple scenes 🙂

What is a scene?

Scenes are a concept often used in home automation to solve a common problem. Once you control a whole lot of devices it becomes necessary sometimes to make sure all of them are in a certain state.

This is what scenes are used for – coordinate all devices to achieve on goal (like watching a movie)

Here is an example I actually use: I have a home cinema setup that I sometimes use to watch a movie. To do that I need to control several (smart) devices. The ceiling light needs to be turned off, the indirect lighting needs to be turned off, motion sensors need to be disabled (so it does not turn back on in the middle of the film) and the receiver needs to turn on (the projector and Blue Ray player are connected to it). I could do all of this manually but to save us from this repetitive work we can save this state in a scene and activate it with one click.

How to use scenes in OpenHab?

All of my devices are controlled by OpenHab so the scene management needs to happen there too. Unfortunately OpenHab does not directly support the concept, however there are a couple of ways around it.

A rather simple yet time consuming idea would be to create a switch item to trigger a custom rule. This rule can then move all device to their desired state. While this works it does not really scale very well. For each scene you need to create a new item AND a new rule.

Fortunately someone from the OpenHab forum came up with a better idea that I also adopted. We can use (otherwise mostly useless) scripts. We will just use one rule controlled by one item that can call any script.

String CallSceneItem ""

This simple String item can now be called from anywhere with the name of an arbitrary script that it will execute. To do that we need one rule (to rule them all ;)).

rule "Start a script for a scene"
when
    Item CallSceneItem received command
then
    logDebug("Rule", "Starting script " + CallSceneItem.state + ".script")
    callScript(CallSceneItem.state + ".script")
end

This rule is again quite simple. It take the received string and tries to call a script with that exact name.

My cinema example from earlier can quite easily be solved using this solution by adding a script for it.

MotionSensorsActivated.sendCommand(OFF)
grLight.sendCommand(OFF)
DenonPower.sendCommand(ON)

This will deactivate my motion sensors, turn off all lights in the room and turn on the Denon receiver. All of this is super simple, just a couple of lines of code. And the best part: each new scene is just another script file. No more items or rules needed.

How to call a scene?

Now that we have those scenes in OpenHab we need to use them. As described above we can just change the state of the one CallSceneItem to the name of a script file to activate the scene. This can for example be done from the basic UI.

Frame label="Scenes" {
        Switch item=CallSceneItem label="Scenes" mappings=["bed"="Reading", "kino"="Cinema", "sleep"="Sleeping"]
    }

This will display a couple of buttons that once pressed start the scene. Again, really simple, just one click and your smart home will do the rest for you!

UI to show and start my scenes in OpenHab
The (German) UI for my scenes

Those scenes in OpenHab could be started just as easily from another rule via some voice assistant or a smart switch.

Some more examples

Of course scenes heavily depend on what devices you are using in your smart home and what you are trying to do. Here are two more examples from my daily use.

Reading scene

The first rule is used for reading in the evening when I go to bed. It will turn off all light bulbs and other lights. Then it will activate the indirect light in my bedroom at just 25% brightness and turn on the reading light next to my bed. That’s it. It is just another script file.

grBulbs.sendCommand(OFF)
grDimmerK.sendCommand(OFF)
grDimmerWZ.sendCommand(25)
Sonoff2.sendCommand(ON)

Sleeping scene

My third script was a little more complex to implement. I wanted another scene which works similar to the one above but will also turn of all lights some time later. I can push that button and go to bed knowing that all lights will turn off automatically soon. The problem here is that I found no way of including timers in a script file, so I simply added this part directly in the rule.

rule "Start a script for a scene"
when
    Item CallSceneItem received command
then
    if (CallSceneItem.state == "sleep") {
        logDebug("Rule", "Starting sleep mode")
        grDimmerWZ.sendCommand(25)
        grBulbs.sendCommand(OFF)
        grDimmerK.sendCommand(OFF)
        Sonoff2.sendCommand(OFF)
        MotionSensorsActivated.sendCommand(OFF)
        createTimer(now.plusMinutes(1)) [| // change the time here if you need more
                grDimmerWZ.sendCommand(0)
                logDebug("Rule", "Switching off all lights, good night!")
            ]
        return // important if you do not want a script file to get called
    }

    logDebug("Rule", "Starting script " + CallSceneItem.state + ".script")
    callScript(CallSceneItem.state + ".script")
end

Of course this solution makes the rule file more complex but I can live with that. We could also move all the static commands to a script file and just leave the timer. The rule would look much cleaner then.

rule "Start a script for a scene"
when
    Item CallSceneItem received command
then
    if (CallSceneItem.state == "sleep") {
        createTimer(now.plusMinutes(1)) [|
                grDimmerWZ.sendCommand(0)
                logDebug("Rule", "Switching off all lights, good night!")
            ]
    }

    logDebug("Rule", "Starting script " + CallSceneItem.state + ".script")
    callScript(CallSceneItem.state + ".script")
end

The script would be another simple file.

grDimmerWZ.sendCommand(25)
grBulbs.sendCommand(OFF)
grDimmerK.sendCommand(OFF)
Sonoff2.sendCommand(OFF)
MotionSensorsActivated.sendCommand(OFF)

Overall I wish scenes in OpenHab had native support, but I think this solution is good enough for now. I never had any problems any creating a new scene just takes me a couple of seconds.