Demo OpenHAB Google Home automation app

This is a sample of how one could control OpenHAB via Google Home voice commands.

For official implementation please see here. This implementation relies on OpenHAB metadata which in my opinion is more flexible. It is inspired by Alexa Smart Home Skill

This only works as a self hosted solution. For deployment instructions please read here

Sample configuration


// Complex Washing machine. Group acts as an umbrella and each group item has separate traits and allows you to control multiple options by having just single device on Google Home
Group Washer       "Washer"               {google="action.devices.types.WASHER"}
String Washer_Cycle       "Cycle" (Washer) {google="action.devices.traits.Modes" [ mode="Cycle=cycle", modeSettings="Low=low,Medium=medium,High=high", modeCommandMap="Low=1,Medium=1,High=2", lang="en", ordered=false ]}
String Washer_Temperature "Temperature" (Washer) {google="action.devices.traits.Modes" [ mode="temperature=temperature", modeSettings="Tap Cold=tap cold,Cold Warm=cold warm,Hot=hot,Extra Hot=extra hot", modeCommandMap="Tap Cold=30,Cold Warm=40,Hot=60,Extra Hot=90", lang="en", ordered=true ]}
Switch Washer_Power       "Power"       (Washer) {google="action.devices.traits.OnOff"}

// All items are the same in group, and all are of type `Switch`
Switch Light_Outdoor_All "All Outdoor Lights" {google="action.devices.types.SWITCH" [groupType="Switch"]}

// Lock/Unlock with custom commands
String Door  "Door" {google="action.devices.types.DOOR" [trait="action.devices.traits.LockUnlock", lockCommand="LOCK", unlockCommand="UNLOCK"]} 

// control fan speed by saying `set Blower speed to default`
String Blower "Blower" { synonyms="Ventilation", google="action.devices.types.FAN" [lang="en", speeds="ventilation_level_0=away:zero,ventilation_level_1=default:standard:one,ventilation_level_2=high:two,ventilation_level_3=max:turbo:three", ordered="true"] }

// Simple lamp on off
Switch Lamp  "Main Lamp"    {google="action.devices.types.SWITCH"}

// Lamp with brightness controll
Dimmer BathroomLight  "Bathroom Lamp"    {google="action.devices.types.LIGHT"}

//Player - play, pause, resume, next, previous
Player Spotify_Squeezebox_Player "Squeezebox"  { google="action.devices.types.REMOTECONTROL"}

Supported Devices

Devices allow you to have icons and certain synonyms in your google Home. Each device has a default trait (read: action) assigned, but you can easily mix and match and change them.

Device Default Trait
action.devices.types.VACUUM action.devices.traits.StartStop
action.devices.types.GATE action.devices.traits.OpenClose
aaction.devices.types.SWITCH action.devices.traits.OnOff
action.devices.types.GARAGE action.devices.traits.OpenClose
action.devices.types.DOOR action.devices.traits.OpenClose
action.devices.types.LOCK action.devices.traits.LockUnlock
action.devices.types.FAN action.devices.traits.FanSpeed
action.devices.types.WASHER action.devices.traits.OnOff
action.devices.types.BLINDS action.devices.traits.OpenClose
action.devices.types.LIGHT action.devices.traits.OnOff, action.devices.traits.Brightness
action.devices.types.SPEAKER[1] action.devices.traits.Volume[1]
action.devices.types.SOUNDBAR[1] action.devices.traits.Volume[1]
action.devices.types.TV[1] action.devices.traits.OnOff
action.devices.types.REMOTECONTROL[1] action.devices.traits.MediaState[1]
action.devices.types.SECURITYSYSTEM action.devices.traits.ArmDisarm
action.devices.types.SCENE action.devices.traits.Scene

[1] - not officially supported by google yet. Can break at any time

Global configuration options

roomHint

Allows you to assign device to a room instead of doing so via Google Home App. This is just a hint, and can be overriden in Google Home App.

// put Home Cinema in living room
Group HomeCinema           "Home Cinema"                        { google="action.devices.types.TV" [roomHint="Living room"]}

synonyms

Comma separated list of additional nams that you can use to control devices

// so now you can say Gate, Gates, Main Gate
Switch Gate  "Gate"  { google="action.devices.types.GATE", synonyms="Gates,Main Gate" },

Two Factor authentication

Allows you to add two factor authentication (TFA) to your items. For now this is somewhat limited for simplicity:

  • if dealing with a Group, you can only have TFA defined on the Group level. No support for TFA based on action
  • if on TFA is always required for a device, no matter if you are turning it on or of, arming or disarming

TFA comes in two flavours: pin and ack

Pin mode

Means that you will be prompted for a pin to do an action. You have to define tfaPin property in Google metada section

// Google will ask you for your pin (4567) when arming or disarming Main Security
Switch MainSecurity "Main Security" { google="action.devices.types.SECURITYSYSTEM" [tfaPin="4567"] }

ack mode

Means that you will aknwoledge an action. You have to define tfaAck property in Google metada section

// Google will ask you for are you sure you want to arm/disarm Main Security
Switch MainSecurity "Main Security" { google="action.devices.types.SECURITYSYSTEM" [tfaAck="true"] }

Supported Traits

Traits are things that actually make a device work. Each of them allows you to say things like Unlock main door or Set Bedroom fan speed to low

Each trait maps onto one or more openhab item type.

Each device must have at least one trait, but you can add more than one, if Openhab item that handles this trait does support it

Trait Sample command
action.devices.traits.OpenClose Open the garage door
action.devices.traits.OnOff Turn on the bedroom light
action.devices.traits.LockUnlock Lock the front door
action.devices.traits.FanSpeed Set the fan to low
action.devices.traits.Modes Set the dryer to permanent press.
action.devices.traits.Toggles Turn on sterilization for the dryer.
action.devices.traits.StartStop Stop the washer
action.devices.traits.Brightness Set light brightness to 55%
action.devices.traits.Volume[1] Set player volume to 55%
action.devices.traits.MediaState[1] Pause player
[action.devices.traits.ArmDisarm](https://developers.google.com/actions/smarthome/traits/armdisarm Arm Security System

[1] - not officially supported by google yet. Can break at any time



Trait action.devices.traits.OpenClose

Examples

// device GATE defaults to OpenClose trait
Switch Gate  "Gate"         {google="action.devices.types.GATE"} 
 
// Use OpenClase with SWITCH device instead of OnOff
Switch Lamp  "Main Lamp"    {google="action.devices.types.SWITCH" [trait="action.devices.traits.OpenClose"]}

// Inverted blinds. So "open to 30 percent" will actually send 70 percent to Openhab. And Open will send DOWN
Rollershutter Blinds  "Blinds"    {google="action.devices.types.BLINDS" [inverted=true]} 

// Custom direction mapping. Only supported on String type
String Blinds  "Blinds"    {google="action.devices.types.BLINDS" [directionMap=UP=UP_100,DOWN=DOWN_100]} 

Supported configuration options

  • inverted=[true] - Inverts percentage and command Open will send Off, 30 percent will send 70 percent, etc.
Supported Openhab item notes
Rollershutter Will send percentage. If percentage is zero will send DOWN, if 100 then UP (unless inverted)
String Will send percentage as is (unless inverted)
Dimmer Will send percentage. If percentage is zero will send DOWN, if 100 then UP (unless inverted)
Switch If percentage is zero will send send ON if 100 then OFF (unless inverted)



Trait action.devices.traits.OnOff

Examples

// device Washer defaults to OnOff trait
Switch Washer_Power "Power"  {google="action.devices.types.WASHER"}
 
// device Switch defaults to OnOff trait
Switch Lamp  "Main Lamp"    {google="action.devices.types.SWITCH"}

// will send POWERON when turned on, POWEROFF when turned off
String Computer  "Computer" {google="action.devices.types.SWITCH" [onCommand="POWERON", offCommand="POWEROFF"]} 

// Use OnOff with a fan
Switch Fan  "Fan"    {google="action.devices.types.FAN" [trait="action.devices.traits.OnOff"]}

Supported configuration options

  • onCommand=[command] - what to send when turning on. Only if Openhab item is type of String
  • offCommand=[command] - what to send when turning off. Only if Openhab item is type of String
Supported Openhab item notes
Rollershutter In case of on will send UP else DOWN
String In case of on will send ON else OFF unless onCommand or offCommand configuration is given
Dimmer In case of on will send ON else OFF
Switch In case of on will send ON else OFF



Trait action.devices.traits.Scene

Examples

//  `start party mode` `stop party mode` `activate party mode`
// with custom commands
String PartyMode "Party Mode" { google="action.devices.types.SCENE" [activateCommand="START", deactivateCommand="STOP", reversible="true"]}

// default switch with on/off
Switch PartyMode "Party Mode" { google="action.devices.types.SCENE" [reversible="true"]}

Supported configuration options

  • activateCommand=[command] - what to send when activating scene. Only if Openhab item is type of String
  • deactivateCommand=[command] - what to send when deactivating scene. Only if Openhab item is type of String
  • reversible=[true] - if scene can be reversed
Supported Openhab item notes
String In case of activate will send ON else OFF unless activateCommand or deactivateCommand configuration is given
Switch In case of activate will send ON else OFF



Trait action.devices.traits.LockUnlock

Examples

// device Lock defaults to LockUnlock trait
Switch Lock "Lock"  {google="action.devices.types.LOCK"}
 
// will send UNLOCK when unlocking or LOCK when locking
String Door  "Door" {google="action.devices.types.DOOR" [trait="action.devices.traits.LockUnlock", lockCommand="LOCK", unlockCommand="UNLOCK"]} 

// Use LockUnlock with a door
Switch Fan  "Fan"    {google="action.devices.types.DOOR"  trait="action.devices.traits.LockUnlock"}

Supported configuration options

  • lockCommand=[command] - what to send when locking. Only if Openhab item is type of String
  • unlockCommand=[command] - what to send when unlocking, Only if Openhab item is type of String
Supported Openhab item notes
String In case of lock will send ON else OFF unless lockCommand or unlockCommand configuration is given
Switch In case of lock will send ON else OFF



Trait action.devices.traits.FanSpeed

Examples

// FAN device defaults to action.devices.traits.FanSpeed
// Blower supports three speed commands: level_0, level_1, level_2, which are named
// - level_0 away or zero
// - level_1 default or standard or one
// - level_2 high or two
String Blower "Blower" { synonyms="Ventilation", google="action.devices.types.FAN" [lang="en", speeds="level_0=away:zero,level_1=default:standard:one,level_2=high:two", ordered="true"] }

Supported configuration options

  • speeds=[speedCommand1=name:alias1:alias2,speedCommand2=name2:otheralias] - supported fan speed commands (separated with ,) with their names (supports multiple aliases separated by :)
  • ordered=[true] - if true means that defined speeds are in increasing order and you can use commands like increase fan speed
  • lang=[lang] - language code in which speed names are defined. Defaults to 'en' (English)
Supported Openhab item notes
String will send command defined in speeds
Number will send command defined in speeds. Note that it mus be numeric, e.g. speeds="0=zero,50=half
Dimmer will send command defined in speeds. Note that it mus be numeric, e.g. speeds="0=zero,50=half



Trait action.devices.traits.Modes

Note: queries seem to be broken for some modes

This one is really tricky. It allows you to specify modes that device supports and control them, e.g. set washer gemperature to High. The problem that the mode (temperature) and it's value (High) can only have values that google supports (with exact casing) Otherwise google will sync the device but will not execute any command

Examples

String Booster   "Booster" { google="action.devices.types.FAN" [ traits="action.devices.traits.Modes",  mode="Level=level", modeSettings="Low=low,Medium=medium,High=high", modeCommandMap="Low=level_1,Medium=level_2", lang="en", ordered=false]}

Supported configuration options

Supported Openhab item notes
String will send mode setting, or command defined in commandMap
Number will send command from commandMap based on setting. commandMap is required and key must be numeric, e.g. Low=0,Medium=1



Trait action.devices.traits.Toggles

Toggles is an advanced version of OnOff for items that can have two states (on/off). And while you can only have one OnOff trait on google device, device can have many Toggles NOTE: can only have values that google supports (with exact casing) Otherwise google will sync the device but will not execute any command

Examples

// `turn on Power saving on Home Cinema`
String HomeCinemaPowerSave   "Home Cinema" { google="action.devices.types.TV" [ traits="action.devices.traits.Toggles",  toggle="Power Save=power save:power saving", toggleOnCommand="ECO", toggleOffCommand="NORMAL", lang="en"]}

//multiple toggles via group
Group HomeCinema { google="action.devices.types.TV"  }
String HomeCinemaPowerSave  "Home Cinema Power" (HomeCinema) { google="action.devices.traits.Toggles" [ toggle="Power Save=power save:power saving", toggleOnCommand="ECO", toggleOffCommand="NORMAL", lang="en"]}
String HomeCinemaBluetooth  "Home Cinema Bluetooth" (HomeCinema) { google="action.devices.traits.Toggles" [ toggle="bluetooth=bluetooth", lang="en"]}

Supported configuration options

Supported Openhab item notes
String will send ON or toggleOnCommand when toggling on, OFF or toggleOffCommand when toggling off
Switch
Dimmer



Trait action.devices.traits.StartStop

Examples

Switch Washer       "Washer"  { google="action.devices.types.WASHER" [trait="action.devices.traits.StartStop" ] }

// hey google, vacuum the kitchen
String RoborockRoom  "Roborock Room" (Roborock) { google="action.devices.types.VACUUM" [trait="action.devices.traits.StartStop",  zones="kitchen,living room,bedroom,table"]}

Supported configuration options

  • pausable=[true] - can the device be paused
Supported Openhab item notes
String In case of start will send START else STOP. If pausable is enabled for pause will send PAUSE and for resume RESUME
Switch In case of start will send ON else OFF. Does not support pause



Trait action.devices.traits.Brightness

Examples

// device Light defaults to Brightness and OnOff traits
Dimmer BathroomLight  "Bathroom Lamp"    {google="action.devices.types.LIGHT"}

// Light
  can be split  into separate items with Brightness ans Switch
Group ComplexLight              "ComplexLight"               {google="action.devices.types.LIGHT"}
Number ComplexLight_Brightness  "Brightness" (ComplexLight)  {google="action.devices.traits.Brightness"}
Switch ComplexLight_OnOff       "Power"      (ComplexLight)  {google="action.devices.traits.OnOff"}

Supported configuration options

  • none
Supported Openhab item notes
String Will send percentage as is
Switch Will send percentage as is
Dimmer Will send percentage as is



Trait action.devices.traits.Volume

Note : this trait is not officially supported by google, but does seem to work, trait is reverse engineered. more on this here

Note2: volume quering does not seem to work

Examples

// device Speaker defaults to Volume trait
Dimmer SqueezeboxPlayer  "Squeezebox Player"    {google="action.devices.types.SPEAKER"}

// When asking to "increase volume" volumeIncrementStep indicates how much should we increase.
// this is due to unknown properties of the trait
String SqueezeboxPlayer  "Squeezebox Player"    {google="action.devices.types.SPEAKER" [volumeIncrementStep="10"]}

Supported configuration options

  • volumeIncrementStep=[number] - step by which volume should increase when doing relative volume control. Defaults to 1
Supported Openhab item notes
String Will send volume level as is
Dimmer Will send volume level as is



Trait action.devices.traits.MediaState

Note : this trait is not officially supported by google, but does seem to work, trait is reverse engineered. more on this here

Note2: query is not supported because procotol is unknown

Examples

//Player - play, pause, resume, next, previous
Player Spotify_Squeezebox_Player "Squeezebox"  { google="action.devices.types.REMOTECONTROL"}



Supported configuration options

  • none
Supported Openhab item notes
Player -
String Supported commands - PAUSE, STOP, PLAY, NEXT, PREVIOUS, FATFORWARD

Trait action.devices.traits.ArmDisarm

Examples

// simple Security System as a switch without levels
Switch MainSecurity "Main Security" { google="action.devices.types.SECURITYSYSTEM" }

// with custom commands for on/off
String MainSecurity "Main Security" { google="action.devices.types.SECURITYSYSTEM" [disarmCommand="DISARM", armCommand="ARM] }
 
// with multiple levels (only for String item type)
String MainSecurity "Main Security" { google="action.devices.types.SECURITYSYSTEM" [availableArmLevels="stay=Stay:At Home,arm=Arm,sleep=Sleep  ] }

Supported configuration options

  • armCommand=[command] - what to send when arming. Only if Openhab item is type of String
  • disarmCommand=[command] - what to send when disarming, Only if Openhab item is type of String
  • availableArmLevels=[command=name:synonym,command2=name2:synonym2] - available arm levels, , Only if Openhab item is type of String
Supported Openhab item notes
String In case of arm will send ON else OFF unless armCommand or disarmCommand configuration is given. In case of specific arm level will send as is
Switch In case of arm will send ON else OFF