supportedFanSpeeds in 2.2.6

Has anyone figured out how to use the new supportedFanSpeeds attribute in 2.2.6 for the FanControl capability? It's defined as having type JSON_OBJECT, and a simple JSON array of the supported speed names from among Hubitat's possibilities is the only thing that would make sense to me. So, that would give you something like:

List<String> fanSpeedList = ["low", "medium", "high", "auto", "off"]
groovy.json.JsonBuilder fanSpeedsJSON = new groovy.json.JsonBuilder(fanSpeedList)
sendEvent(name: "supportedFanSpeeds", value: fanSpeedsJSON)

This seems to work, in that the attribute value gets populated. However, it does not have any effect: the "Set Speed" command on the device page still shows all options (not sure if this was ever really intended to change that, though), and a Dashboard tile still shows all of them too (do I remember that this was part of the reason for introducing this?).

So, I guess that leaves two possibilities: I'm doing it wrong, or 2.2.6 is a "transitional" release that introduces the capability changes but doesn't make use of them yet. I'm used to the former being the case, but given similar changes in 2.2.6 that also haven't been made use of yet, I'm guessing it might be the latter this time. :slight_smile: Anyone know for sure? (Guessing staff would have to comment on this since I see no other documentation than the above, but if anyone happens to have figured something out regardles...)

If you want the enum list in the device setSpeed command to reflect the values in your custom supportedFanSpeeds you will need to override the capability setSpeed command in the driver via something like:

command "setSpeed", [[name: "Fan speed*",type:"ENUM", description:"Fan speed to set", constraints: getFanLevel.collect {k,v -> k}]]

where getFanLevel in this case is:

import groovy.transform.Field
@Field Map getFanLevel = [
	"low": 25
	,"medium": 50
	,"medium-high": 75
	,"high": 100
	,"on" : 100
	,"off": 0
]
2 Likes

Thanks! Is a JSON array still the correct format for the fanSpeedList attribute itself, or does that also need to be a name/number map? I might override the command in my driver to avoid confusion (should anyone besides me use it...), but I'm also just curious what the new attribute is supposed to do since right now it doesn't appear to have any effect (aside from, I suppose, being there and something apps could read and adjust their behavior if needed?).

3 Likes

yes, that is the intent

I think the intent was for this to be actual formatted json, however these are actually just simple lists created as such:

sendEvent(name: "supportedThermostatModes", value: ["off", "heat", "cool", "auto", "emergency heat", "locked out", "fan", "dry"])
1 Like

Does the Generic Component Thermostat honour supportedThermostatModes events sent to the child?

Yes it does

1 Like

In what way? Can you explain how it interprets the event and what changes (if any) it makes to the behaviour of the child component ?? I'm sending the event, and from what I can see, it makes zero difference to the range of modes available... so maybe I'm missing where this has an impact

It sends the event exactly how it was received.. Think of the component drivers as dumb relays for events / commands..

Oh... so its behaviour isn't modified and it will incorrectly report a fan / thermo mode capability range incorrectly that isn't supported at all... ie any dashboard relying on the Generic Component won't be able to modify the range of heat/cool/off/etc... where obviously many Thermostats don't support those modes... kinda seems a bit daft to offer a range of settings that are fixed and unable to be modified ... but I guess my option is to not use the Generic Components and push my own private child driver to be more aligned to the parent thermostat. Correct?

Also, where is the most logical place to post an event on the supportedFanSpeeds or supportedThermostatModes ? Is that on every refresh? Or just once at some appropriate lifecycle point in the drivers start/creation ???

You only need to do it once.. I normally do all this in configure()..

Yes but if the hub was to be rebooted, how does configure get run on startup? So do you mind letting me know the best place for ongoing lifecycle state to ensure it runs once, whilst the driver is up and active and the event service is up? ie maybe after 30 seconds from starting up??

initialize() runs on hub restart/reboot

It will persist through reboots..

1 Like

Hard to confirm, but it looks as though the Generic Component Fan Control does not correctly deal with events sent from the parent that set supportedFanSpeeds - as the events don't seem to arrive, display or passed on as attributes to dashboards etc that might use them ???

This works as expected for me. I'm sure Hubitat has lots of built-in drivers that use it, but I'm using in a custom driver (for the Inovelli LZW36 fan/light switch) I wrote. I'm not sure what you're doing, but something like this:

myChildDevice.sendEvent([name: "supportedFanSpeeds", value: ["low", "medium", "high", "off"])

...should work (as should the named-parameter equivalent, though I'm not using it myself), where myChildDevice is a object referring to the device in question.

One issue is that this value doesn't seem to get used anywhere useful--notably, Dashboard still displays all the standard possibilities (or did last time I checked). An app could theoretically check these values and adjust its UI to match, but right now it's not clear to me how widespread this use is outside of anything internal to the driver itself (I suspect not at all).

1 Like

The issue that you've not confirmed is if the child component (that we can't debug or see inside of) is actually ignoring/dropping all but switch and speed attributes, and not passing / keeping the send event that is being sent to it - I have a dashboard that isn't seeing any supportedFanSpeeds events from the child when the parent sends them, but the speed/switch are working fine

I may not have been clear, but part of what I meant by "working" was that the device was parsing and generating the events as expected:

Screenshot: Current States section showing supportedFanSpeeds attribute

I'm not sure where your question with Dashboard fits into this; if you are using an "Attribute" tile to, for some reason, display supportedFanSpeeds, then it should pull that from the device page--and match what shows there. More likely, I suspect you have a "Fan" tile and are expecting the popup to show only the speeds indicated by this attribute. I asked about this above, and that is (currently?) not something Dashboard does, which again just shows all the standard attributes regardless; see my original post, post 3, and the staff replies to both.

This attribute is new, and perhaps more apps will take advantage of it going forward. But the lack of use is a separate issue from the event not getting generated at all. :slight_smile: I don't seem to have run into any problems there. If I'm missing something else, let me know and I can test what we are able to! This should be nearly anything (we don't need access to the source to tell when an event is generated, for example).

Are you talking about a child created as a Generic Component Fan Control where these events are appearing? Not a custom child that uses a custom driver, but the closed-source out-of-the-box Generic Component Fan Control ???

EDIT: The reason I'm asking is that this same approach with a child Generic Component Thermostat works with its "supportedXyz" events, but not the Generic Component Fan Control .... so with different behaviour I can only assume the code between the two children Generic Component drivers are different.

Yes, I am using the built-in component driver. I assume you are, too? (If not, you should of course have control over anything that happens in your own drivers, but just checking...) I linked to my full code above, but here is the relevant line if you wanted to verify:

fanChild = addChildDevice("hubitat", "Generic Component Fan Control", "${thisId}-2", [name: "${device.displayName} Fan", isComponent: false])

EDIT: Wait, do you mean the thermostat driver? If so, apologies for the confusion, as I originally started this thread for the supportedFanSpeeds attribute on fan control drivers (which is also the only place I see this documented, but I'm not sure if there were thermostat changes I don't remember or you're working with one that uses this as a child device; assuming it's not part of the capability, you won't get an event here on a component thermostat driver because it is not an attribute that is either part of an implemented capability or declared as custom).

EDIT 2: OK, I see supportedThermostatFanModes was added recently has always been here (?) and assume it should work similarly--but that I have not tested. Would be easy with a virtual parent driver to test, though...