Compare commits

...

99 Commits

Author SHA1 Message Date
Vinay Rao
0b81793b0f Merge pull request #2081 from SmartThingsCommunity/staging
Rolling down staging to master
2017-06-09 13:03:54 -07:00
Vinay Rao
16f41bddae Merge pull request #2080 from workingmonk/bug/mark_files_deprecated
SLC-82 Marking old connect apps and device types as deprecated
2017-06-09 13:01:45 -07:00
Vinay Rao
117adea586 SLC-82 Marking old connect apps and device types as deprecated 2017-06-09 11:44:06 -07:00
Vinay Rao
783538e36d Merge pull request #2070 from dkirker/ICP-1097
ICP-1097 Fix Sengled Classic default level on pairing
2017-06-08 16:28:50 -07:00
Vinay Rao
320c8918f8 Merge pull request #2075 from lymanepp/master
MSA-2076: Fix debug message
2017-06-07 15:32:43 -07:00
Lyman Epp
0f3656cd12 Fix debug message 2017-06-07 12:22:33 -05:00
Vinay Rao
6110aaa0fa Merge pull request #2074 from SmartThingsCommunity/master
Rolling up master to staging
2017-06-06 12:01:26 -07:00
Vinay Rao
c391ce4b43 Merge pull request #2073 from SmartThingsCommunity/staging
Rolling down staging to master
2017-06-06 11:55:16 -07:00
Vinay Rao
073bac8dac Merge pull request #2069 from larsfinander/DVCSMP-2688_Remove_sending_turningOn_Off_events_staging
DVCSMP-2688 Remove sending turningOn/Off events
2017-06-06 11:50:59 -07:00
Vinay Rao
3c83bfb53b Merge pull request #2071 from SmartThingsCommunity/production
Rolling down production to staging
2017-06-06 11:34:24 -07:00
Donald Kirker
6325101f52 ICP-1097 Fix Sengled Classic default level on pairing
Code brought oever from @varzac commit 8bcbe7b924
Original commit message:

> Fix sengled use of FF for max level
> This works around the fact that sengled element touches can get back
> into a state of reporting an invalid value (of FF) if the physical
> button on the bulb is used to cycle back to the 100% state.  Here we
> interpret FF as FE for sengled and then issue a move to level command to
> put it in a state where it will report FE until the level is changed
> again.
>
> This resolves: https://smartthings.atlassian.net/browse/DVCSMP-2597

While the Classic does not have a physical button, since it does represent 100% as FF we want to always catch this.
2017-06-06 03:29:41 -07:00
Lars Finander
945a972082 DVCSMP-2688 Remove sending turningOn/Off events
-Removed createSwitchEvent()
2017-06-05 16:50:03 -06:00
Tom Manley
535fc112de Merge pull request #2055 from jmagnuson/DVCSMP-2537
DVCSMP-2537 Add CRC16 un-encapsulation to Z-Wave switches
2017-06-02 16:36:50 -05:00
Jon Magnuson
a844e85c47 Remove extra comment slash 2017-06-02 16:25:04 -05:00
Tom Manley
b65acdb91f Merge pull request #2060 from varzac/aeon-multisensor-gen5
[DVCSMP-2680] Correctly configure Aeon Multisensor Gen5
2017-06-02 12:02:59 -05:00
Vinay Rao
4067e6e7e2 Merge pull request #2058 from juano2310/jumping_fix
ICP-1124 - Sylvania SMART BR30 RGBW ' s color ticker moving randomly
2017-06-01 17:40:42 -07:00
Zach Varberg
4c6d1eddb2 Correctly configure Aeon Multisensor Gen5
Previously this device had been changed to use configureAfterSecure to
work around the secure inclusion for Z-Wave.  However, support was added
hub side for handling this so it needed to be changed back to using the
normal configure process.

This resolves: https://smartthings.atlassian.net/browse/DVCSMP-2680
2017-06-01 08:28:12 -05:00
Vinay Rao
10d2097ebe Merge pull request #2065 from bflorian/MSA-1951-1-production-fingerprint
MSA-1951 added second Inovelli fingerprint
2017-05-31 17:35:00 -07:00
Bob Florian
d3728d95b2 MSA-1951 added second Inovelli fingerprint 2017-05-31 16:45:55 -07:00
Vinay Rao
60f6e9c02c Merge pull request #2064 from SmartThingsCommunity/staging
Rolling down staging to master
2017-05-31 13:56:22 -07:00
Vinay Rao
b645872d8f Merge pull request #2063 from SmartThingsCommunity/staging
Rolling up staging to production
2017-05-31 13:42:12 -07:00
Vinay Rao
d3731b49fe Merge pull request #2062 from SmartThingsCommunity/production
Rolling down production to staging
2017-05-31 11:44:22 -07:00
Vinay Rao
da139056e1 Merge pull request #2047 from dkirker/ICP-1076
ICP-1076 Fix Aeon Door/Window Sensor 6 initial value of null
2017-05-31 11:24:20 -07:00
Donald Kirker
d864c5e3b3 ICP-1076 Fix Aeon Door/Window Sensor 6 initial value of null 2017-05-31 11:00:43 -07:00
juano2310
74a35eeddb ICP-1124 - Sylvania SMART BR30 RGBW ' s color ticker moving randomly
state

overwrite: true
2017-05-30 18:18:22 -04:00
Vinay Rao
7064ce972a Merge pull request #2048 from dkirker/ICP-1016
ICP-1016 Fix default value for states for Aeon Siren Gen5
2017-05-30 11:53:51 -07:00
Vinay Rao
936ee59242 Merge pull request #2056 from jackchi/zwave-lock-1hr-ping
[DHF-7] [ICP-1084] Adds scheduled 1 hr ping for offline devices
2017-05-30 00:27:24 -07:00
jackchi
79a6a6472e [DHF-7] [ICP-1084] Adds scheduled 1 hr ping for offline devices; updates checkInterval to 1 hour 2017-05-29 11:02:48 -07:00
bflorian
919111ed22 Merge pull request #2051 from bflorian/MSA-1951-1-staging
MSA-1951 Added Inovelli 2-Channel Smart Plug
2017-05-26 13:55:20 -04:00
Bob Florian
fc1f1508ad MSA-1951 Added Inovelli 2-Channel Smart Plug 2017-05-26 13:38:45 -04:00
Donald Kirker
7f3cd0cdaa ICP-1016 Fix default value for states for Aeon Siren Gen5 2017-05-26 01:39:05 -07:00
Vinay Rao
423c25df53 Merge pull request #2045 from workingmonk/hotfix/siren
ICP-1056 Updating the icon and ocf device type for fortrezz siren
2017-05-25 17:17:48 -07:00
Vinay Rao
df8e435fcc ICP-1056 Updating the icon and ocf device type for fortrezz siren 2017-05-25 17:09:54 -07:00
Jon Magnuson
8aceef9be4 Add CRC16 un-encapsulation to Z-Wave switches
Fixes DVCSMP-2663 and DVCSMP-2537.
2017-05-25 17:07:12 -05:00
Vinay Rao
144314d9ae Merge pull request #2042 from twack/ocf-update-fortrezz-siren
ICP-1056 ocf-update-fortrezz-siren
2017-05-25 11:04:17 -07:00
Vinay Rao
a1f39849ed Merge pull request #2043 from SmartThingsCommunity/staging
Rolling down staging to master
2017-05-25 10:58:53 -07:00
Vinay Rao
8eed22ca0c Merge pull request #2041 from parijatdas/aeon-multisensor
[CHF-616] Health check Aeon Multi sensor motion detector
2017-05-25 10:58:25 -07:00
twack
d626c5f2a1 ocf-update-fortrezz-siren 2017-05-25 07:57:19 -07:00
Parijat Das
1dae5d3936 Added health check implementation for Aeon MultiSensor 2017-05-25 18:56:38 +05:30
Vinay Rao
807ff53c6d Merge pull request #2036 from SmartThingsCommunity/master
Rolling up master to staging
2017-05-23 13:52:46 -07:00
Vinay Rao
f95319ce59 Merge pull request #2035 from SmartThingsCommunity/staging
Rolling down staging to master
2017-05-23 13:51:00 -07:00
Vinay Rao
453dbbdde3 Merge pull request #2034 from SmartThingsCommunity/staging
Rolling up staging to production
2017-05-23 13:49:56 -07:00
Vinay Rao
52427802a8 Merge pull request #2033 from SmartThingsCommunity/production
Rolling down production to staging
2017-05-23 13:49:12 -07:00
Vinay Rao
72bb22a4b8 ICP-1051 Moving samjin outlet to smartpower outlet DTH (#2032)
* ICP-1051 Moving samjin outlet to smartpower outlet DTH
2017-05-23 12:19:09 -07:00
Duncan McKee
e817f5c415 Merge pull request #1748 from mckeed/DVCSMP-2489
DVCSMP-2489 Everspring ST814 and ST815 Multilevel Sensors
2017-05-23 13:35:39 -04:00
Duncan McKee
10964873cd Merge pull request #2001 from mckeed/DVCSMP-2493
DVCSMP-2493 Notify Multi-Channel Control app when root device is deleted
2017-05-23 13:33:55 -04:00
Zach Varberg
20f086fe69 Merge pull request #2023 from varzac/fix-multisensor-npe
[DVCSMP-2668] Fix NPE for smartsense multi
2017-05-23 09:08:47 -05:00
Vinay Rao
21f7a00cc9 Merge pull request #2026 from unixbeast/DVCSMP-2672
DVCSMP-2672 updating read attribute for valve capability
2017-05-22 17:59:00 -07:00
Dave Hastings
06faa988c8 DVCSMP-2672 updating read attribute for valve capability
updating tile for fortrezz
2017-05-22 17:57:54 -07:00
Vinay Rao
fe5f5c35b2 Merge pull request #2025 from SmartThingsCommunity/staging
Rolling down staging to master
2017-05-22 17:44:28 -07:00
Vinay Rao
2c4cd8d922 Merge pull request #2003 from unixbeast/icp_781
ICP-781 Fixing DTH for valve capability
2017-05-22 15:23:57 -07:00
Dave Hastings
772cd7005a ICP-781 Fixing DTH for valve capability
Making suggested fixes

making fixes

fixing to correctly use createEvent

fixing DTH

Also adding the fortrezz water valve

refactoring a bit

adding back in debug messages

updating ocf device type

adding zigbee water valve

refactor
2017-05-22 15:22:18 -07:00
Vinay Rao
afb4755447 Merge pull request #2022 from dkirker/ICP-951
ICP-951 Add deviceJoinName for Aeon Panic Button
2017-05-22 11:53:42 -07:00
Vinay Rao
49f35e48da Merge pull request #2018 from jackchi/zwave-lock-wwst-naming
[ICP-975] Proper WWST Z-Wave Lock names
2017-05-22 11:50:33 -07:00
Donald Kirker
93d8e96efc ICP-951 Add deviceJoinName for Aeon Panic Button
Also properly report 1 button for Aeon Panic Button
2017-05-22 11:45:27 -07:00
jackchi
6fbaf15f42 [CP-975] Proper WWST Z-Wave Lock names 2017-05-22 11:41:54 -07:00
Zach Varberg
97c9ec7a95 Fix NPE for smartsense multi
There was a common NPE caused by assuming there would be additional
attributes reported with one acceleration value.  This corrects it to
instead properly handle the case where there weren't additional
attributes.

This resolves: https://smartthings.atlassian.net/browse/DVCSMP-2668
2017-05-22 11:52:13 -05:00
Aaron Miller
d7b448b699 Merge pull request #2016 from aaron-miller/DVCSMP-2665
DVCSMP-2665 Prevent 'Smart Nightlight' from over scheduling
2017-05-22 09:24:22 -05:00
Aaron Miller
9285536f73 Merge pull request #2013 from aaron-miller/DVCSMP-2659
DVCSMP-2659 Reduce Hello Home Phrase Detector Logs
2017-05-22 09:23:22 -05:00
Aaron Miller
e7713caec9 DVCSMP-2665 Prevent 'Smart Nightlight' from over scheduling 2017-05-19 14:09:08 -05:00
Vinay Rao
5b2a46300d Merge pull request #1539 from skt123/ct100
[CHF-481] Health Check Implementation for CT100 Programmable Thermostat.
2017-05-18 23:49:06 -07:00
Vinay Rao
c8b4b7be1c Merge pull request #2014 from jackchi/wwst-proper-names
[DVCSMP-2664] WWST Proper Naming
2017-05-18 16:00:39 -07:00
jackchi
20f1493788 [DVCSMP-2664] WWST Proper Naming 2017-05-18 14:47:46 -07:00
Aaron Miller
f0de2f1a19 DVCSMP-2659 Reduce Hello Home Phrase Detector Logs 2017-05-18 09:56:17 -05:00
Vinay Rao
1263a6e2e1 Merge pull request #2002 from twack/ocf-update-aeon-siren
ICP-950 ocf-update-aeon-siren
2017-05-18 07:52:00 -07:00
sushant.k1
d41162afe4 [CHF-481]
Added Health Check Implementation for CT100 Programmable Thermostat.
2017-05-18 18:36:57 +05:30
Vinay Rao
19d9406b6a Merge pull request #2010 from parijatdas/aeon-multisensor-6
[CHF-610] Health Check Aeon MultiSensor 6
2017-05-17 22:54:30 -07:00
Vinay Rao
a6d52ab9ac Merge pull request #1996 from SmartThingsCommunity/dth-ux-remaining-staging
[DVCSMP-2607] Standardize remaining SmartThingsPublic ON/CLOSED/TAMPERED & ACTIVE/INACTIVE state colors
2017-05-17 22:54:07 -07:00
Jack Chi
01c2968f91 Merge pull request #1834 from parijatdas/zwave_water_valve
[CHF-569] Health Check zwave-water-valve
2017-05-17 17:05:10 -07:00
jackchi
483a25e900 [DVCSMP-2607] Standardize remaining SmartThingsPublic ON/CLOSED/TAMPERED & OPEN state colors 2017-05-17 16:19:40 -07:00
Vinay Rao
0d9a08e922 Merge pull request #2007 from SmartThingsCommunity/master
Rolling up master to staging
2017-05-16 15:47:08 -07:00
Vinay Rao
40b75ce665 Merge pull request #2006 from SmartThingsCommunity/staging
Rolling down staging to master
2017-05-16 15:37:10 -07:00
Vinay Rao
a4d9cd51a3 Merge pull request #2005 from SmartThingsCommunity/staging
Rolling up staging to production
2017-05-16 14:37:45 -07:00
Vinay Rao
9b01a7d8be Merge pull request #2004 from SmartThingsCommunity/production
Rolling down production to staging
2017-05-16 14:37:15 -07:00
Parijat Das
12bb6c0492 Added health-check for Z-wave Water Valve 2017-05-16 12:26:48 +05:30
Parijat Das
9e3a6e830f Added health-check for Aeon Labs Multisensor 6 2017-05-16 12:16:01 +05:30
twack
92e1586fa6 ocf-update-aeon-siren 2017-05-15 20:13:47 -07:00
Vinay Rao
7cf8bb1917 Merge pull request #1998 from larsfinander/DVCSMP-2656_OpenT2T_Update_to_5_5_submission_staging
DVCSMP-2656 OpenT2T: Update to 5/15 submission
2017-05-15 12:31:34 -07:00
Lars Finander
d4fd778a64 DVCSMP-2656 OpenT2T: Update to 5/15 submission 2017-05-15 13:25:44 -06:00
Jack Chi
eb870e5f31 Merge pull request #1943 from parijatdas/smartalert_siren
[CHF-590] Fixed typo error
2017-05-15 10:47:25 -07:00
Vinay Rao
d60657e466 Merge pull request #1992 from dkirker/production
PROB-1615: Add SYLVANIA Smart 10-Year A19 bulb fingerprint
2017-05-11 15:08:13 -07:00
Donald Kirker
d8dc70ae9e PROB-1615 Add SYLVANIA Smart 10-Year A19 bulb fingerprint 2017-05-11 14:03:24 -07:00
Vinay Rao
a99e050c6b Merge pull request #1975 from jackchi/device-ux-remaining
[DVCSMP-2607] Standardize remaining SmartThingsPublic DTH colors
2017-05-11 13:35:42 -07:00
jackchi
5bf7caca0d [DVCSMP-2607] Standardize remaining SmartThingsPublic ON/CLOSED/TAMPERED & OPEN state colors 2017-05-11 12:23:38 -07:00
Vinay Rao
3457bbad42 Merge pull request #1991 from tslagle13/gideon-change
[MSA-1968] - Publish gideon smarthome changes
2017-05-11 11:12:30 -07:00
tslagle13
c6c4b09fbb [MSA-1968] - Publish gideon smarthome changes
small change to sensor readings
2017-05-11 11:06:44 -07:00
Aaron Miller
3eddd68532 Merge pull request #1978 from aaron-miller/DVCSMP-2612
[DVCSMP-2612] Unschedule execution for Left It Open when door is closed
2017-05-11 08:51:36 -05:00
Aaron Miller
8d79379bba Merge pull request #1927 from aaron-miller/DVCSMP-2595
[DVCSMP-2595] Set scheduled executions for Lights off with no motion SA to overwrite
2017-05-10 13:29:03 -05:00
Vinay Rao
7e25d32c70 Merge pull request #1990 from SmartThingsCommunity/master
Rolling up master to staging
2017-05-09 16:04:19 -05:00
Vinay Rao
dd4da29bcd Merge pull request #1989 from SmartThingsCommunity/staging
Rolling down staging to master
2017-05-09 16:03:53 -05:00
Aaron Miller
b6136bf1d5 [DVCSMP-2612] Unschedule execution for Left It Open when door is closed 2017-05-05 13:22:46 -05:00
Vinay Rao
68f5cda945 Merge pull request #1977 from ccurtiST/PROB-1347
PROB-1347 Lux values showing as ${unit} in recently tab of Aeon Multipurpose
2017-05-05 11:06:46 -07:00
Christopher Curti
da42ee63fb Replaced ${unit}', unit:"lux" with lux', unit: "" to fix issue with seeing ${unit} in the recently tab of Aeon multisensor illuminance values. Tested all three DTHs and lux was displayed rather then ${unit} 2017-05-05 09:31:44 -07:00
Vinay Rao
c58132a69e Merge pull request #1974 from SmartThingsCommunity/staging
Rolling down staging to master
2017-05-03 11:54:21 -07:00
Vinay Rao
f069ea3087 Merge pull request #1965 from SmartThingsCommunity/staging
Rolling down staging to master
2017-05-02 16:14:39 -07:00
Parijat Das
1d629cfc9a Fixed typo in README url 2017-04-25 11:50:10 +05:30
Aaron Miller
5b7a7097b8 [DVCSMP-2595] Set scheduled executions for Lights off with no motion SA to overwrite 2017-04-20 13:20:55 -05:00
Duncan McKee
52c57f66fb DVCSMP-2493 Notify Multi-Channel Control app when root device is deleted 2017-03-06 13:31:32 -05:00
Duncan McKee
91c358c3a6 Everspring ST814 and ST815 Multilevel Sensors 2017-03-05 18:50:55 -05:00
76 changed files with 1432 additions and 361 deletions

View File

@@ -38,9 +38,9 @@ metadata {
tiles (scale: 2){
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL", icon: "st.Lighting.light18") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', icon:"st.switches.light.on", backgroundColor:"#79b821"
attributeState "turningOn", label:'${name}', icon:"st.switches.light.on", backgroundColor:"#00A0DC"
attributeState "turningOff", label:'${name}', icon:"st.switches.light.off", backgroundColor:"#ffffff"
}
tileAttribute ("device.color", key: "COLOR_CONTROL") {
@@ -52,20 +52,20 @@ metadata {
}
standardTile("motion", "device.motion", width: 2, height: 2, canChangeIcon: true, canChangeBackground: true) {
state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC"
state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc"
}
valueTile("temperature", "device.temperature", width: 2, height: 2) {
state "temperature", label:'${currentValue}°', unit:"F", icon:"", // would be better if the units would switch to the desired units of the system (imperial or metric)
backgroundColors:[
[value: 0, color: "#1010ff"], // blue=cold
[value: 65, color: "#a0a0f0"],
[value: 70, color: "#e0e050"],
[value: 75, color: "#f0d030"], // yellow
[value: 80, color: "#fbf020"],
[value: 85, color: "#fbdc01"],
[value: 90, color: "#fb3a01"],
[value: 95, color: "#fb0801"] // red=hot
[value: 0, color: "#153591"], // blue=cold
[value: 65, color: "#44b621"], // green
[value: 70, color: "#44b621"], // green
[value: 75, color: "#f1d801"], // yellow
[value: 80, color: "#f1d801"], // yellow
[value: 85, color: "#f1d801"], // yellow
[value: 90, color: "#d04e00"], // red
[value: 95, color: "#bc2323"] // red=hot
]
}

View File

@@ -0,0 +1,268 @@
/**
*
* Inovelli 2-Channel Smart Plug
*
* github: Eric Maycock (erocm123)
* Date: 2017-04-27
* Copyright Eric Maycock
*
* Includes all configuration parameters and ease of advanced configuration.
*
* 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.
*
*/
metadata {
definition(name: "Inovelli 2-Channel Smart Plug", namespace: "erocm123", author: "Eric Maycock") {
capability "Actuator"
capability "Sensor"
capability "Switch"
capability "Polling"
capability "Refresh"
capability "Health Check"
fingerprint manufacturer: "015D", prod: "0221", model: "251C", deviceJoinName: "Show Home 2-Channel Smart Plug"
fingerprint manufacturer: "0312", prod: "B221", model: "251C", deviceJoinName: "Inovelli 2-Channel Smart Plug"
}
simulator {}
preferences {}
tiles {
multiAttributeTile(name: "switch", type: "lighting", width: 6, height: 4, canChangeIcon: true) {
tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
attributeState "turningOff", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
attributeState "turningOn", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
}
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label: "", action: "refresh.refresh", icon: "st.secondary.refresh"
}
main(["switch"])
details(["switch",
childDeviceTiles("all"), "refresh"
])
}
}
def parse(String description) {
def result = []
def cmd = zwave.parse(description)
if (cmd) {
result += zwaveEvent(cmd)
logging("Parsed ${cmd} to ${result.inspect()}", 1)
} else {
logging("Non-parsed event: ${description}", 2)
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd, ep = null) {
logging("BasicReport ${cmd} - ep ${ep}", 2)
if (ep) {
def event
childDevices.each {
childDevice ->
if (childDevice.deviceNetworkId == "$device.deviceNetworkId-ep$ep") {
childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
}
}
if (cmd.value) {
event = [createEvent([name: "switch", value: "on"])]
} else {
def allOff = true
childDevices.each {
n ->
if (n.currentState("switch").value != "off") allOff = false
}
if (allOff) {
event = [createEvent([name: "switch", value: "off"])]
} else {
event = [createEvent([name: "switch", value: "on"])]
}
}
return event
}
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
logging("BasicSet ${cmd}", 2)
def result = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "digital")
def cmds = []
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 1)
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
return [result, response(commands(cmds))] // returns the result of reponse()
}
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd, ep = null) {
logging("SwitchBinaryReport ${cmd} - ep ${ep}", 2)
if (ep) {
def event
def childDevice = childDevices.find {
it.deviceNetworkId == "$device.deviceNetworkId-ep$ep"
}
if (childDevice) childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
if (cmd.value) {
event = [createEvent([name: "switch", value: "on"])]
} else {
def allOff = true
childDevices.each {
n->
if (n.currentState("switch").value != "off") allOff = false
}
if (allOff) {
event = [createEvent([name: "switch", value: "off"])]
} else {
event = [createEvent([name: "switch", value: "on"])]
}
}
return event
} else {
def result = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "digital")
def cmds = []
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 1)
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
return [result, response(commands(cmds))] // returns the result of reponse()
}
}
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
logging("MultiChannelCmdEncap ${cmd}", 2)
def encapsulatedCommand = cmd.encapsulatedCommand([0x32: 3, 0x25: 1, 0x20: 1])
if (encapsulatedCommand) {
zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
}
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
logging("ManufacturerSpecificReport ${cmd}", 2)
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
logging("msr: $msr", 2)
updateDataValue("MSR", msr)
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// This will capture any commands not handled by other instances of zwaveEvent
// and is recommended for development so you can see every command the device sends
logging("Unhandled Event: ${cmd}", 2)
}
def on() {
logging("on()", 1)
commands([
zwave.switchAllV1.switchAllOn(),
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
])
}
def off() {
logging("off()", 1)
commands([
zwave.switchAllV1.switchAllOff(),
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
])
}
void childOn(String dni) {
logging("childOn($dni)", 1)
def cmds = []
cmds << new physicalgraph.device.HubAction(command(encap(zwave.basicV1.basicSet(value: 0xFF), channelNumber(dni))))
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchBinaryV1.switchBinaryGet(), channelNumber(dni))))
sendHubCommand(cmds, 1000)
}
void childOff(String dni) {
logging("childOff($dni)", 1)
def cmds = []
cmds << new physicalgraph.device.HubAction(command(encap(zwave.basicV1.basicSet(value: 0x00), channelNumber(dni))))
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchBinaryV1.switchBinaryGet(), channelNumber(dni))))
sendHubCommand(cmds, 1000)
}
void childRefresh(String dni) {
logging("childRefresh($dni)", 1)
def cmds = []
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchBinaryV1.switchBinaryGet(), channelNumber(dni))))
sendHubCommand(cmds, 1000)
}
def poll() {
logging("poll()", 1)
commands([
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
encap(zwave.switchBinaryV1.switchBinaryGet(), 2),
])
}
def refresh() {
logging("refresh()", 1)
commands([
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
encap(zwave.switchBinaryV1.switchBinaryGet(), 2),
])
}
def ping() {
logging("ping()", 1)
refresh()
}
def installed() {
logging("installed()", 1)
command(zwave.manufacturerSpecificV1.manufacturerSpecificGet())
createChildDevices()
}
def updated() {
logging("updated()", 1)
if (!childDevices) {
createChildDevices()
} else if (device.label != state.oldLabel) {
childDevices.each {
if (it.label == "${state.oldLabel} (CH${channelNumber(it.deviceNetworkId)})") {
def newLabel = "${device.displayName} (CH${channelNumber(it.deviceNetworkId)})"
it.setLabel(newLabel)
}
}
state.oldLabel = device.label
}
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
sendEvent(name: "needUpdate", value: device.currentValue("needUpdate"), displayed: false, isStateChange: true)
}
def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) {
logging("${device.displayName} parameter '${cmd.parameterNumber}' with a byte size of '${cmd.size}' is set to '${cmd2Integer(cmd.configurationValue)}'", 2)
}
private encap(cmd, endpoint) {
if (endpoint) {
zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint: endpoint).encapsulate(cmd)
} else {
cmd
}
}
private command(physicalgraph.zwave.Command cmd) {
if (state.sec) {
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
} else {
cmd.format()
}
}
private commands(commands, delay = 1000) {
delayBetween(commands.collect {
command(it)
}, delay)
}
private channelNumber(String dni) {
dni.split("-ep")[-1] as Integer
}
private void createChildDevices() {
state.oldLabel = device.label
for (i in 1..2) {
addChildDevice("Switch Child Device", "${device.deviceNetworkId}-ep${i}", null, [completedSetup: true, label: "${device.displayName} (CH${i})",
isComponent: true, componentName: "ep$i", componentLabel: "Channel $i"
])
}
}
private def logging(message, level) {
if (logLevel != "0") {
switch (logLevel) {
case "1":
if (level > 1) log.debug "$message"
break
case "99":
log.debug "$message"
break
}
}
}

View File

@@ -0,0 +1,49 @@
/**
* Switch Child Device
*
* Copyright 2017 Eric Maycock
*
* 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.
*
*/
metadata {
definition (name: "Switch Child Device", namespace: "erocm123", author: "Eric Maycock") {
capability "Switch"
capability "Actuator"
capability "Sensor"
capability "Refresh"
}
tiles {
multiAttributeTile(name:"switch", type: "lighting", width: 3, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState:"turningOn"
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC", nextState:"turningOff"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
}
}
void on() {
parent.childOn(device.deviceNetworkId)
}
void off() {
parent.childOff(device.deviceNetworkId)
}
void refresh() {
parent.childRefresh(device.deviceNetworkId)
}

View File

@@ -39,8 +39,8 @@ metadata {
}
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
attributeState("active", label:'tamper active', backgroundColor:"#53a7c0")
attributeState("inactive", label:'tamper inactive', backgroundColor:"#ffffff")
attributeState("active", label:'tamper active', backgroundColor:"#00A0DC")
attributeState("inactive", label:'tamper inactive', backgroundColor:"#CCCCCC")
}
}

View File

@@ -37,8 +37,8 @@ metadata {
}
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
attributeState("active", label:'tamper active', backgroundColor:"#53a7c0")
attributeState("inactive", label:'tamper inactive', backgroundColor:"#ffffff")
attributeState("active", label:'tamper active', backgroundColor:"#00A0DC")
attributeState("inactive", label:'tamper inactive', backgroundColor:"#CCCCCC")
}
}

View File

@@ -34,8 +34,8 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"FGMS", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
tileAttribute("device.motion", key:"PRIMARY_CONTROL") {
attributeState("inactive", label:"no motion", icon:"st.motion.motion.inactive", backgroundColor:"#79b821")
attributeState("active", label:"motion", icon:"st.motion.motion.active", backgroundColor:"#ffa81e")
attributeState("inactive", label:"no motion", icon:"st.motion.motion.inactive", backgroundColor:"#cccccc")
attributeState("active", label:"motion", icon:"st.motion.motion.active", backgroundColor:"#00A0DC")
}
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {

View File

@@ -95,12 +95,12 @@ metadata {
multiAttributeTile(name:"doorCtrl", type:"generic", width:6, height:4) {tileAttribute("device.doorState", key: "PRIMARY_CONTROL")
{
attributeState "unknown", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", nextState:"Sent"
attributeState "open", label: '${name}', action:"closeDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#0000ff" , nextState:"Sent"
attributeState "opening", label: '${name}', action:"closeDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ffa81e"
attributeState "closed", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#79b821", nextState:"Sent"
attributeState "closing", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ffa81e"
attributeState "jammed", label: '${name}', action:"closeDoorHiI", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff0000", nextState:"Sent"
attributeState "forced close", label: 'forced\rclose', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff8000", nextState:"Sent"
attributeState "open", label: '${name}', action:"closeDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#00A0DC" , nextState:"Sent"
attributeState "opening", label: '${name}', action:"closeDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#00A0DC"
attributeState "closed", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ffffff", nextState:"Sent"
attributeState "closing", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ffffff"
attributeState "jammed", label: '${name}', action:"closeDoorHiI", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff0000", nextState:"Sent"
attributeState "forced close", label: 'forced\rclose', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff8000", nextState:"Sent"
attributeState "fault", label: 'FAULT', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff0000", nextState:"Sent"
attributeState "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
}
@@ -135,13 +135,13 @@ metadata {
}
standardTile("autoClose", "device.autoCloseEnable", width: 2, height: 2){
state "on", label: 'Auto', action:"autoCloseOff", icon: "st.doors.garage.garage-closing", backgroundColor: "#79b821", nextState:"Sent"
state "on", label: 'Auto', action:"autoCloseOff", icon: "st.doors.garage.garage-closing", backgroundColor: "#00A0DC", nextState:"Sent"
state "off", label: 'Auto', action:"autoCloseOn", icon: "st.doors.garage.garage-closing", nextState:"Sent"
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
}
standardTile("autoOpen", "device.autoOpenEnable", width: 2, height: 2){
state "on", label: 'Auto', action:"autoOpenOff", icon: "st.doors.garage.garage-opening", backgroundColor: "#79b821", nextState:"Sent"
state "on", label: 'Auto', action:"autoOpenOff", icon: "st.doors.garage.garage-opening", backgroundColor: "#00A0DC", nextState:"Sent"
state "off", label: 'Auto', action:"autoOpenOn", icon: "st.doors.garage.garage-opening", nextState:"Sent"
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
}
@@ -189,13 +189,13 @@ metadata {
standardTile("aux1", "device.Aux1", width: 2, height: 2, canChangeIcon: true) {
state "off", label:'Aux 1', action:"Aux1On", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"Sent"
state "on", label:'Aux 1', action:"Aux1Off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"Sent"
state "on", label:'Aux 1', action:"Aux1Off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"Sent"
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
}
standardTile("aux2", "device.Aux2", width: 2, height: 2, canChangeIcon: true) {
state "off", label:'Aux 2', action:"Aux2On", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"Sent"
state "on", label:'Aux 2', action:"Aux2Off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"Sent"
state "on", label:'Aux 2', action:"Aux2Off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"Sent"
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
}

View File

@@ -21,6 +21,7 @@ metadata {
capability "Battery"
fingerprint deviceId: "0x0101", inClusters: "0x86,0x72,0x70,0x80,0x84,0x85"
fingerprint mfr: "0086", prod: "0001", model: "0026", deviceJoinName: "Aeon Panic Button"
}
simulator {
@@ -130,5 +131,12 @@ def updated() {
}
def initialize() {
sendEvent(name: "numberOfButtons", value: 4)
def zwMap = getZwaveInfo()
def buttons = 4 // Default for Key Fob
// Only one button for Aeon Panic Button
if (zwMap && zwMap.mfr == "0086" && zwMap.prod == "0001" && zwMap.model == "0026") {
buttons = 1
}
sendEvent(name: "numberOfButtons", value: buttons)
}

View File

@@ -0,0 +1,2 @@
.st-ignore
README.md

View File

@@ -0,0 +1,43 @@
# Aeon Multisensor 6
Cloud Execution
Works with:
* [Aeon Labs MultiSensor 6](https://www.smartthings.com/products/aeon-labs-multisensor-6)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Troubleshooting](#troubleshooting)
## Capabilities
* **Motion Sensor** - can detect motion
* **Temperature Measurement** - defines device measures current temperature
* **Relative Humidity Measurement** - allow reading the relative humidity from devices that support it
* **Illuminance Measurement** - gives the illuminance reading from devices that support it
* **Ultraviolet Index** - gives the ability to get the ultraviolet index from devices that report it
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
* **Sensor** - detects sensor events
* **Battery** - defines device uses a battery
* **Health Check** - indicates ability to get device health notifications
## Device Health
Aeon Labs MultiSensor 6 is polled by the hub.
As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row,
it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time.
* __32min__ checkInterval
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [Aeon Labs MultiSensor 6 Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206157226)

View File

@@ -22,6 +22,7 @@ metadata {
capability "Configuration"
capability "Sensor"
capability "Battery"
capability "Health Check"
attribute "tamper", "enum", ["detected", "clear"]
attribute "batteryStatus", "string"
@@ -29,6 +30,7 @@ metadata {
fingerprint deviceId: "0x2101", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x7A", outClusters: "0x5A"
fingerprint deviceId: "0x2101", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x7A,0x5A"
fingerprint mfr:"0086", prod:"0102", model:"0064", deviceJoinName: "Aeon Labs MultiSensor 6"
}
simulator {
@@ -103,7 +105,7 @@ metadata {
}
valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) {
state "illuminance", label:'${currentValue} ${unit}', unit:"lux"
state "illuminance", label:'${currentValue} lux', unit:""
}
valueTile("ultravioletIndex", "device.ultravioletIndex", inactiveLabel: false, width: 2, height: 2) {
@@ -127,7 +129,14 @@ metadata {
}
}
def installed(){
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def updated() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
log.debug "Updated with settings: ${settings}"
log.debug "${device.displayName} is now ${device.latestValue("powerSupply")}"
@@ -326,6 +335,13 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
createEvent(descriptionText: cmd.toString(), isStateChange: false)
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
secure(zwave.batteryV1.batteryGet())
}
def configure() {
// This sensor joins as a secure device if you double-click the button to include it
log.debug "${device.displayName} is configuring its settings"
@@ -410,4 +426,4 @@ private command(physicalgraph.zwave.Command cmd) {
private commands(commands, delay=200) {
log.info "sending commands: ${commands}"
delayBetween(commands.collect{ command(it) }, delay)
}
}

View File

@@ -22,8 +22,6 @@ metadata {
capability "Battery"
capability "Health Check"
command "configureAfterSecure"
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x98,0x7A", outClusters:"0x5A"
fingerprint mfr:"0086", prod:"0102", model:"004A", deviceJoinName: "Aeon Labs MultiSensor (Gen 5)"
}
@@ -86,17 +84,17 @@ metadata {
state "humidity", label:'${currentValue}% humidity', unit:""
}
valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) {
state "luminosity", label:'${currentValue} ${unit}', unit:"lux"
state "luminosity", label:'${currentValue} lux', unit:""
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "battery", label:'${currentValue}% battery', unit:""
}
standardTile("configureAfterSecure", "device.configure", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "configure", label:'', action:"configureAfterSecure", icon:"st.secondary.configure"
standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "configure", label:'', action:"configure", icon:"st.secondary.configure"
}
main(["motion", "temperature", "humidity", "illuminance"])
details(["motion", "temperature", "humidity", "illuminance", "battery", "configureAfterSecure"])
details(["motion", "temperature", "humidity", "illuminance", "battery", "configure"])
}
}
@@ -131,8 +129,8 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
if (!isConfigured()) {
// we're still in the process of configuring a newly joined device
log.debug("not sending wakeUpNoMoreInformation yet")
result += response(configureAfterSecure())
log.debug("not sending wakeUpNoMoreInformation yet: late configure")
result += response(configure())
} else {
result += response(zwave.wakeUpV1.wakeUpNoMoreInformation())
}
@@ -150,11 +148,6 @@ def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulat
}
}
def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityCommandsSupportedReport cmd) {
// log.debug "Received SecurityCommandsSupportedReport"
response(configureAfterSecure())
}
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [ name: "battery", unit: "%" ]
if (cmd.batteryLevel == 0xFF) {
@@ -226,36 +219,6 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
createEvent(descriptionText: cmd.toString(), isStateChange: false)
}
def configureAfterSecure() {
// log.debug "configureAfterSecure()"
def request = [
// send temperature, humidity, and illuminance every 8 minutes
zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 128|64|32),
zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 8*60),
// send battery every 20 hours
zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 1),
zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 20*60*60),
// send no-motion report 60 seconds after motion stops
zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 60),
// send binary sensor report instead of basic set for motion
zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: 2),
// disable notification-style motion events
zwave.notificationV3.notificationSet(notificationType: 7, notificationStatus: 0),
zwave.batteryV1.batteryGet(),
zwave.sensorBinaryV2.sensorBinaryGet(sensorType:0x0C)
]
setConfigured()
secureSequence(request) + ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
@@ -265,7 +228,36 @@ def ping() {
def configure() {
// log.debug "configure()"
//["delay 30000"] + secure(zwave.securityV1.securityCommandsSupportedGet())
def request = []
// send temperature, humidity, and illuminance every 8 minutes
request << zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 128|64|32)
request << zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 8*60)
// send battery every 20 hours
request << zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 1)
request << zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 20*60*60)
// send no-motion report 60 seconds after motion stops
request << zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 60)
// send binary sensor report instead of basic set for motion
request << zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: 2)
// Turn on the Multisensor Gen5 PIR sensor
request << zwave.configurationV1.configurationSet(parameterNumber: 4, size: 1, scaledConfigurationValue: 1)
// disable notification-style motion events
request << zwave.notificationV3.notificationSet(notificationType: 7, notificationStatus: 0)
request << zwave.batteryV1.batteryGet()
request << zwave.sensorBinaryV2.sensorBinaryGet(sensorType: 0x0C) //motion
request << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x01) //temperature
request << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x03) //illuminance
request << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x05) //humidity
setConfigured()
secureSequence(request) + ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
}
private setConfigured() {
@@ -282,5 +274,4 @@ private secure(physicalgraph.zwave.Command cmd) {
private secureSequence(commands, delay=200) {
delayBetween(commands.collect{ secure(it) }, delay)
}
}

View File

@@ -0,0 +1,2 @@
.st-ignore
README.md

View File

@@ -0,0 +1,48 @@
# Aeon Multisensor
Cloud Execution
Works with:
* [Aeotec MultiSensor (DSB05-ZWUS)](https://www.smartthings.com/products/aeotec-multisensor-5)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Battery](#battery-specification)
* [Troubleshooting](#troubleshooting)
## Capabilities
* **Motion Sensor** - can detect motion
* **Temperature Measurement** - defines device measures current temperature
* **Relative Humidity Measurement** - allow reading the relative humidity from devices that support it
* **Illuminance Measurement** - gives the illuminance reading from devices that support it
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
* **Sensor** - detects sensor events
* **Battery** - defines device uses a battery
* **Health Check** - indicates ability to get device health notifications
## Device Health
Aeon Labs MultiSensor is polled by the hub.
As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row,
it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time.
* __32min__ checkInterval
## Battery Specification
Four AAA batteries are required.
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [Aeon MultiSensor Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206157226-How-to-connect-Aeon-Labs-MultiSensors)

View File

@@ -20,6 +20,7 @@ metadata {
capability "Illuminance Measurement"
capability "Sensor"
capability "Battery"
capability "Health Check"
fingerprint deviceId: "0x2001", inClusters: "0x30,0x31,0x80,0x84,0x70,0x85,0x72,0x86"
}
@@ -79,7 +80,7 @@ metadata {
state "humidity", label:'${currentValue}% humidity', unit:""
}
valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) {
state "luminosity", label:'${currentValue} ${unit}', unit:"lux"
state "luminosity", label:'${currentValue} lux', unit:""
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "battery", label:'${currentValue}% battery', unit:""
@@ -93,6 +94,16 @@ metadata {
}
}
def installed(){
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def updated(){
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
// Parse incoming device messages to generate events
def parse(String description)
{
@@ -179,6 +190,13 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
[:]
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
secure(zwave.batteryV1.batteryGet())
}
def configure() {
delayBetween([
// send binary sensor report instead of basic set for motion
@@ -193,4 +211,4 @@ def configure() {
// set data reporting period to 5 minutes
zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 300).format()
])
}
}

View File

@@ -16,7 +16,7 @@
* Date: 2014-07-15
*/
metadata {
definition (name: "Aeon Siren", namespace: "smartthings", author: "SmartThings") {
definition (name: "Aeon Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.smoke") {
capability "Actuator"
capability "Alarm"
capability "Switch"
@@ -61,6 +61,8 @@ metadata {
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
response(secure(zwave.basicV1.basicGet()))
}
def updated() {
@@ -163,4 +165,4 @@ private secure(physicalgraph.zwave.Command cmd) {
* */
def ping() {
secure(zwave.basicV1.basicGet())
}
}

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Bose SoundTouch
*

View File

@@ -9,6 +9,7 @@ metadata {
capability "Configuration"
capability "Refresh"
capability "Sensor"
capability "Health Check"
attribute "thermostatFanState", "string"
@@ -18,6 +19,7 @@ metadata {
command "quickSetHeat"
fingerprint deviceId: "0x08", inClusters: "0x43,0x40,0x44,0x31,0x80,0x85,0x60"
fingerprint mfr:"0098", prod:"6401", model:"0107", deviceJoinName: "2Gig CT100 Programmable Thermostat"
}
// simulator metadata
@@ -106,6 +108,16 @@ metadata {
}
}
def updated() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def parse(String description)
{
def result = []
@@ -439,6 +451,14 @@ def setCoolingSetpoint(Double degrees, Integer delay = 30000) {
], delay)
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
log.debug "ping() called"
refresh()
}
def configure() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSupportedGet().format(),

View File

@@ -108,11 +108,20 @@ def updated(){
}
}
def getCommandClassVersions() {
[
0x20: 1, // Basic
0x26: 1, // SwitchMultilevel
0x56: 1, // Crc16Encap
0x70: 1, // Configuration
]
}
def parse(String description) {
def result = null
if (description != "updated") {
log.debug "parse() >> zwave.parse($description)"
def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
def cmd = zwave.parse(description, commandClassVersions)
if (cmd) {
result = zwaveEvent(cmd)
}
@@ -179,6 +188,16 @@ def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelS
[createEvent(name:"switch", value:"on"), response(zwave.switchMultilevelV1.switchMultilevelGet().format())]
}
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
def versions = commandClassVersions
def version = versions[cmd.commandClass as Integer]
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
if (encapsulatedCommand) {
zwaveEvent(encapsulatedCommand)
}
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in
[:]

View File

@@ -0,0 +1,163 @@
/**
* Copyright 2017 SmartThings
*
* 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.
*
* Everspring ST815 Illuminance Sensor
*
* Author: SmartThings
* Date: 2017-3-4
*/
metadata {
definition (name: "Everspring Illuminance Sensor", namespace: "smartthings", author: "SmartThings") {
capability "Illuminance Measurement"
capability "Battery"
capability "Configuration"
capability "Sensor"
capability "Health Check"
fingerprint mfr:"0060", prod:"0007", model:"0001"
}
simulator {
for( int i = 0; i <= 100; i += 20 ) {
status "illuminace ${i} lux": new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(
scaledSensorValue: i, precision: 0, sensorType: 3, scale: 1).incomingMessage()
}
for( int i = 0; i <= 100; i += 20 ) {
status "battery ${i}%": new physicalgraph.zwave.Zwave().batteryV1.batteryReport(
batteryLevel: i).incomingMessage()
}
status "wakeup": "command: 8407, payload: "
}
tiles(scale: 2) {
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
state "temperature", label:'${currentValue}°',
backgroundColors:[
[value: 32, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 92, color: "#d04e00"],
[value: 98, color: "#bc2323"]
]
}
valueTile("humidity", "device.humidity", inactiveLabel: false, width: 2, height: 2) {
state "humidity", label:'${currentValue}% humidity', unit:""
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "battery", label:'${currentValue}% battery', unit:""
}
main( ["temperature", "humidity"] )
details( ["temperature", "humidity", "battery"] )
}
}
def updated() {
state.configured = false
}
def parse(String description) {
def result = []
def cmd = zwave.parse(description, [0x20: 1, 0x31: 2, 0x70: 1, 0x71: 1, 0x80: 1, 0x84: 2, 0x85: 2])
if (cmd) {
result = zwaveEvent(cmd)
}
if (result instanceof List) {
log.debug "Parsed '$description' to ${result.collect { it.respondsTo("toHubAction") ? it.toHubAction() : it }}"
} else {
log.debug "Parsed '$description' to ${result}"
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
def result = [
createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)
]
if (state.configured) {
result << response(zwave.batteryV1.batteryGet())
} else {
result << response(configure())
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.alarmv1.AlarmReport cmd) {
if (cmd.alarmType == 1 && cmd.alarmType == 0xFF) {
return createEvent(descriptionText: "${device.displayName} battery is low", isStateChange: true)
} else if (cmd.alarmType == 2 && cmd.alarmLevel == 1) {
return createEvent(descriptionText: "${device.displayName} powered up", isStateChange: false)
}
}
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd) {
def map = [:]
switch( cmd.sensorType ) {
case 3:
// luminance
map.value = cmd.scaledSensorValue.toInteger().toString()
map.unit = "lux"
map.name = "illuminance"
break;
}
return createEvent(map)
}
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"
map.isStateChange = true
} else {
map.value = cmd.batteryLevel
}
def response_cmds = []
if (!currentTemperature) {
response_cmds << zwave.sensorMultilevelV2.sensorMultilevelGet().format()
response_cmds << "delay 1000"
}
response_cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
return [createEvent(map), response(response_cmds)]
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
log.debug "Unhandled: ${cmd.toString()}"
return [:]
}
def configure() {
state.configured = true
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
delayBetween([
// Auto report time interval in minutes
zwave.configurationV1.configurationSet(parameterNumber: 5, size: 2, scaledConfigurationValue: 20).format(),
// Auto report lux change threshold
zwave.configurationV1.configurationSet(parameterNumber: 6, size: 2, scaledConfigurationValue: 30).format(),
// Get battery report triggers WakeUpNMI
zwave.batteryV1.batteryGet().format()
])
}

View File

@@ -0,0 +1,188 @@
/**
* Copyright 2017 SmartThings
*
* 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.
*
* Everspring ST814 Temperature/Humidity Sensor
*
* Author: SmartThings
* Date: 2017-3-4
*/
metadata {
definition (name: "Everspring ST814", namespace: "smartthings", author: "SmartThings") {
capability "Temperature Measurement"
capability "Relative Humidity Measurement"
capability "Battery"
capability "Configuration"
capability "Sensor"
capability "Health Check"
fingerprint mfr:"0060", prod:"0006", model:"0001"
}
simulator {
for( int i = 0; i <= 100; i += 20 ) {
status "temperature ${i}F": new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(
scaledSensorValue: i, precision: 1, sensorType: 1, scale: 1).incomingMessage()
}
for( int i = 0; i <= 100; i += 20 ) {
status "humidity ${i}%": new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(
scaledSensorValue: i, precision: 0, sensorType: 5).incomingMessage()
}
for( int i = 0; i <= 100; i += 20 ) {
status "battery ${i}%": new physicalgraph.zwave.Zwave().batteryV1.batteryReport(
batteryLevel: i).incomingMessage()
}
status "wakeup": "command: 8407, payload: "
}
tiles(scale: 2) {
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
state "temperature", label:'${currentValue}°',
backgroundColors:[
[value: 32, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 92, color: "#d04e00"],
[value: 98, color: "#bc2323"]
]
}
valueTile("humidity", "device.humidity", inactiveLabel: false, width: 2, height: 2) {
state "humidity", label:'${currentValue}% humidity', unit:""
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "battery", label:'${currentValue}% battery', unit:""
}
main( ["temperature", "humidity"] )
details( ["temperature", "humidity", "battery"] )
}
}
def updated() {
state.configured = false
}
def parse(String description) {
def result = []
def cmd = zwave.parse(description, [0x20: 1, 0x31: 2, 0x70: 1, 0x71: 1, 0x80: 1, 0x84: 2, 0x85: 2])
if (cmd) {
result = zwaveEvent(cmd)
}
if (result instanceof List) {
log.debug "Parsed '$description' to ${result.collect { it.respondsTo("toHubAction") ? it.toHubAction() : it }}"
} else {
log.debug "Parsed '$description' to ${result}"
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
def result = [
createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)
]
if (state.configured) {
result << response(zwave.batteryV1.batteryGet())
} else {
result << response(configure())
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.alarmv1.AlarmReport cmd) {
if (cmd.alarmType == 1 && cmd.alarmType == 0xFF) {
return createEvent(descriptionText: "${device.displayName} battery is low", isStateChange: true)
} else if (cmd.alarmType == 2 && cmd.alarmLevel == 1) {
return createEvent(descriptionText: "${device.displayName} powered up", isStateChange: false)
}
}
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd) {
def map = [:]
switch( cmd.sensorType ) {
case 1:
/* temperature */
def cmdScale = cmd.scale == 1 ? "F" : "C"
map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
map.unit = getTemperatureScale()
map.name = "temperature"
break
case 5:
/* humidity */
map.value = cmd.scaledSensorValue.toInteger().toString()
map.unit = "%"
map.name = "humidity"
break
}
return createEvent(map)
}
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"
map.isStateChange = true
} else {
map.value = cmd.batteryLevel
}
def response_cmds = []
if (!currentTemperature) {
response_cmds << zwave.sensorMultilevelV2.sensorMultilevelGet().format()
response_cmds << "delay 1000"
}
response_cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
return [createEvent(map), response(response_cmds)]
}
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
def result = null
def encapsulatedCommand = cmd.encapsulatedCommand([0x20: 1, 0x31: 2, 0x70: 1, 0x71: 1, 0x80: 1, 0x84: 2, 0x85: 2])
log.debug ("Command from endpoint ${cmd.sourceEndPoint}: ${encapsulatedCommand}")
if (encapsulatedCommand) {
result = zwaveEvent(encapsulatedCommand)
}
result
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
log.debug "Unhandled: ${cmd.toString()}"
return [:]
}
def configure() {
state.configured = true
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
delayBetween([
// Auto report time interval in minutes
zwave.configurationV1.configurationSet(parameterNumber: 6, size: 2, scaledConfigurationValue: 20).format(),
// Auto report temperature change threshold
zwave.configurationV1.configurationSet(parameterNumber: 7, size: 1, scaledConfigurationValue: 2).format(),
// Auto report humidity change threshold
zwave.configurationV1.configurationSet(parameterNumber: 8, size: 1, scaledConfigurationValue: 5).format(),
// Get battery report triggers WakeUpNMI
zwave.batteryV1.batteryGet().format()
])
}

View File

@@ -68,8 +68,8 @@
tiles {
standardTile("contact", "device.contact", width: 2, height: 2) {
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e"
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821"
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13"
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#00A0DC"
}
valueTile("temperature", "device.temperature", inactiveLabel: false) {
state "temperature", label:'${currentValue}°',
@@ -86,7 +86,7 @@
}
standardTile("tamper", "device.alarm") {
state("secure", label:'secure', icon:"st.locks.lock.locked", backgroundColor:"#ffffff")
state("tampered", label:'tampered', icon:"st.locks.lock.unlocked", backgroundColor:"#53a7c0")
state("tampered", label:'tampered', icon:"st.locks.lock.unlocked", backgroundColor:"#00a0dc")
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
state "battery", label:'${currentValue}% battery', unit:""

View File

@@ -107,8 +107,8 @@
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
}
standardTile("acceleration", "device.acceleration") {
state("active", label:'vibration', icon:"st.motion.acceleration.active", backgroundColor:"#53a7c0")
state("inactive", label:'still', icon:"st.motion.acceleration.inactive", backgroundColor:"#ffffff")
state("active", label:'vibration', icon:"st.motion.acceleration.active", backgroundColor:"#00a0dc")
state("inactive", label:'still', icon:"st.motion.acceleration.inactive", backgroundColor:"#cccccc")
}

View File

@@ -12,13 +12,13 @@
*
*/
metadata {
definition (name: "Fortrezz Water Valve", namespace: "smartthings", author: "SmartThings") {
definition (name: "Fortrezz Water Valve", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.watervalve") {
capability "Actuator"
capability "Health Check"
capability "Valve"
capability "Refresh"
capability "Sensor"
fingerprint deviceId: "0x1000", inClusters: "0x25,0x72,0x86,0x71,0x22,0x70"
fingerprint mfr:"0084", prod:"0213", model:"0215", deviceJoinName: "FortrezZ Water Valve"
}
@@ -34,19 +34,22 @@ metadata {
}
// tile definitions
tiles {
standardTile("contact", "device.contact", width: 2, height: 2, canChangeIcon: true) {
state "open", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC", nextState:"closing"
state "closed", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff", nextState:"opening"
state "opening", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC"
state "closing", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
tiles(scale: 2) {
multiAttributeTile(name:"valve", type: "generic", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.valve", key: "PRIMARY_CONTROL") {
attributeState "open", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC", nextState:"closing"
attributeState "closed", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff", nextState:"opening"
attributeState "opening", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC"
attributeState "closing", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
}
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
standardTile("refresh", "device.valve", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
}
main "contact"
details(["contact","refresh"])
main "valve"
details(["valve","refresh"])
}
}
@@ -62,22 +65,23 @@ def updated(){
def parse(String description) {
log.trace description
def result = null
def cmd = zwave.parse(description)
if (cmd) {
result = createEvent(zwaveEvent(cmd))
return zwaveEvent(cmd)
}
log.debug "Parse returned ${result?.descriptionText}"
return result
log.debug "Could not parse message"
return null
}
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
def value = cmd.value ? "closed" : "open"
[name: "contact", value: value, descriptionText: "$device.displayName valve is $value"]
return [createEventWithDebug([name: "contact", value: value, descriptionText: "$device.displayName valve is $value"]),
createEventWithDebug([name: "valve", value: value, descriptionText: "$device.displayName valve is $value"])]
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
[:] // Handles all Z-Wave commands we aren't interested in
return createEvent([:]) // Handles all Z-Wave commands we aren't interested in
}
def open() {
@@ -98,3 +102,9 @@ def ping() {
def refresh() {
zwave.switchBinaryV1.switchBinaryGet().format()
}
def createEventWithDebug(eventMap) {
def event = createEvent(eventMap)
log.debug "Event created with ${event?.descriptionText}"
return event
}

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Hue Bloom
*

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Hue Bridge
*

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Hue Bulb
*

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Hue Lux Bulb
*

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Hue White Ambiance Bulb
*

View File

@@ -62,8 +62,8 @@ metadata {
state "off", label: '${name}', action: "on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
standardTile("contact", "device.contact", inactiveLabel: false) {
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e"
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821"
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13"
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#00A0DC"
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"

View File

@@ -4,7 +4,7 @@ Cloud Execution
Works with:
* [FortrezZ Siren Strobe Alarm](https://www.smartthings.com/works-with-smartthings/other/fortrezz-water-valve)
* [FortrezZ Siren Strobe Alarm](https://www.smartthings.com/products/fortrezz-siren-strobe-alarm)
## Table of contents

View File

@@ -16,7 +16,7 @@
* Date: 2013-03-05
*/
metadata {
definition (name: "SmartAlert Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.smokedetector") {
definition (name: "SmartAlert Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.smoke") {
capability "Actuator"
capability "Switch"
capability "Sensor"

View File

@@ -44,9 +44,9 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {

View File

@@ -29,6 +29,7 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3200", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3200-Sgb", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "4257050-RZHAC", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 000F, 0B04", outClusters: "0019", manufacturer: "SmartThings", model: "outletv4", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019"
}

View File

@@ -56,8 +56,8 @@ metadata {
state("closing", label:'${name}', icon:"st.doors.garage.garage-closing", backgroundColor:"#00A0DC")
}
standardTile("contact", "device.contact") {
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13")
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00A0DC")
}
standardTile("acceleration", "device.acceleration", decoration: "flat") {
state("active", label:'${name}', icon:"st.motion.acceleration.active", backgroundColor:"#00A0DC")

View File

@@ -61,8 +61,8 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name: "motion", type: "generic", width: 6, height: 4) {
tileAttribute("device.motion", key: "PRIMARY_CONTROL") {
attributeState "active", label: 'motion', icon: "st.motion.motion.active", backgroundColor: "#53a7c0"
attributeState "inactive", label: 'no motion', icon: "st.motion.motion.inactive", backgroundColor: "#ffffff"
attributeState "active", label: 'motion', icon: "st.motion.motion.active", backgroundColor: "#00A0DC"
attributeState "inactive", label: 'no motion', icon: "st.motion.motion.inactive", backgroundColor: "#cccccc"
}
}
valueTile("temperature", "device.temperature", width: 2, height: 2) {

View File

@@ -87,8 +87,8 @@ metadata {
state("closed", label: 'Closed', icon: "st.contact.contact.closed", backgroundColor: "#00a0dc")
}
standardTile("acceleration", "device.acceleration", width: 2, height: 2) {
state("active", label: 'Active', icon: "st.motion.acceleration.active", backgroundColor: "#53a7c0")
state("inactive", label: 'Inactive', icon: "st.motion.acceleration.inactive", backgroundColor: "#ffffff")
state("active", label: 'Active', icon: "st.motion.acceleration.active", backgroundColor: "#00a0dc")
state("inactive", label: 'Inactive', icon: "st.motion.acceleration.inactive", backgroundColor: "#cccccc")
}
valueTile("temperature", "device.temperature", width: 2, height: 2) {
state("temperature", label: '${currentValue}°',
@@ -178,7 +178,7 @@ private List<Map> handleAcceleration(descMap) {
result += parseAxis(descMap.additionalAttrs)
}
} else if (descMap.clusterInt == 0xFC02 && descMap.attrInt == 0x0012) {
def addAttrs = descMap.additionalAttrs
def addAttrs = descMap.additionalAttrs ?: []
addAttrs << ["attrInt": descMap.attrInt, "value": descMap.value]
result += parseAxis(addAttrs)
}

View File

@@ -49,6 +49,6 @@ def arrived() {
def departed() {
log.trace "Executing 'arrived'"
log.trace "Executing 'departed'"
sendEvent(name: "presence", value: "not present")
}

View File

@@ -22,16 +22,16 @@ metadata {
tiles {
standardTile("contact", "device.contact", width: 2, height: 2) {
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821", action: "open")
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e", action: "close")
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00A0DC", action: "open")
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13", action: "close")
}
standardTile("freezerDoor", "device.contact", width: 2, height: 2, decoration: "flat") {
state("closed", label:'Freezer', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
state("open", label:'Freezer', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
state("closed", label:'Freezer', icon:"st.contact.contact.closed", backgroundColor:"#00A0DC")
state("open", label:'Freezer', icon:"st.contact.contact.open", backgroundColor:"#e86d13")
}
standardTile("mainDoor", "device.contact", width: 2, height: 2, decoration: "flat") {
state("closed", label:'Fridge', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
state("open", label:'Fridge', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
state("closed", label:'Fridge', icon:"st.contact.contact.closed", backgroundColor:"#00A0DC")
state("open", label:'Fridge', icon:"st.contact.contact.open", backgroundColor:"#e86d13")
}
standardTile("control", "device.contact", width: 1, height: 1, decoration: "flat") {
state("closed", label:'${name}', icon:"st.contact.contact.closed", action: "open")

View File

@@ -25,8 +25,8 @@ metadata {
tiles(scale: 2) {
standardTile("contact", "device.contact", width: 4, height: 4) {
state("closed", label:'${name}', icon:"st.fridge.fridge-closed", backgroundColor:"#79b821")
state("open", label:'${name}', icon:"st.fridge.fridge-open", backgroundColor:"#ffa81e")
state("closed", label:'${name}', icon:"st.fridge.fridge-closed", backgroundColor:"#00A0DC")
state("open", label:'${name}', icon:"st.fridge.fridge-open", backgroundColor:"#e86d13")
}
childDeviceTile("freezerDoor", "freezerDoor", height: 2, width: 2, childTileName: "freezerDoor")
childDeviceTile("mainDoor", "mainDoor", height: 2, width: 2, childTileName: "mainDoor")

View File

@@ -27,7 +27,7 @@ metadata {
tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
}
@@ -35,7 +35,7 @@ metadata {
tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOn", label:'${name}', backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute("device.level", key: "SECONDARY_CONTROL") {
@@ -59,7 +59,7 @@ metadata {
tileAttribute("device.switch", key: "SECONDARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'…', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOn", label:'…', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'…', action:"switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute("device.level", key: "VALUE_CONTROL") {

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Copyright 2015 SmartThings
*
@@ -40,11 +42,11 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"rich-control", type: "switch", canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "on", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "offline", label:'${name}', icon:"st.Home.home30", backgroundColor:"#ff0000"
attributeState "offline", label:'${name}', icon:"st.Home.home30", backgroundColor:"#cccccc"
}
tileAttribute ("currentIP", key: "SECONDARY_CONTROL") {
attributeState "currentIP", label: ''

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Copyright 2015 SmartThings
*
@@ -46,8 +48,8 @@
}
standardTile("motion", "device.motion", width: 2, height: 2) {
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC")
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#CCCCCC")
state("offline", label:'${name}', icon:"st.motion.motion.inactive", backgroundColor:"#ff0000")
}

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Copyright 2015 SmartThings
*
@@ -38,11 +40,11 @@
tiles(scale: 2) {
multiAttributeTile(name:"rich-control", type: "switch", canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "offline", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ff0000"
attributeState "offline", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#cccccc"
}
tileAttribute ("currentIP", key: "SECONDARY_CONTROL") {
attributeState "currentIP", label: ''
@@ -50,11 +52,11 @@
}
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#00A0DC", nextState:"turningOff"
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#00A0DC", nextState:"turningOff"
state "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
state "offline", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ff0000"
state "offline", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#cccccc"
}
standardTile("refresh", "device.switch", inactiveLabel: false, height: 2, width: 2, decoration: "flat") {

View File

@@ -25,6 +25,7 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY A19 ON/OFF/DIM", deviceJoinName: "SYLVANIA Smart A19 Soft White"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY A19 ON/OFF/DIM 10 Year", deviceJoinName: "SYLVANIA Smart 10-Year A19"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, FF00", outClusters: "0019", manufacturer: "MRVL", model: "MZ100", deviceJoinName: "Wemo Bulb"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B05", outClusters: "0019", manufacturer: "OSRAM SYLVANIA", model: "iQBR30", deviceJoinName: "Sylvania Ultra iQ"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY PAR38 ON/OFF/DIM", deviceJoinName: "SYLVANIA Smart PAR38 Soft White"
@@ -65,22 +66,29 @@ def parse(String description) {
else {
sendEvent(event)
}
}
else {
def cluster = zigbee.parse(description)
if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) {
if (cluster.data[0] == 0x00) {
} else {
def descMap = zigbee.parseDescriptionAsMap(description)
if (descMap && descMap.clusterInt == 0x0006 && descMap.commandInt == 0x07) {
if (descMap.data[0] == "00") {
log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
}
else {
} else {
log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
}
}
else {
} else if (device.getDataValue("manufacturer") == "sengled" && descMap && descMap.clusterInt == 0x0008 && descMap.attrInt == 0x0000) {
// This is being done because the sengled element touch/classic incorrectly uses the value 0xFF for the max level.
// Per the ZCL spec for the UINT8 data type 0xFF is an invalid value, and 0xFE should be the max. Here we
// manually handle the invalid attribute value since it will be ignored by getEvent as an invalid value.
// We also set the level of the bulb to 0xFE so future level reports will be 0xFE until it is changed by
// something else.
if (descMap.value.toUpperCase() == "FF") {
descMap.value = "FE"
}
sendHubCommand(zigbee.command(zigbee.LEVEL_CONTROL_CLUSTER, 0x00, "FE0000").collect { new physicalgraph.device.HubAction(it) }, 0)
sendEvent(zigbee.getEventFromAttrData(descMap.clusterInt, descMap.attrInt, descMap.encoding, descMap.value))
} else {
log.warn "DID NOT PARSE MESSAGE for description : $description"
log.debug "${cluster}"
log.debug "${descMap}"
}
}
}

View File

@@ -34,7 +34,7 @@ import physicalgraph.zigbee.zcl.DataType
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,000A,0101,0020", outClusters: "000A,0019", manufacturer: "Yale", model: "YRD210 PB DB", deviceJoinName: "Yale Push Button Deadbolt Lock"
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,000A,0101,0020", outClusters: "000A,0019", manufacturer: "Yale", model: "YRD220/240 TSDB", deviceJoinName: "Yale Touch Screen Deadbolt Lock"
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,000A,0101,0020", outClusters: "000A,0019", manufacturer: "Yale", model: "YRL210 PB LL", deviceJoinName: "Yale Push Button Lever Lock"
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,000A,0101,0020", outClusters: "000A,0019", manufacturer: "Yale", model: "YRD226/246 TSDB", deviceJoinName: "Yale Touch Screen Deadbolt Lock"
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,000A,0101,0020", outClusters: "000A,0019", manufacturer: "Yale", model: "YRD226/246 TSDB", deviceJoinName: "Yale Touch Screen Deadbolt Lock"
}
tiles(scale: 2) {

View File

@@ -46,9 +46,9 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
@@ -103,12 +103,12 @@ def parse(String description) {
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
sendEvent(name: "hue", value: hueValue, descriptionText: "Color has changed")
state.hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
runIn(5, updateColor, [overwrite: true])
}
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
sendEvent(name: "saturation", value: saturationValue, descriptionText: "Color has changed", displayed: false)
state.saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
runIn(5, updateColor, [overwrite: true])
}
}
else if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) {
@@ -127,6 +127,11 @@ def parse(String description) {
}
}
def updateColor() {
sendEvent(name: "hue", value: state.hueValue, descriptionText: "Color has changed")
sendEvent(name: "saturation", value: state.saturationValue, descriptionText: "Color has changed", displayed: false)
}
def on() {
zigbee.on()
}
@@ -204,9 +209,9 @@ def setColor(value){
log.trace "setColor($value)"
zigbee.on() +
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
}
def setHue(value) {

View File

@@ -27,7 +27,6 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702, 0B05", outClusters: "0003, 000A, 0019", manufacturer: "Jasco Products", model: "45853", deviceJoinName: "GE ZigBee Plug-In Switch"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702, 0B05", outClusters: "000A, 0019", manufacturer: "Jasco Products", model: "45856", deviceJoinName: "GE ZigBee In-Wall Switch"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 000F, 0B04", outClusters: "0019", manufacturer: "SmartThings", model: "outletv4", deviceJoinName: "Outlet"
}
tiles(scale: 2) {

View File

@@ -41,9 +41,9 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
}

View File

@@ -39,7 +39,7 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"valve", type: "generic", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.contact", key: "PRIMARY_CONTROL") {
tileAttribute ("device.valve", key: "PRIMARY_CONTROL") {
attributeState "open", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC", nextState:"closing"
attributeState "closed", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff", nextState:"opening"
attributeState "opening", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC", nextState:"closing"
@@ -83,6 +83,9 @@ def parse(String description) {
}
}
sendEvent(event)
//handle valve attribute
event.name = "valve"
sendEvent(event)
}
else {
def descMap = zigbee.parseDescriptionAsMap(description)

View File

@@ -45,9 +45,9 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {

View File

@@ -49,9 +49,9 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {

View File

@@ -75,6 +75,10 @@ def parse(String description) {
return result
}
def uninstalled() {
sendEvent(name: "epEvent", value: "delete all", isStateChange: true, displayed: false, descriptionText: "Delete endpoint devices")
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
[ createEvent(descriptionText: "${device.displayName} woke up", isStateChange:true),
response(["delay 2000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]) ]

View File

@@ -88,11 +88,20 @@ def updated(){
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def getCommandClassVersions() {
[
0x20: 1, // Basic
0x26: 1, // SwitchMultilevel
0x56: 1, // Crc16Encap
0x70: 1, // Configuration
]
}
def parse(String description) {
def result = null
if (description != "updated") {
log.debug "parse() >> zwave.parse($description)"
def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
def cmd = zwave.parse(description, commandClassVersions)
if (cmd) {
result = zwaveEvent(cmd)
}
@@ -159,6 +168,16 @@ def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelS
[createEvent(name:"switch", value:"on"), response(zwave.switchMultilevelV1.switchMultilevelGet().format())]
}
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
def versions = commandClassVersions
def version = versions[cmd.commandClass as Integer]
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
if (encapsulatedCommand) {
zwaveEvent(encapsulatedCommand)
}
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in
[:]

View File

@@ -30,9 +30,15 @@ metadata {
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x98", outClusters: "0x5A,0x82"
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x80,0x71,0x85,0x70,0x72,0x86,0x30,0x31,0x84,0x59,0x73,0x5A,0x8F,0x98,0x7A", outClusters:"0x20" // Philio multi+
fingerprint mfr:"0086", prod:"0002", model:"001D", deviceJoinName: "Aeon Labs Door/Window Sensor (Gen 5)"
fingerprint mfr:"014A", prod:"0001", model:"0002", deviceJoinName: "Ecolink Door/Window Sensor"
fingerprint mfr:"0086", prod:"0102", model:"0070", deviceJoinName: "Aeon Labs Door/Window Sensor 6"
fingerprint mfr:"0086", prod:"0102", model:"0059", deviceJoinName: "Aeon Labs Recessed Door Sensor"
fingerprint mfr:"014A", prod:"0001", model:"0002", deviceJoinName: "Ecolink Door/Window Sensor"
fingerprint mfr:"014A", prod:"0001", model:"0003", deviceJoinName: "Ecolink Tilt Sensor"
fingerprint mfr:"011A", prod:"0601", model:"0903", deviceJoinName: "Enerwave Magnetic Door/Window Sensor"
fingerprint mfr:"014F", prod:"2001", model:"0102", deviceJoinName: "Nortek GoControl Door/Window Sensor"
fingerprint mfr:"0063", prod:"4953", model:"3031", deviceJoinName: "Jasco Hinge Pin Door Sensor"
fingerprint mfr:"019A", prod:"0003", model:"0003", deviceJoinName: "Sensative Strips"
}
// simulator metadata
@@ -107,9 +113,9 @@ def updated() {
def configure() {
commands([
zwave.manufacturerSpecificV2.manufacturerSpecificGet(),
zwave.batteryV1.batteryGet()
], 6000)
zwave.sensorBinaryV2.sensorBinaryGet(sensorType: zwave.sensorBinaryV2.SENSOR_TYPE_DOOR_WINDOW),
zwave.manufacturerSpecificV2.manufacturerSpecificGet()
], 1000)
}
def sensorValueEvent(value) {
@@ -184,11 +190,17 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
cmds << command(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
cmds << "delay 1200"
}
if (device.currentValue("contact") == null) { // Incase our initial request didn't make it
cmds << command(zwave.sensorBinaryV2.sensorBinaryGet(sensorType: zwave.sensorBinaryV2.SENSOR_TYPE_DOOR_WINDOW))
}
if (!state.lastbat || now() - state.lastbat > 53*60*60*1000) {
cmds << command(zwave.batteryV1.batteryGet())
} else {
} else { // If we check the battery state we will send NoMoreInfo in the handler for BatteryReport so that we definitely get the report
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
}
[event, response(cmds)]
}

View File

@@ -26,7 +26,24 @@ metadata {
fingerprint deviceId: "0x4003", inClusters: "0x98"
fingerprint deviceId: "0x4004", inClusters: "0x98"
fingerprint mfr:"0129", prod:"0002", model:"0000", deviceJoinName: "Yale Key Free Touchscreen Deadbolt"
fingerprint mfr:"0090", prod:"0001", model:"0236", deviceJoinName: "KwikSet SmartCode 910 Deadbolt Door Lock"
fingerprint mfr:"0090", prod:"0003", model:"0238", deviceJoinName: "KwikSet SmartCode 910 Deadbolt Door Lock"
fingerprint mfr:"0090", prod:"0001", model:"0001", deviceJoinName: "KwikSet SmartCode 910 Contemporary Deadbolt Door Lock"
fingerprint mfr:"0090", prod:"0003", model:"0339", deviceJoinName: "KwikSet SmartCode 912 Lever Door Lock"
fingerprint mfr:"0090", prod:"0003", model:"4006", deviceJoinName: "KwikSet SmartCode 914 Deadbolt Door Lock" //backlit version
fingerprint mfr:"0090", prod:"0003", model:"0440", deviceJoinName: "KwikSet SmartCode 914 Deadbolt Door Lock"
fingerprint mfr:"0090", prod:"0001", model:"0642", deviceJoinName: "KwikSet SmartCode 916 Touchscreen Deadbolt Door Lock"
fingerprint mfr:"0090", prod:"0003", model:"0642", deviceJoinName: "KwikSet SmartCode 916 Touchscreen Deadbolt Door Lock"
fingerprint mfr:"003B", prod:"6341", model:"0544", deviceJoinName: "Schlage Camelot Touchscreen Deadbolt Door Lock"
fingerprint mfr:"003B", prod:"6341", model:"5044", deviceJoinName: "Schlage Century Touchscreen Deadbolt Door Lock"
fingerprint mfr:"003B", prod:"634B", model:"504C", deviceJoinName: "Schlage Connected Keypad Lever Door Lock"
fingerprint mfr:"0129", prod:"0002", model:"0800", deviceJoinName: "Yale Touchscreen Deadbolt Door Lock" // YRD120
fingerprint mfr:"0129", prod:"0002", model:"0000", deviceJoinName: "Yale Touchscreen Deadbolt Door Lock" // YRD220, YRD240
fingerprint mfr:"0129", prod:"0002", model:"FFFF", deviceJoinName: "Yale Touchscreen Lever Door Lock" // YRD220
fingerprint mfr:"0129", prod:"0004", model:"0800", deviceJoinName: "Yale Push Button Deadbolt Door Lock" // YRD110
fingerprint mfr:"0129", prod:"0004", model:"0000", deviceJoinName: "Yale Push Button Deadbolt Door Lock" // YRD210
fingerprint mfr:"0129", prod:"0001", model:"0000", deviceJoinName: "Yale Push Button Lever Door Lock" // YRD210
fingerprint mfr:"0129", prod:"8002", model:"0600", deviceJoinName: "Yale Assure Lock with Bluetooth"
}
simulator {
@@ -69,13 +86,13 @@ import physicalgraph.zwave.commands.doorlockv1.*
import physicalgraph.zwave.commands.usercodev1.*
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
// Device-Watch pings if no device events received for 1 hour (checkInterval)
sendEvent(name: "checkInterval", value: 1 * 60 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def updated() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
// Device-Watch pings if no device events received for 1 hour (checkInterval)
sendEvent(name: "checkInterval", value: 1 * 60 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
try {
if (!state.init) {
state.init = true
@@ -135,6 +152,10 @@ def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityCommandsSupported
def zwaveEvent(DoorLockOperationReport cmd) {
def result = []
unschedule("followupStateCheck")
unschedule("stateCheck")
def map = [ name: "lock" ]
if (cmd.doorLockMode == 0xFF) {
map.value = "locked"
@@ -348,7 +369,7 @@ def zwaveEvent(UserCodeReport cmd) {
code = state["set$name"] ?: decrypt(state[name]) ?: "****"
state.remove("set$name".toString())
} else {
map = [ name: "codeReport", value: cmd.userIdentifier, data: [ code: code ] ]
map = [ name: "codeReport", value: cmd.userIdentifier, data: [ code: code ], isStateChange: true ]
map.descriptionText = "$device.displayName code $cmd.userIdentifier is set"
map.displayed = (cmd.userIdentifier != state.requestCode && cmd.userIdentifier != state.pollCode)
map.isStateChange = true
@@ -439,11 +460,12 @@ def zwaveEvent(physicalgraph.zwave.commands.timev1.TimeGet cmd) {
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
// The old Schlage locks use group 1 for basic control - we don't want that, so unsubscribe from group 1
def result = [ createEvent(name: "lock", value: cmd.value ? "unlocked" : "locked") ]
result << response(zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId))
if (state.assoc != zwaveHubNodeId) {
result << response(zwave.associationV1.associationGet(groupingIdentifier:2))
}
result
def cmds = [
zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId).format(),
"delay 1200",
zwave.associationV1.associationGet(groupingIdentifier:2).format()
]
[result, response(cmds)]
}
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
@@ -513,11 +535,18 @@ def unlockwtimeout() {
lockAndCheck(DoorLockOperationSet.DOOR_LOCK_MODE_DOOR_UNSECURED_WITH_TIMEOUT)
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
refresh()
runIn(30, followupStateCheck)
secure(zwave.doorLockV1.doorLockOperationGet())
}
def followupStateCheck() {
runEvery1Hour(stateCheck)
stateCheck()
}
def stateCheck() {
sendHubCommand(new physicalgraph.device.HubAction(secure(zwave.doorLockV1.doorLockOperationGet())))
}
def refresh() {

View File

@@ -85,11 +85,21 @@ metadata {
details(["switch", "power", "energy", "levelSliderControl", "refresh", "reset"])
}
def getCommandClassVersions() {
[
0x20: 1, // Basic
0x26: 3, // SwitchMultilevel
0x56: 1, // Crc16Encap
0x70: 1, // Configuration
0x32: 3, // Meter
]
}
// parse events into attributes
def parse(String description) {
def result = null
if (description != "updated") {
def cmd = zwave.parse(description, [0x20: 1, 0x26: 3, 0x70: 1, 0x32:3])
def cmd = zwave.parse(description, commandClassVersions)
if (cmd) {
result = zwaveEvent(cmd)
log.debug("'$description' parsed to $result")
@@ -124,6 +134,21 @@ def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelR
dimmerEvents(cmd)
}
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
def versions = commandClassVersions
def version = versions[cmd.commandClass as Integer]
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
if (encapsulatedCommand) {
zwaveEvent(encapsulatedCommand)
}
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in
[:]
}
def dimmerEvents(physicalgraph.zwave.Command cmd) {
def result = []
def value = (cmd.value ? "on" : "off")

View File

@@ -89,10 +89,19 @@ def updated() {
} catch (e) { log.debug e }
}
def getCommandClassVersions() {
[
0x20: 1, // Basic
0x32: 1, // SwitchMultilevel
0x56: 1, // Crc16Encap
0x72: 2, // ManufacturerSpecific
]
}
def parse(String description) {
def result = null
if(description == "updated") return
def cmd = zwave.parse(description, [0x20: 1, 0x32: 1, 0x72: 2])
def cmd = zwave.parse(description, commandClassVersions)
if (cmd) {
result = zwaveEvent(cmd)
}
@@ -157,6 +166,16 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
result
}
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
def versions = commandClassVersions
def version = versions[cmd.commandClass as Integer]
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
if (encapsulatedCommand) {
zwaveEvent(encapsulatedCommand)
}
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
log.debug "$device.displayName: Unhandled: $cmd"
[:]

View File

@@ -29,7 +29,7 @@ metadata {
fingerprint mfr: "0060", prod: "0001", model: "0002", deviceJoinName: "Everspring Motion Sensor" // Everspring SP814
fingerprint mfr: "0060", prod: "0001", model: "0003", deviceJoinName: "Everspring Motion Sensor" // Everspring HSP02
fingerprint mfr: "011A", prod: "0601", model: "0901", deviceJoinName: "Enerwave Motion Sensor" // Enerwave ZWN-BPC
fingerprint mfr: "0063", prod: "4953", model: "3133", deviceJoinName: "GE Smart Motion Sensor"
fingerprint mfr: "0063", prod: "4953", model: "3133", deviceJoinName: "GE Portable Smart Motion Sensor"
}
simulator {

View File

@@ -37,8 +37,8 @@ metadata {
tiles {
standardTile("motion", "device.motion", width: 3, height: 2) {
state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC"
state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#CCCCCC"
}
valueTile("temperature", "device.temperature", inactiveLabel: false) {

View File

@@ -16,7 +16,7 @@
* Date: 2014-07-15
*/
metadata {
definition (name: "Z-Wave Siren", namespace: "smartthings", author: "SmartThings") {
definition (name: "Z-Wave Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.smoke") {
capability "Actuator"
capability "Alarm"
capability "Battery"

View File

@@ -22,6 +22,7 @@ metadata {
attribute "alarmState", "string"
fingerprint deviceId: "0xA100", inClusters: "0x20,0x80,0x70,0x85,0x71,0x72,0x86"
fingerprint mfr:"0138", prod:"0001", model:"0001", deviceJoinName: "First Alert Smoke Detector"
fingerprint mfr:"0138", prod:"0001", model:"0002", deviceJoinName: "First Alert Smoke Detector and Carbon Monoxide Alarm (ZCOMBO)"
}

View File

@@ -71,9 +71,17 @@ def updated(){
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def getCommandClassVersions() {
[
0x20: 1, // Basic
0x56: 1, // Crc16Encap
0x70: 1, // Configuration
]
}
def parse(String description) {
def result = null
def cmd = zwave.parse(description, [0x20: 1, 0x70: 1])
def cmd = zwave.parse(description, commandClassVersions)
if (cmd) {
result = createEvent(zwaveEvent(cmd))
}
@@ -120,6 +128,15 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
}
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
def versions = commandClassVersions
def version = versions[cmd.commandClass as Integer]
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
if (encapsulatedCommand) {
zwaveEvent(encapsulatedCommand)
}
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in

View File

@@ -89,9 +89,17 @@ def updated(){
}
}
def getCommandClassVersions() {
[
0x20: 1, // Basic
0x56: 1, // Crc16Encap
0x70: 1, // Configuration
]
}
def parse(String description) {
def result = null
def cmd = zwave.parse(description, [0x20: 1, 0x70: 1])
def cmd = zwave.parse(description, commandClassVersions)
if (cmd) {
result = createEvent(zwaveEvent(cmd))
}
@@ -138,6 +146,16 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
}
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
def versions = commandClassVersions
def version = versions[cmd.commandClass as Integer]
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
if (encapsulatedCommand) {
zwaveEvent(encapsulatedCommand)
}
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in

View File

@@ -0,0 +1,2 @@
.st-ignore
README.md

View File

@@ -0,0 +1,38 @@
# Z-Wave Water Valve
Cloud Execution
Works with:
* [Leak Intelligence Leak Gopher Water Shutoff Valve](https://www.smartthings.com/works-with-smartthings/other/leak-intelligence-leak-gopher-water-shutoff-valve)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Troubleshooting](#Troubleshooting)
## Capabilities
* **Actuator** - represents that a Device has commands
* **Health Check** - indicates ability to get device health notifications
* **Valve** - allows for the control of a valve device
* **Polling** - represents that poll() can be implemented for the device
* **Refresh** - _refresh()_ command for status updates
* **Sensor** - detects sensor events
## Device Health
SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE`
* __32min__ checkInterval
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [Leak Intelligence Leak Gopher Water Shutoff Valve Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/209631423-Leak-Gopher-Z-Wave-Valve-Control)

View File

@@ -12,14 +12,16 @@
*
*/
metadata {
definition (name: "Z-Wave Water Valve", namespace: "smartthings", author: "SmartThings") {
definition (name: "Z-Wave Water Valve", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.watervalve") {
capability "Actuator"
capability "Health Check"
capability "Valve"
capability "Polling"
capability "Refresh"
capability "Sensor"
fingerprint deviceId: "0x1006", inClusters: "0x25"
fingerprint mfr:"0173", prod:"0003", model:"0002", deviceJoinName: "Leak Intelligence Leak Gopher Water Shutoff Valve"
}
// simulator metadata
@@ -35,7 +37,7 @@ metadata {
// tile definitions
tiles(scale: 2) {
multiAttributeTile(name:"valve", type: "generic", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.contact", key: "PRIMARY_CONTROL") {
tileAttribute ("device.valve", key: "PRIMARY_CONTROL") {
attributeState "open", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC", nextState:"closing"
attributeState "closed", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff", nextState:"opening"
attributeState "opening", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC"
@@ -43,7 +45,7 @@ metadata {
}
}
standardTile("refresh", "device.contact", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
standardTile("refresh", "device.valve", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
}
@@ -53,24 +55,32 @@ metadata {
}
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def updated() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
response(refresh())
}
def parse(String description) {
log.trace "parse description : $description"
def result = null
def cmd = zwave.parse(description, [0x20: 1])
if (cmd) {
result = createEvent(zwaveEvent(cmd))
return zwaveEvent(cmd)
}
log.debug "Parse returned ${result?.descriptionText}"
return result
log.debug "Could not parse message"
return null
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
def value = cmd.value == 0xFF ? "open" : cmd.value == 0x00 ? "closed" : "unknown"
[name: "contact", value: value, descriptionText: "$device.displayName valve is $value"]
def value = cmd.value == 0xFF ? "open" : cmd.value == 0x00 ? "closed" : "unknown"
return [createEventWithDebug([name: "contact", value: value, descriptionText: "$device.displayName valve is $value"]),
createEventWithDebug([name: "valve", value: value, descriptionText: "$device.displayName valve is $value"])]
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) { //TODO should show MSR when device is discovered
@@ -80,20 +90,22 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
log.debug "productTypeId: ${cmd.productTypeId}"
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
updateDataValue("MSR", msr)
[descriptionText: "$device.displayName MSR: $msr", isStateChange: false]
return createEventWithDebug([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
}
def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLocallyNotification cmd) {
[descriptionText: cmd.toString(), isStateChange: true, displayed: true]
return createEventWithDebug([descriptionText: cmd.toString(), isStateChange: true, displayed: true])
}
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
def value = cmd.value == 0xFF ? "open" : cmd.value == 0x00 ? "closed" : "unknown"
[name: "contact", value: value, descriptionText: "$device.displayName valve is $value"]
return [createEventWithDebug([name: "contact", value: value, descriptionText: "$device.displayName valve is $value"]),
createEventWithDebug([name: "valve", value: value, descriptionText: "$device.displayName valve is $value"])]
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
[:] // Handles all Z-Wave commands we aren't interested in
return createEvent([:]) // Handles all Z-Wave commands we aren't interested in
}
def open() {
@@ -114,6 +126,13 @@ def poll() {
zwave.switchBinaryV1.switchBinaryGet().format()
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
refresh()
}
def refresh() {
log.debug "refresh() is called"
def commands = [zwave.switchBinaryV1.switchBinaryGet().format()]
@@ -122,3 +141,9 @@ def refresh() {
}
delayBetween(commands,100)
}
def createEventWithDebug(eventMap) {
def event = createEvent(eventMap)
log.debug "Event created with ${event?.descriptionText}"
return event
}

View File

@@ -765,7 +765,6 @@ def turnOffSwitch() {
} else {
device.off();
return [Device_id: params.id, result_action: "200"]
}
}
@@ -789,6 +788,7 @@ def getTempSensorsStatus(id) {
return []
} else {
def bat = getBatteryStatus(device.id)
return [temperature: device.currentValue('temperature')] + bat
def scale = [Scale: location.temperatureScale]
return [temperature: device.currentValue('temperature')] + bat + scale
}
}
}

View File

@@ -15,66 +15,66 @@ definition(
)
preferences {
section("Light switches to turn off") {
input "switches", "capability.switch", title: "Choose light switches", multiple: true
}
section("Turn off when there is no motion and presence") {
input "motionSensor", "capability.motionSensor", title: "Choose motion sensor"
input "presenceSensors", "capability.presenceSensor", title: "Choose presence sensors", multiple: true
}
section("Delay before turning off") {
input "delayMins", "number", title: "Minutes of inactivity?"
}
section("Light switches to turn off") {
input "switches", "capability.switch", title: "Choose light switches", multiple: true
}
section("Turn off when there is no motion and presence") {
input "motionSensor", "capability.motionSensor", title: "Choose motion sensor"
input "presenceSensors", "capability.presenceSensor", title: "Choose presence sensors", multiple: true
}
section("Delay before turning off") {
input "delayMins", "number", title: "Minutes of inactivity?"
}
}
def installed() {
subscribe(motionSensor, "motion", motionHandler)
subscribe(presenceSensors, "presence", presenceHandler)
subscribe(motionSensor, "motion", motionHandler)
subscribe(presenceSensors, "presence", presenceHandler)
}
def updated() {
unsubscribe()
subscribe(motionSensor, "motion", motionHandler)
subscribe(presenceSensors, "presence", presenceHandler)
unsubscribe()
subscribe(motionSensor, "motion", motionHandler)
subscribe(presenceSensors, "presence", presenceHandler)
}
def motionHandler(evt) {
log.debug "handler $evt.name: $evt.value"
if (evt.value == "inactive") {
runIn(delayMins * 60, scheduleCheck, [overwrite: false])
}
log.debug "handler $evt.name: $evt.value"
if (evt.value == "inactive") {
runIn(delayMins * 60, scheduleCheck, [overwrite: true])
}
}
def presenceHandler(evt) {
log.debug "handler $evt.name: $evt.value"
if (evt.value == "not present") {
runIn(delayMins * 60, scheduleCheck, [overwrite: false])
}
log.debug "handler $evt.name: $evt.value"
if (evt.value == "not present") {
runIn(delayMins * 60, scheduleCheck, [overwrite: true])
}
}
def isActivePresence() {
// check all the presence sensors, make sure none are present
def noPresence = presenceSensors.find{it.currentPresence == "present"} == null
!noPresence
// check all the presence sensors, make sure none are present
def noPresence = presenceSensors.find{it.currentPresence == "present"} == null
!noPresence
}
def scheduleCheck() {
log.debug "scheduled check"
def motionState = motionSensor.currentState("motion")
log.debug "scheduled check"
def motionState = motionSensor.currentState("motion")
if (motionState.value == "inactive") {
def elapsed = now() - motionState.rawDateCreated.time
def threshold = 1000 * 60 * delayMins - 1000
if (elapsed >= threshold) {
if (!isActivePresence()) {
log.debug "Motion has stayed inactive since last check ($elapsed ms) and no presence: turning lights off"
switches.off()
} else {
log.debug "Presence is active: do nothing"
}
} else {
log.debug "Motion has not stayed inactive long enough since last check ($elapsed ms): do nothing"
def elapsed = now() - motionState.rawDateCreated.time
def threshold = 1000 * 60 * delayMins - 1000
if (elapsed >= threshold) {
if (!isActivePresence()) {
log.debug "Motion has stayed inactive since last check ($elapsed ms) and no presence: turning lights off"
switches.off()
} else {
log.debug "Presence is active: do nothing"
}
} else {
log.debug "Motion has not stayed inactive long enough since last check ($elapsed ms): do nothing"
}
} else {
log.debug "Motion is active: do nothing"
log.debug "Motion is active: do nothing"
}
}
}

View File

@@ -162,6 +162,17 @@ def registerAllDeviceSubscriptions() {
registerChangeHandler(inputs)
}
//Subscribe to events from a list of devices
def registerChangeHandler(myList) {
myList.each { myDevice ->
def theAtts = myDevice.supportedAttributes
theAtts.each { att ->
subscribe(myDevice, att.name, deviceEventHandler)
log.info "Registering for ${myDevice.displayName}.${att.name}"
}
}
}
//Endpoints function: Subscribe to events from a specific device
def registerDeviceChange() {
def subscriptionEndpt = params.subscriptionURL

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Bose SoundTouch (Connect)
*

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Hue Service Manager
*
@@ -1083,7 +1085,6 @@ def on(childDevice) {
log.debug "Executing 'on'"
def id = getId(childDevice)
updateInProgress()
createSwitchEvent(childDevice, "on")
put("lights/$id/state", [on: true])
return "Bulb is turning On"
}
@@ -1092,7 +1093,6 @@ def off(childDevice) {
log.debug "Executing 'off'"
def id = getId(childDevice)
updateInProgress()
createSwitchEvent(childDevice, "off")
put("lights/$id/state", [on: false])
return "Bulb is turning Off"
}
@@ -1108,8 +1108,6 @@ def setLevel(childDevice, percent) {
else
level = Math.min(Math.round(percent * 254 / 100), 254)
createSwitchEvent(childDevice, level > 0, percent)
// For Zigbee lights, if level is set to 0 ST just turns them off without changing level
// that means that the light will still be on when on is called next time
// Lets emulate that here
@@ -1128,7 +1126,6 @@ def setSaturation(childDevice, percent) {
// 0 - 254
def level = Math.min(Math.round(percent * 254 / 100), 254)
// TODO should this be done by app only or should we default to on?
createSwitchEvent(childDevice, "on")
put("lights/$id/state", [sat: level, on: true])
return "Setting saturation to $percent"
}
@@ -1140,7 +1137,6 @@ def setHue(childDevice, percent) {
// 0 - 65535
def level = Math.min(Math.round(percent * 65535 / 100), 65535)
// TODO should this be done by app only or should we default to on?
createSwitchEvent(childDevice, "on")
put("lights/$id/state", [hue: level, on: true])
return "Setting hue to $percent"
}
@@ -1151,7 +1147,6 @@ def setColorTemperature(childDevice, huesettings) {
updateInProgress()
// 153 (6500K) to 500 (2000K)
def ct = hueSettings == 6500 ? 153 : Math.round(1000000 / huesettings)
createSwitchEvent(childDevice, "on")
put("lights/$id/state", [ct: ct, on: true])
return "Setting color temperature to $ct"
}
@@ -1210,7 +1205,6 @@ def setColor(childDevice, huesettings) {
if (huesettings.switch == "off")
value.on = false
createSwitchEvent(childDevice, value.on ? "on" : "off")
put("lights/$id/state", value)
return "Setting color to $value"
}
@@ -1322,32 +1316,6 @@ private List getRealHubFirmwareVersions() {
return location.hubs*.firmwareVersionString.findAll { it }
}
/**
* Sends appropriate turningOn/turningOff state events depending on switch or level changes.
*
* @param childDevice device to send event for
* @param setSwitch The new switch state, "on" or "off"
* @param setLevel Optional, switchLevel between 0-100, used if you set level to 0 for example since
* that should generate "off" instead of level change
*/
private void createSwitchEvent(childDevice, setSwitch, setLevel = null) {
if (setLevel == null) {
setLevel = childDevice.device?.currentValue("level")
}
// Create on, off, turningOn or turningOff event as necessary
def currentState = childDevice.device?.currentValue("switch")
if ((currentState == "off" || currentState == "turningOff")) {
if (setSwitch == "on" || setLevel > 0) {
childDevice.sendEvent(name: "switch", value: "turningOn", displayed: false)
}
} else if ((currentState == "on" || currentState == "turningOn")) {
if (setSwitch == "off" || setLevel == 0) {
childDevice.sendEvent(name: "switch", value: "turningOff", displayed: false)
}
}
}
/**
* Return the supported color range for different Hue lights. If model is not specified
* it defaults to the smallest Gamut (B) to ensure that colors set on a mix of devices

View File

@@ -27,84 +27,82 @@ definition(
preferences {
section("Monitor this door or window") {
input "contact", "capability.contactSensor"
}
section("And notify me if it's open for more than this many minutes (default 10)") {
input "openThreshold", "number", description: "Number of minutes", required: false
}
section("Delay between notifications (default 10 minutes") {
input "frequency", "number", title: "Number of minutes", description: "", required: false
section("Monitor this door or window") {
input "contact", "capability.contactSensor"
}
section("And notify me if it's open for more than this many minutes (default 10)") {
input "openThreshold", "number", description: "Number of minutes", required: false
}
section("Delay between notifications (default 10 minutes") {
input "frequency", "number", title: "Number of minutes", description: "", required: false
}
section("Via text message at this number (or via push notification if not specified") {
input("recipients", "contact", title: "Send notifications to") {
input "phone", "phone", title: "Phone number (optional)", required: false
}
section("Via text message at this number (or via push notification if not specified") {
input("recipients", "contact", title: "Send notifications to") {
input "phone", "phone", title: "Phone number (optional)", required: false
}
}
}
}
def installed() {
log.trace "installed()"
subscribe()
log.trace "installed()"
subscribe()
}
def updated() {
log.trace "updated()"
unsubscribe()
subscribe()
log.trace "updated()"
unsubscribe()
subscribe()
}
def subscribe() {
subscribe(contact, "contact.open", doorOpen)
subscribe(contact, "contact.closed", doorClosed)
subscribe(contact, "contact.open", doorOpen)
subscribe(contact, "contact.closed", doorClosed)
}
def doorOpen(evt)
{
log.trace "doorOpen($evt.name: $evt.value)"
def t0 = now()
def delay = (openThreshold != null && openThreshold != "") ? openThreshold * 60 : 600
runIn(delay, doorOpenTooLong, [overwrite: false])
log.debug "scheduled doorOpenTooLong in ${now() - t0} msec"
def doorOpen(evt) {
log.trace "doorOpen($evt.name: $evt.value)"
def delay = (openThreshold != null && openThreshold != "") ? openThreshold * 60 : 600
runIn(delay, doorOpenTooLong, [overwrite: true])
}
def doorClosed(evt)
{
log.trace "doorClosed($evt.name: $evt.value)"
def doorClosed(evt) {
log.trace "doorClosed($evt.name: $evt.value)"
unschedule(doorOpenTooLong)
}
def doorOpenTooLong() {
def contactState = contact.currentState("contact")
def freq = (frequency != null && frequency != "") ? frequency * 60 : 600
def contactState = contact.currentState("contact")
def freq = (frequency != null && frequency != "") ? frequency * 60 : 600
if (contactState.value == "open") {
def elapsed = now() - contactState.rawDateCreated.time
def threshold = ((openThreshold != null && openThreshold != "") ? openThreshold * 60000 : 60000) - 1000
if (elapsed >= threshold) {
log.debug "Contact has stayed open long enough since last check ($elapsed ms): calling sendMessage()"
sendMessage()
runIn(freq, doorOpenTooLong, [overwrite: false])
} else {
log.debug "Contact has not stayed open long enough since last check ($elapsed ms): doing nothing"
}
} else {
log.warn "doorOpenTooLong() called but contact is closed: doing nothing"
}
if (contactState.value == "open") {
def elapsed = now() - contactState.rawDateCreated.time
def threshold = ((openThreshold != null && openThreshold != "") ? openThreshold * 60000 : 60000) - 1000
if (elapsed >= threshold) {
log.debug "Contact has stayed open long enough since last check ($elapsed ms): calling sendMessage()"
sendMessage()
runIn(freq, doorOpenTooLong, [overwrite: false])
} else {
log.debug "Contact has not stayed open long enough since last check ($elapsed ms): doing nothing"
}
} else {
log.warn "doorOpenTooLong() called but contact is closed: doing nothing"
}
}
void sendMessage()
{
def minutes = (openThreshold != null && openThreshold != "") ? openThreshold : 10
def msg = "${contact.displayName} has been left open for ${minutes} minutes."
log.info msg
if (location.contactBookEnabled) {
sendNotificationToContacts(msg, recipients)
}
else {
if (phone) {
sendSms phone, msg
} else {
sendPush msg
}
void sendMessage() {
def minutes = (openThreshold != null && openThreshold != "") ? openThreshold : 10
def msg = "${contact.displayName} has been left open for ${minutes} minutes."
log.info msg
if (location.contactBookEnabled) {
sendNotificationToContacts(msg, recipients)
} else {
if (phone) {
sendSms phone, msg
} else {
sendPush msg
}
}
}

View File

@@ -98,7 +98,7 @@ def motionHandler(evt) {
else {
state.motionStopTime = now()
if(delayMinutes) {
runIn(delayMinutes*60, turnOffMotionAfterDelay, [overwrite: false])
runIn(delayMinutes*60, turnOffMotionAfterDelay, [overwrite: true])
} else {
turnOffMotionAfterDelay()
}

View File

@@ -1,3 +1,5 @@
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
/**
* Copyright 2015 SmartThings
*

View File

@@ -125,19 +125,19 @@
if(allOk) {
if(everyoneIsAway() && (state.sunMode == "sunrise")) {
log.info("Home is Empty Setting New Away Mode")
log.debug("Home is Empty Setting New Away Mode")
def delay = (falseAlarmThreshold != null && falseAlarmThreshold != "") ? falseAlarmThreshold * 60 : 10 * 60
runIn(delay, "setAway")
}
if(everyoneIsAway() && (state.sunMode == "sunset")) {
log.info("Home is Empty Setting New Away Mode")
log.debug("Home is Empty Setting New Away Mode")
def delay = (falseAlarmThreshold != null && falseAlarmThreshold != "") ? falseAlarmThreshold * 60 : 10 * 60
runIn(delay, "setAway")
}
else {
log.info("Home is Occupied Setting New Home Mode")
log.debug("Home is Occupied Setting New Home Mode")
setHome()
@@ -152,7 +152,7 @@
log.debug("Checking if everyone is away")
if(everyoneIsAway()) {
log.info("Nobody is home, running away sequence")
log.debug("Nobody is home, running away sequence")
def delay = (falseAlarmThreshold != null && falseAlarmThreshold != "") ? falseAlarmThreshold * 60 : 10 * 60
runIn(delay, "setAway")
}
@@ -161,7 +161,7 @@
else {
def lastTime = state[evt.deviceId]
if (lastTime == null || now() - lastTime >= 1 * 60000) {
log.info("Someone is home, running home sequence")
log.debug("Someone is home, running home sequence")
setHome()
}
state[evt.deviceId] = now()
@@ -175,14 +175,14 @@
if(everyoneIsAway()) {
if(state.sunMode == "sunset") {
def message = "Performing \"${awayNight}\" for you as requested."
log.info(message)
log.debug(message)
sendAway(message)
location.helloHome.execute(settings.awayNight)
}
else if(state.sunMode == "sunrise") {
def message = "Performing \"${awayDay}\" for you as requested."
log.info(message)
log.debug(message)
sendAway(message)
location.helloHome.execute(settings.awayDay)
}
@@ -192,19 +192,19 @@
}
else {
log.info("Somebody returned home before we set to '${newAwayMode}'")
log.debug("Somebody returned home before we set to '${newAwayMode}'")
}
}
//set home mode when house is occupied
def setHome() {
sendOutOfDateNotification()
log.info("Setting Home Mode!!")
log.debug("Setting Home Mode!!")
if(anyoneIsHome()) {
if(state.sunMode == "sunset"){
if (location.mode != "${homeModeNight}"){
def message = "Performing \"${homeNight}\" for you as requested."
log.info(message)
log.debug(message)
sendHome(message)
location.helloHome.execute(settings.homeNight)
}
@@ -213,7 +213,7 @@
if(state.sunMode == "sunrise"){
if (location.mode != "${homeModeDay}"){
def message = "Performing \"${homeDay}\" for you as requested."
log.info(message)
log.debug(message)
sendHome(message)
location.helloHome.execute(settings.homeDay)
}
@@ -329,4 +329,4 @@
sendNotification("Your version of Hello, Home Phrase Director is currently out of date. Please look for the new version of Hello, Home Phrase Director now called 'Routine Director' in the marketplace.")
state.lastTime = (new Date() + 31).getTime()
}
}
}