# Google Assistant Action

Google Assistant is Google’s virtual personal assistant and uses Actions on Google as the platform for "Actions" (software applications) to extend the functionality of the Google Assistant. Users engage Google Assistant in conversation to get things done, like controlling their devices and things at home. You can use the officially certified openHAB Action for Google Assistant to easily manage and control your smart home by conversational experiences between you and your openHAB smart home powered by voiced commands.

This guide describes step by step how to use the openHAB Google Assistant Smart Home Action (opens new window). The openHAB Action links your openHAB setup through the myopenHAB.org (opens new window) cloud service to the Google Assistant platform (for technical insights, please refer to this guide (opens new window) to read more about setup options and development information).

With the Action you can voice control your openHAB items and it supports lights, plugs, switches, thermostats and many more. The openHAB Action comes with multiple language support like English, German or French language.

If you have any issues, questions or an idea for additional features, please take a look at the repository on GitHub (opens new window).

# General Configuration Instructions

TIP

This integration relies on the cloud connector addon. More information can be found in the corresponding docs page (opens new window).

# Requirements

# Item configuration

To expose items (opens new window) to Google Assistent you will need to add metadata (opens new window) in the ga namespace.

Currently the following devices are supported (also depending on Google's API capabilities):

Hint: The value of ga is not case-sensitive.

# Switch

Device Type Switch (opens new window)
Supported Traits OnOff (opens new window)
Supported Items Switch
Configuration (optional) inverted=true/false
(optional) checkState=true/false

Example:

Switch { ga="Switch" [ inverted=false ] }

# Light

Device Type Light (opens new window)
Supported Traits OnOff (opens new window), ColorSetting (opens new window), Brightness (opens new window) (depending on used item type)
Supported Items Switch, Dimmer, Color
Configuration (optional) inverted=true/false
(optional) checkState=true/false
(optional) colorTemperatureRange="minK,maxK"
Switch { ga="Light" [ inverted=true ] }
Dimmer { ga="Light" }
Color  { ga="Light" [ colorTemperatureRange="2000,9000" ] }

# Light as Group with separate Color and Brightness

Device Type Light (opens new window)
Supported Traits OnOff (opens new window), ColorSetting (opens new window), Brightness (opens new window)
Supported Items Group as light with the following members: (optional) Number or Dimmer as lightBrightness, (optional) Number or Dimmer as lightColorTemperature, (optional) Color as lightColor, (optional) Switch as lightPower
Configuration (optional) useKelvin=true/false
(optional) checkState=true/false
(optional) colorTemperatureRange="minK,maxK"
Hint: if you want to use lightColorTemperature you either need to set useKelvin=true or colorTemperatureRange
Group  lightGroup { ga="Light" [ useKelvin=true, colorTemperatureRange="2000,9000" ] }
Switch powerItem            (lightGroup) { ga="lightPower" }
Dimmer brightnessItem       (lightGroup) { ga="lightBrightness" }
Color  colorItem            (lightGroup) { ga="lightColor" }
Number colorTemperatureItem (lightGroup) { ga="lightColorTemperature" }

# Scene

Device Type Scene (opens new window)
Supported Traits Scene (opens new window)
Supported Items Switch
Configuration (optional) sceneReversible=true/false
(optional) checkState=true/false
Switch { ga="Scene" [ sceneReversible=false ] }

# Outlet, Coffee_Maker, WaterHeater, Fireplace

Device Type Outlet (opens new window), Coffee_Maker (opens new window), WaterHeater (opens new window), Fireplace (opens new window)
Supported Traits OnOff (opens new window)
Supported Items Switch
Configuration (optional) inverted=true/false
(optional) checkState=true/false
Switch { ga="Outlet" [ inverted=true ] }
Switch { ga="Coffee_Maker" [ inverted=true ] }
Switch { ga="WaterHeater" [ inverted=false ] }
Switch { ga="Fireplace" }

# Valve

Device Type Valve (opens new window)
Supported Traits OpenClose (opens new window)
Supported Items Switch
Configuration (optional) inverted=true/false
(optional) checkState=true/false
Switch { ga="Valve" [ inverted=true ] }

# Sprinkler, Vacuum

Device Type Sprinkler (opens new window), Vacuum (opens new window)
Supported Traits StartStop (opens new window)
Supported Items Switch
Configuration (optional) inverted=true/false
(optional) checkState=true/false
Switch { ga="Sprinkler" [ inverted=true ] }
Switch { ga="Vacuum" [ inverted=false ] }

# Lock

Device Type Lock (opens new window)
Supported Traits LockUnlock (opens new window)
Supported Items Contact (no device control), Switch
Configuration (optional) (optional) inverted=true/false
(optional) checkState=true/false
ackNeeded=true/false
(optional) pinNeeded="1234"
Switch { ga="Lock" [ ackNeeded=true ] }
Switch { ga="Lock" [ pinNeeded="1234" ] }

# SecuritySystem as Switch

Device Type SecuritySystem (opens new window)
Supported Traits ArmDisarm (opens new window)
Supported Items Switch
Configuration (optional) (optional) inverted=true/false
(optional) checkState=true/false
ackNeeded=true/false
(optional) pinNeeded="1234"
(optional) pinOnDisarmOnly=true/false
(optional) waitForStateChange=2

When used as a Switch, you will be limited to arming and disarming the system.

See SecuritySystem as Group for explanation on the configuration options.

Google Command: "Hey Google, arm House Alarm" OR "Hey Google, disarm House Alarm".

Switch houseAlarm "House Alarm" { ga="SecuritySystem", pinNeeded="1234" }

# SecuritySystem as Group with advanced functionality

Device Type SecuritySystem (opens new window)
Supported Traits ArmDisarm (opens new window)
StatusReport (opens new window)
Supported Items Group as SecuritySystem with the following members:
Switch as securitySystemArmed
(optional) String as securitySystemArmLevel
(optional) Switch as securitySystemTrouble
(optional) String as securitySystemTroubleCode
(optional) Contact as securitySystemZone
Configuration (optional) inverted=true/false
(optional) checkState=true/false
(optional) ackNeeded=true/false
(optional) pinNeeded="1234"
(optional) pinOnDisarmOnly=true/false
(optional) waitForStateChange=2
(optional) armLevels="L1=Level 1,L2=Level 2"

Specifically on Zone Contacts:
(required) zoneType=OpenClose/Motion
(optional) blocking=true/false

Configuring the SecuritySystem as a Group will enable a lot of advanced functionality.

The Switch and the Group configuration support the following configuration parameters:

  • checkState=true will compare the current state with the requested one and responds accordingly.
  • ackNeeded=true will request an acknowledgement before performing an action.
  • pinNeeded="1234" will request and check the configured PIN before performing an action.
  • pinOnDisarmOnly=true will enforce the PIN on disarming only. Arming will be done without the PIN.
  • waitForStateChange=0 defines the number of seconds to wait for the security system state to update before checking that the arm/disarm was successful. Defaults to 0 if not specified.

When configured as a group, you can add arm levels as well as report errors and get details of zones causing the system to not arm.

armLevels="Key=Label" - The label is used for commanding Google Assistant, the key is the matching value sent to openHAB.

Google Command: "Hey Google, set House Alarm to Level 1" (L1 sent to item).

When using arm levels, Google will send the mapped level ID (L1,L2 in below example) to the item tagged with securitySystemArmLevel when you use the arm command. It will then use the status of the item securitySystemArmed to confirm that arming was successful.

When arming and not using arm levels or disarming, Google will send ON/OFF to the item tagged securitySystemArmed.

If arming fails and blocking zones have been configured with securitySystemZone and blocking=true, Google will attempt to check for zones that are causing the arming to fail.

ga=securitySystemTrouble and ga=securitySystemTroubleCode are used in a StatusReport to report any errors on the alarm, e.g. a flat battery.

Group   gHouseAlarm "House Alarm" { ga="SecuritySystem" [ pinNeeded="1234", armLevels="L1=Level 1,L2=Level 2" ] }
Switch  alarmArmed            (gHouseAlarm) { ga="securitySystemArmed" }
String  alarmArmLevel         (gHouseAlarm) { ga="securitySystemArmLevel" }
Switch  alarmTrouble          (gHouseAlarm) { ga="securitySystemTrouble" }
String  alarmTroubleErrorCode (gHouseAlarm) { ga="securitySystemTroubleCode" }
Contact frontDoorSensor       (gHouseAlarm) { ga="securitySystemZone" [ zoneType="OpenClose", blocking="true" ] }

# Camera

Device Type Camera (opens new window)
Supported Traits CameraStream (opens new window)
Supported Items String
Configuration (optional) protocols="hls,dash,smooth_stream,progressive_mp4" (choose suitable)
String { ga="Camera" [ protocols="hls,dash" ] }

# Speaker (volume control only)

Device Type Speaker (opens new window)
Supported Traits Volume (opens new window)
Supported Items Dimmer
Configuration (optional) checkState=true/false
(optional) volumeDefaultPercentage="20"
(optional) levelStepSize="5"
(optional) volumeMaxLevel="100"
Dimmer { ga="Speaker" [ volumeDefaultPercentage="50", levelStepSize="10", volumeMaxLevel="90" ] }

# TV

Device Type TV (opens new window)
Supported Traits OnOff (opens new window), Volume (opens new window), TransportControl (opens new window), InputSelector (opens new window), AppSelector (opens new window), Channel (opens new window) (depending on used members)
Supported Items Group as TV with the following optional members: Switch as tvPower, Switch as tvMute, Dimmer as tvVolume, String as tvChannel, String as tvInput, String as tvApplication, Player as tvTransport
Configuration (optional) checkState=true/false
(optional) volumeDefaultPercentage="20"
(optional) levelStepSize="5"
(optional) volumeMaxLevel="100"
(optional) transportControlSupportedCommands="NEXT,PREVIOUS,PAUSE,RESUME"
(optional) availableChannels="channelNumber=channelId=channelName:channelSynonym:...,..."
(optional) availableInputs="inputKey=inputName:inputSynonym:...,..."
(optional) availableApplications="applicationKey=applicationName:applicationSynonym:...,..."
(optional) lang="en"
Group  tvGroup { ga="TV" [ volumeDefaultPercentage="20", levelStepSize="10", volumeMaxLevel="100", transportControlSupportedCommands="NEXT,PREVIOUS,PAUSE,RESUME", availableChannels="1=Channel1=NBC,2=Channel2=CBS", availableInputs="hdmi1=xbox:gaming,hdmi2=settopbox", availableApplications: "youtube=YouTube:Tube,netflix=Netflix:Chill" ] }
Switch powerItem       (tvGroup) { ga="tvPower" }
Switch muteItem        (tvGroup) { ga="tvMute" }
Dimmer volumeItem      (tvGroup) { ga="tvVolume" }
String channelItem     (tvGroup) { ga="tvChannel" }
String inputItem       (tvGroup) { ga="tvInput" }
String applicationItem (tvGroup) { ga="tvApplication" }
Player transportItem   (tvGroup) { ga="tvTransport" }

# Fan, Hood, AirPurifier

Device Type Fan (opens new window), Hood (opens new window), AirPurifier (opens new window)
Supported Traits OnOff (opens new window), FanSpeed (opens new window) (depending on used item type)
Supported Items Switch (no speed control), Dimmer
Configuration (optional) checkState=true/false
(optional) speeds="0=away:zero,50=default:standard:one,100=high:two"
(optional) lang="en"
(optional) ordered=true/false
Hint: if you are using a Dimmer then speeds is required

Fans (and similar device types, like AirPurifier or Hood) support the FanSpeed trait. With that you will be able to set up and use human speakable modes, e.g. "fast" for 100% or "slow" for 25%.

speeds will be a comma-separated list of modes with a percentage number followed by an equal sign and different aliases for that mode after a colon. So here both "high" and "two" would set the speed to 100%. You are also able to define the language of those aliases. The option ordered will tell the system that your list is ordered and you will then be able to also say "faster" or "slower" and Google will use the next or previous speed.

Dimmer { ga="Fan" [ speeds="0=away:zero,50=default:standard:one,100=high:two", lang="en", ordered=true ] }
Switch { ga="Hood" }
Dimmer { ga="AirPurifier" [ speeds="0=off,50=mid,100=high" ] }

# Awning, Blinds, Curtain, Door, Garage, Gate, Pergola, Shutter, Window

Device Type Awning (opens new window), Blinds (opens new window), Curtain (opens new window), Door (opens new window), Garage (opens new window), Gate (opens new window), Pergola (opens new window), Shutter (opens new window), Window (opens new window)
Supported Traits OpenClose (opens new window), StartStop (opens new window)
Supported Items Contact (no device control), Switch (no open percentage), Rollershutter
Configuration (optional) inverted=true/false
(optional) checkState=true/false

Blinds and similar devices should always use the Rollershutter item type for proper functionality. Since Google and openHAB use the opposite percentage value for "opened" and "closed", the action will translate this automatically. If the values are still inverted in your case, you can state the inverted=true option for all Rollershutter items.

Since Google only tells the open percentage (and not the verb "close" or "down"), it can not be differentiated between saying "set blind to 100%" or "open blind". Therefore, it is not possible to "not invert" the verbs, if the user chooses to invert the numbers.

Rollershutter { ga="Awning" }
Rollershutter { ga="Blinds" [ inverted=true ] }
Rollershutter { ga="Curtain" }
Switch        { ga="Door" }
Rollershutter { ga="Garage" }
Contact       { ga="Gate" }
Rollershutter { ga="Pergola" }
Rollershutter { ga="Shutter" }
Rollershutter { ga="Window" }

# Charger

Device Type Charger (opens new window)
Supported Traits EnergyStorage (opens new window)
Supported Items Group as Charger with the following optional members: Switch as chargerCharging, Switch as chargerPluggedIn, Number or Dimmer as chargerCapacityRemaining, Number or Dimmer as chargerCapacityUntilFull
Configuration (optional) checkState=true/false
(optional) isRechargeable=true/false
(optional) unit="PERCENTAGE"

The configuration option unit supports the following values: PERCENTAGE (default), SECONDS, MILES, KILOMETERS, KILOWATT_HOURS

The setting isRechargeable defaults to false if not explicitly set to true.

If no chargerCharging item is specified, the device will only support queries.

Group  chargerGroup { ga="Charger" [ isRechargeable=true, unit="KILOWATT_HOURS" ] }
Switch chargingItem         (chargerGroup) { ga="chargerCharging" }
Switch pluggedInItem        (chargerGroup) { ga="chargerPluggedIn" }
Number capacityRemainItem   (chargerGroup) { ga="chargerCapacityRemaining" }
Number capacityFullItem     (chargerGroup) { ga="chargerCapacityUntilFull" }

# TemperatureSensor

Device Type Sensor (opens new window)
Supported Traits TemperatureControl (opens new window)
Supported Items Number
Configuration (optional) useFahrenheit=true/false
Number { ga="TemperatureSensor" [ useFahrenheit=true ] }

# Thermostat

Device Type Thermostat (opens new window)
Supported Traits TemperatureSetting (opens new window)
Supported Items Group as Thermostat with the following optional members: Number as thermostatTemperatureAmbient, Number as thermostatTemperatureSetpoint, Number as thermostatTemperatureSetpointLow, Number as thermostatTemperatureSetpointHigh, Number as thermostatHumidityAmbient, String or Number as thermostatMode
Configuration (optional) checkState=true/false
(optional) useFahrenheit=true/false
(optional) thermostatTemperatureRange="10,30"
(optional) modes="off=OFF:WINDOW_OPEN,heat=COMFORT:BOOST,eco=ECO,on=ON,auto"

Thermostat requires a group of items to be properly configured to be used with Google Assistant. The default temperature unit is Celsius. To change the temperature unit to Fahrenheit, add the config option useFahrenheit=true to the thermostat group. To set the temperature range your thermostat supports, add the config option thermostatTemperatureRange="10,30" to the thermostat group. If your thermostat supports a range for the setpoint you can use both thermostatTemperatureSetpointLow and thermostatTemperatureSetpointHigh instead of the single thermostatTemperatureSetpoint item.

If your thermostat does not have a mode, you should create one and manually assign a value (e.g. heat, cool, on, etc.) to have proper functionality.

To map the default thermostat modes of Google (opens new window) (on, off, heat, cool, etc.) to custom ones for your specific setup, you can use the modes config option on the thermostat group. E.g. [ modes="off=OFF:WINDOW_OPEN,heat=COMFORT:BOOST,eco=ECO,on=ON,auto" ] will enable the following five modes in Google Home "off, heat, eco, on, auto" that will be translated to "OFF, COMFORT, ECO, ON, auto". You can specify alternative conversions using the colon sign, so that in the former example "BOOST" in openHAB would also be translated to "heat" in Google. For the translation of Google modes to openHAB always the first option after the equal sign is used. By default the integration will provide "off,heat,cool,on,heatcool,auto,eco".

You can also set up a Thermostat for using it as a temperature sensor. To do so, create a Thermostat group and only add one item member as "thermostatTemperatureAmbient". However, it is recommended to prefer the TemperatureSensor type for simple temperature reports (but currently there is no UI support in Google Home).

Group  thermostatGroup { ga="Thermostat" [ modes="off=OFF:WINDOW_OPEN,heat=COMFORT:BOOST,eco=ECO,on=ON,auto", thermostatTemperatureRange="10,30", useFahrenheit=false ] }
Number ambientItem      (thermostatGroup) { ga="thermostatTemperatureAmbient" }
Number humidityItem     (thermostatGroup) { ga="thermostatHumidityAmbient" }
Number setpointItem     (thermostatGroup) { ga="thermostatTemperatureSetpoint" }
Number setpointItemLow  (thermostatGroup) { ga="thermostatTemperatureSetpointLow" }
Number setpointItemHigh (thermostatGroup) { ga="thermostatTemperatureSetpointHigh" }
String modeItem         (thermostatGroup) { ga="thermostatMode" }

# Sensor

Device Type Sensor (opens new window)
Supported Traits SensorState (opens new window)
Supported Items Number, Dimmer
Configuration sensorName="SmokeLevel"
valueUnit="PARTS_PER_MILLION"
states="no smoke=10,smoke detected=50,high=90"

Please see the SensorState documentation (opens new window) for more details on configuration options. For now only exact matches of the numeric value will report the descriptive state value.

Number { ga="Sensor" [ sensorName="AirQuality", valueUnit="AQI", states="good=10,moderate=50,poor=90" ] }

# Additional Information

Item labels are not mandatory in openHAB, but for the Google Assistant Action they are absolutely necessary!

It is the "label text" (e.g. "Kitchen Lights" for example above) and not the item's name that will be available to you via voice commands or in the Google Home app, so make it unique and easy to say!

If you do not want to adjust your labels to be human spellable, you can use the "name" config option in the metadata: [ name="Kitchen Lights" ]. This will overwrite the label as the device's name.

Furthermore, you can state synonyms for the device name: Switch KitchenLight "Kitchen Lights" { synonyms="Top Light", ga="Light" }.

To ease setting up new devices you can add a room hint: [ roomHint="Living Room" ].

For devices supporting the OpenClose trait, the attributes [ discreteOnly=false, queryOnly=false ] can be configured.

  • discreteOnly defaults to false. When set to true, this indicates that the device must either be fully open or fully closed (that is, it does not support values between 0% and 100%). An example of such a device may be a valve.
  • queryOnly defaults to false. Is set to true for Contact items. Indicates if the device can only be queried for state information and cannot be controlled. Sensors that can only report open state should set this field to true.

All device types support checking the current state before sending an updated state by a command. This can be enabled by setting [ checkState=true ] in the metadata. When this is enabled, the current state of the target item is queried and compared to the potential new state triggered by the command. If it is identical, a special error message is triggered and communicated to the user.


NOTE: metadata is not available via paperUI in openHAB v2. Either you create your items via ".items" files, or you can:

  • add metadata via console:

    smarthome:metadata add BedroomLights ga Light
    
  • add metadata using the REST API:

    PUT /rest/items/BedroomLights/metadata/ga
    
    {
      "value": "Light"
    }
    

# Two-Factor-Authentication

For some actions, Google recommends to use TFA (Two-Factor-Authentication) to prevent accidental or unauthorized triggers of sensitive actions. See Two-factor authentication  |  Actions on Google Smart Home (opens new window).

The openHAB Google Assistant integration supports both ackNeeded and pinNeeded. You can use both types on all devices types and traits.

ackNeeded: "A two-factor authentication that requires explicit acknowledgement (yes or no) and can also use trait states as response feedback. This challenge type is not recommended for security devices and traits."

pinNeeded: "A two-factor authentication that requires a personal identification number (PIN), which is ideal for security devices and traits."

Example:

Switch DoorLock   "Front Door"  { ga="Lock" [ ackNeeded=true ] }
Switch HouseAlarm "House Alarm" { ga="SecuritySystem" [ pinNeeded="1234" ] }

# Setup & Usage on Google Assistant App

  • Make sure Google Play Services is up to date.
  • Visit "Google Home" app entry in Google Play Store on Android.
  • Set up the voice-activated speaker, Pixel, or Android phone (version 6+) with the same account.
  • Make sure you're the correct user.
  • Start the updated Google Home app on your phone.
  • Go to the settings part: Account > Settings.

openHAB Google App

  • Go to the home control part: Assistant > Home control.

openHAB Google App

  • Press the + button.

openHAB Google App

  • Select openHAB.

openHAB Google App

openHAB Google App

  • Allow Google access to your account.

openHAB Google App openHAB Google App

  • You will now be able to see your previously configured items and devices. Assign them to a room. Press Done.

openHAB Google App openHAB Google App

  • You can now control those devices from the Google Assistant.

openHAB Google App openHAB Google App

# Example Voice Commands

Here are some example voice commands:

  • Turn on Office Lights.
  • Dim/Brighten Office Lights (increments 15%).
  • Set Office Lights to 35%.
  • Open/Close the blinds
  • Turn off Pool Waterfall.
  • Turn on House Fan.
  • Turn on Home Theater Scene.
  • Set Basement Thermostat to 15 degrees.
  • What is the current Basement Thermostat Temperature?

# Frequently Asked Question

My New items did not appear in the Google Home app.

  • Say: Hey Google, sync my devices.

I'm not able to connect openHAB to Google Home.

  • Check, recheck and after that check again your items!

  • The items that you want to expose to Google Assistant should have the right metadata assigned.

  • The items that you want to expose to Google Assistant must have a item label! Item Definition and Syntax (opens new window)

  • If you expose thermostats make sure than you have:

    • A Group item with the metadata value { ga="Thermostat" }
    • A Number or String item with the metadata value { ga="thermostatMode" } as part of the thermostat group
    • A Number item with the metadata value { ga="thermostatTemperatureAmbient" } as part of the thermostat group
    • A Number item with the metadata value { ga="thermostatTemperatureSetpoint" } as part of the thermostat group
    Group  g_HK_Basement_TSTAT  "Basement Thermostat"                                 { ga="Thermostat" [ useFahrenheit=true ] }
    Number HK_Basement_Mode     "Basement Heating/Cooling Mode" (g_HK_Basement_TSTAT) { ga="thermostatMode" }
    Number HK_Basement_Setpoint "Basement Setpoint"             (g_HK_Basement_TSTAT) { ga="thermostatTemperatureSetpoint" }
    Number HK_Basement_Temp     "Basement Temperature"          (g_HK_Basement_TSTAT) { ga="thermostatTemperatureAmbient" }
    
  • If none of the above solutions works for you:

    • Remove all the metadata.
    • Make a new .item file with 1 item to expose.
    Switch TestLight "Test Light" { ga="Switch" }
    
    • Relink your account.