3 different methods to use scenes with Google Home & openHAB

It occurred to me that you could make the scene Rule generic using Design Pattern: Associated Items.

It is a little complex but I’ve implemented stuff like this before so know it will work:

  • create your proxy items as you have
  • also create a Group for each scene and add all the Items that are controlled by scene to that Group
  • create another Group to hold the Items that store the states for those controlled Items
  • put those Groups in a parent Group
  • all the Items and Groups are named such that we can generate their names based on another Items’ name, in this case the Groups are named such that we can generate their name from the Proxy Item and the scene value Items are named such that we can generate their name from the Proxy Item and the Item being controlled
// Put the Scene Groups in Scene_Items
Group Scenes_Items
// Put all the Items that hold the state for a scene in Scene_States
Group Scenes_States

Switch Evening // Proxy Item
Group Evening_Items (Scene_Items) // Group to hold the Items controlled in these scene

Switch Morning
Group Morning_Items (Scene_Items)

...

Switch LEDStrip_Group2_Power (Evening_Items,Morning_Items) ...
Switch Evening_LEDStrip_Group2_Power (Scene_States)
Switch Morning_LEDStrip_Group2_Power (Scene_States)
...

Color LEDStrip_Group2_Color (Evening_Items,Morning_Items)...
Color Evening_LEDStrip_Group2_Color (Scene_States)
Color Morning_LEDStrip_Group2_Color (Scene_States)

...
rule "Lighting Scene"
when
    Item Evening received command ON or
    Item Morning received command ON or
    ...
then
    // Get the Group if Items that are controlled during this scene
    val items = Scene_Items.members.findFirst[ grp | grp.name == triggeringItem.name+"_Items" ] as GroupItem

    // Loop through all the Items controlled by this scene
    items.members.forEach[ GenericItem i |

        // Get the state for this Item and Scene
        val sceneState = Scene_States.members.findFirst[ GenericItem st | st.name == triggeringItem.name+"_"+i.name ]

        // sendCommand the Scene state
        i.sendCommand(sceneState.state)
    ]
end

Everything is controlled by Group membership.

To add a scene:

  • add proxy Item
  • add trigger to the rule above
  • add a Group for the scene named the same as the proxy item with “_Items” appended to the name
  • add the Items controlled by the scene to the Group
  • add new Items named the same as the proxy item + “_” + Item name to hold the value that the device should be set to during this state and add these Items to Scene_States

To add/remove Items to an existing scene simply add/remove them from the Items Group.

You never have to touch the rules beyond adding the trigger (see below) which is nice and it saves having a lot of rules for each and every scene.

And once 2.3 is released (or for those on a recent snapshot) you can add all the scene proxy items to a Group and change the trigger to

Member of SceneProxies received command ON

and you won’t even have to add/remove the Rule trigger in when adding/removing a new scene.

On reflection, you could probably eliminate Scene_Items and just put everything into Scene_States but keeping the Groups separate from the new state Items makes the code a little clearer I think.

I just typed in the above, There is almost certainly some typos. Also, you will want to add some error checking and logging to use it in production.

Edit: It occurred to me after watching the video that you could also dynamicaly add/remove Items to a scene Group. There are ways to change group membership from within rules, but I don’t know how easy it is to persist the membership across OH restarts. You may need to store the names of the members of the Group to a String Item that is persisted and have a System started rule restore the membership settings. I’ll leave that as an exercise to the student. :slight_smile:

4 Likes

Wow, RIch - this is some PhD level rule-ology :smiley:

I was thinking about using your group design patter for this (I hadn’t converted all my scenes to method 3, yet). I’ll definitely try that and update the main post with the generic rule code, thanks!

1 Like

Main post updated (added Method 3.5) - with the generic rule implementation you suggested, @rlkoshak . It works well, I just made a few minor changes (kept “Scene_” in front of all the items, for easier persistence definition (all “Scene_” items can be persisted by one statement).

I thought about making the “Store” rule set also use a generic rule, but that’s when things got a bit too confusing (the only way I could think of doing it would be to use the same idea of grouped items, only reverse the Scene_States and Scene_Items groups in the rule code. But, all the extra groups would get confusing quickly. It’s not too bad to just have one explicit rule for each scene, to store the item states.

1 Like

I suspect you are misinterpreting the .persist file syntax. Scene_* means all members of the Scene_ group, not all Items that start with Scene_. Keeping the names with Scene_ in front will not help you with the .persist file.

The store side would be a lot more complicated for sure. I would do something like the following.

  • set the rule to process the voice command
  • parsed the command to determine the scene being saved
  • pull the same Scene_Items group you already have defined (e.g Evening_Items)
  • loop through the members of that Group
  • for each member use the Associated Items DP naming convention to grab the associated adjustment item and transfer the state to the scene item. Since everything has a unique name, you could do this all with just one Group.

I suspect you’re right - bah, I know you are :smiley:

I was thinking of the rrd4j persistence config where you just list the items with wildcards (e.g. Light*…). I didn’t realize (until I just read) that rrd4j isn’t useful for Color items - so I’m moving to the mapdb persistence, now…

On second thought - I may not be so wrong after all @rlkoshak - just switched to mapdb persistence, and used the following in my .persist file:

Items {
	* : strategy = everyChange, restoreOnStartup
	
	Light*,Scene*,LEDStrip* : strategy = everyMinute, restoreOnStartup

}

It appears to be working well, maintaining states for all lights, Scene_ storage items and now, also the color items.

It’s working because of the first line:

  • : strategy …

Which applies to all Items.

The second line does nothing because Scene* et Al means every member of the Scene group, not every Item whose name starts with Scene.

https://docs.openhab.org/configuration/persistence.html#items

<groupName>* - all members of this group will be persisted, but not the group itself.

The star is not a wild card in .persist files.

You know, Rich - if everyone (including me) just RTFM’d, this forum would be a very boring/empty place :slight_smile:

Of course you’re right - I need to go relook at my persistence strategies so I’m not persisting every item in my system…

Offtopic question, you wrote

how do you switch via voice? I for example use IFTTT and the REST web services to trigger the switch via voice. Is there a better way?

Stefan

That’s actually a very much on-topic question :slight_smile: - I’m using the Google Home action to activate the proxy switch by voice. It’s very easy to set up, you just need to tag the switch with a Lighting tag and connect Google Home to your myopenhab cloud(you can also watch my video link posted in the introduction of the post above) and it’s much quicker than ifttt.

thanks man! I didn’t know this was meanwhile available :wink: Do you know if it supports German language as well? Not sure if that even matters.

English, German, French and Japanese, with more languages coming soon :slight_smile:

:frowning:

even routines aren’t available out of the box in Google. We are always 6-12 months behind

Ah but routines are just one of the methods I listed above- you don’t need them! Just follow my how to video for the action (make a switch for the scene - for example “Night Scene” - and configure it with the “Lighting” tag,) Connect it to Google Home and follow “Method 2” or “Method 3” in this post, to make changes to all your lights when the switch is turned on by Google.

Routines are just a way to make multiple things happen from within Google, but they limit what you can do to each item…

understood. just wanted to whine about google not supporting German customers as fast as I wished :wink:

thank you Bartus, I have been able to implement the method 3 straight forward!
I have a question, it seems to me that every time I must reboot the openhab server, I have to restore from scratch the wanted scene since there is no persistence of the scene status.
Did you find any smart solution to workaround?
thank you

Great! I’m glad it worked for you :slight_smile:

To store the values between restarts, you’ll need to set up persistence. My preferred service is mapdb (because it can store color values, which the default service, rrd4j, cannot). See my post #9 above - I’m having no issues with scene item states restoring after startup BUT I am using the standard persistence strategy (i.e. I’m storing values for all my items in the system). I haven’t had issues with this, but if I find the time, I’ll probably put all my scene storage items in a single group, and persist that group between restarts.

Also, check out this great blog article on persistence in case you haven’t set one up already. It explains persistence topics very well!

1 Like

Quick update to method 3.5 above, to take advantage of the new “Member of” rule clause available since openHAB 2.3 - it makes the Set rule even more generic and allows easier addition of new scenes/routines!

1 Like

@bartus
Great guide! I implemented method 3.5 and it works fine.
Did you already looked further into rule development for generic rules for storing or item mapping? :grinning:

In my Google Home app new ‘Switchable’ things only appear after I disconnect my OpenHAB from Google Home and reconnect again. Is this a normal behavior or is it possible to refresh these items without the need of a reconnect?

@Chris_si - thanks! Glad it’s working for you )

I haven’t had time to look at the generic rules lately, but when I tried it last, it appeared to be a more complex effort than I was ready to tackle at the time…I’ve stuck with method 3.5 and adding new scenes is pretty easy still (just add the new group/scene items and a rule to handle them).

For adding new items to your Google Home, just say “Hey Google, Sync my devices!” and it will search your linked apps for any new items (this works for me just fine)…

2 Likes