OpenHAB is a great platform!!!
Unfortunately, does require a bit of tinkering if you want it to do slightly more than your regular stuff…
I personally have struggled quite a bit with my Harmony Hub systems. Not necessarily getting it to identify the Hubs in OpenHAB, this part has actually been greatly improved and is quite seamless, however, when I wanted to get it to work with my Apple Homekit, that’s where it became more complicated.
The biggest pain in the @$$ is making sure it communicates in both directions. Meaning whether you initiated starting your TV from Homekit or from the Harmony remote/app, it will reflect back in the Apple Home app.
Now, unlike OH, that fully supports a dropdown list to choose which activity you want to start from the available ones, Homekit is unablke to do so… hence the only (current) solution is to have each activity show up as its own Switch. So in my example I will show using two activities that I have “TV” and “Movies”.
My Setup:
- I have OH installed on a Raspberry Pi 3 with the latest Openhabian (at the time of writing this tutorial, 1.4.1).
- I have 2 Harmony Hubs. 1 in the Living room and one in the Master bedroom (I want to control both).
** Both Hubs have an STB for regular TV channel viewing and an Amazon Fire TV with Kodi on it for streaming. - I am using Apple Homekit for all my smart home devices and wanted to control my entertainment as well with it.
** Apple homekit has some difficulties getting voice commands for certain items. Therefore, to make it easy for me to simply say “Hey Siri, turn on …” I changed the Activity names in the Logitech Harmony app before starting the OH configuration.
I definitely recommend having the control setup fully configured within the Harmony. It will make your life a lot easier by just interacting with the Activities and letting Harmony take care of the rest.
I renamed the default “Watch TV” activity to simply “TV”. Also renamed the “Fire TV” activity to “Movies”. And since I have two hubs, one in the Living room and one in the Master bedroom, once I located the correct Homekit switches I created with OH, I am now able to simply say “Hey Siri, turn on Living room TV” or “Hey Siri, turn on Master bedroom Movies”.
Assumption: I am assuming that you have already installed the Homekit integration for OH (‘Paper UI -> Add-ons -> Misc -> HomeKit Integration’) and added OH as a bridge manually to your Apple Home app. If not, please refer to: https://docs.openhab.org/addons/ios/homekit/readme.html
So, once I had my Harmony side updated I set up OH.
First, add the OH Harmony binding in ‘Paper UI -> Add-ons -> Bindings -> Harmony Hub Binding’. Once installed, Go to your ‘Paper UI -> Inbox’ to scan for your hubs. OH does a very nice job identifying all your home hubs (within the same network) along with all configured devices (your TVs, STBs, Receivers…).
On the identified list, I only added the Harmony Hubs (clicking the check mark for the Hub things) to my managed OH Things, again, because I am letting Harmony take care of the ON and OFF automation. Now I have my Hubs under ‘Paper UI -> Configuration -> Things’:
As you can see, I also renamed the Hub names in advance in the Harmony setup app. Just to it simple to differentiate between the two.
Clicking on one of them will also show you the supported triggers for each one (ignore the Current Activity with a different color, this is because I have it set up already):
Please note the full Identifier name for Current Activity! We will need this when we define it in the items section.
From here moving on we will configure the files manually through SSH. These files are located under ‘/etc/openhab2/’. There is a folder for each file we will need: items, rules. If this is your first time setting these up I definitely recommend going through the OH beginners guide.
My items file:
// Logitech Harmony Hub - Living Room
Switch LivingRoom_TV "TV" [ "Switchable" ]
Switch LivingRoom_Movies "Movies" [ "Switchable" ]
String LivingRoomHub "Current Activity [%s]" { channel="harmonyhub:hub:LivingRoom:currentActivity" }
// Logitech Harmony Hub - Master Bedroom
Switch MasterBedroom_TV "TV" [ "Switchable" ]
Switch MasterBedroom_Movies "Movies" [ "Switchable" ]
String MasterBedroomHub "Current Activity [%s]" { channel="harmonyhub:hub:MasterBedroom:currentActivity" }
I have two Harmony hubs as mentioned. The first two items for each are simply the switches that are then exposed to Homekit.
-
Switch
:Designates this item to be a Switch item (ON/OFF) -
LivingRoom_TV
:The OH name for the item. Can be whatever you want it to be -
"TV"
:The name of the switch as it will show up in Homekit and OH -
[ "Switchable" ]
:Exposes this item to Homekit
The third item on each creates a linked item between on OH item and the current running activity on the Harmony Hub. This is not exposed to Homekit, as I mentioned previously it does not support it. We do need this item later as we create rules in OH to identify the status of the Hub to match the switches.
-
String
:Designates this item to be of String type (as it has the activity names as strings) -
LivingRoomHub
:The OH name for the item. Can be whatever you want it to be -
"Current Activity [%s]"
:Used to report and update the current activity of the OH item -
{ channel="harmonyhub:hub:LivingRoom:currentActivity" }
:Connects the OH item to the correct channel (refer to my previous comment regarding the Current Activity property identifier)
Now that we have our items properly configured, we can move to setting up the rules. Here is my rules file:
rule "Starting Values"
when
System started
then
if ( LivingRoom_TV.state == NULL ) { postUpdate(LivingRoom_TV,OFF) }
if ( LivingRoom_Movies.state == NULL ) { postUpdate(LivingRoom_Movies,OFF) }
if ( MasterBedroom_TV.state == NULL ) { postUpdate(MasterBedroom_TV,OFF) }
if ( MasterBedroom_Movies.state == NULL ) { postUpdate(MasterBedroom_Movies,OFF) }
end
rule "Catch Living Room Hub State for HomeKit"
when
Item LivingRoomHub changed
then
switch (LivingRoomHub.state) {
case "PowerOff" : {
postUpdate(LivingRoom_TV,OFF)
postUpdate(LivingRoom_Movies,OFF)
}
case "Movies" : {
postUpdate(LivingRoom_TV,OFF)
postUpdate(LivingRoom_Movies,ON)
}
case "TV" : {
postUpdate(LivingRoom_TV,ON)
postUpdate(LivingRoom_Movies,OFF)
}
}
end
rule "Catch Master Bedroom Hub State for HomeKit"
when
Item MasterBedroomHub changed
then
switch (MasterBedroomHub.state) {
case "PowerOff" : {
postUpdate(MasterBedroom_TV,OFF)
postUpdate(MasterBedroom_Movies,OFF)
}
case "Movies" : {
postUpdate(MasterBedroom_TV,OFF)
postUpdate(MasterBedroom_Movies,ON)
}
case "TV" : {
postUpdate(MasterBedroom_TV,ON)
postUpdate(MasterBedroom_Movies,OFF)
}
}
end
rule "Living Room TV Start"
when
Item LivingRoom_TV changed from OFF to ON
then
if (LivingRoomHub.state != "TV")
{
LivingRoomHub.sendCommand("TV")
}
postUpdate(LivingRoom_Movies,OFF)
end
rule "Living Room Movies Start"
when
Item LivingRoom_Movies changed from OFF to ON
then
if (LivingRoomHub.state != "Movies")
{
LivingRoomHub.sendCommand("Movies")
}
postUpdate(LivingRoom_TV,OFF)
end
rule "Master Bedroom TV Start"
when
Item MasterBedroom_TV changed from OFF to ON
then
if (MasterBedroomHub.state != "TV")
{
MasterBedroomHub.sendCommand("TV")
}
postUpdate(MasterBedroom_Movies,OFF)
end
rule "Master Bedroom Movies Start"
when
Item MasterBedroom_Movies changed from OFF to ON
then
if (MasterBedroomHub.state != "Movies")
{
MasterBedroomHub.sendCommand("Movies")
}
postUpdate(MasterBedroom_TV,OFF)
end
rule "When all Living Room devices are off"
when
Item LivingRoom_TV changed from ON to OFF or
Item LivingRoom_Movies changed from ON to OFF
then
Thread::sleep(250)
if (LivingRoomHub.state != "PowerOff")
{
if (LivingRoomHub.state == "TV" && LivingRoom_TV.state == OFF) {
LivingRoomHub.sendCommand("PowerOff")
}
if (LivingRoomHub.state == "Movies" && LivingRoom_Movies.state == OFF) {
LivingRoomHub.sendCommand("PowerOff")
}
}
end
rule "When all MasterBedroom devices are off"
when
Item MasterBedroom_TV changed from ON to OFF or
Item MasterBedroom_Movies changed from ON to OFF
then
Thread::sleep(250)
if (MasterBedroomHub.state != "PowerOff")
{
if (MasterBedroomHub.state == "TV" && MasterBedroom_TV.state == OFF) {
MasterBedroomHub.sendCommand("PowerOff")
}
if (MasterBedroomHub.state == "Movies" && MasterBedroom_Movies.state == OFF) {
MasterBedroomHub.sendCommand("PowerOff")
}
}
end
Now I’ll try to simplify it as much as I can.
First section just set the initial values of the switches to OFF if they are not set already when the system boots up for both switches on both hubs.
The rest is divided between Living room rules and Master bedroom rules, but they are the same. You can obviously play with these rules by removing a hub if you only have one and/or adding additional activities if you have more.
The rule “Catch Living Room Hub State for HomeKit” looks for changes happening on the Hub itself and then uses these changes to reflect back on the OH switches, which then reflect these changes in HomeKit…
Note that I am using the postUpdate
and not sendCommand
option since I just need the switches to reflect this update and not actually to have the switch make a change on the hub.
The subsequent rules for start and activity using the switches monitor for each specific switch if it changed from OFF to ON, meaning it was either pressed in the OH web and/or app UI (exposing the item in a sitemap) or pressed ON using the Apple Home app (because we used the [ "Switchable" ]
option with the items). The rule then checks if the relevant hub is potentially already running this activity. If not, it will tell the hub using sendCommand
to switch to that activity. It will also update the other switch to reflect the fact that it is no longer running that activity using the postUpdate
command.
For example; You have your Harmony Hub currently on ‘TV’. So, currently you have the ‘TV’ switch on ON and your ‘Movies’ switch on OFF. Flipping the ‘Movies’ switch to ON will do two things:
- Send a command to the Harmony Hub to tell it to switch the the Movies activity.
- Will update the OH/Apple Home TV switch to reflect an OFF state.
Last but not least, switching to OFF using the OH/Apple Home switches.
Since up till now we made sure that if you have two activities (can obviously be more) and you flipped one ON, Our rules will flip the other switches OFF, if you actually flip the only remaining activity the is ON to OFF it means that you want to power off your entertainment system. The last rules refer to all devices off.
First, I check if any of the corresponding switches for that hub have changed from ON to OFF. If so, after a short delay I validate if the current Hub state is powered off. If not, for each switch I validate if that hub is running the specific activity that its OH item if currently switched to OFF. If that is the case then it issues the PowerOFF command to the Hub.
I did not include a description about exposing the items in OH as well, as I am using OH in this specific case as a HomeKit bridge, therefore I have no need to expose them in the sitemap. However, for those who want that as well, there is a very good sitemap example at the bottom of the binding help page: https://docs.openhab.org/addons/bindings/harmonyhub/readme.html
This is it!!! I truly hope this helps anyone else struggling to get this working (I know I did…).
Good luck!