Thursday, 6 December 2018

Green Millhouse: OK Google, turn on the living room air conditioner

My Broadlink RM3 IR blaster has been working pretty well, so I thought I'd share how I've been using it with a couple of IR-controlled air conditioners in my house, to control them with the Google Home Assistant via OpenHAB.

The RM3 sits in a little niche that has line-of-sight to both these devices (a Daikin in the living room, and a Panasonic in the dining area). Using the RM-Bridge Android app, the fun2code website and the method I've documented over on the OpenHAB forums), I've learnt the ON and OFF codes for each device, and put them into broadlink.map:
PANASONIC_AIRCON_ON=D3ADB33F...

PANASONIC_AIRCON_OFF=13371337...

DAIKIN_AIRCON_ON=F00F00FAAFAA...

DAIKIN_AIRCON_OFF=F00D00FAAFAA...

The "basic" way of invoking the commands is by using a String Item for your IR-blaster device, and a Switch in your sitemap, like this:

items/remotecontrollable.items:
String RM3_MINI {channel="broadlink:rm3:34-ea-34-58-9d-5b:command"}

sitemaps/default.sitemap:
sitemap default label="My house" {
  Frame label="Aircon" {
    Switch
      item=RM3_MINI 
      label="Dining Area"
      mappings=[PANASONIC_AIRCON_ON="On", PANASONIC_AIRCON_OFF="Off"]
  }
  ...
}

Which gives you this:

... which is completely fine for basic UI control. But if you want the Google Home Assistant (aka "OK Google") to be able to operate it, it won't work. The reason for this is that the Switchable trait that you have to give the item can only take the simple values ON and OFF, not a string like PANASONIC_AIRCON_ON. So while it *might* work if you named your remote control commands ON and OFF, you're hosed if you want to add a second switchable device.
The best solution I could find was to set up a second Item, which is literally the most basic Switch you can have. You can also give it a label that makes it easier to remember and say when commanding your Google Home device. You then use a rule to make the new item's state shadow the "command" item's state. I'll demonstrate the difference by configuring the Living Room aircon in this Google-friendly way:

items/remotecontrollable.items:
String RM3_MINI {channel="broadlink:rm3:34-ea-34-58-9d-5b:command"}
Switch AC_LIVING_ONOFF "Living Room Air Conditioner" [ "Switchable" ] 

Notice the "label" in the Switch is the one that will be used for Google voice commands.

rules/remotecontrollable.rules:
rule "Translate Living Room ON/OFF to aircon state"
when
  Item AC_LIVING_ONOFF changed 
then 
  val isOn = (AC_LIVING_ONOFF.state.toString() == "ON")
  val daikinState = if(isOn) "DAIKIN_AIRCON_ON" else "DAIKIN_AIRCON_OFF"
  RM3_MINI.sendCommand(daikinState)
end

This rule keeps the controlling channel (RM3_MINI) in line with the human-input channel (the OpenHAB UI or the Google Home Assistant input). Finally the sitemap:

sitemaps/default.sitemap:
sitemap default label="My house" {
  Frame label="Aircon" {
    Switch item=AC_LIVING_ONOFF label="Living Room On/Off" 
  }
  ...
}

I quite like the fact that the gory detail of which command to send (the DAIKIN_AIRCON_ON stuff) is not exposed in the sitemap by doing it this way. You also get a nicer toggle switch as a result:



The final step is to ensure the AC_LIVING_ONOFF item is being exposed via the MyOpenHAB connector service, which in turn links to the Google Assistant integration. And now I can say "Hey Google, turn on the living room air conditioner" and within 5 seconds it's spinning up.