i8beef / HomeAutio.Mqtt.GoogleHome

MIT License
215 stars 29 forks source link

Add support for the FanSpeed Trait #25

Closed diabl0w closed 5 years ago

diabl0w commented 5 years ago

fanspeed trait is not currently implemented correctly. It seems to be similar to the "mode" and "toggle" traits. one main difference I've seen in docs is that the command parameters seem to use one less nested object than the mode and toggle traits. For example, FanSpeed uses:

"params": { "fanSpeed": "S1"

and the mode trait uses:

"params": { "updateModeSettings": { "drytype": "permpress"

i8beef commented 5 years ago

Give the builds a moment to all go through, but this should map commands responses correctly. QUERY and SYNC actually looked ok, and your JSON in the other ticket looked right with the one comment I had about the command.

diabl0w commented 5 years ago

Wow, thank you so much for fixing so quickly. I set my json appropriately. Will the builds go through at some point tonight?

On Fri, Nov 2, 2018, 10:13 PM Michael Hallock notifications@github.com wrote:

Give the builds a moment to all go through, but this should map commands responses correctly. QUERY and SYNC actually looked ok, and your JSON in the other ticket looked right with the one comment I had about the command.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/i8beef/HomeAutio.Mqtt.GoogleHome/issues/25#issuecomment-435552821, or mute the thread https://github.com/notifications/unsubscribe-auth/APYcMq3ti88svBi9sx9D_pHhEKXdNuAEks5urPu4gaJpZM4YMlHx .

i8beef commented 5 years ago

They are already out there. Docker builds too.

diabl0w commented 5 years ago

Unfortunately, it doesnt seem to be fixed. The image I used:

latest-arm32: Pulling from i8beef/homeautio.mqtt.googlehome 2e5bbd238113: Pull complete 63c92bf530e6: Pull complete 9f2183a60db2: Pull complete 3c3deca82557: Pull complete 9538fd7673d4: Pull complete d46e60a8e1b6: Pull complete Digest: sha256:d6785b5746738b7ecd45988398a9438ece056699a819c7680b104463a2fcf8e1 Status: Downloaded newer image for i8beef/homeautio.mqtt.googlehome:latest-arm32 bad3c9e785b2d36228cf9d3e855798d2ab77a82b4d00b358f5455207ba5e7cde

I am using the same config, but with the changes to the command json object that you pointed out. In the logs, there is a query intent to the purifier but nothing else

i8beef commented 5 years ago

Are you remembering to tell Google to "sync my devices" after the restart? And what does the log say?

diabl0w commented 5 years ago

i went all the way through unlinking my account -> completely removed the docker image with "docker system prune -a" -> redownload the latest release and docker run -> link my account again

this is what i do to test things out because everything starts fresh.

the logs say:

[23:23:55 INF] Request starting HTTP/1.1 POST http://192.168.111.101:5000/google/home/smarthome application/json;charset=UTF-8 134 [23:23:55 INF] Route matched with {action = "Post", controller = "GoogleHome"}. Executing action HomeAutio.Mqtt.GoogleHome.Controllers.GoogleHomeController.Post (HomeAutio.Mqtt.GoogleHome) [23:23:55 INF] Successfully validated the token. [23:23:55 INF] Authorization was successful. [23:23:55 INF] Executing action method HomeAutio.Mqtt.GoogleHome.Controllers.GoogleHomeController.Post (HomeAutio.Mqtt.GoogleHome) with arguments (["HomeAutio.Mqtt.GoogleHome.Models.Request.Request"]) - Validation state: Valid [23:23:55 INF] Received QUERY intent for devices: bedroom/airpurifier [23:23:55 INF] Executed action method HomeAutio.Mqtt.GoogleHome.Controllers.GoogleHomeController.Post (HomeAutio.Mqtt.GoogleHome), returned result Microsoft.AspNetCore.Mvc.OkObjectResult in 2.0948ms. [23:23:55 INF] Executing ObjectResult, writing value of type 'HomeAutio.Mqtt.GoogleHome.Models.Response.Response'. [23:23:55 INF] Executed action HomeAutio.Mqtt.GoogleHome.Controllers.GoogleHomeController.Post (HomeAutio.Mqtt.GoogleHome) in 55.2288ms [23:23:55 INF] Request finished in 82.6103ms 200 application/json; charset=utf-8

diabl0w commented 5 years ago

it seems like the layout for attributes for fanspeed is different than modes/toggles as well... not sure if that can be the issue. i probably wont explain this properly, but ill try. For modes they have two parts of their attributes: attributes -> availableModes -> "name": "modename" attributes -> availableModes -> "settings" -> "setting_name":"settingname" whereas fanspeed only uses: attributes -> availableFanSpeeds -> "speeds" -> "speed_name":"speedname"

i8beef commented 5 years ago

When I put in what I THINK you should have for a SYNC request in the Google validator, it passes. Do you get a device that shows up in your Google Home app? I don't have a fan to try it right now... and I'm unsure if Google's Home app would just show the OnOff control or if it would give you a real fan level control too. I know my modes / toggles don't work in Google's App.

And no, the structure isn't a problem. The app actually takes that exact structure and passes it to Google as you typed it in for attributes during SYNC. Your JSON you sent matches up with Google's expectations around that. But this is also why I'm surprised it doesn't work. There's not too much special I have to do for fan speed, it was really on the command side where I needed to make sure the COMMAND value mapped to the right response status. I think that Google should definitely be getting the SYNC intent right.

Have you tried "set my air purifier to high", drop the "speed" out of your command?

diabl0w commented 5 years ago

I removed the On/Off trait (so it only has fanspeed trait) and the device still shows up, but i still can't control it. When removing on/off trait, and say Google turn off purifier, then it just gives me a Google search result about plugging in an air purifier (as expected). When i ask Google to change the fan speed, I still get the "device doesn't have this functionality yet" response. If I remove the fanspeed trait, then google responds with a google search result instead. so obviously its seeing something in its query for it, cuz it makes a difference if the trait is defined in my file

No matter how I have ever configured it (on/off trait only, fanspeed only, or both) it always shows up the same in Google Home app as just a air purifier icon with a settings icon on it, just like a camera stream device.

I've tried all types of Google commands to get it to work, using every combination of ommiting and including the words "purifier, fan, speed, high, low". the necessary word seems to be fan (i.e set air purifier "fan" to low) "fan speed" also gets a response. but the response either way is always "does not have this functionality"

i8beef commented 5 years ago

Hmmm theoretically it all looks right to me. I can play with it more this weekend and maybe set up a device to debug through. If you wanna send me your googleDevices.json file, I can try it out with my test calls and get the actual responses so we can see if anything stands out.

Or at least the one device setup's JSON.

diabl0w commented 5 years ago

Awesome, I really appreciate the support. Theoretically, I think, you don't even need a device, just the devices.json and then query Google and see if it responds or not, as long as it says "okay, setting fan speed to low" then we should be good.

here's a link to the whole file https://pastebin.com/8mX68yyi

i8beef commented 5 years ago

One thing I see is you don't have a "reversable": "false" attribute. Try adding that and see if it makes a difference.

diabl0w commented 5 years ago

that fixed part of it! now we're super close! it executes the action, but it seems to crash the program tho. logs:

`[05:08:07 INF] Request starting HTTP/1.1 POST http://192.168.111.101:5000/google/home/smarthome application json;charset=UTF-8 278 [05:08:12 INF] Route matched with {action = "Post", controller = "GoogleHome"}. Executing action HomeAutio. qtt.GoogleHome.Controllers.GoogleHomeController.Post (HomeAutio.Mqtt.GoogleHome) [05:08:13 INF] Removing expired grants [05:08:16 INF] Request starting HTTP/1.1 GET http://192.168.111.101:5000/google/home/.well-known/openid-con iguration [05:08:16 INF] Invoking IdentityServer endpoint: IdentityServer4.Endpoints.DiscoveryEndpoint for /.well-kno n/openid-configuration [05:08:18 INF] Request finished in 2401.5834ms 200 application/json; charset=UTF-8 [05:08:19 INF] Request starting HTTP/1.1 GET http://192.168.111.101:5000/google/home/.well-known/openid-con iguration/jwks [05:08:19 INF] Invoking IdentityServer endpoint: IdentityServer4.Endpoints.DiscoveryKeyEndpoint for /.well- nown/openid-configuration/jwks [05:08:19 INF] Request finished in 335.1122ms 200 application/json; charset=UTF-8 [05:08:20 INF] Successfully validated the token. [05:08:20 INF] Authorization was successful. [05:08:22 INF] Executing action method HomeAutio.Mqtt.GoogleHome.Controllers.GoogleHomeController.Post (Hom Autio.Mqtt.GoogleHome) with arguments (["HomeAutio.Mqtt.GoogleHome.Models.Request.Request"]) - Validation s ate: Valid [05:08:22 INF] Received EXECUTE intent for commands: action.devices.commands.SetFanSpeed

Unhandled Exception: [05:08:22 INF] Executed action method HomeAutio.Mqtt.GoogleHome.Controllers.GoogleHome ontroller.Post (HomeAutio.Mqtt.GoogleHome), returned result Microsoft.AspNetCore.Mvc.OkObjectResult in 184. 654ms. System.NullReferenceException: Object reference not set to an instance of an object. at HomeAutio.Mqtt.GoogleHome.MqttService.HandleGoogleHomeCommand(Command command) in /app/HomeAutio.Mqtt GoogleHome/MqttService.cs:line 185 at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.b__7_1(Object state) at System.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback call ack, Object state) --- End of stack trace from previous location where exception was thrown --- at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback call ack, Object state) at System.Threading.QueueUserWorkItemCallback.ExecuteWorkItem() at System.Threading.ThreadPoolWorkQueue.Dispatch() at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()`

i8beef commented 5 years ago

That should fix it.

diabl0w commented 5 years ago

working perfect! thank you so much!

i8beef commented 5 years ago

Awesome! Thanks for trying everything out. There are several untested device types, and that's one more that works now.