Compare commits

...

20 Commits

Author SHA1 Message Date
PASCI
93219abcc8 Modifying 'Slightly smarter use of motion sensor' 2017-01-10 09:55:02 -08:00
PASCI
4b8e94b7ca MSA-1693: It control a SWITCH combining a MOTION SENSOR and a TIMEFRAME interval.
The MOTION works as expected outside the TIMEFRAME interval.
The SWITCH is always ON during the TIMEFRAME interval.
If there is no MOTION the SWITCH is turned OFF at the end of the TIMEFRAME interval.
2017-01-09 10:18:57 -08:00
Jack Chi
c028515fcd Merge pull request #1546 from skt123/dimmer_switch
[CHF-487] Health Check for Z-Wave Dimmer Switch
2016-12-29 10:29:43 -08:00
Jack Chi
751c98d123 Merge pull request #1550 from parijatdas/enerwave
[CHF-488] [CHF-489] [CHF-490] Implementation of HealthCheck for Enerwave Duplex Receptacle ZW15R, Enerwave On/Off Switch ZW15S and Leviton 15A Switch VRS15-1LZ
2016-12-29 10:27:18 -08:00
Jack Chi
5b874e8f3a Merge pull request #1545 from pchomal/dimmerswitch_generic
[CHF-477] Health Check for Z-Wave Dimmer Switch Generic
2016-12-27 11:36:51 -08:00
Parijat Das
9e10405527 Added fingerprints for the following devices:
1. Enerwave Duplex Receptacle ZW15R
2. Enerwave On/Off Switch ZW15S
3. Leviton 15A Switch VRS15-1LZ
2016-12-20 18:33:50 +05:30
sushant.k1
32ceaff54d [CHF-487]
Added Health Check Implementation for:
1. 1,000-Watt In-Wall Smart Dimmer Switch (GE 12725)
2. In-Wall Smart Fan Control (GE 12730)
2016-12-20 12:08:16 +05:30
piyush.c
5b1da30a47 [CHF-477]
Health Check implementation for Z-Wave Dimmer Switch Generic with checkinterval of 32min
2016-12-20 10:39:08 +05:30
Vinay Rao
0a82077b24 Merge pull request #1519 from SmartThingsCommunity/staging
Rolling down staging hotfix to master
2016-12-07 14:15:16 -08:00
Vinay Rao
38ef9e5c77 Merge pull request #1517 from SmartThingsCommunity/production
Rolling down production hotfix to staging
2016-12-07 12:10:01 -08:00
Vinay Rao
6a71615ca5 Merge pull request #1505 from varzac/sendevent-appengine-fix
DPROT-215 Don't use sendEvent for AppEngine parse events
2016-12-02 11:39:24 -08:00
Zach Varberg
9939591005 Don't use sendEvent for AppEngine parse events
With the changes made for
https://smartthings.atlassian.net/browse/DPROT-200 there were a few DTHs
that were using sendEvent to directly send events generated during
parse.  However, because using sendEvent didn't result in parse
returning an event AppEngine would send the description up to the cloud
DTH to be handled.  In some cases this resulted in multiple events for
the same device trigger.

This resolves: https://smartthings.atlassian.net/browse/DPROT-215
2016-12-01 14:52:24 -06:00
Vinay Rao
d7f2bc1d79 Merge pull request #1502 from bflorian/PROB-1426-life360-logging
PROB-1426 adding logging to Life360
2016-11-28 13:20:16 -08:00
bflorian
3c5d727d4c PROB-1426 adding logging to Life360 2016-11-28 16:00:42 -05:00
Vinay Rao
bbad6dfa7a Merge pull request #1501 from SmartThingsCommunity/staging
Rolling down staging hotfix to master
2016-11-28 10:35:24 -08:00
Vinay Rao
df6c815aa4 Merge pull request #1500 from SmartThingsCommunity/production
Rolling down production hotfix to staging
2016-11-28 10:34:01 -08:00
Tom Manley
d16ac00eb6 Merge pull request #1493 from tpmanley/hotfix/zll-dimmer-join-failure
zll-dimmer-bulb: Fix bug in configure preventing devices from joining
2016-11-23 23:30:08 -06:00
Tom Manley
1941f56007 zll-dimmer-bulb: Fix bug in configure preventing devices from joining
The configureHealthCheck method and therefore the configure method was
returning a boolean which was causing an exception during the initial
join that would prevent the device from showing up to the user.

https://smartthings.atlassian.net/browse/PROB-1428
2016-11-23 23:01:05 -06:00
Vinay Rao
f34df19a65 Merge pull request #1490 from SmartThingsCommunity/master
Rolling up master to staging
2016-11-22 13:00:00 -08:00
Vinay Rao
20239ca982 Merge pull request #1488 from SmartThingsCommunity/staging
Rolling up to production for deploy
2016-11-22 12:43:20 -08:00
12 changed files with 152 additions and 19 deletions

View File

@@ -22,9 +22,10 @@ metadata {
capability "Sensor"
capability "Health Check"
fingerprint mfr:"0063", prod:"4457", deviceJoinName: "Z-Wave Wall Dimmer"
fingerprint mfr:"0063", prod:"4944", deviceJoinName: "Z-Wave Wall Dimmer"
fingerprint mfr:"0063", prod:"5044", deviceJoinName: "Z-Wave Plug-In Dimmer"
fingerprint mfr:"0063", prod:"4457", deviceJoinName: "GE In-Wall Smart Dimmer "
fingerprint mfr:"0063", prod:"4944", deviceJoinName: "GE In-Wall Smart Dimmer "
fingerprint mfr:"0063", prod:"5044", deviceJoinName: "GE Plug-In Smart Dimmer "
fingerprint mfr:"0063", prod:"4944", model:"3034", deviceJoinName: "GE In-Wall Smart Fan Control"
}
simulator {

View File

@@ -39,7 +39,7 @@ metadata {
}
def generatePresenceEvent(boolean present) {
log.debug "Here in generatePresenceEvent!"
log.info "Life360 generatePresenceEvent($present)"
def value = formatValue(present)
def linkText = getLinkText(device)
def descriptionText = formatDescriptionText(linkText, present)

View File

@@ -128,7 +128,7 @@ private Map parseCatchAllMessage(String description) {
if (cluster.command == 0x07) {
if (cluster.data[0] == 0x00){
log.debug "TEMP REPORTING CONFIG RESPONSE" + cluster
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
resultMap = [name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]]
}
else {
log.warn "TEMP REPORTING CONFIG FAILED- error code:${cluster.data[0]}"

View File

@@ -132,7 +132,7 @@ private Map parseCatchAllMessage(String description) {
if (cluster.command == 0x07) {
if (cluster.data[0] == 0x00) {
log.debug "TEMP REPORTING CONFIG RESPONSE" + cluster
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
resultMap = [name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]]
}
else {
log.warn "TEMP REPORTING CONFIG FAILED- error code:${cluster.data[0]}"

View File

@@ -161,7 +161,7 @@ private Map parseCatchAllMessage(String description) {
if (cluster.command == 0x07) {
if(cluster.data[0] == 0x00) {
log.debug "TEMP REPORTING CONFIG RESPONSE" + cluster
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
resultMap = [name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]]
}
else {
log.warn "TEMP REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
@@ -339,7 +339,7 @@ private Map getContactResult(value) {
log.debug "Contact: ${device.displayName} value = ${value}"
def descriptionText = value == 'open' ? '{{ device.displayName }} was opened' : '{{ device.displayName }} was closed'
sendEvent(name: 'contact', value: value, descriptionText: descriptionText, displayed: false, translatable: true)
sendEvent(name: 'status', value: value, descriptionText: descriptionText, translatable: true)
return [name: 'status', value: value, descriptionText: descriptionText, translatable: true]
}
private getAccelerationResult(numValue) {

View File

@@ -119,7 +119,7 @@ private Map parseCatchAllMessage(String description) {
if (cluster.command == 0x07){
if (cluster.data[0] == 0x00) {
log.debug "TEMP REPORTING CONFIG RESPONSE" + cluster
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
resultMap = [name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]]
}
else {
log.warn "TEMP REPORTING CONFIG FAILED- error code:${cluster.data[0]}"

View File

@@ -103,7 +103,7 @@ private Map parseCatchAllMessage(String description) {
if (cluster.command == 0x07) {
if (cluster.data[0] == 0x00){
log.debug "TEMP REPORTING CONFIG RESPONSE" + cluster
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
resultMap = [name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]]
}
else {
log.warn "TEMP REPORTING CONFIG FAILED- error code:${cluster.data[0]}"

View File

@@ -127,8 +127,8 @@ def configureHealthCheck() {
def configure() {
log.debug "configure()"
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
configureHealthCheck()
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
}
def updated() {

View File

@@ -24,6 +24,10 @@ metadata {
fingerprint inClusters: "0x26", deviceJoinName: "Z-Wave Dimmer"
fingerprint mfr:"001D", prod:"1902", deviceJoinName: "Z-Wave Dimmer"
fingerprint mfr:"001D", prod:"1B03", model:"0334", deviceJoinName: "Leviton Universal Dimmer"
fingerprint mfr:"011A", prod:"0102", model:"0201", deviceJoinName: "Enerwave In-Wall Dimmer"
fingerprint mfr:"001D", prod:"1001", model:"0334", deviceJoinName: "Leviton 3-Speed Fan Controller"
fingerprint mfr:"001D", prod:"0602", model:"0334", deviceJoinName: "Leviton Magnetic Low Voltage Dimmer"
fingerprint mfr:"001D", prod:"0401", model:"0334", deviceJoinName: "Leviton 600W Incandescent Dimmer"
}
simulator {

View File

@@ -25,6 +25,9 @@ metadata {
fingerprint mfr:"0063", prod:"4F50", model:"3031", deviceJoinName: "GE Plug-in Outdoor Switch"
fingerprint mfr:"001D", prod:"1D04", model:"0334", deviceJoinName: "Leviton Outlet"
fingerprint mfr:"001D", prod:"1C02", model:"0334", deviceJoinName: "Leviton Switch"
fingerprint mfr:"001D", prod:"0301", model:"0334", deviceJoinName: "Leviton 15A Switch"
fingerprint mfr:"011A", prod:"0101", model:"0102", deviceJoinName: "Enerwave On/Off Switch"
fingerprint mfr:"011A", prod:"0101", model:"0603", deviceJoinName: "Enerwave Duplex Receptacle"
}
// simulator metadata

View File

@@ -0,0 +1,125 @@
//==================================================================================
/**
* Motion-Switch-Sched SmartApp
*
* Copyright 2017 PASCI Ciro Ippolito 2017
***********************************************************************************
* 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: "Motion Switch SmartTimeframe",
namespace: "PASCI",
author: "PASCI",
description: "Motion Activated switch + Override timeframe.",
category: "Convenience",
iconUrl: "http://cdn.device-icons.smartthings.com/Home/home30-icn@2x.png",
iconX2Url: "http://cdn.device-icons.smartthings.com/Home/home30-icn@2x.png",
iconX3Url: "http://cdn.device-icons.smartthings.com/Home/home30-icn@2x.png"
)
//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("When MOTION is detected") {
input "themotion", "capability.motionSensor", required: true, title: "WHERE"
}
section("Turn ON this SWITCH") {
input "OUTLE", "capability.switch", required: true, title: "WHICH"
}
section("ON for how long") {
input "minutes", "number", required: true, title: "MINUTES)"
}
section("ON OVERRIDE time frame (if there is no motion)") {
input "FROMTime", "time", title: "From", required: true
input "TOTime", "time", title: "To", required: true
}
}
//==================================================================================
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
//==================================================================================
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
//==================================================================================
def initialize() {
log.debug "Installata at: " + now()
schedule(FROMTime, handlerFROMTIME)
schedule(TOTime, handlerTOTime)
subscribe(themotion, "motion.active", handler_Motion___Active)
subscribe(themotion, "motion.inactive", handler_motion_inactive)
}
// HANDLERS
//==================================================================================
def handlerFROMTIME() {
log.debug "FROM TIME at ${new Date()}"
OUTLE.on()
}
//==================================================================================
def handlerTOTime() {
log.debug "TO TIME at ${new Date()}"
checkMotion();
/*
def motionState = themotion.currentState("motion")
log.debug "state of motion sensor is: " + motionState.value
log.debug "TURN OFF at ${new Date()}"
log.debug "state of motion sensor is: " + themotion.motion
if (motionState.value == "active"){
log.debug "state of motion sensor is ACTIVE"
}else{
OUTLE.off()
log.debug "state of motion sensor is INACTIVE"
}
*/
}
//==================================================================================
def handler_Motion___Active(evt) {
log.debug("MOT Active")
OUTLE.on()
}
//==================================================================================
def handler_motion_inactive(evt) {
log.debug("MOT Inactive")
def between = timeOfDayIsBetween(FROMTime, TOTime, new Date(), location.timeZone)
if (between) {
log.debug("It dasan't mattar Christopha")
OUTLE.on()
} else {
runIn(60 * minutes, checkMotion)
}
}
//==================================================================================
def checkMotion() {
log.debug "In checkMotion scheduled method"
// get the current state object for the motion sensor
def motionState = themotion.currentState("motion")
if (motionState.value == "inactive") {
def elapsed = now() - motionState.date.time // time elapsed between now and when the motion reported inactive
def threshold = 1000 * 60 * minutes // elapsed time is in milliseconds
if (elapsed >= threshold) {
log.debug "Motion has stayed inactive long enough since last check ($elapsed ms): turning switch off"
OUTLE.off()
} else {
log.debug "Motion has not stayed inactive long enough since last check ($elapsed ms): doing nothing"
}
} else {
// Motion active; just log it and do nothing
log.debug "Motion is active, do nothing and wait for inactive"
}
}
//==================================================================================
//==================================================================================

View File

@@ -289,12 +289,12 @@ def initializeLife360Connection() {
state.life360AccessToken = result.data.access_token
return true;
}
log.debug "Response=${result.data}"
log.info "Life360 initializeLife360Connection, response=${result.data}"
return false;
}
catch (e) {
log.debug e
log.error "Life360 initializeLife360Connection, error: $e"
return false;
}
@@ -656,7 +656,7 @@ def generateInitialEvent (member, childDevice) {
try { // we are going to just ignore any errors
log.debug "Generate Initial Event for New Device for Member = ${member.id}"
log.info "Life360 generateInitialEvent($member, $childDevice)"
def place = state.places.find{it.id==settings.place}
@@ -677,6 +677,8 @@ def generateInitialEvent (member, childDevice) {
// log.debug "Distance Away = ${distanceAway}"
boolean isPresent = (distanceAway <= placeRadius)
log.info "Life360 generateInitialEvent, member: ($memberLatitude, $memberLongitude), place: ($placeLatitude, $placeLongitude), radius: $placeRadius, dist: $distanceAway, present: $isPresent"
// log.debug "External Id=${app.id}:${member.id}"
@@ -718,7 +720,7 @@ def haversine(lat1, lon1, lat2, lon2) {
def placeEventHandler() {
log.debug "In placeEventHandler method."
log.info "Life360 placeEventHandler: params=$params, settings.place=$settings.place"
// the POST to this end-point will look like:
// POST http://test.com/webhook?circleId=XXXX&placeId=XXXX&userId=XXXX&direction=arrive
@@ -729,8 +731,6 @@ def placeEventHandler() {
def direction = params?.direction
def timestamp = params?.timestamp
log.debug "Life360 Event: Circle: ${circleId}, Place: ${placeId}, User: ${userId}, Direction: ${direction}"
if (placeId == settings.place) {
def presenceState = (direction=="in")
@@ -745,10 +745,10 @@ def placeEventHandler() {
if (deviceWrapper) {
deviceWrapper.generatePresenceEvent(presenceState)
log.debug "Event raised on child device: ${externalId}"
log.debug "Life360 event raised on child device: ${externalId}"
}
else {
log.debug "Couldn't find child device associated with inbound Life360 event."
log.warn "Life360 couldn't find child device associated with inbound Life360 event."
}
}