Are there any examples or documentation of using DYNAMIC_ENUM

I found a reference to the attribute type DYNAMIC_ENUM and it seems to work fine when I declare on such as:

attribute "heaterMode", "DYNAMIC_ENUM",["OFF","Heater","Solar Pref","Solar Only"]

How does one change the available enumerations on this Attribute later in code? It feels like there might be a setValues() method? https://docs.hubitat.com/index.php?title=Attribute_Object

You use sendEvent, like all other attributes.
There's not much value in declaring it as this type vs string as these aren't constrained at this point anyway...

You just answered the question I was mulling over while drinking my coffee... Why would I use this instead of string. :wink:

2 Likes

So to the heart of the question...there is no user interface option at this point for enumerated lists outside the standard ones? Any plans to enable this? I am finding it limiting that a user can not change attributes or access custom commands from a dashboard. I could use the latter approach to work around this by exposing a command to select it's valid mode....but right now it seems my only option is to create a child device for each option and manage those as buttons. Doable but pretty arduous and leads to a pretty bloated UI.

So sendEvent would change the currentValue of the attribute right, not the list of valid enumerations? I get that it does not matter with currently available UI code, but it might with some future interface layer that can read this aspect of the data dictionary.

You could do this, which will build a dropdown list in the driver ui for the setHeaterMode command

command "setHeaterMode", [[name:"Heater mode*","type":"ENUM","description":"Heater mode to set","constraints":["Off", "Heater", "yada"]]]
attribute "heaterMode",  "string"
1 Like

That's right along the lines of what I was looking for and works great in the Driver UI.

heater

I think ideally this would translate into the Dashboard display as well, but that ties back to the idea of exposing access to a custom command in a Dashboard.
Thanks for this!

1 Like

Yeah, unfortunately you're limited to the templates that are available as far as dashboard control goes. You could use virtual switches for each mode and use RM to tie them into the mode selection on this device. Unfortunately I think that might be your only option at the moment, unless you can find a capability that fits in with your use-case.

The capabilities list is here.

1 Like

@Ryan780
I have also been looking for a way of getting this functionality on the dashboard, have you managed to resolve this?

Resolve it? There is no resolving it. The dashboard is limited to what Hubitat releases. They don't have any interest in making the code available to us. So, we are limited to what they provide.

Because rules engines read the attribute enum list and allow you to pick which one to trigger on.

With a String data type, that doesn't happen.

Having the ability to modify the enum list at run time, as part of a configuration step is a very valid use case.

I have an application that enrolls many different sensors. Those sensors all use the same data model, but need to report it differently through a common attribute, depending on a readable configuration byte. I'm faced with the decision whether to create many different drivers that differ only in their attribute enum set or a single driver with an all encompassing attribute enum set. I chose the latter for simplicity, but would greatly appreciate the ability to modify the enum set at runtime, based on that configuration byte.

At present my attribute enum set looks like this:

attribute "state", "enum",
    ["open", "closed", "wet", "dry", "motion detected", "no motion", "smoke detected", "no smoke",
     "co detected", "no co", "shatter detected", "no shatter", "panic detected", "no panic",
     "high temp detected", "low temp detected", "temp ok"]

That's 9 different sensor types, all in one driver, which is super convenient. However, when building rule triggers, the full list of enums show up even though the configuration byte suggests the sensor is a water sensor. Still, this inconvenience is preferred over having to manage 9 different driver files.

So yes, a runtime setValues(List enums) command would be useful.

We have discussed dynamic capabilities, commands and attributes in the past and made the determination that bang for the buck didnt exist.

Hi @mike.maxwell,

Sorry to resurrect this thread. I have an interesting case for some device drivers I'm creating. I'm supporting some appliances such as dishwashers, dryers, washers, etc. The API gives me a list of programs such device can support. Even between two different dishwashers, they can support a different list of programs. So my idea is to get this list from the API and expose it in a combo box where the user can choose and set it. I have a APP to create the drivers automatically based on the user account. I tried to set the list of programs when the child is created but without success. Do you know how I could make it work?

you should be able to do this by having the parent send an event on behalf of the child device, the device would then read that event into an enum for the preference setting.
I've not tried anything like this, but that would be the general tactic i would attempt.

So I tried to do this in the child:

   command "setProgram", [[name:"Program*", "type":"ENUM", "description":"Program to set", "constraints":listOfPrograms]]
    attribute "listOfPrograms", "DYNAMIC_ENUM", ["1", "2", "3"]

But setProgram is empty in the driver's page. After that I would send an event from the APP to update "listOfPrograms". Could you tell me what I did wrong?

EDIT:

I tried as well:

   command "setProgram", [[name:"Program*", "type":"ENUM", "description":"Program to set", "constraints":getPrograms()]]
    attribute "listOfPrograms", "DYNAMIC_ENUM", ["1", "2", "3"]

def getPrograms() {
return getDataValue("listOfPrograms")
}

But it didn't work either.

use enum for the device custom attribute type, we don't support dynamic_enum, also drop the value list
then from parent, childDevice.sendEvent(name:"listOfPrograms", value:new groovy.json.JsonBuilder(someDataStructureHere))
in the device build a method that returns a data structure built from listOfPrograms, something like:
def getPrograms() {
return parseJson(device.currentValue("listOfPrograms"))
}
in the driver preference section add the preference:
input(name:"selectedProgram", type:"enum",title: "select program", options:getPrograms())

then read selectedProgram value in the device updated method...

I'm getting this error: Cannot invoke method currentValue() on null object on line 33

If getPrograms() return an array list (e.g return ["1", "2"]), it works.

did you send the event for that attribute value from the parent app?, in the child device, does listOfPrograms have the value you sent from the parent app?
also try replacing "device" with "this" is this.currentValue...

No because I can't save the driver, I get the error I mentioned.

EDIT:
Using "this.currentValue" gives me this error: No signature of method: Script1.currentValue() is applicable for argument types: (java.lang.String) values: [listOfPrograms] on line 33

you may have to deal with the attribute not being populated initially.
you can put an if around the input, if (this.currentValue("listOfPrograms") != null) {input blablabla}