I do have four ZW4SF in my mesh. Also using Hubitat's native Google Home integration.
I am using @Vyrolan's modified version of @erniemiller's ZW4SF driver . With the Hubitat Google Home integration updates in 2.3.9.192, the driver "just works" for me now without any modification. I did have some issues with the driver and GH prior to 2.3.9.192.
Edit 1:
The 2.3.9.192 Google Home integration update expects drivers to implement required functionality. For capability "FanControl" that includes among other things having supportedFanSpeeds populated. There are a lot of fan (and I'm sure other types) drivers out there not in compliance with Hubitat's Driver Capabilities documentation.
I have suggested to the Hubitat crew that they implement null safe checks in the Google Home integration for driver required functionality to mimic past behavior. Not sure if they will accept my recommendation in any future update.
Edit 2:
In the alternative to implementation of null safe checks and letting bad drivers through as in the past, they could detect and better report in the logs what the failure is, eg: driver xxx is missing required attribute supportedFanSpeeds. And even if a driver cannot be accepted, just skip over the bad device and process the rest as expected.
It’s an engineering philosophy that technology should work even when it fails. Example: a failed escalator still properly functions as stairs to get you up or down a floor,
What is the real purpose of this supportedFanSpeeds Attribute. Do apps use it to determine certain functionality.
Thanks you @gatewoodgreen and @jtp10181 as I finally got something to work this morning. I had initially used a example that @mike.maxwell had provided a while back to manage the setspeed commands and fan speed values. Because of that I initially tried a few things to make this work. Simply sending the event with the value like this doesn't seem to work
I tried a few variations of this and it never seemed to work like it wasn't interpreting the value correctly. It looked good on the devices page, butI kept getting this error below.
It looks like it was having a hard time parsing it and understanding the json format.
I also tried just updating the sendevent command to include the values from the @field map values I had already, and it yielded the same results.
The modified code @gatewoodgreen linked gave me that hint to covert it to Json as part of the send event call. Thought this might help others if they come here with the same problem. Good thing for me is I can use that one line of code to fix the rest of my drivers. Thanks guys
Yes, apps can read the supportedFanSpeeds property of the device and not send an invalid speed change command. Although funny enough Hubitat's own native fan UI (dashboard widgets) doesn't read and adjust to the attribute, so a quality fan driver needs to have a setSpeed() function that accepts all Hubitat valid speeds and translates the invalid speeds to a valid one, or at least doesn't do something dumb with an invalid/unsupported speed call.
Aside another Hubitat required functionality not in all fan drivers is cycleSpeed(). But missing that function doesn't crash Hubitat's native Google Home integration (yet). It will however result in groovy MissingMethodException errors in your Hubitat logs if you try to invoke Cycle Speed function from Rules, Dashboard widgets and other fan related apps.
Example from a driver I am fixing:
dev:188 2024-10-23 07:45:27.100 AM error org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: user_driver_bond_BOND_Fan_With_Direction_779.cycleSpeed() is applicable for argument types: () values: [] (method cycleSpeed)
The capabilities that are defined as a "JSON_OBJECT" have always been a struggle with how should they be populated so they are compatible with everything else. Maybe @bertabcd1234 could shed some light on the current proper way to populate these fields for custom drivers? I think you have spoke to this in the past, maybe on the thermostat drivers?
I have custom drivers that use the fan speeds and the lightEffects so I would like to know.
Thanks Mike, I will adopt that change to my drivers!
Any insight on the "color" attribute? I would have to dig up the old thread but if this is set correctly the color picker will use the level value there instead of the level attribute (which is often the brightness and not the "L" the color picker should use).
It is documented generically as a STRING
And I found what works for the color picker is just sending a map as the value:
Curious what Mike or Victor thinks, but if you ask me:
The format for this has never been standardized AFAIK, and I've seen things ranging from HTML-style RGB hex string to a JSONified map of HSV or similar values
In many built-in drivers, it's not set at all (hueBridgeBulbRGBW, Generic Zigbee RGBW Bulb, Generic Matter RGBW Light, and probably many others)
I am not aware of any built-in (or community?) apps that rely on this value, and given the above, I'd be surprised
The fact that it affects display of the color picker in the UI is probably the result of uncertainty regarding all of this (I'd pick the well established hue, saturation, and level attributes personally)
The inclusion of it as part of the capability spec is likely something that has never been reviewed since modeling the original capability after that of a certain other legacy platform – but it may be time to revisit
It may have been a fix just to satisfy myself after my constant pestering about the color picker incorrectly using the level (brightness) when that is not what it should be using. The H and S are not a problem because they have a singular purpose, but the L by default pulls from the level, which can also be the device brightness and is not always the same as the color "level" depending on the device. Wont go into any other details as I am sure you recall I have discussed it to death in the past.
I really just wanted to be able to separate out the two different "level" values and this was the solution that I think @gopher.ny had me try, and we eventually figured out how to get it to work. If you populate that color attribute as I have, the color picker uses that level instead of the level attribute. Not sure about the H/S, I do not think I tested having them be different from the attribute value.
It is interesting that you bring this up. I have been pulling my hair out trying to figure out what is needed to enable scenes through native Hubitat apps and such. I can't for the life of me get it to work though. What is even more confusing is that the only other device i have that does light effects(Wiz Bulbs with Native driver) seems to use undocumented options to provide the functionality in apps like RL.
Just for testing i created a routine to populate a lightEffects Attribute with the appropriate scene names, Create a setScenes command similar to Wiz devices to see if this would help enable scenes to be scene in apps. It didn't work. I would really love to hear from @mike.maxwell or really anyone that knows what is needed to get Light effects to work in Native Hubitat apps. Right now users of my integration need to use the option to Run a custom option and use actuator to send a custom command. I have tried to use all the appropriate Light based capabilities to get it to work though.
I think it nice to provide an accurate list of supported speeds...
You are probably supporting a fixed speed set device, but the Bond work I am doing needs to support fans with between 2 and 10 different speeds so the app+driver code has a dynamic speed mapper. For fans with less than 5 options, I start removing Hubitat word speed options from the supportedFanSpeeds list.
maxSpeedN below is the numerical count of speed options for the given fan device instance.
translateBondFanSpeedToHE() implements a map of maps of numeric speeds (the devices work on numbers) to Hubitat words. For a 10 speed fan, 10 == high, for five speed, 5 == high, for 3 speed, 3 == high (and 2 == medium) , etc...
The app+driver code also has an inverse map of maps, translateHEFanSpeedToBond(). This one is setup to allow setSpeed() to do the right thing even if some app sends the driver an "unsupported" speed.
I implemented auto as the Bond built-in Breeze feature, but before I integrated Breeze support into the driver, I left auto out of the supportFanSpeeds list.
This requires the app to query these types of attributes then build a list for use in sending the commands, I don't think any of our apps do this currently.
I might post this in the feature request section.