KwickSet User codes


(Yenu Gobena) #1

Hello Team,

I have a quckset 910 and 912. I am looking to set remote user codes but cannot seem to do that.


(Keith Croshaw) #2

I think I heard it’s “coming,” maybe when Hub V2 launches. I don’t see why you would need the hardware though.


(Yenu Gobena) #3

Thanks Keith,

It is unfortunate thought i read somewhere i can do it via smartthing. Quick Question when you say need hardware not sure if i follow. Thanks in advance,

Yenu


(Keith Croshaw) #4

I don’t think the V2 hub will be required I just have a hunch the feature will come out with that release. I think there are some SmartApps that try to do this, i tried one but it wasn’t very clear how it worked. Have you used the IDE?


(Tim Slagle) #5

There is some custom code out there i think :wink:


(Yenu Gobena) #6

Thanks, i did read somewhere there was some custom code. Looking for what now.


(Tim Slagle) #7
/* **DISCLAIMER**
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * Without limitation of the foregoing, Contributors/Regents expressly does not warrant that:
 * 1. the software will meet your requirements or expectations;
 * 2. the software or the software content will be free of bugs, errors, viruses or other defects;
 * 3. any results, output, or data provided through or generated by the software will be accurate, up-to-date, complete or reliable;
 * 4. the software will be compatible with third party software;
 * 5. any errors in the software will be corrected.
 * The user assumes all responsibility for selecting the software and for the results obtained from the use of the software. The user shall bear the entire risk as to the quality and the performance of the software.
 */ 
 
/**
 * Add and remove user codes for locks
 *
 * Copyright RBoy
 * Redistribution of any changes or code is not allowed without permission
 *
 * Change Log:
 * 2015-2-11 - Added support for expiration dates
 * 2015-1-1 - Added option to customizing name
 * 2014-11-27 - Stable created
 *
 */
definition(
		name: "Lock single user code management",
		namespace: "rboy",
		author: "RBoy",
		description: "Add and Delete Single User Codes for Locks",
		category: "Safety & Security",
		iconUrl: "https://s3.amazonaws.com/smartapp-icons/Allstate/lock_it_when_i_leave.png",
		iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Allstate/lock_it_when_i_leave@2x.png"
	  )

import org.joda.time.DateTime

preferences {
	page(name: "setupApp")
}

def setupApp() {
    dynamicPage(name: "setupApp", title: "Lock User Management", install: true, uninstall: true) {    
        section("Select Lock(s)") {
            input "locks","capability.lock", title: "Lock", multiple: true
        }
        section("User Management") {
            input "user", "number", title: "User Slot Number", description: "This is the user slot number on the lock and not the user passcode"
            input "action", "enum", title: "Add/Update/Delete User?", required: true, metadata: [values: ["Add/Update","Delete"]],  refreshAfterSelection: true
        }

		if (action == "Add/Update") {
        	def invalidDate = false
        	if (expDate) {
            	log.debug "Found expiry date in setup"
            	try {
                	Date.parse("yyyy-MM-dd", expDate)
                }
                catch (Exception e) {
                	log.debug "Invalid expiry date in setup"
                    invalidDate = true
                }
            }
            
			section("Add/Update User Code") {
				input "code", "text", title: "User Passcode (check your lock passcode length)", defaultValue: "X", description: "The user passcode for adding/updating a new user (enter X for deleting user)"
			}
            
			section("Code Expiration Date and Time (Optional)") {
            	if (invalidDate == true) {
                	paragraph "INVALID DATE - PLEASE CHECK YOUR DATE FORMAT"
				}
                else {
                	def ed = Date.parse("yyyy-MM-dd", expDate)
                	paragraph "Code expiry date set for ${ed.format("EEE MMM dd yyyy")}"
				}
                
                if (expDate) {
                	if (!expTime) {
                    	paragraph "PLEASE ENTER TIME FOR CODE EXPIRY"
					}
				}
				
                input "expDate", "date", title: "Code expiration date (YYYY-MM-DD)", description: "Date on which the code should be deleted", required: false,  refreshAfterSelection: true
				input "expTime", "time", title: "Code expiration time", description: "(Touch here to set time) The code would be deleted within 5 minutes of this time", required: false,  refreshAfterSelection: true
			}
		}
                		
        section([mobileOnly:true]) {
			label title: "Assign a name for this SmartApp", required: false
		}
    }
}

def installed()
{
	log.debug "Install Settings: $settings"
	state.codes = [:]
	unschedule()
    runEvery5Minutes(expireCodeCheck)
	runIn(1, appTouch)
}

def updated()
{
	log.debug "Update Settings: $settings"
    if (!state.codes) {
    	state.codes = [:]
    }
	unschedule()
    runEvery5Minutes(expireCodeCheck)
	runIn(1, appTouch)
}

def appTouch() {
    if (action == "Delete") {
	  	for (lock in locks) {
            lock.deleteCode(user)
            log.info "$lock deleted user: $user"
            sendNotificationEvent("$lock deleted user: $user")
            sendPush "$lock deleted user: $user"
		}
        log.debug "Removing tracking expiry of user $user"
        state.codes.remove(user) // remove it from the tracker, we don't an unexpected code removal later
	} else {
	  	for (lock in locks) {
			lock.setCode(user, code)
            log.info "$lock added user: $user, code: $code"
            sendNotificationEvent("$lock added user: $user")
            sendPush "$lock added user: $user"
		}

		if (expDate && expTime) {
			def midnightToday = timeToday("2000-01-01T00:00:00.000-0000", location.timeZone)
			def expT = (timeToday(expTime, location.timeZone).time - midnightToday.time)
			String dst = location.timeZone.getDisplayName(location.timeZone.inDaylightTime(new Date(now())), TimeZone.SHORT) // Keep current timezone
			def expD = Date.parse("yyyy-MM-dd Z", expDate + " " + dst).toCalendar()
			def exp = expD.getTimeInMillis() + expT
            log.debug "Removing any existing tracking expiry of user $user"
            state.codes.remove(user) // remove it from the tracker so we don't duplicate if the code being overwritten
			state.codes.put(user,exp) // Add to the expiry list
			def expStr = (new Date(exp)).format("EEE MMM dd yyyy HH:mm z", location.timeZone)
			log.info "$locks user code expiration set to $expStr"
			sendNotificationEvent("$locks user $user code will expire on $expStr")
			sendPush "$locks user $user code will expire on $expStr"
		}
    }
}

def expireCodeCheck() {
	log.debug "ExpireCodeCheck called"
	for (code in state.codes) {
        def expStr = (new Date(code.value)).format("EEE MMM dd yyyy HH:mm z", location.timeZone)
        log.debug "user ${code.key} expires $expStr"
		if (code.value < now()) {
        	def user = code.key
            for (lock in locks) {
                lock.deleteCode(user)
                log.info "$lock deleted expired user: $user"
                sendNotificationEvent("$lock deleted expired user: $user")
                sendPush "$lock deleted expired user: $user"
	        }
            log.debug "Removing tracking of user $user"
            state.codes.remove(user) // remove it from the tracker, we're done here
        }
    }
}

and…

/**
* Change Lock Codes
*
* Author: bigpunk6
*/

preferences {
    section("What Lock") {
                input "lock1","capability.lock", title: "Lock"
    }
    section("User") {
        input "user1", "decimal", title: "User (From 1 to 30) "
        input "code1", "decimal", title: "Code (4 to 8 digits)"
        input "delete1", "enum", title: "Delete User", required: false, metadata: [values: ["Yes","No"]]
    }
}

def installed()
{
        subscribe(app, appTouch)
        subscribe(lock1, "usercode", usercodeget)
}

def updated()
{
        unsubscribe()
        subscribe(app, appTouch)
        subscribe(lock1, "usercode", usercodeget)
}

def appTouch(evt) {
    log.debug "Current Code for user $user1: $lock1.currentUsercode"
    log.debug "user: $user1, code: $code1"
    def idstatus1 = 1
    if (delete1 == "Yes") {
        idstatus1 = 0
    } else {
        idstatus1 = 1
    }
    lock1.usercodechange(user1, code1, idstatus1)
}

def usercodeget(evt){
    log.debug "Current Code for user $user1: $lock1.currentUsercode"
}

Either of these might work for your situation

Not sure which one is better since I don’t have a lock so I included both.


(Keith Croshaw) #8

Let me know if you get one working, I tried the first one and after 30 seconds gave up as I didn’t reaaaaally need it, just thought it was a neat idea.


(Yenu Gobena) #9

Hello Keith,

Thanks for the follow up. Tried it could not get it working. The second one took from a app perspectice but nothing seems to send any commands to the lock


(Keith Croshaw) #10

Yea that was about the extent of my experience, no offence to the developers. Something might have changed on the platform end breaking the code since they published it. I’m pretty sure I heard that some true support for this is on the “roadmap”, with no promises for when.

I don’t find the addition of a user code to be difficult on these locks though. At least the 910 that I have.


(John S) #11

This seems to be working fine for me with my Kwikset 912s and 910.


#12

Exactly… I use a 2Gig Go Control! alarm panel to control the user codes on my 910. Since it’s the secondary controller to ST, all the devices work like a charm in ST.

Nice thing about this setup is apparently I can use all the Lowes Isis type hardware and it should just work,


Using GoControl! Panel as a Secondary Controller to SmartThings?