SmartThings ThingShield - Can't alert on contact state change


#1

I hope that this hasn’t been covered somehow, as it should be a easy fix… I think. Perhaps my Google skills are subpar. For the below code, all that I am trying to do is generate state changes when a contact opens or closes. I get events just fine; the list of “frontDoor is open”/“closed”, etc, but it never changes the icon and thus, to my understanding, never registers as open or closed for alarming purposes.

Can anyone point out what I’m doing wrong?

// Device Handler
metadata {
definition (name: “DoorContactSensors”, author: “Daniel Ogorchock”) {
capability “Contact Sensor”
}

// UI tile definitions
tiles {        
    standardTile("frontDoor", "device.contact", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
		state "open", label:'Front Door', icon:"st.contact.contact.open", backgroundColor:"#ffa81e"
		state "closed", label:'Front Door', icon:"st.contact.contact.closed", backgroundColor:"#79b821", defaultState:true
    }
    standardTile("deckDoor", "device.contact", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
		state "open", label:'Deck Door', icon:"st.contact.contact.open", backgroundColor:"#ffa81e"
		state "closed", label:'Deck Door', icon:"st.contact.contact.closed", backgroundColor:"#79b821", defaultState:true
    }
    standardTile("basementDoor", "device.contact", width: 1, height: 1,  canChangeIcon: true, canChangeBackground: true) {
		state "open", label:'Basement Door', icon:"st.contact.contact.open", backgroundColor:"#ffa81e"
		state "closed", label:'Basement Door', icon:"st.contact.contact.closed", backgroundColor:"#79b821", defaultState:true
    }
    standardTile("garageDoor", "device.contact", width: 1, height: 1,  canChangeIcon: true, canChangeBackground: true) {
		state "open", label:'Garage Door', icon:"st.contact.contact.open", backgroundColor:"#ffa81e"
		state "closed", label:'Garage Door', icon:"st.contact.contact.closed", backgroundColor:"#79b821", defaultState:true
	}
    
    main (["frontDoor","deckDoor","basementDoor","garageDoor"])
    details (["frontDoor","deckDoor","basementDoor","garageDoor"])
}

}

def parse(String description) {

def name = null
def value = zigbee.parse(description)?.text
def result

// Don't care about ping
if (value == "ping" || value == " ") 
{
	return
}

def linkText = getLinkText(device)
def descriptionText = getDescriptionText(description, linkText, value)

//log.debug "Description is ${value}"
def incoming_cmd = value.split()

name = incoming_cmd[0]
value = incoming_cmd[1]

if ( value == "open" ) {
	sendEvent(name: name, value: value, isStateChange:true)
    result = createEvent(name: name, value: value)
    log.debug "test '${name}'='${value}'"
}
if ( value == "closed" ) {
	sendEvent(name: name, value: value)
    result = createEvent(name: name, value: value)
    //log.debug "test '${name}' is closed"
}

}


(Kevin) #2

I just want to point out that device handlers aren’t really meant to be used this way, but I understand what you’re doing and can’t think of a better way to do it, so I’ll explain how you can make it work.

You should add a namespace to your device handler.

Tiles reference device attributes like “device.contact” and creating or sending an event with that attribute name “contact”, causes the tiles referencing that attribute to change.

In your code, the names “frontDoor”, “deckDoor”, etc. are the tile names and the only place they are used is the main and details lines. The main line can only reference one tile so you need to choose one and make it look like:

main "frontDoor"

At the moment, all of your tiles are referencing the “contact” attribute which is why it’s not working. In order for the tiles to show different values, you will need to create an attribute for each of them and reference them like “device.frontDoorContact”, “device.deckDoorContact”, etc. (these are just examples, you can name the attributes anything you want)

The attribute definitions go in the metadata below the capability line and they can look something like:

attribute "frontDoorContact", "String"
attribute "deckDoorContact", "String"

To change the attribute values, you need to raise the event using either createEvent or sendEvent, not both.

To make the parse method work, you need to make sure that the incoming command names match the attribute names and once you do that, assuming the only possible values are “open” and “closed”, you should be able to replace everything between the “value = incoming_cmd[1]” line and the last closing bracket with:

createEvent(name: name, value: value, isStateChange: true)


#3

Thank you! I have a lot to figure out with the relationships between the devices, device types, and smartapps… Your notes are very helpful.