[Alpha] Community-maintained Google Home integration

Interesting. I'm not able to reproduce that behavior. Are there any errors in your logs from when you tried to sync with the empty device type?

Thanks! this is working great with my iris sensors.
It looks like "Humidity measurement" is missing from the device pull down when setting up a device type though. Can this be added?

I will try it again with debugging turned on.

There should be a Relateive Humidity Measurement entry. Those choices are all based on Hubitat's device capabilities.

Doh, Wow not sure how I missed that. Sorry

I'm setting up my Ikea Fyrtur blinds in this integration to get proper open/close commands and ran into an issue with direction. The commonly recommended driver seems to operate in reverse to how your integration is expecting. When I ask Google to "open the corner shades", they close and vice versa when I ask to close the shades they open.

The Ikea driver says setPosition 100 is closed and setPosition 0 is open which is the opposite of your technically correct implementation based on Google's documentation. Any chance you could add a "invert direction" toggle to the OpenClose trait to correct backwards drivers like this and use 100 for closed and 0 for open?

That seems reasonable. Added an issue for that.

Thanks! For now I inverted the position in the driver for my own use by using 100-position and got them working as expected with your integration. Conceptually in your integration it would work the same way, invertEnabled == true ? setPosition(100-value) : setPosition(value).

I contributed the change back to that thread for those that want it but since there's no official maintainer for this driver a lot of people will have already copy/pasted the original and stick with that. I'm sure there will also be other drivers that could benefit from a toggle.

1 Like

Since I'm working with blinds I found one more thing that may or may not be an actual issue.

In handleExecuteRequest you wait 5 seconds for the device to report its new state. However, something like blinds or curtains take a lot longer than 5 seconds to fully open or close so the loop finishes before reaching the actual final state.
Here's a debug log from asking Google to close my blinds, you can see it stops checking after 5 seconds and reports 78% as the final position as that's how far they got but still reports success. The blinds did fully close like they were supposed to.

app:3212020-04-01 10:25:45.625 am debug[requestId:15467067969563825349, payload:[commands:[[status:SUCCESS, ids:[385], states:[online:true, openPercent:78]]]]]
app:3212020-04-01 10:25:45.515 am debugDevice: current value of level (78) does does not yet match expected value (0)
app:3212020-04-01 10:25:45.407 am debugDevice: current value of level (81) does does not yet match expected value (0)
app:3212020-04-01 10:25:45.296 am debugDevice: current value of level (81) does does not yet match expected value (0)
app:3212020-04-01 10:25:45.185 am debugDevice: current value of level (81) does does not yet match expected value (0)
app:3212020-04-01 10:25:45.074 am debugDevice: current value of level (81) does does not yet match expected value (0)
app:3212020-04-01 10:25:44.966 am debugDevice: current value of level (81) does does not yet match expected value (0)
app:3212020-04-01 10:25:44.855 am debugDevice: current value of level (83) does does not yet match expected value (0)
app:3212020-04-01 10:25:44.740 am debugDevice: current value of level (83) does does not yet match expected value (0)
app:3212020-04-01 10:25:44.634 am debugDevice: current value of level (83) does does not yet match expected value (0)
app:3212020-04-01 10:25:44.527 am debugDevice: current value of level (83) does does not yet match expected value (0)
app:3212020-04-01 10:25:44.419 am debugDevice: current value of level (86) does does not yet match expected value (0)
app:3212020-04-01 10:25:44.266 am debugDevice: current value of level (86) does does not yet match expected value (0)
app:3212020-04-01 10:25:44.125 am debugDevice: current value of level (86) does does not yet match expected value (0)
app:3212020-04-01 10:25:44.018 am debugDevice: current value of level (86) does does not yet match expected value (0)
app:3212020-04-01 10:25:43.910 am debugDevice: current value of level (89) does does not yet match expected value (0)
app:3212020-04-01 10:25:43.800 am debugDevice: current value of level (89) does does not yet match expected value (0)
app:3212020-04-01 10:25:43.679 am debugDevice: current value of level (89) does does not yet match expected value (0)
app:3212020-04-01 10:25:43.556 am debugDevice: current value of level (89) does does not yet match expected value (0)
app:3212020-04-01 10:25:43.450 am debugDevice: current value of level (89) does does not yet match expected value (0)
app:3212020-04-01 10:25:43.342 am debugDevice: current value of level (89) does does not yet match expected value (0)
app:3212020-04-01 10:25:43.235 am debugDevice: current value of level (92) does does not yet match expected value (0)
app:3212020-04-01 10:25:43.128 am debugDevice: current value of level (92) does does not yet match expected value (0)
app:3212020-04-01 10:25:43.022 am debugDevice: current value of level (92) does does not yet match expected value (0)
app:3212020-04-01 10:25:42.911 am debugDevice: current value of level (92) does does not yet match expected value (0)
app:3212020-04-01 10:25:42.810 am debugDevice: current value of level (94) does does not yet match expected value (0)
app:3212020-04-01 10:25:42.695 am debugDevice: current value of level (94) does does not yet match expected value (0)
app:3212020-04-01 10:25:42.588 am debugDevice: current value of level (94) does does not yet match expected value (0)
app:3212020-04-01 10:25:42.480 am debugDevice: current value of level (94) does does not yet match expected value (0)
app:3212020-04-01 10:25:42.368 am debugDevice: current value of level (97) does does not yet match expected value (0)
app:3212020-04-01 10:25:42.260 am debugDevice: current value of level (97) does does not yet match expected value (0)
app:3212020-04-01 10:25:42.149 am debugDevice: current value of level (97) does does not yet match expected value (0)
app:3212020-04-01 10:25:42.041 am debugDevice: current value of level (97) does does not yet match expected value (0)
app:3212020-04-01 10:25:41.935 am debugDevice: current value of level (97) does does not yet match expected value (0)
app:3212020-04-01 10:25:41.820 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:41.706 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:41.576 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:41.451 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:41.344 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:41.238 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:41.105 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:40.978 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:40.867 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:40.758 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:40.647 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:40.511 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:40.402 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:40.293 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:40.177 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:40.065 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:39.966 am debugDevice: current value of level (99) does does not yet match expected value (0)
app:3212020-04-01 10:25:39.959 am debugChecking MFA for Set Position command
app:3212020-04-01 10:25:39.943 am debug{inputs=[{context={locale_country=US, locale_language=en}, intent=action.devices.EXECUTE, payload={commands=[{devices=[{id=385}], execution=[{command=action.devices.commands.OpenClose, params={openPercent=0}}]}]}}], requestId=15467067969563825349}
--- Live Log Started, waiting for events ---

The blinds start moving right away but Google doesn't give its usual "Ok, closing the corner blinds" response for an extra 5 seconds.

I'm not sure what the best way to handle this would be. If you increase the loop to 30 seconds it'll probably catch the final state, but then Google will wait even longer to confirm the command.

Does the integration send the final state (78% in my example) to Google and does Google actually do anything with that information or does it only care about success/failure? If it does, then that final position is important to catch somehow. The Home app doesn't show blind position like it does dimmer % state so I can't really check.
Maybe there could be a short loop to check that the device started responding (position starts increasing or decreasing) to acknowledge the command and then a longer loop that runs in the background to keep an eye on the position and send a separate update with the final position.

This really only affects slow moving things like blinds/shades, garage door openers/gates, and maybe really slow dimming light bulbs so not a big deal in the grand scheme of things.

My blinds are working fine. These are the Ikea blinds? Are you using the driver where the values are inverted? Because the requested value appears to be 0 but it is returning a value of 99. So, something is still inverted.

The log copied from Hubitat is in reverse chronological order so you have to read it from the bottom up. It starts at open (99) and starts moving towards closed (0) but only gets to 78 before the 5 second checking loop ends.
The blinds do work well and far better than those dimmer switch/routine combo workarounds needed with Hubitat's native Google Home integration where the blinds show up as lights.

I'm thinking this final state reporting thing is what's causing a Home bug where I ask Google to "open the corner blinds 50%" and Google responds "ok, opening the corner blinds to 82%" or some arbitrary position because it thinks they're in a different starting position than fully closed or open. It might just be a Google thing though because even with the blinds paired with the Tradfri hub and added to Google Home it did the same thing.

Currently the app waits up to 5 seconds for the device to reach the requested state before reporting success along with the current state of the device. My original plan was to report an error if it didn't reach that state in a few seconds, but as you've pointed out there are some devices that take too long to reach their requested state, so it just reports success anyway.

Google doesn't actually seem to use the state reported there for anything though, so I could turn that off.

Google responds differently to "Open the blinds 50%" and "Open the blinds to 50%". The former will query the current state of the blinds, add 50% to it, and open the blinds to the resulting position. The latter will open the blinds directly to the requested position.
The position reported by a previous command shouldn't matter though; Google will actually send two requests to the app: a QUERY request to get the current state and an EXECUTE request to set the position.

1 Like

Great info, thank you. I just did some experiments using the "open corner blinds X%" to cause it to move in increments and monitored the logs. I see the query for current position and then google is either adding or subtracting my increment to set the new position. It is moving to the correct absolute position based on this math (starting at 10 and requesting open 10 moves to 20, starting at 10 and requesting open 50 moves to 60).

For longer moves than the 5 second limit allows, the response from Google is actually the last position reported by the integration. For example, starting at 30 and requesting open 30, the timer kicks off and it only makes it to 49 before 5 seconds is up. Google uses that in its response, "OK, opening corner blinds to 49 percent" despite actually moving to 60% like it's supposed to.

As another experiment I commented out the part of the response build up that adds the final position:


Running it this way has Google respond "OK, opening corner blinds" without the "to X%" so this might be a solution for when the 5 second timeout occurs but you still want to report success. This way you can still report success without including possibly incomplete information about the final state of the device.

If I find some time later I'll see if I can put together a pull request, I'm sure you have more interesting features to work on.

1 Like

I don't understand. So, the blind are moving to the correct % but google is repeating back your request and saying something different than you requested? But if the command it issued isn't followed, it's supposed to report an error.

The easiest way to fix this is to modify the driver so that the open percentage is simply reported by your command to the device. That would eliminate all of this problem. I can set the "position" attribute immediately after the command is issues and then the level attribute would follow what the blinds are currently set to. Then you would just change the Google Home app to use the position attribute instead of the level.

You would change the setLevel as follows:

def setLevel(data, rate = null) {
    sendEvent(name: "position", value: data)
    if(logEnable) log.debug "Set Level to $data"
    if(invert) data = 100 - data
	data = data.toInteger()    
    def cmd = zigbee.command(CLUSTER_WINDOW_COVERING, COMMAND_GOTO_LIFT_PERCENTAGE, zigbee.convertToHexString(data, 2))
    return cmd
}

I've never liked this driver...I ported it over from ST because someone begged me to and I've avoided tinkering because I don't own any to test with. But I think that might be an easier solution that trying to mess with Google Home.

We can also invert it so that the level is set immediately and the position follows the position but that would be a bigger re-write of the driver and I'd want someone to agree to test it before I'd work on something like that.

Hi all!

I've been able to run the app with a Danalock lock. Is it mandatory to speak to GH in english to interact with the app? Can I do it in Spanish? If so, where must I change my orders to GH?

Thanks in advance,
Angel

You would change the language of your google home. But I don't believe you would have to change anything in HE. For your lock, do you see the English "locked" or the Spanish "bloqueado/bloqueada" (I don't know if a lock if feminine or masculine. :wink: ) listed on the edit device page?

That's a good question, and one I don't really know the answer to. All of the language processing happens on the Google side, so if your assistant is set to Spanish, then you should be able to use Spanish.

There are a few things that have a language specified for them in the GH API (fan speeds and toggles, currently), and the app always specifies English right now. I'm not totally sure how that will interact with an assistant configured for a different language. If you have any issues with it, please do let me know.

I think your driver is actually working well with the inverted, it reports live position updates as the blind is moving which is great.
It's in the Google Home integration that the 5 second timeout exists so when that internal timeout happens the integration just sends the last position reported as its success message.
Here's an example, the blinds started at 30% and I said, "OK google, open the corner blinds 30%".

app:3212020-04-01 01:40:38.313 pm debug[requestId:6697988168335305553, payload:[commands:[[status:SUCCESS, ids:[385], states:[online:true, openPercent:49]]]]]
app:3212020-04-01 01:40:38.209 pm debugDevice: current value of level (49) does does not yet match expected value (60)
app:3212020-04-01 01:40:38.086 pm debugDevice: current value of level (49) does does not yet match expected value (60)
app:3212020-04-01 01:40:37.981 pm debugDevice: current value of level (49) does does not yet match expected value (60)
app:3212020-04-01 01:40:37.874 pm debugDevice: current value of level (49) does does not yet match expected value (60)
app:3212020-04-01 01:40:37.765 pm debugDevice: current value of level (49) does does not yet match expected value (60)
app:3212020-04-01 01:40:37.658 pm debugDevice: current value of level (46) does does not yet match expected value (60)
app:3212020-04-01 01:40:37.551 pm debugDevice: current value of level (46) does does not yet match expected value (60)
app:3212020-04-01 01:40:37.445 pm debugDevice: current value of level (46) does does not yet match expected value (60)
app:3212020-04-01 01:40:37.339 pm debugDevice: current value of level (46) does does not yet match expected value (60)
app:3212020-04-01 01:40:37.229 pm debugDevice: current value of level (46) does does not yet match expected value (60)
app:3212020-04-01 01:40:37.120 pm debugDevice: current value of level (43) does does not yet match expected value (60)
app:3212020-04-01 01:40:36.992 pm debugDevice: current value of level (43) does does not yet match expected value (60)
app:3212020-04-01 01:40:36.886 pm debugDevice: current value of level (43) does does not yet match expected value (60)
app:3212020-04-01 01:40:36.781 pm debugDevice: current value of level (43) does does not yet match expected value (60)
app:3212020-04-01 01:40:36.674 pm debugDevice: current value of level (41) does does not yet match expected value (60)
app:3212020-04-01 01:40:36.566 pm debugDevice: current value of level (41) does does not yet match expected value (60)
app:3212020-04-01 01:40:36.460 pm debugDevice: current value of level (41) does does not yet match expected value (60)
app:3212020-04-01 01:40:36.355 pm debugDevice: current value of level (41) does does not yet match expected value (60)
app:3212020-04-01 01:40:36.249 pm debugDevice: current value of level (41) does does not yet match expected value (60)
app:3212020-04-01 01:40:36.142 pm debugDevice: current value of level (38) does does not yet match expected value (60)
app:3212020-04-01 01:40:36.035 pm debugDevice: current value of level (38) does does not yet match expected value (60)
app:3212020-04-01 01:40:35.929 pm debugDevice: current value of level (38) does does not yet match expected value (60)
app:3212020-04-01 01:40:35.823 pm debugDevice: current value of level (38) does does not yet match expected value (60)
app:3212020-04-01 01:40:35.718 pm debugDevice: current value of level (38) does does not yet match expected value (60)
app:3212020-04-01 01:40:35.610 pm debugDevice: current value of level (35) does does not yet match expected value (60)
app:3212020-04-01 01:40:35.499 pm debugDevice: current value of level (35) does does not yet match expected value (60)
app:3212020-04-01 01:40:35.375 pm debugDevice: current value of level (35) does does not yet match expected value (60)
app:3212020-04-01 01:40:35.269 pm debugDevice: current value of level (35) does does not yet match expected value (60)
app:3212020-04-01 01:40:35.159 pm debugDevice: current value of level (35) does does not yet match expected value (60)
app:3212020-04-01 01:40:35.052 pm debugDevice: current value of level (32) does does not yet match expected value (60)
app:3212020-04-01 01:40:34.944 pm debugDevice: current value of level (32) does does not yet match expected value (60)
app:3212020-04-01 01:40:34.838 pm debugDevice: current value of level (32) does does not yet match expected value (60)
app:3212020-04-01 01:40:34.732 pm debugDevice: current value of level (32) does does not yet match expected value (60)
app:3212020-04-01 01:40:34.626 pm debugDevice: current value of level (32) does does not yet match expected value (60)
app:3212020-04-01 01:40:34.519 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:34.414 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:34.308 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:34.202 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:34.095 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:33.989 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:33.879 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:33.773 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:33.663 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:33.553 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:33.402 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:33.275 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:33.140 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:33.022 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:32.906 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:32.800 pm debugDevice: current value of level (30) does does not yet match expected value (60)
app:3212020-04-01 01:40:32.766 pm debugChecking MFA for Set Position command
app:3212020-04-01 01:40:32.754 pm debug{inputs=[{context={locale_country=US, locale_language=en}, intent=action.devices.EXECUTE, payload={commands=[{devices=[{id=385}], execution=[{command=action.devices.commands.OpenClose, params={openPercent=60}}]}]}}], requestId=6697988168335305553}
app:3212020-04-01 01:40:32.514 pm debug[requestId:6697988168335305301, payload:[devices:[385:[openPercent:30]]]]
app:3212020-04-01 01:40:32.492 pm debug{inputs=[{intent=action.devices.QUERY, payload={devices=[{id=385}]}}], requestId=6697988168335305301}

The integration sent the setPosition(60) command to the blinds and they started moving towards 60. The integration monitors the position for 5 seconds to see if it was successful but at 5 seconds the blinds were only at 49% so the integration sent the success report to Google with 49 as the current position (top line of the log). Google Assistant then responded (after that 5 second delay), "OK, opening corner blinds to 49%" despite having actually gone all the way to 60.
It doesn't actually break anything, it just makes Google respond with a confusing response.

Interesting, I guess that should be re-worked to respond to Google with the value the app sent to the device, rather than the device's current state.

I can't get garage door to open close and lock to unlock, can only lock. Is that some sort of Google restrictions, or I am doing something wrong?