Change labels of child device programatically?

We really cannot reduce the number of device handlers as each of them implements a specific SmartThings “Capability.” SmartApps use the “Capabilties” to filter devices. A device with a specific capability must implement specific attributes and commands to be compatible with standard SmartApps. The values of these attributes must also be standard.

See http://docs.smartthings.com/en/latest/capabilities-reference.html for details of each capability.

You could make a device with multiple capabilities and update the capabilities value since you are passing “contact” or “temperature” with the value. I was also thinking more if you didn’t need to use them in other routines and only cared about status info. Temperature, humidity, voltage, contact, etc could be reduced to a single device.

Not saying youd want to in your stuff but it would “work”.

Are you suggesting that the “capabilities” of a device can be changed at runtime? Do you have any code examples of this? This would be interesting to understand.

Oh no, I wish the capabilities could be dynamic but in this regard (child DTH’s) I don’t think they can be.

What I am saying, and I’ll stress this is not a good idea but it should technically work, you could potentially make a DTH that has the temperature, contact, humidity, and voltage capabilities but still have a single display tile (like above example and just call the tile “Display”). When you send in the value (“contact”, “open”) you could, based on the “contact” part, update the contact capability part to open. The temperature, humidity, voltage, etc would be default value. So you could still reference the DTH as a contact sensor and it would work. You could even update the background color dynamically so if used as a temperature you can change the colors based on values like normal. You could, potentially, have one DTH for those 4.

Problem is you could also be using it only as contact but reference it in a routine incorrectly as temperature, humidity, voltage and never get a value. So like I said it would “work” and if you only cared about status values and not using it in other routines it would be fine. But for what you’re doing you are better off with multiple DTHs.

Didn’t mean to lead you down the rabbit hole.

Again…I’m not recommending this but here is a example of a single child DTH for status:

metadata {
    definition (name: "Child Status Sensor", namespace: "RandomNamespace", author: "Allan (vseven)") {
        capability "Relative Humidity Measurement"
        capability "Temperature Measurement"
        capability "Voltage Measurement"
        capability "Contact Sensor"
        capability "Sensor" 
 
        attribute "lastUpdated", "String"    
        attribute "display", "String"     
    }

    tiles(scale: 2) {
        multiAttributeTile(name:"display", type: "generic"){
            tileAttribute ("device.display", key: "PRIMARY_CONTROL") {
                attributeState "default", label:'${currentValue}', icon:"st.contact.contact.open", backgroundColor:"#00a0dc"
            }
            tileAttribute("device.lastUpdated", key: "SECONDARY_CONTROL") {
                attributeState("default", label:'    Last updated ${currentValue}',icon: "st.Health & Wellness.health9")
            }	
        }
            main(["display"])
            details(["display", "lastUpdate"])
    }
}

def generateEvent(String name, String value) {
    log.debug("Passed values to routine generateEvent in device named $device: Name - $name  -  Value - $value")
    // Update device based on passed value
    sendEvent(name: name,value: value)
    // Update the display based on passed value
    sendEvent(name: "display", value: value)
    // Update lastUpdated date and time
    def nowDay = new Date().format("MMM dd", location.timeZone)
    def nowTime = new Date().format("h:mm a", location.timeZone)
    sendEvent(name: "lastUpdated", value: nowDay + " at " + nowTime)
}

Using this for my Temperature, Humidity, and Contact displays the standard open/closed for the contact then just the values for temperature and humidity. To get the percent or degree symbol you’d have to have a if/then to evaluate the value being passed (temperature, humidity, etc) and append that formatting to the passed value.

Since you are passing in the type it will correctly update that capability also. But this is more of a proof of concept that it can be done then a this is how it should be done. If capabilities could be turned on and off programmatically then you could use one DTH but I don’t think you can change anything in the “definition” section like that. Makes sense…you could assign a contact sensor to something and then have that contact sensor change to a temperature sensor for example and mess everything up.

So long story short just keep all your DTH’s. :wink:

-Allan

That’s my plan. They are really no trouble once written. You really don’t want SmartApps listing devices under “Temperature Senors” that are really being used as “Contact Sensors”, etc…

You’d actually need different tiles for each capability that conform to the attributes for each individual capability.

Basically, it would work only for a display in the ST Phone App. If you want to use the data for anything useful, you need to follow the ST Standard Guidelines for writing a Device Handler.

1 Like

Agree with this, whilst it works for some use cases, it doesnt work for all. And having the multi-capability tiles really messes with CoRE since it can only detect the changes of the specific tiles related to the specific capability of the device.

One thing I would also add, is that when using Preferences as values/strings that are used elsewhere in the code you have to be careful, since ST is not very good at picking up changes. Hence I have found if you change the preference value/string to something else it can take a week before the code sees this change, and can also return ‘null’ for an equal period of time, until it is put back to its original value (or ST notices the new value).

That said Im pleased it works for you and I know it worked well for me in most situations where I was trying to prevent using multiple extra device handlers.

Yeah, it seems to pick it up pretty quick. Then again im setting the label both from the updated() routine and again each time the value is updated from the parent device.

So far no issues with it displaying.

So I have one more issue I’m trying to solve and maybe those following this post can help.

I want to invert the background colors. Now I don’t want to invert the “value” of the contact. Open is still open, closed is still closed, but I do want to flip the color. For example I have a contact closure on a heater. When the heater is off the contact is “open” but I want the background to be blue (the normal closed color). When the header is running (contact closed) I want it to be orange (the normal open color).

I added a “invertColors” preference but I don’t seem to be able to use it without changing the value being passed to the tile and like I said I still want to maintain open and closed. Any ideas?

Just create a custom Device Handler with the colors inverted, save it, publish it, and then change the DH of the Child Device to the custom one. It only takes a few minutes at most. Not really worth trying to make it generic, IMHO.

Yeah but what fun is that? :slight_smile:

I think I may have the answer but I’m hoping I’m wrong. I’ll work on it a little tomorrow.

I just like the idea of having one “Contact” sensor that is flexible instead of one for “On/Off”, another for “Yes/No”, another for “No/Yes”, another for “Open/Closed”, etc.