diff --git a/smartapps/ethayer/keypad.src/keypad.groovy b/smartapps/ethayer/keypad.src/keypad.groovy index 3135c39..74f7209 100644 --- a/smartapps/ethayer/keypad.src/keypad.groovy +++ b/smartapps/ethayer/keypad.src/keypad.groovy @@ -106,6 +106,7 @@ def mainPage() { section('Setup', hideable: true, hidden: true) { input(name: 'keypad', title: 'Keypad', type: 'capability.lockCodes', multiple: false, required: true) label title: 'Label', defaultValue: "Keypad: ${keypad.label}", required: false, description: 'recommended to start with Keypad:' + paragraph 'Lock Manager © 2017 v1.3' } } } diff --git a/smartapps/ethayer/lock-manager.src/lock-manager.groovy b/smartapps/ethayer/lock-manager.src/lock-manager.groovy index a9777cf..5258854 100755 --- a/smartapps/ethayer/lock-manager.src/lock-manager.groovy +++ b/smartapps/ethayer/lock-manager.src/lock-manager.groovy @@ -15,6 +15,7 @@ preferences { page name: 'mainPage', title: 'Installed', install: true, uninstall: true, submitOnChange: true page name: 'infoRefreshPage' page name: 'notificationPage' + page name: 'helloHomePage' page name: 'lockInfoPage' page name: 'keypadPage' page name: 'askAlexaPage' @@ -39,13 +40,22 @@ def mainPage() { } } section('Global Settings') { - // needs to run any time a lock is added - href(name: 'toKeypadPage', page: 'keypadPage', title: 'Keypad Routines (optional)', image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/keypad.png') href(name: 'toNotificationPage', page: 'notificationPage', title: 'Notification Settings', description: notificationPageDescription(), state: notificationPageDescription() ? 'complete' : '', image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/bullhorn.png') + + def actions = location.helloHome?.getPhrases()*.label + if (actions) { + href(name: 'toHelloHomePage', page: 'helloHomePage', title: 'Hello Home Settings', image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/home.png') + } + + def keypadApps = getKeypadApps() + if (keypadApps) { + href(name: 'toKeypadPage', page: 'keypadPage', title: 'Keypad Routines (optional)', image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/keypad.png') + } } section('Advanced', hideable: true, hidden: true) { input(name: 'overwriteMode', title: 'Overwrite?', type: 'bool', required: true, defaultValue: true, description: 'Overwrite mode automatically deletes codes not in the users list') input(name: 'enableDebug', title: 'Enable IDE debug messages?', type: 'bool', required: true, defaultValue: false, description: 'Show activity from Lock Manger in logs for debugging.') + paragraph 'Lock Manager © 2017 v1.3' } } } @@ -135,6 +145,26 @@ def notificationPage() { } } +def helloHomePage() { + dynamicPage(name: 'helloHomePage', title: 'Global Hello Home Settings (optional)') { + def actions = location.helloHome?.getPhrases()*.label + actions?.sort() + section('Hello Home Phrases') { + input(name: 'manualUnlockRoutine', title: 'On Manual Unlock', type: 'enum', options: actions, required: false, multiple: true, image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/unlock-alt.png') + input(name: 'manualLockRoutine', title: 'On Manual Lock', type: 'enum', options: actions, required: false, multiple: true, image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/lock.png') + + input(name: 'codeUnlockRoutine', title: 'On Code Unlock', type: 'enum', options: actions, required: false, multiple: true, image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/unlock-alt.png' ) + + paragraph 'Supported on some locks:' + input(name: 'codeLockRoutine', title: 'On Code Lock', type: 'enum', options: actions, required: false, multiple: true, image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/lock.png') + + paragraph 'These restrictions apply to all the above:' + input "userNoRunPresence", "capability.presenceSensor", title: "DO NOT run Actions if any of these are present:", multiple: true, required: false + input "userDoRunPresence", "capability.presenceSensor", title: "ONLY run Actions if any of these are present:", multiple: true, required: false + } + } +} + def askAlexaPage() { dynamicPage(name: 'askAlexaPage', title: 'Ask Alexa Message Settings') { section('Que Messages with the Ask Alexa app') { @@ -366,7 +396,7 @@ def debugger(message) { } } -private anyoneHome(sensors) { +def anyoneHome(sensors) { def result = false if(sensors.findAll { it?.currentPresence == "present" }) { result = true diff --git a/smartapps/ethayer/lock-user.src/lock-user.groovy b/smartapps/ethayer/lock-user.src/lock-user.groovy index 8dd2731..5356f33 100755 --- a/smartapps/ethayer/lock-user.src/lock-user.groovy +++ b/smartapps/ethayer/lock-user.src/lock-user.groovy @@ -199,6 +199,7 @@ def mainPage() { label(title: "Name for App", defaultValue: 'User: ' + userName, required: true, image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/user.png') input name: 'userName', title: "Name for user", required: true, image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/user.png' input(name: "userSlot", type: "enum", options: parent.availableSlots(settings.userSlot), title: "Select slot", required: true, refreshAfterSelection: true ) + paragraph 'Lock Manager © 2017 v1.3' } } } diff --git a/smartapps/ethayer/lock.src/lock.groovy b/smartapps/ethayer/lock.src/lock.groovy index 2001cb5..d074dbf 100644 --- a/smartapps/ethayer/lock.src/lock.groovy +++ b/smartapps/ethayer/lock.src/lock.groovy @@ -99,6 +99,7 @@ def mainPage() { } else { paragraph 'Lock is loading data' } + paragraph 'Lock Manager © 2017 v1.3' } } } @@ -181,16 +182,19 @@ def askAlexaPage() { } def helloHomePage() { - dynamicPage(name: 'helloHomePage',title: 'Keypad Settings (optional)', install: true, uninstall: true) { + dynamicPage(name: 'helloHomePage', title: 'Hello Home Settings (optional)') { def actions = location.helloHome?.getPhrases()*.label actions?.sort() section('Hello Home Phrases') { input(name: 'manualUnlockRoutine', title: 'On Manual Unlock', type: 'enum', options: actions, required: false, multiple: true, image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/unlock-alt.png') input(name: 'manualLockRoutine', title: 'On Manual Lock', type: 'enum', options: actions, required: false, multiple: true, image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/lock.png') - if (state.supportsKeypadData) { - input(name: 'keypadLockRoutine', title: 'On keypad Lock', type: 'enum', options: actions, required: false, multiple: true) - } + input(name: 'codeUnlockRoutine', title: 'On Code Unlock', type: 'enum', options: actions, required: false, multiple: true, image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/unlock-alt.png' ) + + paragraph 'Supported on some locks:' + input(name: 'codeLockRoutine', title: 'On Code Lock', type: 'enum', options: actions, required: false, multiple: true, image: 'https://dl.dropboxusercontent.com/u/54190708/LockManager/lock.png') + + paragraph 'These restrictions apply to all the above:' input "userNoRunPresence", "capability.presenceSensor", title: "DO NOT run Actions if any of these are present:", multiple: true, required: false input "userDoRunPresence", "capability.presenceSensor", title: "ONLY run Actions if any of these are present:", multiple: true, required: false } @@ -398,15 +402,31 @@ def codeUsed(evt) { parent.setAccess() message += '. Now burning code.' } + // user specific if (userApp.userUnlockPhrase) { userApp.executeHelloPresenceCheck(userApp.userUnlockPhrase) } + // lock specific + if (codeUnlockRoutine) { + executeHelloPresenceCheck(codeUnlockRoutine) + } + // global + if (parent.codeUnlockRoutine) { + parent.executeHelloPresenceCheck(parent.codeUnlockRoutine) + } + } else if (manualUse) { // unlocked manually + // lock specific if (manualUnlockRoutine) { executeHelloPresenceCheck(manualUnlockRoutine) } + // global + if (parent.manualUnlockRoutine) { + parent.executeHelloPresenceCheck(parent.manualUnlockRoutine) + } + message = "${lock.label} was unlocked manually" if (notifyMaunualUnlock) { send(message) @@ -420,9 +440,18 @@ def codeUsed(evt) { // door was locked if (userApp) { message = "${lock.label} was locked by ${userApp.userName}" + // user specific if (userApp.userLockPhrase) { userApp.executeHelloPresenceCheck(userApp.userLockPhrase) } + // lock specific + if (codeLockRoutine) { + executeHelloPresenceCheck(codeLockRoutine) + } + // gobal + if (parent.codeLockRoutine) { + parent.executeHelloPresenceCheck(parent.codeLockRoutine) + } } if (data && data.usedCode == 0) { message = "${lock.label} was locked by keypad" @@ -439,9 +468,16 @@ def codeUsed(evt) { if (manualUse) { // locked manually message = "${lock.label} was locked manually" + + // lock specific if (manualLockRoutine) { executeHelloPresenceCheck(manualLockRoutine) } + // global + if (parent.manualLockRoutine) { + parent.executeHelloPresenceCheck(parent.manualLockRoutine) + } + if (notifyMaunualLock) { send(message) } @@ -706,6 +742,14 @@ def debugger(message) { } } +def anyoneHome(sensors) { + def result = false + if(sensors.findAll { it?.currentPresence == "present" }) { + result = true + } + result +} + def executeHelloPresenceCheck(routines) { if (userNoRunPresence && userDoRunPresence == null) { if (!anyoneHome(userNoRunPresence)) {