Help with changing tile states

(Brice; #1

Hi all,

I am working on a custom device type, but I am having some trouble understanding how to change my tile states programatically. I have this tile:

                standardTile("panic", "device.panic", width: 1, height: 1, canChangeIcon: false, canChangeBackground: true) {
                        state "off", label:'Panic', action:'panicConfirm', icon:"st.alarm.alarm.alarm", backgroundColor:"#ff0000"
                        state "confirm", label:'Confirm', action: 'panic', icond:"st.alarm.alarm.alarm", backgroundColor:"#ff6600"

And these functions defined:

def panicConfirm() {
	log.debug "Entering panic confirm"
	sendEvent(name: "panic", state: "confirm")

def panic() {
	log.debug "Sending panic command"
	zigbee.smartShield(text: "panic").format()

I added panic and panicConfirm as custom commands in the device type settings. When I press the “panic” tile, I can see that it does call my panicConfirm method, but the tile state does not change to the “confirm” state. What am I missing here?

(Steve S) #2

@obycode - you need to put “panic” as a custom attribute and leave panicConfirm as a command.

(Brice; #3

@Steve28 - Thanks for the reply. I tried adding “panic” as a custom attribute, but I am still not seeing my tile change into the “confirm” state. In my log, I see the “Entering panic confirm” when I tap the tile, but the tile does not change colors as I expect. Is there something else missing?

(Brice; #4

Could anyone provide a good explanation about what these custom attributes and commands really mean from a programmer’s prospective? I haven’t found good documentation on this and I’m still unclear on what these do? I am familiar with object-oriented and message passing programming, so if someone could help me translate these back into that language, it would be very helpful.

(Steve S) #5

@obycode - can you post your parse() function. Maybe you’re not forming your response Map correctly.

As far as documentation goes - it’s the Wild West out here. You have to post stuff here, look at as many examples as you can, hours of trial-and-error, and blindly stumble around until you find a solution. Also some of the documentation is flat out wrong as well, so even if you do find some and things don’t work right, don’t be surprised.

I have been extremely disappointed and feel a bit duped from when I bought in to smartthings - with some decent documentation, this community could be a great resource to vastly expand the capabilities at a much faster rate.

Thankfully there are very helpful people here to help each other.

(Brice; #6

Oh, that must be my problem. I thought that the parse() function was just for handling the messages coming from the device, so I don’t have anything in there to handle this command coming from the hub. How does this command come in? I tried reverting to a very simple parse():

// parse events into attributes
def parse(String description) {
	def value = zigbee.parse(description)?.text
	def name = value && value != "ping" ? "response" : null
	def result = createEvent(name: name, value: value)
	log.debug "Parse returned ${result?.descriptionText}"
	return result

but I do not see anything coming in after pressing the button.

(Brice; #7

@Steve28 - I’m disappointed to hear that the documentation is a recurring problem. Hopefully that can improve, either officially, or with the community. I’ll be happy to help as I learn more!

(Steve S) #8

@obycode - I’m no expert… but the parse() function is called when the physical device sends an event to the hub/cloud/whatever. So, the z-wave device sends out a blip of data, and that gets sent to the device handler’s parse() function.

I’m not 100% sure what all the different options are, but I know at the very least, you need to have parse return a Map with a name: and a value:

so in the parse method you have you would have to figure out from the incoming description what value you wanted to have for “panic” such that the line:

def result = createEvent(name: name, value: value)

was something like:

def result = createEvent(name: "panic", value: "confirm")

that would cause your tile to update.

you might be able to leave your parse the way it is and use

sendEvent(name: "panic", value: "confirm")

note I changed the word “state” to “value” from your code.

(Brice; #9

Oh wow, yes, so after all this, I just had a silly mistake of somehow substituting “state” in place of “value”. Thanks for catching that! Once I make that change, everything works as expected. Thanks so much!!