Hi, im having problem of battery reading after change to your customized device type. Any thoughts?
Jeff
Hi, im having problem of battery reading after change to your customized device type. Any thoughts?
Jeff
Hi, thanks for putting together this solution for the Kwikset locks. I was able to create the device type and app, and successfully sent the PIN codes to the locks. However, once I did this, the locks no longer are controllable from my dashboard. They say āBack door is unknownā , āFront door is unknownā etc. without any ability to lock and unlock them.
Did I do something wrong in the install of the app?
Curious if anyone has gotten an update on this since in November ST said it wasnāt far off. Obviously a sought after feature. Itās great nice people are sharing work around they have created but it would be nice if it was integrated. Kwikset has released new models so itās not like these locks are a one time product.
ST would love an update.
@CoryS said:
We need more people like you around here. Instead of complaining and throwing temper tantrums while swearing to boycott all things SmartThings, you simply did something about it instead.
In my head, this translates as āIām tired of non-technical customers who paid their money and expect things to just work. I want a product that people MUST write their own code for and create their own github repositories to adequately use.ā
@differentcomputers What would iPhone or Android be without app developers? Apps extend the platforms native functionality, and makeup for holes in it until it can be officially addressed.
Iām sorry, did I miss the memo about ST being a beta product for developers only? Should I ask for my money back because I donāt know Groovy?
What would the iPhone be without the worldās best smartphone UI and functionality that is simple and straightforward for the customers to understand and harness?
@differentcomputers the iPhone shipped without an app store or even the aikability to send MMS which has been around for years. Instead they focused on the core user experenice and waited to extend functionality until it was well polished. That seemed to work out okay for them.
Also, you seemed to have missed my point. Because of generous devs like the one in this thread you are not expected, nor do you have to learn practically anything.
they focused on the core user experenice
Exactly. Right on the nose. Just what Iām talking about.
My ST core user experience is that I canāt do relatively simple things without coding.
And if you think copy & pasting from github into a new device type on IDE.Smarthings.com is not āhaving to learn practically anything,ā you are radically overestimating whatās necessary for mass market acceptance.
It depends what you consider core. I considered a core feature on a phone to be able to take a video, being my flip phone had done it for years, but not even the second generation iPhone supported it. However, numerous app store apps filled in the gap and provided this ācoreā functionality. Iām sure someone had to do a lot more than copy and pasting to pull that off. Heck, for years people had to jailbreak their phones just to set a background image. That was way more hassle than pasting some pre-made code into the IDE.
If you really expect every single corner of home automation to be apart of the core experience a year in, then Iām not sure what to tell you other than your expectations for a startup are a little out of control, especially when they provide the tools to people to provide their own solutions for the community while they work on doing it their way.
@coryS - any idea if officially managing codes for door locks in ST is getting close?
@brandon I only know what they share with everyone. I havenāt heard anything about it from them. The app listed here does work well though.
@coryS ok cool, thanks
@bigpunk6 - trying to setup this app to adjust user codes for a recently paired kwikset door lock but am having trouble figuring out how to copy over the device type code the correct way. am I supposed to copy the whole code from here into the code window of my new device type? i get the feeling Iām only supposed to copy parts of your code into certain parts of my new device type code.
Please forgive meā¦Iām obviously a newbie at this kind of thing.
Thanks
@coryS - any chance you can help answer my question in the post above? secondary question: am I supposed to pair my door lock AFTER I create the new device type so that the door lock automatically begins to use the new device type? or if I already have my door lock paired, is it a problem to update its device type to the new custom one? hmmm, maybe I donāt know what Iām talking about haha.
any help is greatly appreciatedā¦ just wish this functionality was baked in, but I guess they arenāt quite there yet.
thanks,
@brandon pair it like normal then go into the IDE, select the device and change it to the new type.
@coryS hmmm, I click into the door lock device (at the āMy Devicesā IDE page), but donāt know where to change itās device type.
Also, what about the code issue I had above? When creating the new device type, I wasnāt sure if I was supposed to just copy all of the code here and paste it over the default code and then thatās it?
Thanks
@brandon , replace the existing code. To change the type bring up the device and hit edit, from there you should find a drop down with all the different device types. Your new one should be at the bottom.
@coryS Ok I found where to change the Device Type now, thanks!
Follow up Q regarding the code: it looks like when I paste the full code from the github page over the new Device Type default code then save it, it does away with the Capabilities, Custom Attributes, and Custom Command the instructions said to specify for it. I see the āmetadataā in the default Device Type code shows these things specified, but the code on the github page doesnāt so maybe thatās why this occurs?
Are you sure Iām not supposed to just copy and paste parts of the github code over the default Device Type code in light of this?
@Brandon Iād have to look at the code, it may just be a modification you make to it. Anyway, here is the complete code I use that will work fine for ya.
/**
* This is a custom version of the Z-Wave Lock Device Type code. This code adds support for user codes with the use of a Smartapp.
*
* This Device Type was designed for the Kwikset Deadbolt so might not be compatible with other locks.
*
* Installation
*
* Create a new device type (https://graph.api.smartthings.com/ide/devices)
* Capabilities:
* Configuration
* Battery
* Polling
* Lock
* Custom Attribute
* user1
* code1
* Custom Command
* usercodechange
*/
metadata {
// Automatically generated. Make future change here.
definition (name: "Custom Lock", author: "cory.simpson@gmail.com") {
capability "Configuration"
capability "Lock"
capability "Polling"
capability "Battery"
attribute "user1", "string"
attribute "code1", "string"
command "usercodechange"
}
simulator {
status "locked": "command: 9881, payload: 00 62 03 FF 00 00 FE FE"
status "unlocked": "command: 9881, payload: 00 62 03 00 00 00 FE FE"
reply "9881006201FF,delay 4200,9881006202": "command: 9881, payload: 00 62 03 FF 00 00 FE FE"
reply "988100620100,delay 4200,9881006202": "command: 9881, payload: 00 62 03 00 00 00 FE FE"
}
tiles {
standardTile("toggle", "device.lock", width: 2, height: 2) {
state "locked", label:'locked', action:"lock.unlock", icon:"st.locks.lock.locked", backgroundColor:"#79b821", nextState:"unlocking"
state "unlocked", label:'unlocked', action:"lock.lock", icon:"st.locks.lock.unlocked", backgroundColor:"#ffffff", nextState:"locking"
state "locking", label:'locking', icon:"st.locks.lock.locked", backgroundColor:"#79b821"
state "unlocking", label:'unlocking', icon:"st.locks.lock.unlocked", backgroundColor:"#ffffff"
}
standardTile("lock", "device.lock", inactiveLabel: false, decoration: "flat") {
state "default", label:'lock', action:"lock.lock", icon:"st.locks.lock.locked", nextState:"locking"
}
standardTile("unlock", "device.lock", inactiveLabel: false, decoration: "flat") {
state "default", label:'unlock', action:"lock.unlock", icon:"st.locks.lock.unlocked", nextState:"unlocking"
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
state "battery", label:'${currentValue}% battery', action:"batteryupdate", unit:""
}
valueTile("usercode", "device.usercode", inactiveLabel: false, decoration: "flat") {
state "usercode", label:'${currentValue}', unit:""
}
standardTile("refresh", "device.lock", inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
}
standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
}
main "toggle"
details(["toggle", "lock", "unlock", "battery", "usercode", "configure", "refresh"])
}
}
import physicalgraph.zwave.commands.doorlockv1.*
//parse
def parse(String description) {
def result = null
if (description.startsWith("Err")) {
result = createEvent(descriptionText:description, displayed:true)
} else {
def cmd = zwave.parse(description, [ 0x98: 1])
if (cmd) {
result = zwaveEvent(cmd)
}
}
log.debug "\"$description\" parsed to ${result.inspect()}"
log.debug "Parse result $result"
result
}
def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
def encapsulatedCommand = cmd.encapsulatedCommand([0x20: 1,0x62: 1, 0x63: 1, 0x70: 1, 0x71: 2, 0x75: 1, 0x80:1, 0x85: 2, 0x4E: 2, 0x4C: 1, 0x8B: 1, 0x5D: 2])
log.debug "encapsulated: $encapsulatedCommand"
if (encapsulatedCommand) {
zwaveEvent(encapsulatedCommand)
}
}
def zwaveEvent(DoorLockOperationReport cmd) {
def map = [ name: "lock" ]
if (cmd.doorLockMode == 0xFF) {
map.value = "locked"
} else if (cmd.doorLockMode >= 0x40) {
map.value = "unknown"
} else if (cmd.doorLockMode & 1) {
map.value = "unlocked with timeout"
} else {
map.value = "unlocked"
}
createEvent(map)
}
def zwaveEvent(physicalgraph.zwave.commands.alarmv2.AlarmReport cmd) {
def map = null
if (cmd.zwaveAlarmType == 6) {
if (1 <= cmd.zwaveAlarmEvent && cmd.zwaveAlarmEvent < 10) {
map = [ name: "lock", value: (cmd.zwaveAlarmEvent & 1) ? "locked" : "unlocked" ]
}
switch(cmd.zwaveAlarmEvent) {
case 1:
map.descriptionText = "$device.displayName was manually locked"
break
case 2:
map.descriptionText = "$device.displayName was manually unlocked"
break
case 5:
if (cmd.eventParameter) {
map.descriptionText = "$device.displayName was locked with code ${cmd.eventParameter.first()}"
}
break
case 6:
if (cmd.eventParameter) {
map.descriptionText = "$device.displayName was unlocked with code ${cmd.eventParameter.first()} zwaveAlarmEvent"
}
break
case 9:
map.descriptionText = "$device.displayName was autolocked"
break
case 7:
case 8:
case 0xA:
map = [ name: "lock", value: "unknown", descriptionText: "$device.displayName was not locked fully" ]
break
case 0xB:
map = [ name: "lock", value: "unknown", descriptionText: "$device.displayName is jammed" ]
break
case 0xC:
map = [ descriptionText: "$device.displayName: all user codes deleted", display: true ]
break
case 0xD:
map = [ descriptionText: "$device.displayName: user code deleted", display: true ]
break
case 0xE:
map = [ descriptionText: "$device.displayName: user code added", display: true ]
break
default:
map = map ?: [ descriptionText: "$device.displayName: alarm event $cmd.zwaveAlarmEvent", display: false ]
break
}
} else switch(cmd.alarmType) {
case 17:
map = [ name: "lock", value: "unknown" ]
map.descriptionText = "$device.displayName Secured at Keypad ā Bolt Jammed"
break
case 18:
map = [ name: "lock", value: "locked" ]
if(cmd.alarmLevel) {
map.descriptionText = "$device.displayName Secured by User ${cmd.alarmLevel} at Keypad"
map = [ name: "code", value: ${cmd.alarmLevel} ]
}
break
case 19:
map = [ name: "lock", value: "unlocked" ]
if(cmd.alarmLevel) {
map.descriptionText = "$device.displayName Un-Secured by User ${cmd.alarmLevel} at Keypad"
}
break
case 21:
map = [ name: "lock", value: "locked" ]
map.descriptionText = "$device.displayName Secured using Keyed cylinder or inside thumb-turn"
break
case 22:
map = [ name: "lock", value: "unlocked" ]
map.descriptionText = "$device.displayName Un-Secured using Keyed cylinder or inside thumb-turn"
break
case 23:
map = [ name: "lock", value: "unknown" ]
map.descriptionText = "$device.displayName Secured by Controller ā Bolt Jammed"
break
case 24:
map = [ name: "lock", value: "locked" ]
map.descriptionText = "$device.displayName Secured by Controller"
break
case 25:
map = [ name: "lock", value: "unlocked" ]
map.descriptionText = "$device.displayName Un-Secured by Controller"
break
case 26:
map = [ name: "lock", value: "unknown" ]
map.descriptionText = "$device.displayName Lock Auto Secured ā Bolt Jammed"
break
case 27:
map = [ name: "lock", value: "locked" ]
map.descriptionText = "$device.displayName Lock Auto Secured"
break
case 32:
map = [ name: "lock", value: "unknown" ]
map.descriptionText = "All User Codes deleted from $device.displayName"
break
case 33:
map = [ name: "lock", value: "unknown" ]
map.descriptionText = "User ${cmd.alarmLevel} deleted from $device.displayName"
break
case 112:
map = [ name: "lock", value: "unknown" ]
if(cmd.alarmLevel) {
map.descriptionText = "New User: ${cmd.alarmLevel} added to $device.displayName"
}
break
case 161:
map = [ name: "lock", value: "unknown" ]
map.descriptionText = "Failed User Code attempt at Keypad on $device.displayName"
break
case 162:
map = [ name: "lock", value: "unknown" ]
if(cmd.alarmLevel) {
map.descriptionText = "Attempted access by user ${cmd.alarmLevel} outside of scheduled on $device.displayName"
}
break
case 167:
map = [ name: "lock", value: "unknown" ]
map.descriptionText = "Low battery level on $device.displayName"
break
case 168:
map = [ name: "lock", value: "unknown" ]
map.descriptionText = "Critical battery level on $device.displayName"
break
case 169:
map = [ name: "lock", value: "unknown" ]
map.descriptionText = "Battery level too low to operate $device.displayName"
break
default:
map = [ displayed: false, descriptionText: "$device.displayName: $cmd" ]
}
createEvent(map)
}
def zwaveEvent(physicalgraph.zwave.commands.associationv2.AssociationReport cmd) {
def result = []
state.associationQuery = null
if (cmd.nodeId.any { it == zwaveHubNodeId }) {
log.debug "$device.displayName is associated to $zwaveHubNodeId"
state.assoc = zwaveHubNodeId
} else {
result << response(secure(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId)))
}
result
}
//battery
def batteryupdate() {
def result = secure(zwave.batteryV1.batteryGet())
log.debug "battery $result"
result
}
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [ name: "battery", unit: "%" ]
if (cmd.batteryLevel == 0xFF) {
map.value = 1
map.descriptionText = "$device.displayName has a low battery"
} else {
map.value = cmd.batteryLevel
}
createEvent(map)
}
//User
def usercodechange(user1, code1, idstatus1) {
log.debug "Set $code1 for User $user1"
log.debug "Set User ID Status to $idstatus1"
secureSequence([
zwave.userCodeV1.userCodeSet(userIdentifier: user1, userIdStatus: idstatus1, code: code1),
zwave.userCodeV1.userCodeGet(userIdentifier: user1)
], 4200)
}
def zwaveEvent(physicalgraph.zwave.commands.usercodev1.UserCodeReport cmd) {
log.debug "$cmd"
def map = [ name: "usercode" ]
map.value = cmd.code
createEvent(map)
}
//Configuration
def configupdate() {
secure(zwave.configurationV1.configurationGet(parameterNumber: 1))
}
def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
log.debug "$cmd"
def map = [ name: "config", value: cmd.configurationValue]
if (cmd.configurationValue) {
switch(cmd.configurationValue) {
case "[1]":
map.descriptionText = "User $cmd.parameterNumber is Type: Owner (Default)"
log.debug "Owner"
break
case "[3]":
map.descriptionText = "User $cmd.parameterNumber is Type: Guest (Required for Year Day Schedules)"
break
case "[4]":
map.descriptionText = "User $cmd.parameterNumber is Type: Worker (Required for Week Day Schedules)"
break
case "[255]":
map.descriptionText = "User $cmd.parameterNumber not found"
break
default:
map = [ displayed: false, descriptionText: "$device.displayName: $cmd" ]
}
}
createEvent(map)
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
log.warn "Unexpected zwave command $cmd"
createEvent(displayed: false, descriptionText: "$device.displayName: $cmd")
}
def lockAndCheck(doorLockMode) {
secureSequence([
zwave.doorLockV1.doorLockOperationSet(doorLockMode: doorLockMode),
zwave.doorLockV1.doorLockOperationGet()
], 4200)
}
def lock() {
lockAndCheck(DoorLockOperationSet.DOOR_LOCK_MODE_DOOR_SECURED)
}
def unlock() {
lockAndCheck(DoorLockOperationSet.DOOR_LOCK_MODE_DOOR_UNSECURED)
}
def unlockwtimeout() {
lockAndCheck(DoorLockOperationSet.DOOR_LOCK_MODE_DOOR_UNSECURED_WITH_TIMEOUT)
}
def refresh() {
def result = [secure(zwave.doorLockV1.doorLockOperationGet())]
if (state.assoc == zwaveHubNodeId) {
//log.debug "$device.displayName is associated to ${state.assoc}"
} else if (!state.associationQuery) {
log.debug "checking association"
result << "delay 4200"
result << zwave.associationV1.associationGet(groupingIdentifier:2).format() // old Schlage locks use group 2 and don't secure the Association CC
result << secure(zwave.associationV1.associationGet(groupingIdentifier:1))
state.associationQuery = new Date().time
} else if (new Date().time - state.associationQuery.toLong() > 9000) {
log.debug "setting association"
result << "delay 6000"
result << zwave.associationV1.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId).format()
result << secure(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId))
result << zwave.associationV1.associationGet(groupingIdentifier:2).format()
result << secure(zwave.associationV1.associationGet(groupingIdentifier:1))
state.associationQuery = new Date().time
}
result
}
def updated() {
}
def secure(physicalgraph.zwave.Command cmd) {
def result = zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
log.debug "Result $result"
result
}
def secureSequence(commands, delay=4200) {
delayBetween(commands.collect{ secure(it) }, delay)
}
@coryS Awesome, that did the trick. Thanks man!!