Compare commits
1 Commits
user186_7
...
MSA-2519-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06eed7c207 |
@@ -124,10 +124,6 @@ metadata {
|
||||
input "holdType", "enum", title: "Hold Type",
|
||||
description: "When changing temperature, use Temporary (Until next transition) or Permanent hold (default)",
|
||||
required: false, options:["Temporary", "Permanent"]
|
||||
input "deadbandSetting", "number", title: "Minimum temperature difference between the desired Heat and Cool " +
|
||||
"temperatures in Auto mode:\nNote! This must be the same as configured on the thermostat",
|
||||
description: "temperature difference °F", defaultValue: 5,
|
||||
required: false
|
||||
}
|
||||
|
||||
}
|
||||
@@ -176,7 +172,7 @@ def generateEvent(Map results) {
|
||||
if (name=="temperature" || name=="heatingSetpoint" || name=="coolingSetpoint" ) {
|
||||
sendValue = getTempInLocalScale(value, "F") // API return temperature values in F
|
||||
event << [value: sendValue, unit: locationScale]
|
||||
} else if (name=="maxCoolingSetpoint" || name=="minCoolingSetpoint" || name=="maxHeatingSetpoint" || name=="minHeatingSetpoint") {
|
||||
} else if (name=="maxCoolingSetpoint" || name=="minCoolingSetpoint" || name=="maxHeatingSetpoint" || name=="minHeatingSetpoint") {
|
||||
// Old attributes, keeping for backward compatibility
|
||||
sendValue = getTempInLocalScale(value, "F") // API return temperature values in F
|
||||
event << [value: sendValue, unit: locationScale, displayed: false]
|
||||
@@ -469,7 +465,7 @@ def enforceSetpointLimits(setpoint, data, raise = null) {
|
||||
def maxSetpoint = (setpoint == "heatingSetpoint") ? device.getDataValue("maxHeatingSetpointFahrenheit") : device.getDataValue("maxCoolingSetpointFahrenheit")
|
||||
minSetpoint = minSetpoint ? Double.parseDouble(minSetpoint) : ((setpoint == "heatingSetpoint") ? 45 : 65) // default 45 heat, 65 cool
|
||||
maxSetpoint = maxSetpoint ? Double.parseDouble(maxSetpoint) : ((setpoint == "heatingSetpoint") ? 79 : 92) // default 79 heat, 92 cool
|
||||
def deadband = deadbandSetting ? deadbandSetting : 5 // °F
|
||||
def deadband = 5 // °F
|
||||
def delta = (locationScale == "F") ? 1 : 0.5
|
||||
def targetValue = getTempInDeviceScale(data.targetValue, locationScale)
|
||||
def heatingSetpoint = getTempInDeviceScale(data.heatingSetpoint, locationScale)
|
||||
@@ -479,8 +475,8 @@ def enforceSetpointLimits(setpoint, data, raise = null) {
|
||||
targetValue = maxSetpoint
|
||||
} else if (targetValue < minSetpoint) {
|
||||
targetValue = minSetpoint
|
||||
} else if ((raise != null) && ((setpoint == "heatingSetpoint" && targetValue == heatingSetpoint) ||
|
||||
(setpoint == "coolingSetpoint" && targetValue == coolingSetpoint))) {
|
||||
} else if ((setpoint == "heatingSetpoint" && targetValue == heatingSetpoint) ||
|
||||
(setpoint == "coolingSetpoint" && targetValue == coolingSetpoint)){
|
||||
// Ensure targetValue differes from old. When location scale differs from device,
|
||||
// converting between C -> F -> C may otherwise result in no change.
|
||||
targetValue += raise ? delta : - delta
|
||||
|
||||
@@ -320,18 +320,7 @@ def zwaveEvent(DoorLockOperationReport cmd) {
|
||||
result << response(secure(zwave.associationV1.associationGet(groupingIdentifier:1)))
|
||||
}
|
||||
}
|
||||
if (generatesDoorLockOperationReportBeforeAlarmReport()) {
|
||||
// we're expecting lock events to come after notification events, but for specific yale locks they come out of order
|
||||
runIn(3, "delayLockEvent", [data: [map: map]])
|
||||
return [:]
|
||||
} else {
|
||||
return result ? [createEvent(map), *result] : createEvent(map)
|
||||
}
|
||||
}
|
||||
|
||||
def delayLockEvent(data) {
|
||||
log.debug "Sending cached lock operation: $data.map"
|
||||
sendEvent(data.map)
|
||||
result ? [createEvent(map), *result] : createEvent(map)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1670,19 +1659,6 @@ def isYaleLock() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this lock generates door lock operation report before alarm report, false otherwise
|
||||
* @return true if this lock generates door lock operation report before alarm report, false otherwise
|
||||
*/
|
||||
def generatesDoorLockOperationReportBeforeAlarmReport() {
|
||||
//Fix for ICP-2367, ICP-2366
|
||||
if(isYaleLock() && "0007" == zwaveInfo.prod && "0001" == zwaveInfo.model) {
|
||||
//Yale Keyless Connected Smart Door Lock
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic function for reading code Slot ID from AlarmReport command
|
||||
* @param cmd: The AlarmReport command
|
||||
* @return user code slot id
|
||||
|
||||
@@ -31,12 +31,6 @@ metadata {
|
||||
fingerprint mfr:"001D", prod:"1603", model:"0334", deviceJoinName: "Leviton 15A Split Duplex Receptacle"
|
||||
fingerprint mfr:"011A", prod:"0101", model:"0102", deviceJoinName: "Enerwave On/Off Switch"
|
||||
fingerprint mfr:"011A", prod:"0101", model:"0603", deviceJoinName: "Enerwave Duplex Receptacle"
|
||||
fingerprint mfr:"0039", prod:"5052", model:"3038", deviceJoinName: "Honeywell Z-Wave Plug-in Switch"
|
||||
fingerprint mfr:"0039", prod:"5052", model:"3033", deviceJoinName: "Honeywell Z-Wave Plug-in Switch (Dual Outlet)"
|
||||
fingerprint mfr:"0039", prod:"4F50", model:"3032", deviceJoinName: "Honeywell Z-Wave Plug-in Outdoor Smart Switch"
|
||||
fingerprint mfr:"0039", prod:"4952", model:"3036", deviceJoinName: "Honeywell Z-Wave In-Wall Smart Switch"
|
||||
fingerprint mfr:"0039", prod:"4952", model:"3037", deviceJoinName: "Honeywell Z-Wave In-Wall Smart Toggle Switch"
|
||||
fingerprint mfr:"0039", prod:"4952", model:"3133", deviceJoinName: "Honeywell Z-Wave In-Wall Tamper Resistant Duplex Receptacle"
|
||||
}
|
||||
|
||||
// simulator metadata
|
||||
|
||||
@@ -25,6 +25,12 @@ metadata {
|
||||
fingerprint mfr:"0063", prod:"5257", deviceJoinName: "GE Wall Switch"
|
||||
fingerprint mfr:"0063", prod:"5052", deviceJoinName: "GE Plug-In Switch"
|
||||
fingerprint mfr:"0113", prod:"5257", deviceJoinName: "Z-Wave Wall Switch"
|
||||
fingerprint mfr:"0039", prod:"5052", model:"3038", deviceJoinName: "Honeywell Z-Wave Plug-in Switch"
|
||||
fingerprint mfr:"0039", prod:"5052", model:"3033", deviceJoinName: "Honeywell Z-Wave Plug-in Switch (Dual Outlet)"
|
||||
fingerprint mfr:"0039", prod:"4F50", model:"3032", deviceJoinName: "Honeywell Z-Wave Plug-in Outdoor Smart Switch"
|
||||
fingerprint mfr:"0039", prod:"4952", model:"3036", deviceJoinName: "Honeywell Z-Wave In-Wall Smart Switch"
|
||||
fingerprint mfr:"0039", prod:"4952", model:"3037", deviceJoinName: "Honeywell Z-Wave In-Wall Smart Toggle Switch"
|
||||
fingerprint mfr:"0039", prod:"4952", model:"3133", deviceJoinName: "Honeywell Z-Wave In-Wall Tamper Resistant Duplex Receptacle"
|
||||
}
|
||||
|
||||
// simulator metadata
|
||||
|
||||
101
smartapps/robinaa2/door-ajar.src/door-ajar.groovy
Normal file
101
smartapps/robinaa2/door-ajar.src/door-ajar.groovy
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* Door Ajar
|
||||
*
|
||||
* Copyright 2018 Robin Adams
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
definition(
|
||||
name: "Door Ajar",
|
||||
namespace: "robinaa2",
|
||||
author: "Robin Adams",
|
||||
description: "Notifies when a door has been open over a specified amount of time.",
|
||||
category: "",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
|
||||
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
|
||||
|
||||
|
||||
preferences {
|
||||
section("Door sensor:") {
|
||||
input "sensor", "capability.contactSensor", required: true, title: "Where?"
|
||||
}
|
||||
section("Timeout:") {
|
||||
input "minutes", "number", required: true, title: "Minutes?"
|
||||
}
|
||||
section("Send Notifications?") {
|
||||
input("recipients", "contact", title: "Send notifications to") {
|
||||
input "phone", "phone", title: "Warn with text message (optional)",
|
||||
description: "Phone Number", required: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def installed() {
|
||||
log.debug "Installed with settings: ${settings}"
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "Updated with settings: ${settings}"
|
||||
|
||||
unsubscribe()
|
||||
initialize()
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
subscribe(sensor, "contact.open", doorOpenHandler)
|
||||
subscribe(sensor, "contact.closed", doorClosedHandler)
|
||||
}
|
||||
|
||||
def doorOpenHandler(evt) {
|
||||
log.debug "doorOpenHandler called: $evt"
|
||||
runIn(60 * minutes, check)
|
||||
}
|
||||
|
||||
def doorClosedHandler(evt) {
|
||||
log.debug "doorClosedHandler called: $evt"
|
||||
}
|
||||
|
||||
def check() {
|
||||
log.debug "In check scheduled method"
|
||||
|
||||
def state = sensor.currentState("contact")
|
||||
|
||||
if (state.value == "open") {
|
||||
// get the time elapsed between now and when the motion reported inactive
|
||||
def elapsed = now() - state.date.time
|
||||
|
||||
// elapsed time is in milliseconds, so the threshold must be converted to milliseconds too
|
||||
def threshold = 1000 * 60 * minutes
|
||||
|
||||
if (elapsed >= threshold) {
|
||||
log.debug "Door has been ajar long enough ($elapsed ms)"
|
||||
|
||||
def message = "The ${sensor.displayName} is open!"
|
||||
if (location.contactBookEnabled && recipients) {
|
||||
log.debug "Contact Book enabled!"
|
||||
sendNotificationToContacts(message, recipients)
|
||||
} else {
|
||||
log.debug "Contact Book not enabled"
|
||||
if (phone) {
|
||||
sendSms(phone, message)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.debug "Door has been re-opened since timer started ($elapsed ms): doing nothing"
|
||||
}
|
||||
} else {
|
||||
// Motion active; just log it and do nothing
|
||||
log.debug "Door was closed, do nothing"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user