How can I get possible values for an attribute?

I am writing an app intended to aggregate discrete sensor values in various ways (e.g. contact, motion or shock sensors) and map the result to an output virtual sensor.

I would like the user (well, me) to select the capability, device(s), device attribute and attribute value to be aggregated/mapped, as it is often done in built-in apps. However I seem to be unable to programmatically retrieve the possible attribute values.

With this code:

                input name: "inputSensors", type: selectedSensorCapability, title: "Sensors to aggregate", multiple:true, required: true, showFilter: true, submitOnChange: true
                if (inputSensors) {
                    def capabilities = inputSensors[0].getCapabilities()
                    def targetCapability = capabilities.find { it.name.toLowerCase() == selectedSensorCapability.substring("capability.".length()).toLowerCase() }
                    logObjectProperties(targetCapability)
                    logObjectProperties(targetCapability.attributes[0])
               (...)

private void logObjectProperties(obj) {
    log.debug "properties of ${getObjectClassName(obj)} BEGIN"
    obj.properties.each { property, value ->
        log.debug "${property}=${value}"
    }
    log.debug "properties of ${getObjectClassName(obj)} END"
}

I get:

In particular, the possibleValues property of the Attribute object is null.

What am I doing wrong? Are these documented classes not accessible somehow?

Attribute object is an abstract class (Attribute Object | Hubitat Documentation), but if you just want a list of all attributes and their values this should be close:

inputSensors.each { dev ->
     List <Attribute>  attrList = dev.getSupportedAttributes()
     attrList.each { attr ->
          log.debug “${attr.dataType} ${attr.name}”
          if(attr.dataType == ‘ENUM’) {
               log.debug “Enum values - ${attr.possibleValues}”
           }
          log.debug “Current value ${dev.currentValue(“${attr.name}”, true)}”
     }
}
3 Likes

Thanks. That got me to what I needed:

            if (selectedSensorCapability) {
                input name: "inputSensors", type: selectedSensorCapability, title: "Sensors to aggregate", multiple:true, required: true, showFilter: true, submitOnChange: true
                if (inputSensors) {
                    def capabilities = inputSensors[0].getCapabilities()
                    def targetCapability = capabilities.find { it.name.toLowerCase() == selectedSensorCapability.substring("capability.".length()).toLowerCase() }
                    def targetAttribute = inputSensors[0].getSupportedAttributes().find { it.name == targetCapability.attributes[0].name }

image

A bit convoluted IMO but it works. Still not clear as to why the Capability objects returned by the device don't return a valid list of Attribute objects...

BTW I cannot declare a List<Attribute> as importing com.hubitat.hub.domain.Attribute (or com.hubitat.hub.domain.Capability) is not allowed.

1 Like