openHAB 4 scenes: Indication if a scene is active?

Just migrated one docker container to 4.0.0 M4. Very nice.

Do the new “no-code” scenes include a functionality to indicate if a scene is active? I didn’t find anything in this documentation Rules - Scenes | openHAB

Thanks for your help.

Simon

No, scenes are stateless! It is a fire and forget.

Thanks Hans-Jörg for your feedback.

Do you know if there’s already something available that would implement a state (template, marketplace, …)?

No, as said, scenes are stateless and this is not going to be changed. Reason for that is quite simple. Think of turning on several lights within a scene. If one of the lights is switched of, the scene is no longer valid.
Only thing you can do, create an item triggering the scene and get that state as indication. But as said, changing one of the items included in the scene gives a setting, not reflecting the scene but your trigger item will still be on.

I try to replicate the functionality of the home app on Apple products (HomeKit). The scenes there indicate if they are active. They actually have a kind of hysteresis implemented (e.g. if the scene includes only one light ON with 80% brightness, the scene is indicated as active if the light is ON with 78%).

I see two options, both requring a proxy item (as previously suggested). Obviously, you can update the proxy item to ON when the scene rule runs, so the question is how to turn it off.

The simple approach is to trigger a second rule on any of the items changing. When that happens, update the proxy item to OFF without bothering to check the states of other items in the scene.

The more complex approach is to trigger the rule on any items changing, but also check the states of all of the items in the scene. If the conditions are met, update the proxy item to ON. Otherwise, set it to OFF.

The advantage of the latter approach is that you can identify when the scene is turned on by coincidence. So if 3 of 4 lights are already on and you turn on the 4th, openHAB would know that the scene is active. If this doesn’t matter to you, then there’s no need to check conditions.

1 Like

I want to implement the second approach. Just checking if anybody did this already. I envision to have just one rule that checks all the scenes and updates the proxies accordingly via naming convention, e. g. “scene_movie_night” will always require a proxy item “proxy_movie_night”. The rule would then have to be able to enumerate the scenes and items in each scene (not sure if this is possible) and update the proxies accordingly.

This looks relevant: UI Scene Widget and Control System
But it is for OH3, doesn’t make use of OH4 scenes and is probably more sophisticated than what I wanted.

It’s possible. It’s just going to be a lot of work to identify/map all of the conditions and maintain it when you make changes. Otherwise, it’s just a rule with a lot of triggers and a lot of conditions.

I’d question if you need to have a proxy item for each individual scene. In many cases, your scenes will be mutually exclusive, in which case a single string item will serve you better.

You might also find that it’s easier to maintain if you use one rule per scene.

I think it is not a lot of work. Here is my first draft, but I’ve only tested it with one simple scene so far that controls five heaters. I consider this a proof of concept.

The rule will run every five seconds, loop over all the scenes that have the tag “with proxy”, determine if the conditions of the scene are fulfilled or not and toggle the corresponding proxy item (by naming convention) ON or OFF:

configuration: {}
triggers:
  - id: "2"
    configuration:
      cronExpression: 0/5 * * * * ? *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - inputs: {}
    id: "1"
    configuration:
      type: application/javascript
      script: >
        var { rules } = require('@runtime');


        (function() {
          const logger = log('sceneProxyUpdater');
          const proxyPrefix = "sceneproxy_";
          
          const scenes = rules.getByTag("with proxy");

          scenes.forEach(scene => {
            let isActive = "ON";
            logger.debug("* scene UID: " +scene.UID);
            scene.actions.forEach(action => {
              const itemName = action.configuration.get("itemName");
              const command = action.configuration.get("command");
              const itemState = items.getItem(itemName).state.toString();
              const isSceneState = command === itemState;
              logger.debug("** item command, current state: "+ itemName + ":" + command + ":" + itemState + ":" + 
                          isSceneState);
              if (!isSceneState) {
                isActive = "OFF";
              }
            });
            const proxyItem = items.getItem(proxyPrefix + scene.UID);
            logger.debug("** proxy item, current/new state: " + proxyItem.name + ":" + proxyItem.state + ":" + isActive);
            if (proxyItem) {
              proxyItem.sendCommandIfDifferent(isActive);    
          }
          });
        })()
    type: script.ScriptAction

I’d like to get rid of the @runtime import, but I haven’t found how to iterate rules with openhab-js yet.

In the overview page of the Main UI I defined a simple cell:

component: oh-cell
config:
  header: Home
  color: blue
  on: =@"sceneproxy_sceneTargetModeOff" == "ON"
  title: Switch heating off
  footer: Tap to switch off
  icon: heating-off
  action: rule
  actionRule: sceneTargetModeOff
  actionFeedback: Scene activated

When I tap on the cell, the scene is activated and latest five seconds later the cell is highlighted. If I turn on or off the heating individually the cell highlight will be updated accordingly.

I haven’t tried this for scenes involving number items (such as brightness), yet. For the rule, the mentioned hysteresis (or tolerance) could be implemented, e. g. for dimmer items +/- 5.

Adding the same for the opposite scene (switch all heating on) was a matter of two minutes:

  • create the proxy item sceneproxy_sceneTargetModeHeat
  • add the with proxy tag to the scene
  • create the cell
    component: oh-cell
    config:
      header: Home
      color: red
      on: =@"sceneproxy_sceneTargetModeHeat" == "ON"
      title: Switch heating on
      footer: Tap to switch on
      icon: heating
      action: rule
      actionRule: sceneTargetModeHeat
      actionFeedback: Scene activated
    

Result:

(obviously UI is not my strong side, I’m sure this could be made nicer)

The same setup works with a scene with two lights (one Hue, one Tradfri), including brightness and color temperature (Kelvin). If I activate the same values via the Hue remote the scene proxy is set to ON after a few seconds. Still, I’d rather add some tolerance, for color temp I’d assume +/- 50K.

Good stuff. Glad you got it working.

Have a look at this

1 Like