Quirky Tripper Support?

i don’t knoew if i did right.

Copied Code click on create
Click on Publish selected for me.

after that i rest the tripper as you send above and tried to connect. it is not connecting still

@anwesh, sounds like you may need to perform a general exclude on the device first since it won’t join to your hub, or did it join already and you see it in your device list and it’s not updating?

I did some progress now.

After Publish the code

I went into My Devices and Added the Device Manually and then connected device from app. it found the thing. but i am not getting any triggers now. i app it shows as open.

After Publish, i can get add the device manually by going to my device and them connect by app. is this right way?

Ok, that’s progress! Try opening/closing the contact sensor, as well as open the device to see the battery and cause a tamper alert. That may “wake up” the device and start communicating it status.

I need to understand 1 thing. You manually created the device in the IDE? You should only need to connect a new device from the app, and it should search and come back and say Found and then Identifying, or something to that effect.

Step i Did

1 - Added Code in My Device Types, clicked on create, clicked on save. After that i click on publish. it gave drop down for me. I clicked on it and Publish.
2. After publish i went in to the Android app and i clicked on connect new devices. it is say im looking for your new things and it is at that windows. after about 20 min i clicked on my devices from the web
3 there i click create new device. please find screen below.

in below screen name i gave as tripper
device network id as trip01
type quirky/wink tripper
version publish and my hub details for location and hub.

After then i tried to search the device from mobile app and it connected.

when i click on Tripper it say open. no activity is triggering.

Yeah you shouldn’t create the device in ide. Steps 1 and 2 are right but 3 may be screwing you up.

  1. I would remove all the devices you manually added, not the device type…keep that…that should be right.
    Check the app and Ide under My Devices to make sure you removed them all.

  2. Start the Connect Now (spinning circle).

  3. (On the Tripper) Take the battery out, press the button, put the battery back in, let go of the button. This should reset the Tripper and set it to pairing mode to look for the hub. I think it will start to blink a few times but won’t blink the whole time, it’s still trying to pair though.
    This device is Zigbee so there is no exclude, just a reset.
    It sounds like you have already done all of this but it never finds it. Can you move the Tripper closer to the hub? It may be too far from the hub, start with the closest device if possible then move out from there.
    I’m sure you have the right device type but I can send you mine if you want just to rule that out.

Do you have any other Zigbee devices connected to the hub now?

1 Like

Yeah, don’t do that.

Do this:

  1. Delete every device you created that way.
  2. Look at the device’s documentation on how to reset it, and redo the Connect New Device process from your SmartThings app.
  3. I recommend being as close to the hub as possible when trying to connect.
  4. Repeat as needed until the device connects. Since you have created your own custom device type, it should find it as the right type.
  5. If it’s found as a “Thing”, then go into the IDE and change Type to your device type. Based on the list you show above, you only have 1 custom device type to pick from.

I have a couple of these and they work very well.

1 Like

@johnconstantelo,
Great minds think alike :smile:

Also you can try to open the IDE and open the Live Logging tab to see if you see any problems there when it’s trying to pair.

1 Like

This is the device type i am using

Hope this is right one.

I was able to connect GE Link Bulbs with out any issues

Ok mine looks a little different and it could be that mine is older, I’m not sure but it works.

Here is mine and may be worth trying to overwrite yours, Save and Publish for Me. Then try to re-pair.

/**
 *  Quirky Wink Tripper Contact Sensor
 *
 *  Copyright 2015 Mitch Pond, SmartThings
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 */

metadata {
    definition (name: "Quirky/Wink Tripper", namespace: "mitchpond", author: "Mitch Pond") {
    
    capability "Contact Sensor"
    capability "Battery"
    capability "Configuration"
    
    attribute "tamper", "string"
    
    command "configure"
    command "resetTamper"
        
    fingerprint endpointId: "01", profileId: "0104", deviceId: "0402", inClusters: "0000,0001,0003,0500,0020,0B05", outClusters: "0003,0019"
    }

    // simulator metadata
    simulator {}

    // UI tile definitions
    tiles {
        standardTile("contact", "device.contact", width: 2, height: 2) {
            state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
            state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
        }
        
        valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false) {
            state "battery", label:'${currentValue}% battery', unit:""
        }
        
        standardTile("tamper", "device.tamper", canChangeIcon: true, canChangeBackground: true) {
            state "OK", label: "Tamper OK", icon: "st.security.alarm.on", backgroundColor:"#79b821"
            state "tampered", label: "Tampered", action: "resetTamper", icon: "st.security.alarm.off", backgroundColor:"#ffa81e", nextState: "OK"
        }
        
        main ("contact")
        details(["contact","battery","tamper"])
    }
}

// Parse incoming device messages to generate events
def parse(String description) {
    //log.debug "description: $description"

    def results = []
    if (description?.startsWith('catchall:')) {
        results = parseCatchAllMessage(description)
    }
    else if (description?.startsWith('read attr -')) {
        results = parseReportAttributeMessage(description)
    }
    else if (description?.startsWith('zone status')) {
        results = parseIasMessage(description)
    }

    log.debug "Parse returned $results"

    if (description?.startsWith('enroll request')) {
        List cmds = enrollResponse()
        log.debug "enroll response: ${cmds}"
        results = cmds?.collect { new physicalgraph.device.HubAction(it) }
    }
    return results
}

def configure() {
    String zigbeeId = swapEndianHex(device.hub.zigbeeId)
    log.debug "Confuguring Reporting, IAS CIE, and Bindings."
    
    def cmd = [
        "zcl global write 0x500 0x10 0xf0 {${zigbeeId}}", "delay 200",
        "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
    
        "zcl global send-me-a-report 0x500 0x0012 0x19 0 0xFF {}", "delay 200", //get notified on tamper
        "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
        
        "zcl global send-me-a-report 1 0x20 0x20 5 3600 {}", "delay 200", //battery report request
        "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
    
        "zdo bind 0x${device.deviceNetworkId} 1 1 0x500 {${device.zigbeeId}} {}", "delay 500",
        "zdo bind 0x${device.deviceNetworkId} 1 1 0x0b05 {${device.zigbeeId}} {}", "delay 500",
        "zdo bind 0x${device.deviceNetworkId} 1 1 1 {${device.zigbeeId}} {}", "delay 500",
        "st rattr 0x${device.deviceNetworkId} 1 1 0x20"
        ]
    cmd
}

def enrollResponse() {
    log.debug "Sending enroll response"
    [    
    "raw 0x500 {01 23 00 00 00}", "delay 200",
    "send 0x${device.deviceNetworkId} 1 1"
    ]
}

private Map parseCatchAllMessage(String description) {
     def results = [:]
     def cluster = zigbee.parse(description)
     if (shouldProcessMessage(cluster)) {
        switch(cluster.clusterId) {
            case 0x0001:
                log.debug "Received a catchall message for battery status. This should not happen."
                results << createEvent(getBatteryResult(cluster.data.last()))
                break
            }
        }

    return results
}

private boolean shouldProcessMessage(cluster) {
    // 0x0B is default response indicating message got through
    // 0x07 is bind message
    boolean ignoredMessage = cluster.profileId != 0x0104 || 
        cluster.command == 0x0B ||
        cluster.command == 0x07 ||
        (cluster.data.size() > 0 && cluster.data.first() == 0x3e)
    return !ignoredMessage
}

private parseReportAttributeMessage(String description) {
    Map descMap = (description - "read attr - ").split(",").inject([:]) { map, param ->
        def nameAndValue = param.split(":")
        map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
    }
    //log.debug "Desc Map: $descMap"

    def results = []
    
    if (descMap.cluster == "0001" && descMap.attrId == "0020") {
        log.debug "Received battery level report"
        results = createEvent(getBatteryResult(Integer.parseInt(descMap.value, 16)))
    }

    return results
}

private parseIasMessage(String description) {
    List parsedMsg = description.split(' ')
    String msgCode = parsedMsg[2]
    int status = Integer.decode(msgCode)
    def linkText = getLinkText(device)

    def results = []
    
    if (status & 0b00000001) {results << createEvent(getContactResult('open'))}
    else if (~status & 0b00000001) results << createEvent(getContactResult('closed'))

    if (status & 0b00000100) {
            //log.debug "Tampered"
            results << createEvent([name: "tamper", value:"tampered"])
    }
    else if (~status & 0b00000100) {
        //don't reset the status here as we want to force a manual reset
        //log.debug "Not tampered"
        //results = createEvent([name: "tamper", value:"OK"])
    }
    
    if (status & 0b00001000) {
        //battery reporting seems unreliable with these devices. However, they do report when low.
        //Just in case the battery level reporting has stopped working, we'll at least catch the low battery warning.
        log.debug "${linkText} reports low battery!"
//        results << createEvent([name: "battery", value: 10])
    }
    else if (~status & 0b00001000) {
        //log.debug "${linkText} battery OK"
    }
    //log.debug results
    return results
}

private getBatteryResult(rawValue) {
    //log.debug 'Battery'
    def linkText = getLinkText(device)

    def result = [
        name: 'battery'
        ]

    def volts = rawValue / 10
    def descriptionText
    if (volts > 3.5) {
        result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
    }
    else {
        def minVolts = 2.1
        def maxVolts = 3.0
        def pct = (volts - minVolts) / (maxVolts - minVolts)
        result.value = Math.min(100, (int) pct * 100)
        result.descriptionText = "${linkText} battery was ${result.value}%"
    }

    return result
}


private Map getContactResult(value) {
    def linkText = getLinkText(device)
    def descriptionText = "${linkText} was ${value == 'open' ? 'opened' : 'closed'}"
    return [
        name: 'contact',
        value: value,
        descriptionText: descriptionText
        ]
}

private resetTamper(){
    log.debug "Tamper alarm reset."
    sendEvent([name: "tamper", value:"OK"])
}

private hex(value) {
    new BigInteger(Math.round(value).toString()).toString(16)
}

private String swapEndianHex(String hex) {
    reverseArray(hex.decodeHex()).encodeHex()
}

private byte[] reverseArray(byte[] array) {
    int i = 0;
    int j = array.length - 1;
    byte tmp;
    while (j > i) {
        tmp = array[j];
        array[j] = array[i];
        array[i] = tmp;
        j--;
        i++;
    }
    return array
}

Thank you very much. you code is working. you rock my day

1 Like

Awesome, I’m glad I was able to help!

I just wanted to say, I am new to the ST v2 and today I was at Home Depot and saw 2 pack of these for $40, I bought them and brought them home. I followed these few last posts and got them connected and working! Thanks!

1 Like

They are definitely great for the price. I would have kept buying them if it wasn’t for the PEQ deal at the time. My only gripe about these is the battery life, not horrible but definitely not great. They serve the purpose though.

What other brand sensors are you using? These are the first sensors I’ve purchased and used, but also curious about the battery life on these, what’s the battery life like if you had to estimate for these ?are there some better alternatives?

FYI: the Wink Hub has a firmware update for these (as well as Outlink and Tapt). I have no idea what the changes are. Updated all of mine last night. Will have to see if the battery lasts any longer now.

They only way to update them is by having a wink hub, right? I only have the ST v1 HUB, so I’m assuming no updates for me, lol.

Yep. Unless ST rolls out OTA support and gets the updates from Wink. Probably not likely. I just happen to have a couple of free Wink hubs that I’ve obtained through various promotions.

One change I have noticed is that the light now blinks when the state changes open/closed.

Mine have always done that, I wonder if the update is older as I moved from wink to smartthings 2 months ago.