mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-09 05:11:52 +00:00
Compare commits
326 Commits
MSA-1765-1
...
MSA-1903-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2cf46a6aa | ||
|
|
5b39a9f840 | ||
|
|
7f61feaebc | ||
|
|
7a467df659 | ||
|
|
538eb057ce | ||
|
|
2ff9486790 | ||
|
|
5429986e81 | ||
|
|
6514087a1a | ||
|
|
0f2b8c18d2 | ||
|
|
ce0363fa43 | ||
|
|
e5739fd425 | ||
|
|
6448a5bc7c | ||
|
|
fd620977bb | ||
|
|
a308bff574 | ||
|
|
068cfaeaad | ||
|
|
fb55349db0 | ||
|
|
476d3caa38 | ||
|
|
9b621c9a7b | ||
|
|
619b3499c8 | ||
|
|
3ec8be708a | ||
|
|
34b2210134 | ||
|
|
8abb82ecae | ||
|
|
55da70cd7c | ||
|
|
80a5a41f7e | ||
|
|
b4276c05e0 | ||
|
|
1db3765a9c | ||
|
|
264e822c9f | ||
|
|
e4642e300f | ||
|
|
b4eed54ddd | ||
|
|
b2b03604a7 | ||
|
|
2b05817843 | ||
|
|
1f6a27f381 | ||
|
|
157bc3ef56 | ||
|
|
096f4f767f | ||
|
|
c15a21b8bf | ||
|
|
c65c9cc185 | ||
|
|
daefec9d1f | ||
|
|
a28c90e492 | ||
|
|
664b300b37 | ||
|
|
2b6d978d13 | ||
|
|
8197097e1d | ||
|
|
4644362465 | ||
|
|
2c25e293c0 | ||
|
|
63d8e6444b | ||
|
|
24f63a514a | ||
|
|
36fe6428ab | ||
|
|
2bc44e0205 | ||
|
|
24d079db7c | ||
|
|
283ed425d8 | ||
|
|
1545707ae3 | ||
|
|
2fd8cf1416 | ||
|
|
7f3a99d889 | ||
|
|
a397fe9fc3 | ||
|
|
f83500fbf8 | ||
|
|
a297e79b0e | ||
|
|
69d52093dc | ||
|
|
fda743a801 | ||
|
|
f7a5ea4820 | ||
|
|
d51ec9e518 | ||
|
|
fe4a5239c7 | ||
|
|
ae41b4adbe | ||
|
|
bdcaf175f0 | ||
|
|
ba10869dd5 | ||
|
|
6f411e1a3e | ||
|
|
4cc41d9d9b | ||
|
|
66875170f4 | ||
|
|
9e80a188df | ||
|
|
ec781b18be | ||
|
|
43bedd41a8 | ||
|
|
f75e8a6b2d | ||
|
|
ce10bcf2cd | ||
|
|
0c8de4402b | ||
|
|
a112d4b00e | ||
|
|
515fab9fa4 | ||
|
|
100e696d02 | ||
|
|
3e988ce657 | ||
|
|
fe887121d3 | ||
|
|
7375abf9c0 | ||
|
|
00224c2d0b | ||
|
|
e985f38cf4 | ||
|
|
a79e0f70fd | ||
|
|
f05daf2f34 | ||
|
|
f26b9ce6b2 | ||
|
|
ac4c353287 | ||
|
|
ed40ca7017 | ||
|
|
7aa8be4322 | ||
|
|
23a0b26cb9 | ||
|
|
00fc9e1ab3 | ||
|
|
3b2d955c55 | ||
|
|
44facec5df | ||
|
|
9f944df598 | ||
|
|
e3c1442278 | ||
|
|
59bfdc9b06 | ||
|
|
e274f2d3fe | ||
|
|
5e23c8e700 | ||
|
|
10c1d6f715 | ||
|
|
55e92b2ad6 | ||
|
|
18343ae4b8 | ||
|
|
6c4da81cd4 | ||
|
|
09e890091a | ||
|
|
2fb3294ce1 | ||
|
|
973d347d2f | ||
|
|
a2afb4cb1b | ||
|
|
693f2c1060 | ||
|
|
74ae369143 | ||
|
|
afa7784999 | ||
|
|
0e9abb0cd2 | ||
|
|
123de9aae4 | ||
|
|
e91907c30a | ||
|
|
237e226697 | ||
|
|
3b48629546 | ||
|
|
d28414c1e8 | ||
|
|
f79db67153 | ||
|
|
8c7cb54934 | ||
|
|
213d71da09 | ||
|
|
b7288b5beb | ||
|
|
364154e8a7 | ||
|
|
c51e035ff2 | ||
|
|
23cfae20b3 | ||
|
|
5e7ded1f73 | ||
|
|
36b4d48056 | ||
|
|
03b9f08eed | ||
|
|
fbdaeea9ae | ||
|
|
9fa9dee606 | ||
|
|
122a7d4146 | ||
|
|
32eb95f7d7 | ||
|
|
343ec9d856 | ||
|
|
1f09a22176 | ||
|
|
b1b356f370 | ||
|
|
c5455321d1 | ||
|
|
e6ca3d8ddf | ||
|
|
9aaab9b11d | ||
|
|
cbd15ae9cc | ||
|
|
fdd330abdf | ||
|
|
df29effc00 | ||
|
|
668f71a217 | ||
|
|
6fae023f7a | ||
|
|
78a509e8f5 | ||
|
|
42d31f29cc | ||
|
|
9b4f6974de | ||
|
|
ea5344f9c8 | ||
|
|
b5e1d652fd | ||
|
|
a03e8f20c5 | ||
|
|
ce52af0376 | ||
|
|
6908733a5c | ||
|
|
e0d307f6b5 | ||
|
|
a06dba0b90 | ||
|
|
0ec8cba885 | ||
|
|
bcfece27c4 | ||
|
|
26f9690190 | ||
|
|
eca8fda0f2 | ||
|
|
ce07c065c8 | ||
|
|
640f9413c3 | ||
|
|
1c52f80eae | ||
|
|
de4d52a28b | ||
|
|
6892965cf1 | ||
|
|
17ec6270d6 | ||
|
|
d233a65ef5 | ||
|
|
b36a985d92 | ||
|
|
8a3c9edf0a | ||
|
|
a560c5b040 | ||
|
|
3ee374028f | ||
|
|
7ac7bd3034 | ||
|
|
f734c5490b | ||
|
|
b93a05d450 | ||
|
|
f5186a41c7 | ||
|
|
c505f95e7a | ||
|
|
173c34150a | ||
|
|
f6b850500e | ||
|
|
4dac7b5379 | ||
|
|
a79d56e467 | ||
|
|
e2d8af48a8 | ||
|
|
0f00c3c7c0 | ||
|
|
0a4d56be04 | ||
|
|
1326881142 | ||
|
|
d30494172f | ||
|
|
2678480244 | ||
|
|
b5e8a46143 | ||
|
|
6237dbd179 | ||
|
|
65f5597ccc | ||
|
|
fced2d7c61 | ||
|
|
74552420ba | ||
|
|
be0c16c76d | ||
|
|
89f1302c99 | ||
|
|
16cb20685c | ||
|
|
30d8e6d835 | ||
|
|
6d0f9d101d | ||
|
|
4ba55e7f0a | ||
|
|
8a41fb6090 | ||
|
|
79c254cfac | ||
|
|
72248b0004 | ||
|
|
d8b35b23ea | ||
|
|
9a53e12427 | ||
|
|
7a7a08ea6e | ||
|
|
950a33dc74 | ||
|
|
2ae163b10b | ||
|
|
e3168793bd | ||
|
|
0baa986c61 | ||
|
|
8484f18a0e | ||
|
|
3c4d86bb31 | ||
|
|
1f69ab6634 | ||
|
|
b0ac006781 | ||
|
|
ef1ebc8347 | ||
|
|
aa1f2f21e8 | ||
|
|
cb6377886d | ||
|
|
7a605373d6 | ||
|
|
90fb9251a6 | ||
|
|
195e0babb2 | ||
|
|
065715f296 | ||
|
|
a544e2f019 | ||
|
|
10acb76b34 | ||
|
|
4fc046f57f | ||
|
|
ff2e70b011 | ||
|
|
79e2789f68 | ||
|
|
a777c298ca | ||
|
|
94a87e5c7f | ||
|
|
22be8ef2e8 | ||
|
|
2f20a339c3 | ||
|
|
65ae2c0ddf | ||
|
|
7e806275ce | ||
|
|
1ed57aab45 | ||
|
|
4eea7ff90f | ||
|
|
b2264538c9 | ||
|
|
2f786f7ecd | ||
|
|
f45ab69045 | ||
|
|
91762f6a46 | ||
|
|
b55c650637 | ||
|
|
e391ee5f53 | ||
|
|
ab79ceb857 | ||
|
|
7b1b9a46bc | ||
|
|
a9a0d296ee | ||
|
|
905096b381 | ||
|
|
e23bed148d | ||
|
|
3b7dd3dd91 | ||
|
|
ca404bc2a2 | ||
|
|
44702cd5fe | ||
|
|
993f8199d6 | ||
|
|
ccfe5dabdf | ||
|
|
f054cb4de1 | ||
|
|
d47a4de072 | ||
|
|
4c5787fff0 | ||
|
|
b2f90954ae | ||
|
|
8a9c38d38e | ||
|
|
28c0cc9619 | ||
|
|
cb6304530e | ||
|
|
fe5a965f6f | ||
|
|
72c75882cf | ||
|
|
a006799ad3 | ||
|
|
2610f00a82 | ||
|
|
6381580e44 | ||
|
|
79aebafdc4 | ||
|
|
1c83a27c40 | ||
|
|
4a66eca03c | ||
|
|
31c037e7ab | ||
|
|
d6c85436d2 | ||
|
|
e822e7137e | ||
|
|
967e1798d5 | ||
|
|
6ef49e92bb | ||
|
|
e528b61ace | ||
|
|
a583a25ef3 | ||
|
|
a192b75e4c | ||
|
|
f97a0a4072 | ||
|
|
dd0aba3dc9 | ||
|
|
e787afd165 | ||
|
|
12be259779 | ||
|
|
379e70b343 | ||
|
|
9cb0ce716b | ||
|
|
2151e2dd3e | ||
|
|
400c55f4ba | ||
|
|
023b9aad2d | ||
|
|
ccb7b6e49d | ||
|
|
34f77a2989 | ||
|
|
318cdedaec | ||
|
|
011a5ddc74 | ||
|
|
649ed033d0 | ||
|
|
e687e76b3e | ||
|
|
1d2fe8af22 | ||
|
|
6e94220e9e | ||
|
|
e54a8644c3 | ||
|
|
0d4b681971 | ||
|
|
0aabce9fa3 | ||
|
|
843d8800ac | ||
|
|
bcc680ee5d | ||
|
|
245e85f850 | ||
|
|
af16720528 | ||
|
|
c6d6ba85f5 | ||
|
|
51832c8db2 | ||
|
|
f001eb0792 | ||
|
|
81550ee25c | ||
|
|
1cc9d8a90b | ||
|
|
bfd2b6c0fa | ||
|
|
9b6e7d3be8 | ||
|
|
7c5734b752 | ||
|
|
2a3c393534 | ||
|
|
91763e7b4d | ||
|
|
1263b72a72 | ||
|
|
bf45430061 | ||
|
|
054ccbeffe | ||
|
|
5cb84a269d | ||
|
|
6e28d83e96 | ||
|
|
2d82b05f90 | ||
|
|
1611fd0144 | ||
|
|
c416c39ac4 | ||
|
|
bc0f849dad | ||
|
|
459e69607b | ||
|
|
fc312286a2 | ||
|
|
cfdc61d72a | ||
|
|
0c26d75792 | ||
|
|
bf491270a9 | ||
|
|
871d75aea6 | ||
|
|
3905d48235 | ||
|
|
d91c02b970 | ||
|
|
e019d22aff | ||
|
|
900ab9f70e | ||
|
|
e8d205c775 | ||
|
|
1800ea2bad | ||
|
|
f164b8832c | ||
|
|
2d3fa22e07 | ||
|
|
54a4620c9b | ||
|
|
0846b6f34c | ||
|
|
a15ca97988 | ||
|
|
a5d0c1d80a | ||
|
|
61356ec8a7 | ||
|
|
ef8611d2ea | ||
|
|
648dee90b6 | ||
|
|
1674dc7339 |
@@ -9,7 +9,7 @@ apply plugin: 'smartthings-slack'
|
||||
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.8"
|
||||
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.11"
|
||||
}
|
||||
repositories {
|
||||
mavenLocal()
|
||||
|
||||
@@ -23,8 +23,8 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("acceleration", "device.acceleration", width: 2, height: 2) {
|
||||
state("inactive", label:'${name}', icon:"st.motion.acceleration.inactive", backgroundColor:"#ffffff")
|
||||
state("active", label:'${name}', icon:"st.motion.acceleration.active", backgroundColor:"#53a7c0")
|
||||
state("inactive", label:'${name}', icon:"st.motion.acceleration.inactive", backgroundColor:"#cccccc")
|
||||
state("active", label:'${name}', icon:"st.motion.acceleration.active", backgroundColor:"#00A0DC")
|
||||
}
|
||||
|
||||
main "acceleration"
|
||||
|
||||
@@ -23,8 +23,8 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("contact", "device.contact", width: 2, height: 2) {
|
||||
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
|
||||
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
|
||||
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00A0DC")
|
||||
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13")
|
||||
}
|
||||
main "contact"
|
||||
details "contact"
|
||||
|
||||
@@ -27,7 +27,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("toggle", "device.lock", width: 2, height: 2) {
|
||||
state "unlocked", label:'unlocked', action:"lock.lock", icon:"st.locks.lock.unlocked", backgroundColor:"#ffffff"
|
||||
state "locked", label:'locked', action:"lock.unlock", icon:"st.locks.lock.locked", backgroundColor:"#79b821"
|
||||
state "locked", label:'locked', action:"lock.unlock", icon:"st.locks.lock.locked", backgroundColor:"#00A0DC"
|
||||
}
|
||||
standardTile("lock", "device.lock", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", label:'lock', action:"lock.lock", icon:"st.locks.lock.locked"
|
||||
|
||||
@@ -29,7 +29,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "on"
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
|
||||
}
|
||||
main "switch"
|
||||
details "switch"
|
||||
|
||||
@@ -24,7 +24,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("motion", "device.motion", width: 2, height: 2) {
|
||||
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
|
||||
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
|
||||
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC")
|
||||
}
|
||||
main "motion"
|
||||
details "motion"
|
||||
|
||||
@@ -24,7 +24,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("presence", "device.presence", width: 2, height: 2) {
|
||||
state("not present", label:'not present', icon:"st.presence.tile.not-present", backgroundColor:"#ffffff")
|
||||
state("present", label:'present', icon:"st.presence.tile.present", backgroundColor:"#53a7c0")
|
||||
state("present", label:'present', icon:"st.presence.tile.present", backgroundColor:"#00A0DC")
|
||||
}
|
||||
main "presence"
|
||||
details "presence"
|
||||
|
||||
@@ -31,7 +31,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
|
||||
}
|
||||
main "switch"
|
||||
details "switch"
|
||||
|
||||
@@ -35,8 +35,8 @@ metadata {
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2) {
|
||||
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "turningOn", label:'${name}', icon:"st.switches.switch.on", backgroundColor:"#79b821"
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
state "turningOn", label:'${name}', icon:"st.switches.switch.on", backgroundColor:"#00A0DC"
|
||||
state "turningOff", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ffffff"
|
||||
}
|
||||
controlTile("levelSliderControl", "device.level", "slider", height: 2, width: 1, inactiveLabel: false) {
|
||||
|
||||
@@ -79,8 +79,8 @@ metadata {
|
||||
standardTile("mode", "device.thermostatMode", inactiveLabel: false, decoration: "flat") {
|
||||
state "off", label:'${name}', action:"thermostat.emergencyHeat", backgroundColor:"#ffffff"
|
||||
state "emergencyHeat", label:'${name}', action:"thermostat.heat", backgroundColor:"#e86d13"
|
||||
state "heat", label:'${name}', action:"thermostat.cool", backgroundColor:"#ffc000"
|
||||
state "cool", label:'${name}', action:"thermostat.off", backgroundColor:"#269bd2"
|
||||
state "heat", label:'${name}', action:"thermostat.cool", backgroundColor:"#e86d13"
|
||||
state "cool", label:'${name}', action:"thermostat.off", backgroundColor:"#00A0DC"
|
||||
}
|
||||
standardTile("fanMode", "device.thermostatFanMode", inactiveLabel: false, decoration: "flat") {
|
||||
state "fanAuto", label:'${name}', action:"thermostat.fanOn", backgroundColor:"#ffffff"
|
||||
|
||||
@@ -24,7 +24,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("water", "device.water", width: 2, height: 2) {
|
||||
state "dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"
|
||||
state "wet", icon:"st.alarm.water.wet", backgroundColor:"#53a7c0"
|
||||
state "wet", icon:"st.alarm.water.wet", backgroundColor:"#00A0DC"
|
||||
}
|
||||
|
||||
main "water"
|
||||
|
||||
@@ -37,7 +37,7 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("presence", "device.presence", width: 2, height: 2, canChangeBackground: true) {
|
||||
state("present", labelIcon:"st.presence.tile.present", backgroundColor:"#53a7c0")
|
||||
state("present", labelIcon:"st.presence.tile.present", backgroundColor:"#00A0DC")
|
||||
state("not present", labelIcon:"st.presence.tile.not-present", backgroundColor:"#ffffff")
|
||||
}
|
||||
valueTile("inRange", "device.inRangeFriendly", inactiveLabel: true, height:1, width:3, decoration: "flat") {
|
||||
|
||||
@@ -38,7 +38,7 @@ metadata {
|
||||
// Main
|
||||
standardTile("main", "device.status", width: 1, height: 1, canChangeIcon: true) {
|
||||
state "paused", label:'Paused', action:"music Player.play", icon:"st.Electronics.electronics19", nextState:"playing", backgroundColor:"#ffffff"
|
||||
state "playing", label:'Playing', action:"music Player.pause", icon:"st.Electronics.electronics19", nextState:"paused", backgroundColor:"#79b821"
|
||||
state "playing", label:'Playing', action:"music Player.pause", icon:"st.Electronics.electronics19", nextState:"paused", backgroundColor:"#00A0DC"
|
||||
}
|
||||
|
||||
// Row 1
|
||||
|
||||
426
devicetypes/drzwave/ezmultipli.src/ezmultipli.groovy
Normal file
426
devicetypes/drzwave/ezmultipli.src/ezmultipli.groovy
Normal file
@@ -0,0 +1,426 @@
|
||||
// Express Controls EZMultiPli Multi-sensor
|
||||
// Motion Sensor - Temperature - Light level - 8 Color Indicator LED - Z-Wave Range Extender - Wall Powered
|
||||
// driver for SmartThings
|
||||
// The EZMultiPli is also known as the HSM200 from HomeSeer.com
|
||||
//
|
||||
// 2017-04-10 - DrZwave (with help from Don Kirker) - changed fingerprint to the new format, lowered the OnTime
|
||||
// and other parameters to be "more in line with ST user expectations", get the luminance in LUX so it reports in lux all the time.
|
||||
// 2016-10-06 - erocm1231 - Added "updated" method to run when configuration options are changed. Depending on model of unit, luminance is being
|
||||
// reported as a relative percentace or as a lux value. Added the option to configure this in the handler.
|
||||
// 2016-01-28 - erocm1231 - Changed the configuration method to use scaledConfiguration so that it properly formatted negative numbers.
|
||||
// Also, added configurationGet and a configurationReport method so that config values can be verified.
|
||||
// 2015-12-04 - erocm1231 - added range value to preferences as suggested by @Dela-Rick.
|
||||
// 2015-11-26 - erocm1231 - Fixed null condition error when adding as a new device.
|
||||
// 2015-11-24 - erocm1231 - Added refresh command. Made a few changes to how the handler maps colors to the LEDs. Fixed
|
||||
// the device not having its on/off status updated when colors are changed.
|
||||
// 2015-11-23 - erocm1231 - Changed the look to match SmartThings v2 devices.
|
||||
// 2015-11-21 - erocm1231 - Made code much more efficient. Also made it compatible when setColor is passed a hex value.
|
||||
// Mapping of special colors: Soft White - Default - Yellow, White - Concentrate - White,
|
||||
// Daylight - Energize - Teal, Warm White - Relax - Yellow
|
||||
// 2015-11-19 - erocm1231 - Fixed a couple incorrect colors, changed setColor to be more compatible with other apps
|
||||
// 2015-11-18 - erocm1231 - Added to setColor for compatibility with Smart Lighting
|
||||
// v0.1.0 - DrZWave - chose better icons, Got color LED to work - first fully functional version
|
||||
// v0.0.9 - jrs - got the temp and luminance to work. Motion works. Debugging the color wheel.
|
||||
// v0.0.8 - DrZWave 2/25/2015 - change the color control to be tiles since there are only 8 colors.
|
||||
// v0.0.7 - jrs - 02/23/2015 - Jim Sulin
|
||||
|
||||
metadata {
|
||||
definition (name: "EZmultiPli", namespace: "DrZWave", author: "Eric Ryherd", oauth: true) {
|
||||
capability "Actuator"
|
||||
capability "Sensor"
|
||||
capability "Motion Sensor"
|
||||
capability "Temperature Measurement"
|
||||
capability "Illuminance Measurement"
|
||||
capability "Switch"
|
||||
capability "Color Control"
|
||||
capability "Configuration"
|
||||
capability "Refresh"
|
||||
|
||||
fingerprint mfr: "001E", prod: "0004", model: "0001" // new format for Fingerprint which is unique for every certified Z-Wave product
|
||||
} // end definition
|
||||
|
||||
simulator {
|
||||
// messages the device returns in response to commands it receives
|
||||
status "motion" : "command: 7105000000FF07, payload: 07"
|
||||
status "no motion" : "command: 7105000000FF07, payload: 00"
|
||||
|
||||
for (int i = 0; i <= 100; i += 20) {
|
||||
status "temperature ${i}F": new physicalgraph.zwave.Zwave().sensorMultilevelV5.sensorMultilevelReport(
|
||||
scaledSensorValue: i, precision: 1, sensorType: 1, scale: 1).incomingMessage()
|
||||
}
|
||||
for (int i = 0; i <= 100; i += 20) {
|
||||
status "luminance ${i} %": new physicalgraph.zwave.Zwave().sensorMultilevelV5.sensorMultilevelReport(
|
||||
scaledSensorValue: i, precision: 0, sensorType: 3).incomingMessage()
|
||||
}
|
||||
|
||||
} //end simulator
|
||||
|
||||
|
||||
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 "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 "turningOff", label:'${name}', icon:"st.switches.light.off", backgroundColor:"#ffffff"
|
||||
}
|
||||
tileAttribute ("device.color", key: "COLOR_CONTROL") {
|
||||
attributeState "color", action:"setColor"
|
||||
}
|
||||
tileAttribute ("statusText", key: "SECONDARY_CONTROL") {
|
||||
attributeState "statusText", label:'${currentValue}'
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
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
|
||||
]
|
||||
}
|
||||
|
||||
// icons to use would be st.Weather.weather2 or st.alarm.temperature.normal - see http://scripts.3dgo.net/smartthings/icons/ for a list of icons
|
||||
valueTile("illuminance", "device.illuminance", width: 2, height: 2, inactiveLabel: false) {
|
||||
// jrs 4/7/2015 - Null on display
|
||||
//state "luminosity", label:'${currentValue} ${unit}'
|
||||
state "luminosity", label:'${currentValue}', unit:'${currentValue}', icon:"",
|
||||
backgroundColors:[
|
||||
[value: 25, color: "#404040"],
|
||||
[value: 50, color: "#808080"],
|
||||
[value: 75, color: "#a0a0a0"],
|
||||
[value: 90, color: "#e0e0e0"],
|
||||
//lux measurement values
|
||||
[value: 150, color: "#404040"],
|
||||
[value: 300, color: "#808080"],
|
||||
[value: 600, color: "#a0a0a0"],
|
||||
[value: 900, color: "#e0e0e0"]
|
||||
]
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
standardTile("configure", "device.configure", inactiveLabel: false, width: 2, height: 2, decoration: "flat") {
|
||||
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
|
||||
}
|
||||
|
||||
main (["temperature","motion", "switch"])
|
||||
details(["switch", "motion", "temperature", "illuminance", "refresh", "configure"])
|
||||
} // end tiles
|
||||
|
||||
preferences {
|
||||
input "OnTime", "number", title: "No Motion Interval", description: "N minutes lights stay on after no motion detected [0, 1-127]", range: "0..127", defaultValue: 2, displayDuringSetup: true, required: false
|
||||
input "OnLevel", "number", title: "Dimmer Onlevel", description: "Dimmer OnLevel for associated node 2 lights [-1, 0, 1-99]", range: "-1..99", defaultValue: -1, displayDuringSetup: true, required: false
|
||||
input "LiteMin", "number", title: "Luminance Report Frequency", description: "Luminance report sent every N minutes [0-127]", range: "0..127", defaultValue: 6, displayDuringSetup: true, required: false
|
||||
input "TempMin", "number", title: "Temperature Report Frequency", description: "Temperature report sent every N minutes [0-127]", range: "0..127", defaultValue: 6, displayDuringSetup: true, required: false
|
||||
input "TempAdj", "number", title: "Temperature Calibration", description: "Adjust temperature up/down N tenths of a degree F [(-127)-(+128)]", range: "-127..128", defaultValue: 0, displayDuringSetup: true, required: false
|
||||
input("lum", "enum", title:"Illuminance Measurement", description: "Percent or Lux", defaultValue: 2 ,required: false, displayDuringSetup: true, options:
|
||||
[1:"Percent",
|
||||
2:"Lux"])
|
||||
}
|
||||
|
||||
} // end metadata
|
||||
|
||||
|
||||
// Parse incoming device messages from device to generate events
|
||||
def parse(String description){
|
||||
//log.debug "==> New Zwave Event: ${description}"
|
||||
def result = []
|
||||
def cmd = zwave.parse(description, [0x31: 5]) // 0x31=SensorMultilevel which we force to be version 5
|
||||
if (cmd) {
|
||||
def cmdData = zwaveEvent(cmd)
|
||||
if (cmdData != [:])
|
||||
result << createEvent(cmdData)
|
||||
}
|
||||
|
||||
def statusTextmsg = ""
|
||||
if (device.currentState('temperature') != null && device.currentState('illuminance') != null) {
|
||||
statusTextmsg = "${device.currentState('temperature').value} ° - ${device.currentState('illuminance').value} ${(lum == "" || lum == null || lum == 1) ? "%" : "LUX"}"
|
||||
sendEvent("name":"statusText", "value":statusTextmsg, displayed:false)
|
||||
}
|
||||
if (result != [null] && result != []) log.debug "Parse returned ${result}"
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
// Event Generation
|
||||
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd){
|
||||
def map = [:]
|
||||
switch (cmd.sensorType) {
|
||||
case 0x01: // SENSOR_TYPE_TEMPERATURE_VERSION_1
|
||||
def cmdScale = cmd.scale == 1 ? "F" : "C"
|
||||
map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
|
||||
map.unit = getTemperatureScale()
|
||||
map.name = "temperature"
|
||||
log.debug "Temperature report"
|
||||
break;
|
||||
case 0x03 : // SENSOR_TYPE_LUMINANCE_VERSION_1
|
||||
map.value = cmd.scaledSensorValue.toInteger().toString()
|
||||
if(lum == "" || lum == null || lum == 1) map.unit = "%"
|
||||
else map.unit = "lux"
|
||||
map.name = "illuminance"
|
||||
log.debug "Luminance report"
|
||||
break;
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) {
|
||||
log.debug "${device.displayName} parameter '${cmd.parameterNumber}' with a byte size of '${cmd.size}' is set to '${cmd.configurationValue}'"
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
|
||||
def map = [:]
|
||||
if (cmd.notificationType==0x07) { // NOTIFICATION_TYPE_BURGLAR
|
||||
if (cmd.event==0x07 || cmd.event==0x08) {
|
||||
map.name = "motion"
|
||||
map.value = "active"
|
||||
map.descriptionText = "$device.displayName motion detected"
|
||||
log.debug "motion recognized"
|
||||
} else if (cmd.event==0) {
|
||||
map.name = "motion"
|
||||
map.value = "inactive"
|
||||
map.descriptionText = "$device.displayName no motion detected"
|
||||
log.debug "No motion recognized"
|
||||
}
|
||||
}
|
||||
if (map.name != "motion") {
|
||||
log.debug "unmatched parameters for cmd: ${cmd.toString()}}"
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
|
||||
if (cmd.value == 0 && device.latestState("color").value != "#ffffff") {
|
||||
sendEvent(name: "color", value: "#ffffff", displayed: true)
|
||||
}
|
||||
[name: "switch", value: cmd.value ? "on" : "off", type: "digital"]
|
||||
}
|
||||
|
||||
def updated()
|
||||
{
|
||||
log.debug "updated() is being called"
|
||||
|
||||
def cmds = configure()
|
||||
|
||||
if (cmds != []) response(cmds)
|
||||
}
|
||||
|
||||
def on() {
|
||||
log.debug "Turning Light 'on'"
|
||||
delayBetween([
|
||||
zwave.basicV1.basicSet(value: 0xFF).format(),
|
||||
zwave.basicV1.basicGet().format()
|
||||
], 500)
|
||||
}
|
||||
|
||||
def off() {
|
||||
log.debug "Turning Light 'off'"
|
||||
delayBetween([
|
||||
zwave.basicV1.basicSet(value: 0x00).format(),
|
||||
zwave.basicV1.basicGet().format()
|
||||
], 500)
|
||||
}
|
||||
|
||||
|
||||
def setColor(value) {
|
||||
log.debug "setColor() : ${value}"
|
||||
def myred
|
||||
def mygreen
|
||||
def myblue
|
||||
def hexValue
|
||||
def cmds = []
|
||||
|
||||
if ( value.level == 1 && value.saturation > 20) {
|
||||
def rgb = huesatToRGB(value.hue as Integer, 100)
|
||||
myred = rgb[0] >=128 ? 255 : 0
|
||||
mygreen = rgb[1] >=128 ? 255 : 0
|
||||
myblue = rgb[2] >=128 ? 255 : 0
|
||||
}
|
||||
else if ( value.level > 1 ) {
|
||||
def rgb = huesatToRGB(value.hue as Integer, value.saturation as Integer)
|
||||
myred = rgb[0] >=128 ? 255 : 0
|
||||
mygreen = rgb[1] >=128 ? 255 : 0
|
||||
myblue = rgb[2] >=128 ? 255 : 0
|
||||
}
|
||||
else if (value.hex) {
|
||||
def rgb = value.hex.findAll(/[0-9a-fA-F]{2}/).collect { Integer.parseInt(it, 16) }
|
||||
myred = rgb[0] >=128 ? 255 : 0
|
||||
mygreen = rgb[1] >=128 ? 255 : 0
|
||||
myblue = rgb[2] >=128 ? 255 : 0
|
||||
}
|
||||
else {
|
||||
myred=value.red >=128 ? 255 : 0 // the EZMultiPli has just on/off for each of the 3 channels RGB so convert the 0-255 value into 0 or 255.
|
||||
mygreen=value.green >=128 ? 255 : 0
|
||||
myblue=value.blue>=128 ? 255 : 0
|
||||
}
|
||||
//log.debug "Red: ${myred} Green: ${mygreen} Blue: ${myblue}"
|
||||
//cmds << zwave.colorControlV1.stateSet(stateDataLength: 3, VariantGroup1: [0x02, myred], VariantGroup2:[ 0x03, mygreen], VariantGroup3:[0x04,myblue]).format() // ST support for this command as of 2015/02/23 does not support the color IDs so this command cannot be used.
|
||||
// So instead we'll use these commands to hack around the lack of support of the above command
|
||||
cmds << zwave.basicV1.basicSet(value: 0x00).format() // As of 2015/02/23 ST is not supporting stateSet properly but found this hack that works.
|
||||
if (myred!=0) {
|
||||
cmds << zwave.colorControlV1.startCapabilityLevelChange(capabilityId: 0x02, startState: myred, ignoreStartState: True, updown: True).format()
|
||||
cmds << zwave.colorControlV1.stopStateChange(capabilityId: 0x02).format()
|
||||
}
|
||||
if (mygreen!=0) {
|
||||
cmds << zwave.colorControlV1.startCapabilityLevelChange(capabilityId: 0x03, startState: mygreen, ignoreStartState: True, updown: True).format()
|
||||
cmds << zwave.colorControlV1.stopStateChange(capabilityId: 0x03).format()
|
||||
}
|
||||
if (myblue!=0) {
|
||||
cmds << zwave.colorControlV1.startCapabilityLevelChange(capabilityId: 0x04, startState: myblue, ignoreStartState: True, updown: True).format()
|
||||
cmds << zwave.colorControlV1.stopStateChange(capabilityId: 0x04).format()
|
||||
}
|
||||
cmds << zwave.basicV1.basicGet().format()
|
||||
hexValue = rgbToHex([r:myred, g:mygreen, b:myblue])
|
||||
if(hexValue) sendEvent(name: "color", value: hexValue, displayed: true)
|
||||
delayBetween(cmds, 100)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
// Handles all Z-Wave commands we aren't interested in
|
||||
[:]
|
||||
}
|
||||
|
||||
// ensure we are passing acceptable param values for LiteMin & TempMin configs
|
||||
def checkLiteTempInput(value) {
|
||||
if (value == null) {
|
||||
value=60
|
||||
}
|
||||
def liteTempVal = value.toInteger()
|
||||
switch (liteTempVal) {
|
||||
case { it < 0 }:
|
||||
return 60 // bad value, set to default
|
||||
break
|
||||
case { it > 127 }:
|
||||
return 127 // bad value, greater then MAX, set to MAX
|
||||
break
|
||||
default:
|
||||
return liteTempVal // acceptable value
|
||||
}
|
||||
}
|
||||
|
||||
// ensure we are passing acceptable param value for OnTime config
|
||||
def checkOnTimeInput(value) {
|
||||
if (value == null) {
|
||||
value=10
|
||||
}
|
||||
def onTimeVal = value.toInteger()
|
||||
switch (onTimeVal) {
|
||||
case { it < 0 }:
|
||||
return 10 // bad value set to default
|
||||
break
|
||||
case { it > 127 }:
|
||||
return 127 // bad value, greater then MAX, set to MAX
|
||||
break
|
||||
default:
|
||||
return onTimeVal // acceptable value
|
||||
}
|
||||
}
|
||||
|
||||
// ensure we are passing acceptable param value for OnLevel config
|
||||
def checkOnLevelInput(value) {
|
||||
if (value == null) {
|
||||
value=99
|
||||
}
|
||||
def onLevelVal = value.toInteger()
|
||||
switch (onLevelVal) {
|
||||
case { it < -1 }:
|
||||
return -1 // bad value set to default
|
||||
break
|
||||
case { it > 99 }:
|
||||
return 99 // bad value, greater then MAX, set to MAX
|
||||
break
|
||||
default:
|
||||
return onLevelVal // acceptable value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ensure we are passing an acceptable param value for TempAdj configs
|
||||
def checkTempAdjInput(value) {
|
||||
if (value == null) {
|
||||
value=0
|
||||
}
|
||||
def tempAdjVal = value.toInteger()
|
||||
switch (tempAdjVal) {
|
||||
case { it < -127 }:
|
||||
return 0 // bad value, set to default
|
||||
break
|
||||
case { it > 128 }:
|
||||
return 128 // bad value, greater then MAX, set to MAX
|
||||
break
|
||||
default:
|
||||
return tempAdjVal // acceptable value
|
||||
}
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
def cmd = []
|
||||
cmd << zwave.switchColorV3.switchColorGet().format()
|
||||
cmd << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType:1, scale:1).format()
|
||||
cmd << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType:3, scale:1).format()
|
||||
cmd << zwave.basicV1.basicGet().format()
|
||||
delayBetween(cmd, 1000)
|
||||
}
|
||||
|
||||
def configure() {
|
||||
log.debug "OnTime=${settings.OnTime} OnLevel=${settings.OnLevel} TempAdj=${settings.TempAdj}"
|
||||
def cmd = delayBetween([
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, scaledConfigurationValue: checkOnTimeInput(settings.OnTime)).format(),
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 2, size: 1, scaledConfigurationValue: checkOnLevelInput(settings.OnLevel)).format(),
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 3, size: 1, scaledConfigurationValue: checkLiteTempInput(settings.LiteMin)).format(),
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 4, size: 1, scaledConfigurationValue: checkLiteTempInput(settings.TempMin)).format(),
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: checkTempAdjInput(settings.TempAdj)).format(),
|
||||
zwave.configurationV1.configurationGet(parameterNumber: 1).format(),
|
||||
zwave.configurationV1.configurationGet(parameterNumber: 2).format(),
|
||||
zwave.configurationV1.configurationGet(parameterNumber: 3).format(),
|
||||
zwave.configurationV1.configurationGet(parameterNumber: 4).format(),
|
||||
zwave.configurationV1.configurationGet(parameterNumber: 5).format()
|
||||
], 100)
|
||||
//log.debug cmd
|
||||
cmd + refresh()
|
||||
}
|
||||
|
||||
def huesatToRGB(float hue, float sat) {
|
||||
while(hue >= 100) hue -= 100
|
||||
int h = (int)(hue / 100 * 6)
|
||||
float f = hue / 100 * 6 - h
|
||||
int p = Math.round(255 * (1 - (sat / 100)))
|
||||
int q = Math.round(255 * (1 - (sat / 100) * f))
|
||||
int t = Math.round(255 * (1 - (sat / 100) * (1 - f)))
|
||||
switch (h) {
|
||||
case 0: return [255, t, p]
|
||||
case 1: return [q, 255, p]
|
||||
case 2: return [p, 255, t]
|
||||
case 3: return [p, q, 255]
|
||||
case 4: return [t, p, 255]
|
||||
case 5: return [255, p, q]
|
||||
}
|
||||
}
|
||||
def rgbToHex(rgb) {
|
||||
def r = hex(rgb.r)
|
||||
def g = hex(rgb.g)
|
||||
def b = hex(rgb.b)
|
||||
def hexColor = "#${r}${g}${b}"
|
||||
|
||||
hexColor
|
||||
}
|
||||
private hex(value, width=2) {
|
||||
def s = new BigInteger(Math.round(value).toString()).toString(16)
|
||||
while (s.size() < width) {
|
||||
s = "0" + s
|
||||
}
|
||||
s
|
||||
}
|
||||
839
devicetypes/erocm123/fibaro-dimmer-2.src/fibaro-dimmer-2.groovy
Normal file
839
devicetypes/erocm123/fibaro-dimmer-2.src/fibaro-dimmer-2.groovy
Normal file
@@ -0,0 +1,839 @@
|
||||
/**
|
||||
*
|
||||
* Fibaro Dimmer 2 (US)
|
||||
*
|
||||
* github: Eric Maycock (erocm123)
|
||||
* email: erocmail@gmail.com
|
||||
* Date: 2016-07-31 8:03PM
|
||||
* Copyright 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: "Fibaro Dimmer 2", namespace: "erocm123", author: "Eric Maycock") {
|
||||
capability "Actuator"
|
||||
capability "Switch"
|
||||
capability "Switch Level"
|
||||
capability "Refresh"
|
||||
capability "Configuration"
|
||||
capability "Sensor"
|
||||
capability "Polling"
|
||||
capability "Energy Meter"
|
||||
capability "Power Meter"
|
||||
capability "Button"
|
||||
capability "Health Check"
|
||||
|
||||
attribute "needUpdate", "string"
|
||||
|
||||
fingerprint deviceId: "0x1101", inClusters: "0x72,0x86,0x70,0x85,0x8E,0x26,0x7A,0x27,0x73,0xEF,0x26,0x2B"
|
||||
fingerprint deviceId: "0x1101", inClusters: "0x5E,0x20,0x86,0x72,0x26,0x5A,0x59,0x85,0x73,0x98,0x7A,0x56,0x70,0x31,0x32,0x8E,0x60,0x75,0x71,0x27"
|
||||
|
||||
}
|
||||
|
||||
preferences {
|
||||
input description: "Once you change values on this page, the corner of the \"configuration\" icon will change orange until all configuration parameters are updated.", title: "Settings", displayDuringSetup: false, type: "paragraph", element: "paragraph"
|
||||
generate_preferences(configuration_model())
|
||||
}
|
||||
|
||||
simulator {
|
||||
|
||||
}
|
||||
|
||||
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:"#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:"#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") {
|
||||
attributeState "level", action:"switch level.setLevel"
|
||||
}
|
||||
tileAttribute ("statusText", key: "SECONDARY_CONTROL") {
|
||||
attributeState "statusText", label:'${currentValue}'
|
||||
}
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
valueTile("power", "device.power", decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:'${currentValue} W'
|
||||
}
|
||||
valueTile("energy", "device.energy", decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:'${currentValue} kWh'
|
||||
}
|
||||
standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:'reset kWh', action:"reset"
|
||||
}
|
||||
standardTile("configure", "device.needUpdate", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "NO" , label:'', action:"configuration.configure", icon:"st.secondary.configure"
|
||||
state "YES", label:'', action:"configuration.configure", icon:"https://github.com/erocm123/SmartThingsPublic/raw/master/devicetypes/erocm123/qubino-flush-1d-relay.src/configure@2x.png"
|
||||
}
|
||||
|
||||
|
||||
main "switch"
|
||||
details (["switch", "power", "energy", "refresh", "configure", "reset"])
|
||||
}
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
def result = null
|
||||
if (description.startsWith("Err")) {
|
||||
result = createEvent(descriptionText:description, isStateChange:true)
|
||||
} else if (description != "updated") {
|
||||
def cmd = zwave.parse(description, [0x20: 1, 0x84: 1, 0x98: 1, 0x56: 1, 0x60: 3])
|
||||
if (cmd) {
|
||||
result = zwaveEvent(cmd)
|
||||
}
|
||||
}
|
||||
|
||||
def statusTextmsg = ""
|
||||
if (device.currentState('power') && device.currentState('energy')) statusTextmsg = "${device.currentState('power').value} W ${device.currentState('energy').value} kWh"
|
||||
sendEvent(name:"statusText", value:statusTextmsg, displayed:false)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
|
||||
logging("BasicReport: $cmd")
|
||||
def events = []
|
||||
if (cmd.value == 0) {
|
||||
events << createEvent(name: "switch", value: "off")
|
||||
} else if (cmd.value == 255) {
|
||||
events << createEvent(name: "switch", value: "on")
|
||||
} else {
|
||||
events << createEvent(name: "switch", value: "on")
|
||||
events << createEvent(name: "switchLevel", value: cmd.value)
|
||||
}
|
||||
|
||||
def request = update_needed_settings()
|
||||
|
||||
if(request != []){
|
||||
return [response(commands(request)), events]
|
||||
} else {
|
||||
return events
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet cmd) {
|
||||
logging("SceneActivationSet: $cmd")
|
||||
logging("sceneId: $cmd.sceneId")
|
||||
logging("dimmingDuration: $cmd.dimmingDuration")
|
||||
logging("Configuration for preference \"Switch Type\" is set to ${settings."20"}")
|
||||
|
||||
if (settings."20" == "2") {
|
||||
logging("Switch configured as Roller blinds")
|
||||
switch (cmd.sceneId) {
|
||||
// Roller blinds S1
|
||||
case 10: // Turn On (1x click)
|
||||
buttonEvent(1, "pushed")
|
||||
break
|
||||
case 13: // Release
|
||||
buttonEvent(1, "held")
|
||||
break
|
||||
case 14: // 2x click
|
||||
buttonEvent(2, "pushed")
|
||||
break
|
||||
case 17: // Brightening
|
||||
buttonEvent(2, "held")
|
||||
break
|
||||
// Roller blinds S2
|
||||
case 11: // Turn Off
|
||||
buttonEvent(3, "pushed")
|
||||
break
|
||||
case 13: // Release
|
||||
buttonEvent(3, "held")
|
||||
break
|
||||
case 14: // 2x click
|
||||
buttonEvent(4, "pushed")
|
||||
break
|
||||
case 15: // 3x click
|
||||
buttonEvent(5, "pushed")
|
||||
break
|
||||
case 18: // Dimming
|
||||
buttonEvent(4, "held")
|
||||
break
|
||||
default:
|
||||
logging("Unhandled SceneActivationSet: ${cmd}")
|
||||
break
|
||||
}
|
||||
} else if (settings."20" == "1") {
|
||||
logging("Switch configured as Toggle")
|
||||
switch (cmd.sceneId) {
|
||||
// Toggle S1
|
||||
case 10: // Off to On
|
||||
buttonEvent(1, "pushed")
|
||||
break
|
||||
case 11: // On to Off
|
||||
buttonEvent(1, "held")
|
||||
break
|
||||
case 14: // 2x click
|
||||
buttonEvent(2, "pushed")
|
||||
break
|
||||
// Toggle S2
|
||||
case 20: // Off to On
|
||||
buttonEvent(3, "pushed")
|
||||
break
|
||||
case 21: // On to Off
|
||||
buttonEvent(3, "held")
|
||||
break
|
||||
case 24: // 2x click
|
||||
buttonEvent(4, "pushed")
|
||||
break
|
||||
case 25: // 3x click
|
||||
buttonEvent(5, "pushed")
|
||||
break
|
||||
default:
|
||||
logging("Unhandled SceneActivationSet: ${cmd}")
|
||||
break
|
||||
|
||||
}
|
||||
} else {
|
||||
if (settings."20" == "0") logging("Switch configured as Momentary") else logging("Switch type not configured")
|
||||
switch (cmd.sceneId) {
|
||||
// Momentary S1
|
||||
case 16: // 1x click
|
||||
buttonEvent(1, "pushed")
|
||||
break
|
||||
case 14: // 2x click
|
||||
buttonEvent(2, "pushed")
|
||||
break
|
||||
case 12: // held
|
||||
buttonEvent(1, "held")
|
||||
break
|
||||
case 13: // release
|
||||
buttonEvent(2, "held")
|
||||
break
|
||||
// Momentary S2
|
||||
case 26: // 1x click
|
||||
buttonEvent(3, "pushed")
|
||||
break
|
||||
case 24: // 2x click
|
||||
buttonEvent(4, "pushed")
|
||||
break
|
||||
case 25: // 3x click
|
||||
buttonEvent(5, "pushed")
|
||||
break
|
||||
case 22: // held
|
||||
buttonEvent(3, "held")
|
||||
break
|
||||
case 23: // release
|
||||
buttonEvent(4, "held")
|
||||
break
|
||||
default:
|
||||
logging("Unhandled SceneActivationSet: ${cmd}")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def buttonEvent(button, value) {
|
||||
logging("buttonEvent() Button:$button, Value:$value")
|
||||
createEvent(name: "button", value: value, data: [buttonNumber: button], descriptionText: "$device.displayName button $button was $value", isStateChange: true)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelReport cmd) {
|
||||
logging(cmd)
|
||||
dimmerEvents(cmd)
|
||||
}
|
||||
|
||||
def dimmerEvents(physicalgraph.zwave.Command cmd) {
|
||||
logging(cmd)
|
||||
def result = []
|
||||
def value = (cmd.value ? "on" : "off")
|
||||
def switchEvent = createEvent(name: "switch", value: value, descriptionText: "$device.displayName was turned $value")
|
||||
result << switchEvent
|
||||
if (cmd.value) {
|
||||
result << createEvent(name: "level", value: cmd.value, unit: "%")
|
||||
}
|
||||
if (switchEvent.isStateChange) {
|
||||
result << response(["delay 3000", zwave.meterV2.meterGet(scale: 2).format()])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.associationv2.AssociationReport cmd) {
|
||||
logging("AssociationReport $cmd")
|
||||
state."association${cmd.groupingIdentifier}" = cmd.nodeId[0]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
|
||||
def encapsulatedCommand = cmd.encapsulatedCommand([0x20: 1, 0x84: 1])
|
||||
if (encapsulatedCommand) {
|
||||
state.sec = 1
|
||||
def result = zwaveEvent(encapsulatedCommand)
|
||||
result = result.collect {
|
||||
if (it instanceof physicalgraph.device.HubAction && !it.toString().startsWith("9881")) {
|
||||
response(cmd.CMD + "00" + it.toString())
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
|
||||
def versions = [0x31: 5, 0x30: 1, 0x9C: 1, 0x70: 2, 0x85: 2]
|
||||
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) {
|
||||
logging("Unhandled Z-Wave Event: $cmd")
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd) {
|
||||
logging(cmd)
|
||||
if (cmd.meterType == 1) {
|
||||
if (cmd.scale == 0) {
|
||||
return createEvent(name: "energy", value: cmd.scaledMeterValue, unit: "kWh")
|
||||
} else if (cmd.scale == 1) {
|
||||
return createEvent(name: "energy", value: cmd.scaledMeterValue, unit: "kVAh")
|
||||
} else if (cmd.scale == 2) {
|
||||
return createEvent(name: "power", value: Math.round(cmd.scaledMeterValue), unit: "W")
|
||||
} else {
|
||||
return createEvent(name: "electric", value: cmd.scaledMeterValue, unit: ["pulses", "V", "A", "R/Z", ""][cmd.scale - 3])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd){
|
||||
logging("SensorMultilevelReport: $cmd")
|
||||
def map = [:]
|
||||
switch (cmd.sensorType) {
|
||||
case 4:
|
||||
map.name = "power"
|
||||
map.value = cmd.scaledSensorValue.toInteger().toString()
|
||||
map.unit = cmd.scale == 1 ? "Btu/h" : "W"
|
||||
break
|
||||
default:
|
||||
map.descriptionText = cmd.toString()
|
||||
}
|
||||
createEvent(map)
|
||||
}
|
||||
|
||||
def on() {
|
||||
commands([zwave.basicV1.basicSet(value: 0xFF), zwave.basicV1.basicGet()])
|
||||
}
|
||||
|
||||
def off() {
|
||||
commands([zwave.basicV1.basicSet(value: 0x00), zwave.basicV1.basicGet()])
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
logging("$device.displayName refresh()")
|
||||
|
||||
def cmds = []
|
||||
if (state.lastRefresh != null && now() - state.lastRefresh < 5000) {
|
||||
logging("Refresh Double Press")
|
||||
def configuration = parseXml(configuration_model())
|
||||
configuration.Value.each
|
||||
{
|
||||
if ( "${it.@setting_type}" == "zwave" ) {
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: "${it.@index}".toInteger())
|
||||
}
|
||||
}
|
||||
cmds << zwave.firmwareUpdateMdV2.firmwareMdGet()
|
||||
} else {
|
||||
cmds << zwave.meterV2.meterGet(scale: 0)
|
||||
cmds << zwave.meterV2.meterGet(scale: 2)
|
||||
cmds << zwave.basicV1.basicGet()
|
||||
}
|
||||
|
||||
state.lastRefresh = now()
|
||||
|
||||
commands(cmds)
|
||||
}
|
||||
|
||||
def ping() {
|
||||
logging("$device.displayName ping()")
|
||||
|
||||
def cmds = []
|
||||
|
||||
cmds << zwave.meterV2.meterGet(scale: 0)
|
||||
cmds << zwave.meterV2.meterGet(scale: 2)
|
||||
cmds << zwave.basicV1.basicGet()
|
||||
|
||||
commands(cmds)
|
||||
}
|
||||
|
||||
def setLevel(level) {
|
||||
if(level > 99) level = 99
|
||||
if(level < 1) level = 1
|
||||
def cmds = []
|
||||
cmds << zwave.basicV1.basicSet(value: level)
|
||||
cmds << zwave.switchMultilevelV1.switchMultilevelGet()
|
||||
|
||||
commands(cmds)
|
||||
}
|
||||
|
||||
def updated()
|
||||
{
|
||||
state.enableDebugging = settings.enableDebugging
|
||||
logging("updated() is being called")
|
||||
sendEvent(name: "checkInterval", value: 2 * 30 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
state.needfwUpdate = ""
|
||||
|
||||
def cmds = update_needed_settings()
|
||||
|
||||
sendEvent(name:"needUpdate", value: device.currentValue("needUpdate"), displayed:false, isStateChange: true)
|
||||
|
||||
response(commands(cmds))
|
||||
}
|
||||
|
||||
private command(physicalgraph.zwave.Command cmd) {
|
||||
if (state.sec) {
|
||||
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
|
||||
} else {
|
||||
cmd.format()
|
||||
}
|
||||
}
|
||||
|
||||
private commands(commands, delay=1500) {
|
||||
delayBetween(commands.collect{ command(it) }, delay)
|
||||
}
|
||||
|
||||
def generate_preferences(configuration_model)
|
||||
{
|
||||
def configuration = parseXml(configuration_model)
|
||||
|
||||
configuration.Value.each
|
||||
{
|
||||
switch(it.@type)
|
||||
{
|
||||
case ["byte","short","four"]:
|
||||
input "${it.@index}", "number",
|
||||
title:"${it.@label}\n" + "${it.Help}",
|
||||
range: "${it.@min}..${it.@max}",
|
||||
defaultValue: "${it.@value}",
|
||||
displayDuringSetup: "${it.@displayDuringSetup}"
|
||||
break
|
||||
case "list":
|
||||
def items = []
|
||||
it.Item.each { items << ["${it.@value}":"${it.@label}"] }
|
||||
input "${it.@index}", "enum",
|
||||
title:"${it.@label}\n" + "${it.Help}",
|
||||
defaultValue: "${it.@value}",
|
||||
displayDuringSetup: "${it.@displayDuringSetup}",
|
||||
options: items
|
||||
break
|
||||
case "decimal":
|
||||
input "${it.@index}", "decimal",
|
||||
title:"${it.@label}\n" + "${it.Help}",
|
||||
range: "${it.@min}..${it.@max}",
|
||||
defaultValue: "${it.@value}",
|
||||
displayDuringSetup: "${it.@displayDuringSetup}"
|
||||
break
|
||||
case "boolean":
|
||||
input "${it.@index}", "boolean",
|
||||
title:"${it.@label}\n" + "${it.Help}",
|
||||
defaultValue: "${it.@value}",
|
||||
displayDuringSetup: "${it.@displayDuringSetup}"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def update_current_properties(cmd)
|
||||
{
|
||||
def currentProperties = state.currentProperties ?: [:]
|
||||
|
||||
currentProperties."${cmd.parameterNumber}" = cmd.configurationValue
|
||||
|
||||
if (settings."${cmd.parameterNumber}" != null)
|
||||
{
|
||||
if (settings."${cmd.parameterNumber}".toInteger() == convertParam("${cmd.parameterNumber}".toInteger(), cmd2Integer(cmd.configurationValue)))
|
||||
{
|
||||
sendEvent(name:"needUpdate", value:"NO", displayed:false, isStateChange: true)
|
||||
}
|
||||
else
|
||||
{
|
||||
sendEvent(name:"needUpdate", value:"YES", displayed:false, isStateChange: true)
|
||||
}
|
||||
}
|
||||
|
||||
state.currentProperties = currentProperties
|
||||
}
|
||||
|
||||
def update_needed_settings()
|
||||
{
|
||||
def cmds = []
|
||||
def currentProperties = state.currentProperties ?: [:]
|
||||
|
||||
def configuration = parseXml(configuration_model())
|
||||
def isUpdateNeeded = "NO"
|
||||
|
||||
if(!state.needfwUpdate || state.needfwUpdate == ""){
|
||||
logging("Requesting device firmware version")
|
||||
cmds << zwave.firmwareUpdateMdV2.firmwareMdGet()
|
||||
}
|
||||
if(!state.association1 || state.association1 == "" || state.association1 == "1"){
|
||||
logging("Setting association group 1")
|
||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId)
|
||||
cmds << zwave.associationV2.associationGet(groupingIdentifier:1)
|
||||
}
|
||||
if(!state.association2 || state.association2 == "" || state.association1 == "2"){
|
||||
logging("Setting association group 2")
|
||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId)
|
||||
cmds << zwave.associationV2.associationGet(groupingIdentifier:2)
|
||||
}
|
||||
|
||||
configuration.Value.each
|
||||
{
|
||||
if ("${it.@setting_type}" == "zwave"){
|
||||
if (currentProperties."${it.@index}" == null)
|
||||
{
|
||||
if (device.currentValue("currentFirmware") == null || "${it.@fw}".indexOf(device.currentValue("currentFirmware")) >= 0){
|
||||
isUpdateNeeded = "YES"
|
||||
logging("Current value of parameter ${it.@index} is unknown")
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: it.@index.toInteger())
|
||||
}
|
||||
}
|
||||
else if (settings."${it.@index}" != null && convertParam(it.@index.toInteger(), cmd2Integer(currentProperties."${it.@index}")) != settings."${it.@index}".toInteger())
|
||||
{
|
||||
if (device.currentValue("currentFirmware") == null || "${it.@fw}".indexOf(device.currentValue("currentFirmware")) >= 0){
|
||||
isUpdateNeeded = "YES"
|
||||
|
||||
logging("Parameter ${it.@index} will be updated to " + settings."${it.@index}")
|
||||
def convertedConfigurationValue = convertParam(it.@index.toInteger(), settings."${it.@index}".toInteger())
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: integer2Cmd(convertedConfigurationValue, it.@byteSize.toInteger()), parameterNumber: it.@index.toInteger(), size: it.@byteSize.toInteger())
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: it.@index.toInteger())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendEvent(name:"needUpdate", value: isUpdateNeeded, displayed:false, isStateChange: true)
|
||||
return cmds
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert 1 and 2 bytes values to integer
|
||||
*/
|
||||
def cmd2Integer(array) {
|
||||
|
||||
switch(array.size()) {
|
||||
case 1:
|
||||
array[0]
|
||||
break
|
||||
case 2:
|
||||
((array[0] & 0xFF) << 8) | (array[1] & 0xFF)
|
||||
break
|
||||
case 3:
|
||||
((array[0] & 0xFF) << 16) | ((array[1] & 0xFF) << 8) | (array[2] & 0xFF)
|
||||
break
|
||||
case 4:
|
||||
((array[0] & 0xFF) << 24) | ((array[1] & 0xFF) << 16) | ((array[2] & 0xFF) << 8) | (array[3] & 0xFF)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
def integer2Cmd(value, size) {
|
||||
switch(size) {
|
||||
case 1:
|
||||
[value]
|
||||
break
|
||||
case 2:
|
||||
def short value1 = value & 0xFF
|
||||
def short value2 = (value >> 8) & 0xFF
|
||||
[value2, value1]
|
||||
break
|
||||
case 3:
|
||||
def short value1 = value & 0xFF
|
||||
def short value2 = (value >> 8) & 0xFF
|
||||
def short value3 = (value >> 16) & 0xFF
|
||||
[value3, value2, value1]
|
||||
break
|
||||
case 4:
|
||||
def short value1 = value & 0xFF
|
||||
def short value2 = (value >> 8) & 0xFF
|
||||
def short value3 = (value >> 16) & 0xFF
|
||||
def short value4 = (value >> 24) & 0xFF
|
||||
[value4, value3, value2, value1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) {
|
||||
update_current_properties(cmd)
|
||||
logging("${device.displayName} parameter '${cmd.parameterNumber}' with a byte size of '${cmd.size}' is set to '${cmd2Integer(cmd.configurationValue)}'")
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.firmwareupdatemdv2.FirmwareMdReport cmd){
|
||||
logging("Firmware Report ${cmd.toString()}")
|
||||
def firmwareVersion
|
||||
switch(cmd.checksum){
|
||||
case "3281":
|
||||
firmwareVersion = "3.08"
|
||||
break;
|
||||
default:
|
||||
firmwareVersion = cmd.checksum
|
||||
}
|
||||
state.needfwUpdate = "false"
|
||||
updateDataValue("firmware", firmwareVersion.toString())
|
||||
createEvent(name: "currentFirmware", value: firmwareVersion)
|
||||
}
|
||||
|
||||
def configure() {
|
||||
state.enableDebugging = settings.enableDebugging
|
||||
logging("Configuring Device For SmartThings Use")
|
||||
def cmds = []
|
||||
|
||||
cmds = update_needed_settings()
|
||||
|
||||
if (cmds != []) commands(cmds)
|
||||
}
|
||||
|
||||
def convertParam(number, value) {
|
||||
switch (number){
|
||||
case 201:
|
||||
if (value < 0)
|
||||
256 + value
|
||||
else if (value > 100)
|
||||
value - 256
|
||||
else
|
||||
value
|
||||
break
|
||||
case 202:
|
||||
if (value < 0)
|
||||
256 + value
|
||||
else if (value > 100)
|
||||
value - 256
|
||||
else
|
||||
value
|
||||
break
|
||||
case 203:
|
||||
if (value < 0)
|
||||
65536 + value
|
||||
else if (value > 1000)
|
||||
value - 65536
|
||||
else
|
||||
value
|
||||
break
|
||||
case 204:
|
||||
if (value < 0)
|
||||
256 + value
|
||||
else if (value > 100)
|
||||
value - 256
|
||||
else
|
||||
value
|
||||
break
|
||||
default:
|
||||
value
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
private def logging(message) {
|
||||
if (state.enableDebugging == null || state.enableDebugging == "true") log.debug "$message"
|
||||
}
|
||||
|
||||
|
||||
def configuration_model()
|
||||
{
|
||||
'''
|
||||
<configuration>
|
||||
<Value type="byte" byteSize="1" index="1" label="Minimum brightness level" min="1" max="98" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
(parameter is set automatically during the calibration process)
|
||||
The parameter can be changed manually after the calibration.
|
||||
Range: 1~98
|
||||
Default: 1
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="byte" byteSize="1" index="2" label="Maximum brightness level" min="2" max="99" value="99" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
(parameter is set automatically during the calibration process)
|
||||
The parameter can be changed manually after the calibration.
|
||||
Range: 2~99
|
||||
Default: 99
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="byte" byteSize="1" index="5" label="Automatic control - dimming step size" min="1" max="99" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter defines the percentage value of dimming step during the automatic control.
|
||||
Range: 1~99
|
||||
Default: 1
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="6" label="Automatic control - time of a dimming step" min="0" max="255" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter defines the time of single dimming step set in parameter 5 during the automatic control.
|
||||
Range: 0~255
|
||||
Default: 1
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="byte" byteSize="1" index="7" label="Manual control - dimming step size" min="1" max="99" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter defines the percentage value of dimming step during the manual control.
|
||||
Range: 1~99
|
||||
Default: 1
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="8" label="Manual control - time of a dimming step" min="0" max="255" value="5" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter defines the time of single dimming step set in parameter 7 during the manual control.
|
||||
Range: 0~255
|
||||
Default: 5
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="9" label="State of the device after a power failure" min="0" max="1" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
The Dimmer 2 will return to the last state before power failure.
|
||||
0 - the Dimmer 2 does not save the state before a power failure, it returns to the "off" position
|
||||
1 - the Dimmer 2 restores its state before power failure
|
||||
Range: 0~1
|
||||
Default: 1
|
||||
</Help>
|
||||
<Item label="Off" value="0" />
|
||||
<Item label="Previous State" value="1" />
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="10" label="Timer functionality (auto - off)" min="0" max="32767" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter allows to automatically switch off the device after specified time (seconds) from switching on the light source.
|
||||
Range: 1~32767
|
||||
Default: 0
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="byte" byteSize="1" index="19" label="Forced switch on brightness level" min="0" max="99" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
If the parameter is active, switching on the Dimmer 2 (S1 single click) will always set this brightness level.
|
||||
Range: 0~99
|
||||
Default: 0
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="20" label="Switch type" min="0" max="2" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
Choose between momentary, toggle and roller blind switch.
|
||||
Range: 0~2
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Momentary" value="0" />
|
||||
<Item label="Toggle" value="1" />
|
||||
<Item label="Roller Blind" value="2" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="22" label="Assign toggle switch status to the device status " min="0" max="1" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
By default each change of toggle switch position results in action of Dimmer 2 (switch on/off) regardless the physical connection of contacts.
|
||||
0 - device changes status on switch status change
|
||||
1 - device status is synchronized with switch status
|
||||
Range: 0~1
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Default" value="0" />
|
||||
<Item label="Synchronized" value="1" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="23" label="Double click option" min="0" max="1" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
set the brightness level to MAX
|
||||
Range: 0~1
|
||||
Default: 1
|
||||
</Help>
|
||||
<Item label="Disabled" value="0" />
|
||||
<Item label="Enabled" value="1" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="26" label="The function of 3-way switch" min="0" max="1" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
Switch no. 2 controls the Dimmer 2 additionally (in 3-way switch mode). Function disabled for parameter 20 set to 2 (roller blind switch).
|
||||
Range: 0~1
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Disabled" value="0" />
|
||||
<Item label="Enabled" value="1" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="28" label="Scene activation functionality" min="0" max="1" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
SCENE ID depends on the switch type configurations.
|
||||
Range: 0~1
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Disabled" value="0" />
|
||||
<Item label="Enabled" value="1" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="29" label="Switch functionality of S1 and S2" min="0" max="1" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter allows for switching the role of keys connected to S1 and S2 without changes in connection.
|
||||
Range: 0~1
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Standard" value="0" />
|
||||
<Item label="Switched" value="1" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="35" label="Auto-calibration after power on" min="0" max="4" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter determines the trigger of auto-calibration procedure, e.g. power on, load error, etc.
|
||||
0 - No auto-calibration of the load after power on
|
||||
1 - Auto-calibration performed after first power on
|
||||
2 - Auto-calibration performed after each power on
|
||||
3 - Auto-calibration performed after first power on or after each LOAD ERROR alarm (no load, load failure, burnt out bulb), if parameter 37 is set to 1 also after alarms: SURGE (Dimmer 2 output overvoltage) and OVERCURRENT (Dimmer 2 output overcurrent)
|
||||
4 - Auto-calibration performed after each power on or after each LOAD ERROR alarm (no load, load failure, burnt out bulb), if parameter 37 is set to 1 also after alarms: SURGE (Dimmer 2 output overvoltage) and OVERCURRENT (Dimmer 2 output overcurrent)
|
||||
Range: 0~4
|
||||
Default: 1
|
||||
</Help>
|
||||
<Item label="0" value="0" />
|
||||
<Item label="1" value="1" />
|
||||
<Item label="2" value="2" />
|
||||
<Item label="3" value="3" />
|
||||
<Item label="4" value="4" />
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="39" label="Max Power load" min="0" max="350" value="250" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter defines the maximum load for a dimmer.
|
||||
Range: 0~350
|
||||
Default: 250
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="byte" byteSize="1" index="50" label="Active power reports" min="0" max="100" value="10" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
The parameter defines the power level change that will result in a new power report being sent. The value is a percentage of the previous report.
|
||||
Range: 0~100
|
||||
Default: 10
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="52" label="Periodic active power and energy reports" min="0" max="32767" value="3600" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
Parameter 52 defines a time period between consecutive reports. Timer is reset and counted from zero after each report.
|
||||
Range: 0~32767
|
||||
Default: 3600
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="53" label="Energy reports" min="0" max="255" value="10" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
Energy level change which will result in sending a new energy report.
|
||||
Range: 0~255
|
||||
Default: 10
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="54" label="Self-measurement" min="0" max="1" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
The Dimmer 2 may include active power and energy consumed by itself in reports sent to the main controller.
|
||||
Range: 0~1
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Disabled" value="0" />
|
||||
<Item label="Enabled" value="1" />
|
||||
</Value>
|
||||
<Value type="boolean" index="enableDebugging" label="Enable Debug Logging?" value="true" setting_type="preference" fw="3.08">
|
||||
<Help>
|
||||
</Help>
|
||||
</Value>
|
||||
</configuration>
|
||||
'''
|
||||
}
|
||||
@@ -14,13 +14,13 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Fibaro Door/Window Sensor ZW5 with Temperature", namespace: "fibargroup", author: "Fibar Group S.A.") {
|
||||
definition (name: "Fibaro Door/Window Sensor ZW5 with Temperature", namespace: "fibargroup", author: "Fibar Group S.A.", ocfDeviceType: "x.com.st.d.sensor.contact") {
|
||||
capability "Battery"
|
||||
capability "Contact Sensor"
|
||||
capability "Sensor"
|
||||
capability "Configuration"
|
||||
capability "Tamper Alert"
|
||||
|
||||
|
||||
capability "Temperature Measurement"
|
||||
|
||||
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x85, 0x59, 0x22, 0x20, 0x80, 0x70, 0x56, 0x5A, 0x7A, 0x72, 0x8E, 0x71, 0x73, 0x98, 0x2B, 0x9C, 0x30, 0x31, 0x86", outClusters: ""
|
||||
@@ -28,26 +28,26 @@ metadata {
|
||||
}
|
||||
|
||||
simulator {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"FGK", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
|
||||
tileAttribute("device.contact", key:"PRIMARY_CONTROL") {
|
||||
attributeState("open", icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
|
||||
attributeState("closed", icon:"st.contact.contact.closed", backgroundColor:"#79b821")
|
||||
attributeState("open", icon:"st.contact.contact.open", backgroundColor:"#e86d13")
|
||||
attributeState("closed", icon:"st.contact.contact.closed", backgroundColor:"#00a0dc")
|
||||
}
|
||||
|
||||
|
||||
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
|
||||
attributeState("active", label:'tamper active', backgroundColor:"#53a7c0")
|
||||
attributeState("inactive", label:'tamper inactive', backgroundColor:"#ffffff")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, , width: 2, height: 2, decoration: "flat") {
|
||||
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, width: 2, height: 2, decoration: "flat") {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
}
|
||||
|
||||
|
||||
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "temperature", label:'${currentValue}°',
|
||||
backgroundColors:[
|
||||
@@ -60,7 +60,7 @@ metadata {
|
||||
[value: 96, color: "#bc2323"]
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
main "FGK"
|
||||
details(["FGK","battery", "temperature"])
|
||||
}
|
||||
@@ -68,9 +68,9 @@ metadata {
|
||||
|
||||
// parse events into attributes
|
||||
def parse(String description) {
|
||||
log.debug "Parsing '${description}'"
|
||||
log.debug "Parsing '${description}'"
|
||||
def result = []
|
||||
|
||||
|
||||
if (description.startsWith("Err 106")) {
|
||||
if (state.sec) {
|
||||
result = createEvent(descriptionText:description, displayed:false)
|
||||
@@ -87,7 +87,7 @@ def parse(String description) {
|
||||
return null
|
||||
} else {
|
||||
def cmd = zwave.parse(description, [0x31: 5, 0x56: 1, 0x71: 3, 0x72: 2, 0x80: 1, 0x84: 2, 0x85: 2, 0x86: 1, 0x98: 1])
|
||||
|
||||
|
||||
if (cmd) {
|
||||
log.debug "Parsed '${cmd}'"
|
||||
zwaveEvent(cmd)
|
||||
@@ -125,13 +125,13 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
|
||||
//(parameter 20 was not changed before device's re-inclusion)
|
||||
def map = [:]
|
||||
if (cmd.notificationType == 6) {
|
||||
switch (cmd.event) {
|
||||
switch (cmd.event) {
|
||||
case 22:
|
||||
map.name = "contact"
|
||||
map.value = "open"
|
||||
map.descriptionText = "${device.displayName}: is open"
|
||||
break
|
||||
|
||||
|
||||
case 23:
|
||||
map.name = "contact"
|
||||
map.value = "closed"
|
||||
@@ -145,7 +145,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
|
||||
map.value = "inactive"
|
||||
map.descriptionText = "${device.displayName}: tamper alarm has been deactivated"
|
||||
break
|
||||
|
||||
|
||||
case 3:
|
||||
map.name = "tamper"
|
||||
map.value = "active"
|
||||
@@ -153,7 +153,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
createEvent(map)
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
||||
createEvent(map)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
|
||||
def event = createEvent(descriptionText: "${device.displayName} woke up", displayed: false)
|
||||
def cmds = []
|
||||
cmds << encap(zwave.batteryV1.batteryGet())
|
||||
@@ -177,32 +177,32 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
|
||||
[event, response(cmds)]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||
log.debug "manufacturerId: ${cmd.manufacturerId}"
|
||||
log.debug "manufacturerName: ${cmd.manufacturerName}"
|
||||
log.debug "productId: ${cmd.productId}"
|
||||
log.debug "productTypeId: ${cmd.productTypeId}"
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
|
||||
log.debug "deviceIdData: ${cmd.deviceIdData}"
|
||||
log.debug "deviceIdDataFormat: ${cmd.deviceIdDataFormat}"
|
||||
log.debug "deviceIdDataLengthIndicator: ${cmd.deviceIdDataLengthIndicator}"
|
||||
log.debug "deviceIdType: ${cmd.deviceIdType}"
|
||||
|
||||
|
||||
if (cmd.deviceIdType == 1 && cmd.deviceIdDataFormat == 1) {//serial number in binary format
|
||||
String serialNumber = "h'"
|
||||
|
||||
|
||||
cmd.deviceIdData.each{ data ->
|
||||
serialNumber += "${String.format("%02X", data)}"
|
||||
}
|
||||
|
||||
|
||||
updateDataValue("serialNumber", serialNumber)
|
||||
log.debug "${device.displayName} - serial number: ${serialNumber}"
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
||||
updateDataValue("version", "${cmd.applicationVersion}.${cmd.applicationSubVersion}")
|
||||
log.debug "applicationVersion: ${cmd.applicationVersion}"
|
||||
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
|
||||
@@ -221,7 +221,7 @@ def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelR
|
||||
map.name = "temperature"
|
||||
map.displayed = true
|
||||
}
|
||||
|
||||
|
||||
createEvent(map)
|
||||
}
|
||||
|
||||
@@ -231,9 +231,9 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
|
||||
|
||||
def configure() {
|
||||
log.debug "Executing 'configure'"
|
||||
|
||||
|
||||
def cmds = []
|
||||
|
||||
|
||||
cmds += zwave.wakeUpV2.wakeUpIntervalSet(seconds:21600, nodeid: zwaveHubNodeId)//FGK's default wake up interval
|
||||
cmds += zwave.manufacturerSpecificV2.manufacturerSpecificGet()
|
||||
cmds += zwave.manufacturerSpecificV2.deviceSpecificGet()
|
||||
@@ -242,7 +242,7 @@ def configure() {
|
||||
cmds += zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0)
|
||||
cmds += zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])
|
||||
cmds += zwave.wakeUpV2.wakeUpNoMoreInformation()
|
||||
|
||||
|
||||
encapSequence(cmds, 500)
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ private encapSequence(commands, delay=200) {
|
||||
|
||||
private encap(physicalgraph.zwave.Command cmd) {
|
||||
def secureClasses = [0x20, 0x2B, 0x30, 0x5A, 0x70, 0x71, 0x84, 0x85, 0x8E, 0x9C]
|
||||
|
||||
|
||||
//todo: check if secure inclusion was successful
|
||||
//if not do not send security-encapsulated command
|
||||
if (secureClasses.find{ it == cmd.commandClassId }) {
|
||||
@@ -269,4 +269,4 @@ private encap(physicalgraph.zwave.Command cmd) {
|
||||
} else {
|
||||
crc16(cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -0,0 +1,41 @@
|
||||
# Fibaro Door Window Sensor ZW5
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [Fibaro Door/Window Sensor ZW5](https://www.smartthings.com/works-with-smartthings/sensors/fibaro-doorwindow-sensor)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Battery](#battery-specification)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Battery** - defines device uses a battery
|
||||
* **Contact Sensor** - can detect contact (possible values: open,closed)
|
||||
* **Sensor** - detects sensor events
|
||||
* **Tamper Alert** - detects tampers
|
||||
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
## Device Health
|
||||
|
||||
Fibaro Door/Window Sensor ZW5 is a Z-wave sleepy device and wakes up every 4 hours.
|
||||
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*4*60 + 2)mins = 482 mins.
|
||||
|
||||
* __482min__ checkInterval
|
||||
|
||||
## Battery Specification
|
||||
|
||||
One 1/2AA 3.6V battery is 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:
|
||||
* [Fibaro Door/Window Sensor ZW5 Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/204075194-Fibaro-Door-Window-Sensor)
|
||||
@@ -14,37 +14,38 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Fibaro Door/Window Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.") {
|
||||
definition (name: "Fibaro Door/Window Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.", ocfDeviceType: "x.com.st.d.sensor.contact") {
|
||||
capability "Battery"
|
||||
capability "Contact Sensor"
|
||||
capability "Sensor"
|
||||
capability "Configuration"
|
||||
capability "Tamper Alert"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x85, 0x59, 0x22, 0x20, 0x80, 0x70, 0x56, 0x5A, 0x7A, 0x72, 0x8E, 0x71, 0x73, 0x98, 0x2B, 0x9C, 0x30, 0x86, 0x84", outClusters: ""
|
||||
}
|
||||
|
||||
simulator {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"FGK", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
|
||||
tileAttribute("device.contact", key:"PRIMARY_CONTROL") {
|
||||
attributeState("open", icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
|
||||
attributeState("closed", icon:"st.contact.contact.closed", backgroundColor:"#79b821")
|
||||
attributeState("open", icon:"st.contact.contact.open", backgroundColor:"#e86d13")
|
||||
attributeState("closed", icon:"st.contact.contact.closed", backgroundColor:"#00a0dc")
|
||||
}
|
||||
|
||||
|
||||
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
|
||||
attributeState("active", label:'tamper active', backgroundColor:"#53a7c0")
|
||||
attributeState("inactive", label:'tamper inactive', backgroundColor:"#ffffff")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, , width: 2, height: 2, decoration: "flat") {
|
||||
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, width: 2, height: 2, decoration: "flat") {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
}
|
||||
|
||||
|
||||
main "FGK"
|
||||
details(["FGK","battery"])
|
||||
}
|
||||
@@ -52,9 +53,9 @@ metadata {
|
||||
|
||||
// parse events into attributes
|
||||
def parse(String description) {
|
||||
log.debug "Parsing '${description}'"
|
||||
log.debug "Parsing '${description}'"
|
||||
def result = []
|
||||
|
||||
|
||||
if (description.startsWith("Err 106")) {
|
||||
if (state.sec) {
|
||||
result = createEvent(descriptionText:description, displayed:false)
|
||||
@@ -71,7 +72,7 @@ def parse(String description) {
|
||||
return null
|
||||
} else {
|
||||
def cmd = zwave.parse(description, [0x56: 1, 0x71: 3, 0x72: 2, 0x80: 1, 0x84: 2, 0x85: 2, 0x86: 1, 0x98: 1])
|
||||
|
||||
|
||||
if (cmd) {
|
||||
log.debug "Parsed '${cmd}'"
|
||||
zwaveEvent(cmd)
|
||||
@@ -109,13 +110,13 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
|
||||
//(parameter 20 was not changed before device's re-inclusion)
|
||||
def map = [:]
|
||||
if (cmd.notificationType == 6) {
|
||||
switch (cmd.event) {
|
||||
switch (cmd.event) {
|
||||
case 22:
|
||||
map.name = "contact"
|
||||
map.value = "open"
|
||||
map.descriptionText = "${device.displayName}: is open"
|
||||
break
|
||||
|
||||
|
||||
case 23:
|
||||
map.name = "contact"
|
||||
map.value = "closed"
|
||||
@@ -129,7 +130,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
|
||||
map.value = "inactive"
|
||||
map.descriptionText = "${device.displayName}: tamper alarm has been deactivated"
|
||||
break
|
||||
|
||||
|
||||
case 3:
|
||||
map.name = "tamper"
|
||||
map.value = "active"
|
||||
@@ -137,7 +138,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
createEvent(map)
|
||||
}
|
||||
|
||||
@@ -150,7 +151,7 @@ def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
||||
createEvent(map)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
|
||||
def event = createEvent(descriptionText: "${device.displayName} woke up", displayed: false)
|
||||
def cmds = []
|
||||
cmds << encap(zwave.batteryV1.batteryGet())
|
||||
@@ -159,32 +160,32 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
|
||||
[event, response(cmds)]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||
log.debug "manufacturerId: ${cmd.manufacturerId}"
|
||||
log.debug "manufacturerName: ${cmd.manufacturerName}"
|
||||
log.debug "productId: ${cmd.productId}"
|
||||
log.debug "productTypeId: ${cmd.productTypeId}"
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
|
||||
log.debug "deviceIdData: ${cmd.deviceIdData}"
|
||||
log.debug "deviceIdDataFormat: ${cmd.deviceIdDataFormat}"
|
||||
log.debug "deviceIdDataLengthIndicator: ${cmd.deviceIdDataLengthIndicator}"
|
||||
log.debug "deviceIdType: ${cmd.deviceIdType}"
|
||||
|
||||
|
||||
if (cmd.deviceIdType == 1 && cmd.deviceIdDataFormat == 1) {//serial number in binary format
|
||||
String serialNumber = "h'"
|
||||
|
||||
|
||||
cmd.deviceIdData.each{ data ->
|
||||
serialNumber += "${String.format("%02X", data)}"
|
||||
}
|
||||
|
||||
|
||||
updateDataValue("serialNumber", serialNumber)
|
||||
log.debug "${device.displayName} - serial number: ${serialNumber}"
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
||||
updateDataValue("version", "${cmd.applicationVersion}.${cmd.applicationSubVersion}")
|
||||
log.debug "applicationVersion: ${cmd.applicationVersion}"
|
||||
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
|
||||
@@ -199,9 +200,11 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
|
||||
|
||||
def configure() {
|
||||
log.debug "Executing 'configure'"
|
||||
|
||||
// Device wakes up every 4 hours, this interval allows us to miss one wakeup notification before marking offline
|
||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
def cmds = []
|
||||
|
||||
|
||||
cmds += zwave.wakeUpV2.wakeUpIntervalSet(seconds:21600, nodeid: zwaveHubNodeId)//FGK's default wake up interval
|
||||
cmds += zwave.manufacturerSpecificV2.manufacturerSpecificGet()
|
||||
cmds += zwave.manufacturerSpecificV2.deviceSpecificGet()
|
||||
@@ -209,7 +212,7 @@ def configure() {
|
||||
cmds += zwave.batteryV1.batteryGet()
|
||||
cmds += zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])
|
||||
cmds += zwave.wakeUpV2.wakeUpNoMoreInformation()
|
||||
|
||||
|
||||
encapSequence(cmds, 500)
|
||||
}
|
||||
|
||||
@@ -228,7 +231,7 @@ private encapSequence(commands, delay=200) {
|
||||
|
||||
private encap(physicalgraph.zwave.Command cmd) {
|
||||
def secureClasses = [0x20, 0x2B, 0x30, 0x5A, 0x70, 0x71, 0x84, 0x85, 0x8E, 0x9C]
|
||||
|
||||
|
||||
//todo: check if secure inclusion was successful
|
||||
//if not do not send security-encapsulated command
|
||||
if (secureClasses.find{ it == cmd.commandClassId }) {
|
||||
@@ -236,4 +239,4 @@ private encap(physicalgraph.zwave.Command cmd) {
|
||||
} else {
|
||||
crc16(cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,35 +14,37 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Fibaro Flood Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.") {
|
||||
definition (name: "Fibaro Flood Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.", ocfDeviceType: "x.com.st.d.sensor.moisture") {
|
||||
capability "Battery"
|
||||
capability "Configuration"
|
||||
capability "Sensor"
|
||||
capability "Tamper Alert"
|
||||
capability "Temperature Measurement"
|
||||
capability "Water Sensor"
|
||||
|
||||
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x22, 0x85, 0x59, 0x20, 0x80, 0x70, 0x56, 0x5A, 0x7A, 0x72, 0x8E, 0x71, 0x73, 0x98, 0x9C, 0x31, 0x86", outClusters: ""
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x22, 0x85, 0x59, 0x20, 0x80, 0x70, 0x56, 0x5A, 0x7A, 0x72, 0x8E, 0x71, 0x73, 0x98, 0x9C, 0x31, 0x86", outClusters: ""
|
||||
fingerprint mfr:"010F", prod:"0B01", model:"2002"
|
||||
fingerprint mfr:"010F", prod:"0B01", model:"1002"
|
||||
}
|
||||
|
||||
simulator {
|
||||
|
||||
}
|
||||
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"FGFS", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
|
||||
tileAttribute("device.water", key:"PRIMARY_CONTROL") {
|
||||
attributeState("dry", icon:"st.alarm.water.dry", backgroundColor:"#79b821")
|
||||
attributeState("wet", icon:"st.alarm.water.wet", backgroundColor:"#ffa81e")
|
||||
}
|
||||
|
||||
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
|
||||
attributeState("active", label:'tamper active', backgroundColor:"#53a7c0")
|
||||
attributeState("inactive", label:'tamper inactive', backgroundColor:"#ffffff")
|
||||
}
|
||||
}
|
||||
|
||||
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
|
||||
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"FGFS", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
|
||||
tileAttribute("device.water", key:"PRIMARY_CONTROL") {
|
||||
attributeState("dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff")
|
||||
attributeState("wet", icon:"st.alarm.water.wet", backgroundColor:"#00a0dc")
|
||||
}
|
||||
|
||||
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
|
||||
attributeState("active", label:'tamper active', backgroundColor:"#cccccc")
|
||||
attributeState("inactive", label:'tamper inactive', backgroundColor:"#00A0DC")
|
||||
}
|
||||
}
|
||||
|
||||
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "temperature", label:'${currentValue}°',
|
||||
backgroundColors:[
|
||||
[value: 31, color: "#153591"],
|
||||
@@ -54,22 +56,22 @@ metadata {
|
||||
[value: 96, color: "#bc2323"]
|
||||
]
|
||||
}
|
||||
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
}
|
||||
|
||||
main "FGFS"
|
||||
details(["FGFS","battery", "temperature"])
|
||||
}
|
||||
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
}
|
||||
|
||||
main "FGFS"
|
||||
details(["FGFS","battery", "temperature"])
|
||||
}
|
||||
}
|
||||
|
||||
// parse events into attributes
|
||||
def parse(String description) {
|
||||
log.debug "Parsing '${description}'"
|
||||
def result = []
|
||||
|
||||
if (description.startsWith("Err 106")) {
|
||||
|
||||
if (description.startsWith("Err 106")) {
|
||||
if (state.sec) {
|
||||
result = createEvent(descriptionText:description, displayed:false)
|
||||
} else {
|
||||
@@ -84,13 +86,13 @@ def parse(String description) {
|
||||
} else if (description == "updated") {
|
||||
return null
|
||||
} else {
|
||||
def cmd = zwave.parse(description, [0x31: 5, 0x56: 1, 0x71: 3, 0x72:2, 0x80: 1, 0x84: 2, 0x85: 2, 0x86: 1, 0x98: 1])
|
||||
def cmd = zwave.parse(description, [0x31: 5, 0x56: 1, 0x71: 3, 0x72:2, 0x80: 1, 0x84: 2, 0x85: 2, 0x86: 1, 0x98: 1])
|
||||
|
||||
if (cmd) {
|
||||
log.debug "Parsed '${cmd}'"
|
||||
zwaveEvent(cmd)
|
||||
}
|
||||
}
|
||||
if (cmd) {
|
||||
log.debug "Parsed '${cmd}'"
|
||||
zwaveEvent(cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//security
|
||||
@@ -107,7 +109,7 @@ def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulat
|
||||
//crc16
|
||||
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd)
|
||||
{
|
||||
def versions = [0x31: 5, 0x72: 2, 0x80: 1]
|
||||
def versions = [0x31: 5, 0x72: 2, 0x80: 1]
|
||||
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)
|
||||
@@ -121,105 +123,124 @@ def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd)
|
||||
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd)
|
||||
{
|
||||
def event = createEvent(descriptionText: "${device.displayName} woke up", displayed: false)
|
||||
def cmds = []
|
||||
cmds << encap(zwave.batteryV1.batteryGet())
|
||||
cmds << "delay 500"
|
||||
cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
|
||||
cmds << "delay 1200"
|
||||
cmds << encap(zwave.wakeUpV1.wakeUpNoMoreInformation())
|
||||
[event, response(cmds)]
|
||||
def cmds = []
|
||||
// cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
|
||||
// cmds << "delay 500"
|
||||
cmds << encap(zwave.batteryV1.batteryGet())
|
||||
[event, response(cmds)]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||
log.debug "manufacturerId: ${cmd.manufacturerId}"
|
||||
log.debug "manufacturerName: ${cmd.manufacturerName}"
|
||||
log.debug "productId: ${cmd.productId}"
|
||||
log.debug "productTypeId: ${cmd.productTypeId}"
|
||||
log.debug "manufacturerName: ${cmd.manufacturerName}"
|
||||
log.debug "productId: ${cmd.productId}"
|
||||
log.debug "productTypeId: ${cmd.productTypeId}"
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
|
||||
log.debug "deviceIdData: ${cmd.deviceIdData}"
|
||||
log.debug "deviceIdDataFormat: ${cmd.deviceIdDataFormat}"
|
||||
log.debug "deviceIdDataLengthIndicator: ${cmd.deviceIdDataLengthIndicator}"
|
||||
log.debug "deviceIdType: ${cmd.deviceIdType}"
|
||||
|
||||
if (cmd.deviceIdType == 1 && cmd.deviceIdDataFormat == 1) {//serial number in binary format
|
||||
log.debug "deviceIdDataFormat: ${cmd.deviceIdDataFormat}"
|
||||
log.debug "deviceIdDataLengthIndicator: ${cmd.deviceIdDataLengthIndicator}"
|
||||
log.debug "deviceIdType: ${cmd.deviceIdType}"
|
||||
|
||||
if (cmd.deviceIdType == 1 && cmd.deviceIdDataFormat == 1) { //serial number in binary format
|
||||
String serialNumber = "h'"
|
||||
|
||||
cmd.deviceIdData.each{ data ->
|
||||
serialNumber += "${String.format("%02X", data)}"
|
||||
}
|
||||
|
||||
updateDataValue("serialNumber", serialNumber)
|
||||
log.debug "${device.displayName} - serial number: ${serialNumber}"
|
||||
}
|
||||
|
||||
cmd.deviceIdData.each{ data ->
|
||||
serialNumber += "${String.format("%02X", data)}"
|
||||
}
|
||||
|
||||
updateDataValue("serialNumber", serialNumber)
|
||||
log.debug "${device.displayName} - serial number: ${serialNumber}"
|
||||
}
|
||||
|
||||
def response_cmds = []
|
||||
if (!device.currentState("temperature")) {
|
||||
response_cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
|
||||
}
|
||||
if (!getDataValue("version") && !zwaveInfo.ver) {
|
||||
log.debug "Requesting Version Report"
|
||||
response_cmds << "delay 500"
|
||||
response_cmds << encap(zwave.versionV1.versionGet())
|
||||
}
|
||||
response_cmds << "delay 1000"
|
||||
response_cmds << encap(zwave.wakeUpV2.wakeUpNoMoreInformation())
|
||||
[[:], response(response_cmds)]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
||||
updateDataValue("version", "${cmd.applicationVersion}.${cmd.applicationSubVersion}")
|
||||
log.debug "applicationVersion: ${cmd.applicationVersion}"
|
||||
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
|
||||
log.debug "zWaveLibraryType: ${cmd.zWaveLibraryType}"
|
||||
log.debug "zWaveProtocolVersion: ${cmd.zWaveProtocolVersion}"
|
||||
log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
|
||||
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
||||
updateDataValue("version", "${cmd.applicationVersion}.${cmd.applicationSubVersion}")
|
||||
log.debug "applicationVersion: ${cmd.applicationVersion}"
|
||||
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
|
||||
log.debug "zWaveLibraryType: ${cmd.zWaveLibraryType}"
|
||||
log.debug "zWaveProtocolVersion: ${cmd.zWaveProtocolVersion}"
|
||||
log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
||||
def result = []
|
||||
def map = [:]
|
||||
map.name = "battery"
|
||||
map.value = cmd.batteryLevel == 255 ? 1 : cmd.batteryLevel.toString()
|
||||
map.unit = "%"
|
||||
map.displayed = true
|
||||
createEvent(map)
|
||||
|
||||
result << createEvent(map)
|
||||
|
||||
if (!getDataValue("serialNumber")) {
|
||||
result << response(encap(zwave.manufacturerSpecificV2.deviceSpecificGet()))
|
||||
} else {
|
||||
result << response(encap(zwave.wakeUpV2.wakeUpNoMoreInformation()))
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
|
||||
def map = [:]
|
||||
if (cmd.notificationType == 5) {
|
||||
switch (cmd.event) {
|
||||
case 2:
|
||||
map.name = "water"
|
||||
map.value = "wet"
|
||||
map.descriptionText = "${device.displayName} is ${map.value}"
|
||||
break
|
||||
|
||||
case 0:
|
||||
map.name = "water"
|
||||
map.value = "dry"
|
||||
map.descriptionText = "${device.displayName} is ${map.value}"
|
||||
break
|
||||
}
|
||||
} else if (cmd.notificationType == 7) {
|
||||
switch (cmd.event) {
|
||||
case 0:
|
||||
map.name = "tamper"
|
||||
map.value = "inactive"
|
||||
map.descriptionText = "${device.displayName}: tamper alarm has been deactivated"
|
||||
if (cmd.notificationType == 5) {
|
||||
switch (cmd.event) {
|
||||
case 2:
|
||||
map.name = "water"
|
||||
map.value = "wet"
|
||||
map.descriptionText = "${device.displayName} is ${map.value}"
|
||||
break
|
||||
|
||||
case 3:
|
||||
map.name = "tamper"
|
||||
map.value = "active"
|
||||
map.descriptionText = "${device.displayName}: tamper alarm activated"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
createEvent(map)
|
||||
|
||||
case 0:
|
||||
map.name = "water"
|
||||
map.value = "dry"
|
||||
map.descriptionText = "${device.displayName} is ${map.value}"
|
||||
break
|
||||
}
|
||||
} else if (cmd.notificationType == 7) {
|
||||
switch (cmd.event) {
|
||||
case 0:
|
||||
map.name = "tamper"
|
||||
map.value = "inactive"
|
||||
map.descriptionText = "${device.displayName}: tamper alarm has been deactivated"
|
||||
break
|
||||
|
||||
case 3:
|
||||
map.name = "tamper"
|
||||
map.value = "active"
|
||||
map.descriptionText = "${device.displayName}: tamper alarm activated"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
createEvent(map)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd) {
|
||||
def map = [:]
|
||||
if (cmd.sensorType == 1) {
|
||||
// temperature
|
||||
def cmdScale = cmd.scale == 1 ? "F" : "C"
|
||||
map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
|
||||
map.unit = getTemperatureScale()
|
||||
map.name = "temperature"
|
||||
map.displayed = true
|
||||
// temperature
|
||||
def cmdScale = cmd.scale == 1 ? "F" : "C"
|
||||
map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
|
||||
map.unit = getTemperatureScale()
|
||||
map.name = "temperature"
|
||||
map.displayed = true
|
||||
}
|
||||
|
||||
createEvent(map)
|
||||
|
||||
createEvent(map)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLocallyNotification cmd) {
|
||||
@@ -228,19 +249,18 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
|
||||
|
||||
def configure() {
|
||||
log.debug "Executing 'configure'"
|
||||
|
||||
def cmds = []
|
||||
|
||||
cmds += zwave.wakeUpV2.wakeUpIntervalSet(seconds:21600, nodeid: zwaveHubNodeId)//FGFS' default wake up interval
|
||||
cmds += zwave.manufacturerSpecificV2.manufacturerSpecificGet()
|
||||
cmds += zwave.manufacturerSpecificV2.deviceSpecificGet()
|
||||
cmds += zwave.versionV1.versionGet()
|
||||
cmds += zwave.batteryV1.batteryGet()
|
||||
cmds += zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0)
|
||||
cmds += zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])
|
||||
cmds += zwave.wakeUpV2.wakeUpNoMoreInformation()
|
||||
// Device wakes up every 4 hours, this interval of 8h 2m allows us to miss one wakeup notification before marking offline
|
||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
encapSequence(cmds, 500)
|
||||
// default initial state
|
||||
sendEvent(name: "water", value: "dry")
|
||||
|
||||
def cmds = []
|
||||
|
||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])
|
||||
cmds << zwave.batteryV1.batteryGet() // other queries sent as response to BatteryReport
|
||||
|
||||
encapSequence(cmds, 200)
|
||||
}
|
||||
|
||||
private secure(physicalgraph.zwave.Command cmd) {
|
||||
@@ -249,7 +269,7 @@ private secure(physicalgraph.zwave.Command cmd) {
|
||||
|
||||
private crc16(physicalgraph.zwave.Command cmd) {
|
||||
//zwave.crc16EncapV1.crc16Encap().encapsulate(cmd).format()
|
||||
"5601${cmd.format()}0000"
|
||||
"5601${cmd.format()}0000"
|
||||
}
|
||||
|
||||
private encapSequence(commands, delay=200) {
|
||||
@@ -257,13 +277,10 @@ private encapSequence(commands, delay=200) {
|
||||
}
|
||||
|
||||
private encap(physicalgraph.zwave.Command cmd) {
|
||||
def secureClasses = [0x20, 0x5A, 0x70, 0x71, 0x84, 0x85, 0x8E, 0x9C]
|
||||
|
||||
//todo: check if secure inclusion was successful
|
||||
//if not do not send security-encapsulated command
|
||||
if (secureClasses.find{ it == cmd.commandClassId }) {
|
||||
secure(cmd)
|
||||
} else {
|
||||
crc16(cmd)
|
||||
}
|
||||
}
|
||||
if (zwaveInfo.zw && !zwaveInfo.zw.contains("s")) {
|
||||
// Secure inclusion failed
|
||||
crc16(cmd)
|
||||
} else {
|
||||
secure(cmd)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Fibaro Motion Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.") {
|
||||
definition (name: "Fibaro Motion Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.", ocfDeviceType: "x.com.st.d.sensor.motion") {
|
||||
capability "Battery"
|
||||
capability "Configuration"
|
||||
capability "Illuminance Measurement"
|
||||
@@ -22,27 +22,28 @@ metadata {
|
||||
capability "Sensor"
|
||||
capability "Tamper Alert"
|
||||
capability "Temperature Measurement"
|
||||
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x20, 0x86, 0x72, 0x5A, 0x59, 0x85, 0x73, 0x84, 0x80, 0x71, 0x56, 0x70, 0x31, 0x8E, 0x22, 0x30, 0x9C, 0x98, 0x7A", outClusters: ""
|
||||
}
|
||||
|
||||
|
||||
simulator {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
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("active", label:"motion", icon:"st.motion.motion.active", backgroundColor:"#ffa81e")
|
||||
}
|
||||
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "temperature", label:'${currentValue}°',
|
||||
backgroundColors:[
|
||||
@@ -55,15 +56,15 @@ metadata {
|
||||
[value: 96, color: "#bc2323"]
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "luminosity", label:'${currentValue} ${unit}', unit:"lux"
|
||||
}
|
||||
|
||||
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, width: 2, height: 2, decoration: "flat") {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
}
|
||||
|
||||
|
||||
main "FGMS"
|
||||
details(["FGMS","battery","temperature","illuminance"])
|
||||
}
|
||||
@@ -71,9 +72,9 @@ metadata {
|
||||
|
||||
// parse events into attributes
|
||||
def parse(String description) {
|
||||
log.debug "Parsing '${description}'"
|
||||
log.debug "Parsing '${description}'"
|
||||
def result = []
|
||||
|
||||
|
||||
if (description.startsWith("Err 106")) {
|
||||
if (state.sec) {
|
||||
result = createEvent(descriptionText:description, displayed:false)
|
||||
@@ -90,7 +91,7 @@ def parse(String description) {
|
||||
return null
|
||||
} else {
|
||||
def cmd = zwave.parse(description, [0x31: 5, 0x56: 1, 0x71: 3, 0x72: 2, 0x80: 1, 0x84: 2, 0x85: 2, 0x86: 1, 0x98: 1])
|
||||
|
||||
|
||||
if (cmd) {
|
||||
log.debug "Parsed '${cmd}'"
|
||||
zwaveEvent(cmd)
|
||||
@@ -158,13 +159,13 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
|
||||
map.descriptionText = "${device.displayName}: motion has stopped"
|
||||
}
|
||||
break
|
||||
|
||||
|
||||
case 3:
|
||||
map.name = "tamper"
|
||||
map.value = "active"
|
||||
map.descriptionText = "${device.displayName}: tamper alarm activated"
|
||||
break
|
||||
|
||||
|
||||
case 8:
|
||||
map.name = "motion"
|
||||
map.value = "active"
|
||||
@@ -172,7 +173,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
createEvent(map)
|
||||
}
|
||||
|
||||
@@ -193,39 +194,39 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd)
|
||||
cmds << "delay 500"
|
||||
cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
|
||||
cmds << "delay 500"
|
||||
cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 3, scale: 1))
|
||||
cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 3, scale: 1))
|
||||
cmds << "delay 1200"
|
||||
cmds << encap(zwave.wakeUpV1.wakeUpNoMoreInformation())
|
||||
[event, response(cmds)]
|
||||
|
||||
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||
log.debug "manufacturerId: ${cmd.manufacturerId}"
|
||||
log.debug "manufacturerName: ${cmd.manufacturerName}"
|
||||
log.debug "productId: ${cmd.productId}"
|
||||
log.debug "productTypeId: ${cmd.productTypeId}"
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
|
||||
log.debug "deviceIdData: ${cmd.deviceIdData}"
|
||||
log.debug "deviceIdDataFormat: ${cmd.deviceIdDataFormat}"
|
||||
log.debug "deviceIdDataLengthIndicator: ${cmd.deviceIdDataLengthIndicator}"
|
||||
log.debug "deviceIdType: ${cmd.deviceIdType}"
|
||||
|
||||
|
||||
if (cmd.deviceIdType == 1 && cmd.deviceIdDataFormat == 1) {//serial number in binary format
|
||||
String serialNumber = "h'"
|
||||
|
||||
|
||||
cmd.deviceIdData.each{ data ->
|
||||
serialNumber += "${String.format("%02X", data)}"
|
||||
}
|
||||
|
||||
|
||||
updateDataValue("serialNumber", serialNumber)
|
||||
log.debug "${device.displayName} - serial number: ${serialNumber}"
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
||||
updateDataValue("version", "${cmd.applicationVersion}.${cmd.applicationSubVersion}")
|
||||
log.debug "applicationVersion: ${cmd.applicationVersion}"
|
||||
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
|
||||
@@ -240,9 +241,11 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
|
||||
|
||||
def configure() {
|
||||
log.debug "Executing 'configure'"
|
||||
|
||||
// Device-Watch simply pings if no device events received for 8 hrs & 2 minutes
|
||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
def cmds = []
|
||||
|
||||
|
||||
cmds += zwave.wakeUpV2.wakeUpIntervalSet(seconds: 7200, nodeid: zwaveHubNodeId)//FGMS' default wake up interval
|
||||
cmds += zwave.manufacturerSpecificV2.manufacturerSpecificGet()
|
||||
cmds += zwave.manufacturerSpecificV2.deviceSpecificGet()
|
||||
@@ -252,7 +255,7 @@ def configure() {
|
||||
cmds += zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0)
|
||||
cmds += zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 3, scale: 1)
|
||||
cmds += zwave.wakeUpV2.wakeUpNoMoreInformation()
|
||||
|
||||
|
||||
encapSequence(cmds, 500)
|
||||
}
|
||||
|
||||
|
||||
@@ -112,10 +112,10 @@ metadata {
|
||||
multiAttributeTile(name:"dtlsDoorCtrl", type:"generic", width:6, height:4) {tileAttribute("device.doorState", key: "PRIMARY_CONTROL")
|
||||
{
|
||||
attributeState "unknown", label: '${name}', action:"openDoor", icon: "st.secondary.tools", nextState:"Sent"
|
||||
attributeState "open", label: '${name}', action:"closeDoor", icon: "st.doors.garage.garage-open", backgroundColor: "#0000ff", nextState:"Sent"
|
||||
attributeState "opening", label: '${name}', action:"closeDoor", icon: "st.doors.garage.garage-opening", backgroundColor: "#ffa81e"
|
||||
attributeState "closed", label: '${name}', action:"openDoor", icon: "st.doors.garage.garage-closed", backgroundColor: "#79b821", nextState:"Sent"
|
||||
attributeState "closing", label: '${name}', action:"openDoor", icon: "st.doors.garage.garage-closing", backgroundColor: "#ffa81e"
|
||||
attributeState "open", label: '${name}', action:"closeDoor", icon: "st.doors.garage.garage-open", backgroundColor: "#00A0DC", nextState:"Sent"
|
||||
attributeState "opening", label: '${name}', action:"closeDoor", icon: "st.doors.garage.garage-opening", backgroundColor: "#00A0DC"
|
||||
attributeState "closed", label: '${name}', action:"openDoor", icon: "st.doors.garage.garage-closed", backgroundColor: "#ffffff", nextState:"Sent"
|
||||
attributeState "closing", label: '${name}', action:"openDoor", icon: "st.doors.garage.garage-closing", backgroundColor: "#ffffff"
|
||||
attributeState "jammed", label: '${name}', action:"closeDoorHiI", icon: "st.doors.garage.garage-open", backgroundColor: "#ff0000", nextState:"Sent"
|
||||
attributeState "forced close", label: "forced", action:"openDoor", icon: "st.doors.garage.garage-closed", backgroundColor: "#ff8000", nextState:"Sent"
|
||||
attributeState "fault", label: 'FAULT', action:"openDoor", icon: "st.secondary.tools", backgroundColor: "#ff0000", nextState:"Sent"
|
||||
|
||||
@@ -24,7 +24,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("sleeping", "device.sleeping", width: 1, height: 1, canChangeIcon: false, canChangeBackground: false) {
|
||||
state("sleeping", label: "Sleeping", icon:"st.Bedroom.bedroom12", backgroundColor:"#ffffff")
|
||||
state("not sleeping", label: "Awake", icon:"st.Health & Wellness.health12", backgroundColor:"#79b821")
|
||||
state("not sleeping", label: "Awake", icon:"st.Health & Wellness.health12", backgroundColor:"#00A0DC")
|
||||
}
|
||||
standardTile("steps", "device.steps", width: 2, height: 2, canChangeIcon: false, canChangeBackground: false) {
|
||||
state("steps", label: '${currentValue} Steps', icon:"st.Health & Wellness.health11", backgroundColor:"#ffffff")
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
39
devicetypes/keen-home/keen-home-smart-vent.src/README.md
Normal file
39
devicetypes/keen-home/keen-home-smart-vent.src/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Keen Home Smart Vent
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [Keen Home Smart Vent](https://www.smartthings.com/works-with-smartthings/keen-home/keen-home-smart-vent)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Troubleshooting](#Troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Switch** - can detect state (possible values: on/off)
|
||||
* **Switch Level** - represents current light level, usually 0-100 in percent
|
||||
* **Sensor** - detects sensor events
|
||||
* **Temperature Measurement** - represents capability to measure temperature
|
||||
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
|
||||
* **Battery** - defines device uses a battery
|
||||
* **Refresh** - _refresh()_ command for status updates
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
## Device Health
|
||||
|
||||
Keen Home Smart Vent with reporting interval of 10 mins.
|
||||
SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE`
|
||||
|
||||
* __22min__ checkInterval
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the sensor is out of range.
|
||||
Pairing needs to be tried again by placing the sensor closer to the hub.
|
||||
Instructions related to pairing, resetting and removing the different motion sensors from SmartThings can be found in the following links
|
||||
for the different models:
|
||||
* [Keen Home Smart Vent Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/205302050-Keen-Home-Smart-Vent)
|
||||
@@ -11,6 +11,7 @@ metadata {
|
||||
capability "Sensor"
|
||||
capability "Temperature Measurement"
|
||||
capability "Battery"
|
||||
capability "Health Check"
|
||||
|
||||
command "getLevel"
|
||||
command "getOnOff"
|
||||
@@ -20,10 +21,7 @@ metadata {
|
||||
command "setZigBeeIdTile"
|
||||
command "clearObstruction"
|
||||
|
||||
fingerprint endpoint: "1",
|
||||
profileId: "0104",
|
||||
inClusters: "0000,0001,0003,0004,0005,0006,0008,0020,0402,0403,0B05,FC01,FC02",
|
||||
outClusters: "0019"
|
||||
fingerprint endpoint: "1", profileId: "0104", inClusters: "0000,0001,0003,0004,0005,0006,0008,0020,0402,0403,0B05,FC01,FC02", outClusters: "0019"
|
||||
}
|
||||
|
||||
// simulator metadata
|
||||
@@ -40,10 +38,10 @@ metadata {
|
||||
// UI tile definitions
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", action: "switch.off", icon: "st.vents.vent-open-text", backgroundColor: "#53a7c0"
|
||||
state "on", action: "switch.off", icon: "st.vents.vent-open-text", backgroundColor: "#00a0dc"
|
||||
state "off", action: "switch.on", icon: "st.vents.vent-closed", backgroundColor: "#ffffff"
|
||||
state "obstructed", action: "clearObstruction", icon: "st.vents.vent-closed", backgroundColor: "#ff0000"
|
||||
state "clearing", action: "", icon: "st.vents.vent-closed", backgroundColor: "#ffff33"
|
||||
state "obstructed", action: "clearObstruction", icon: "st.vents.vent-closed", backgroundColor: "#e86d13"
|
||||
state "clearing", action: "", icon: "st.vents.vent-closed", backgroundColor: "#ffffff"
|
||||
}
|
||||
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false) {
|
||||
state "level", action:"switch level.setLevel"
|
||||
@@ -466,15 +464,27 @@ def refresh() {
|
||||
getBattery()
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
def ping() {
|
||||
return refresh()
|
||||
}
|
||||
|
||||
def configure() {
|
||||
log.debug "CONFIGURE"
|
||||
|
||||
// Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time)
|
||||
// enrolls with default periodic reporting until newer 5 min interval is confirmed
|
||||
sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
// get ZigBee ID by hidden tile because that's the only way we can do it
|
||||
setZigBeeIdTile()
|
||||
|
||||
def configCmds = [
|
||||
// bind reporting clusters to hub
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0006 {${device.zigbeeId}} {}", "delay 500",
|
||||
//commenting out switch cluster bind as using wrapper onOffConfig of zigbee class
|
||||
//"zdo bind 0x${device.deviceNetworkId} 1 1 0x0006 {${device.zigbeeId}} {}", "delay 500",
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0008 {${device.zigbeeId}} {}", "delay 500",
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0402 {${device.zigbeeId}} {}", "delay 500",
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0403 {${device.zigbeeId}} {}", "delay 500",
|
||||
@@ -510,5 +520,5 @@ def configure() {
|
||||
// "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
|
||||
]
|
||||
|
||||
return configCmds + refresh()
|
||||
return configCmds + zigbee.onOffConfig() + refresh()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/**
|
||||
* Spruce Controller - Pre Release V2 10/11/2015
|
||||
*
|
||||
* Spruce Controller V2_4 Big Tiles *
|
||||
* Copyright 2015 Plaid Systems
|
||||
*
|
||||
* Author: NC
|
||||
@@ -21,82 +20,96 @@
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "Spruce Controller", namespace: "plaidsystems", author: "NCauffman") {
|
||||
capability "Switch"
|
||||
capability "Configuration"
|
||||
capability "Refresh"
|
||||
capability "Actuator"
|
||||
capability "Valve"
|
||||
definition (name: 'Spruce Controller', namespace: 'plaidsystems', author: 'Plaid Systems') {
|
||||
capability 'Switch'
|
||||
capability 'Configuration'
|
||||
capability 'Refresh'
|
||||
capability 'Actuator'
|
||||
capability 'Valve'
|
||||
|
||||
attribute "switch", "string"
|
||||
attribute "switch1", "string"
|
||||
attribute "switch2", "string"
|
||||
attribute "switch8", "string"
|
||||
attribute "switch5", "string"
|
||||
attribute "switch3", "string"
|
||||
attribute "switch4", "string"
|
||||
attribute "switch6", "string"
|
||||
attribute "switch7", "string"
|
||||
attribute "switch9", "string"
|
||||
attribute "switch10", "string"
|
||||
attribute "switch11", "string"
|
||||
attribute "switch12", "string"
|
||||
attribute "switch13", "string"
|
||||
attribute "switch14", "string"
|
||||
attribute "switch15", "string"
|
||||
attribute "switch16", "string"
|
||||
attribute "status", "string"
|
||||
attribute 'switch', 'string'
|
||||
attribute 'switch1', 'string'
|
||||
attribute 'switch2', 'string'
|
||||
attribute 'switch8', 'string'
|
||||
attribute 'switch5', 'string'
|
||||
attribute 'switch3', 'string'
|
||||
attribute 'switch4', 'string'
|
||||
attribute 'switch6', 'string'
|
||||
attribute 'switch7', 'string'
|
||||
attribute 'switch9', 'string'
|
||||
attribute 'switch10', 'string'
|
||||
attribute 'switch11', 'string'
|
||||
attribute 'switch12', 'string'
|
||||
attribute 'switch13', 'string'
|
||||
attribute 'switch14', 'string'
|
||||
attribute 'switch15', 'string'
|
||||
attribute 'switch16', 'string'
|
||||
attribute 'rainsensor', 'string'
|
||||
attribute 'status', 'string'
|
||||
attribute 'tileMessage', 'string'
|
||||
attribute 'minutes', 'string'
|
||||
attribute 'VALUE_UP', 'string'
|
||||
attribute 'VALUE_DOWN', 'string'
|
||||
|
||||
command "programOn"
|
||||
command "programOff"
|
||||
command "on"
|
||||
command "off"
|
||||
command "z1on"
|
||||
command "z1off"
|
||||
command "z2on"
|
||||
command "z2off"
|
||||
command "z3on"
|
||||
command "z3off"
|
||||
command "z4on"
|
||||
command "z4off"
|
||||
command "z5on"
|
||||
command "z5off"
|
||||
command "z6on"
|
||||
command "z6off"
|
||||
command "z7on"
|
||||
command "z7off"
|
||||
command "z8on"
|
||||
command "z8off"
|
||||
command "z9on"
|
||||
command "z9off"
|
||||
command "z10on"
|
||||
command "z10off"
|
||||
command "z11on"
|
||||
command "z11off"
|
||||
command "z12on"
|
||||
command "z12off"
|
||||
command "z13on"
|
||||
command "z13off"
|
||||
command "z14on"
|
||||
command "z14off"
|
||||
command "z15on"
|
||||
command "z15off"
|
||||
command "z16on"
|
||||
command "z16off"
|
||||
command "offtime"
|
||||
command 'levelUp'
|
||||
command 'levelDown'
|
||||
command 'programOn'
|
||||
command 'programOff'
|
||||
command 'programWait'
|
||||
command 'programEnd'
|
||||
|
||||
command "refresh"
|
||||
command "rain"
|
||||
command "manual"
|
||||
command "setDisplay"
|
||||
command 'on'
|
||||
command 'off'
|
||||
command 'zon'
|
||||
command 'zoff'
|
||||
command 'z1on'
|
||||
command 'z1off'
|
||||
command 'z2on'
|
||||
command 'z2off'
|
||||
command 'z3on'
|
||||
command 'z3off'
|
||||
command 'z4on'
|
||||
command 'z4off'
|
||||
command 'z5on'
|
||||
command 'z5off'
|
||||
command 'z6on'
|
||||
command 'z6off'
|
||||
command 'z7on'
|
||||
command 'z7off'
|
||||
command 'z8on'
|
||||
command 'z8off'
|
||||
command 'z9on'
|
||||
command 'z9off'
|
||||
command 'z10on'
|
||||
command 'z10off'
|
||||
command 'z11on'
|
||||
command 'z11off'
|
||||
command 'z12on'
|
||||
command 'z12off'
|
||||
command 'z13on'
|
||||
command 'z13off'
|
||||
command 'z14on'
|
||||
command 'z14off'
|
||||
command 'z15on'
|
||||
command 'z15off'
|
||||
command 'z16on'
|
||||
command 'z16off'
|
||||
|
||||
command "settingsMap"
|
||||
command "writeTime"
|
||||
command "writeType"
|
||||
command "notify"
|
||||
command "updated"
|
||||
|
||||
fingerprint endpointId: "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18", profileId: "0104", deviceId: "0002", deviceVersion: "00", inClusters: "0000,0003,0004,0005,0006,000F", outClusters: "0003, 0019", manufacturer: "PLAID SYSTEMS", model: "PS-SPRZ16-01"
|
||||
command 'config'
|
||||
command 'refresh'
|
||||
command 'rain'
|
||||
command 'manual'
|
||||
command 'manualTime'
|
||||
command 'settingsMap'
|
||||
command 'writeTime'
|
||||
command 'writeType'
|
||||
command 'notify'
|
||||
command 'updated'
|
||||
|
||||
//ST release
|
||||
//fingerprint endpointId: '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18', profileId: '0104', deviceId: '0002', deviceVersion: '00', inClusters: '0000,0003,0004,0005,0006,000F', outClusters: '0003, 0019', manufacturer: 'PLAID SYSTEMS', model: 'PS-SPRZ16-01'
|
||||
//new release
|
||||
fingerprint endpointId: "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18", profileId: "0104", deviceId: "0002", deviceVersion: "00", inClusters: "0000,0003,0004,0005,0006,0009,000A,000F", outClusters: "0003, 0019", manufacturer: "PLAID SYSTEMS", model: "PS-SPRZ16-01"
|
||||
|
||||
}
|
||||
|
||||
@@ -104,162 +117,230 @@ metadata {
|
||||
simulator {
|
||||
// status messages
|
||||
|
||||
// reply messages
|
||||
|
||||
// reply messages
|
||||
}
|
||||
|
||||
preferences {
|
||||
input description: "Press Configure button after making changes to these preferences", displayDuringSetup: true, type: "paragraph", element: "paragraph", title: ""
|
||||
input "RainEnable", "bool", title: "Rain Sensor Attached?", required: false, displayDuringSetup: true
|
||||
input "ManualTime", "number", title: "Automatic shutoff time when a zone is turned on manually?", required: false, displayDuringSetup: true
|
||||
}
|
||||
input description: 'If you have a rain sensor wired to the rain sensor input on the Spruce controller, turn it on here.', displayDuringSetup: true, type: 'paragraph', element: 'paragraph', title: 'Rain Sensor'
|
||||
input description: 'The SYNC SETTINGS button must be pressed after making a change to the Rain sensor:', displayDuringSetup: false, type: 'paragraph', element: 'paragraph', title: ''
|
||||
input 'RainEnable', 'bool', title: 'Rain Sensor Attached?', required: false, displayDuringSetup: true
|
||||
input description: 'Adjust manual water time with arrows on main tile. The time indicated in the first small tile indicates the time the zone will water when manually switched on.', displayDuringSetup: false, type: 'paragraph', element: 'paragraph', title: ''
|
||||
}
|
||||
|
||||
// UI tile definitions
|
||||
tiles {
|
||||
|
||||
standardTile("status", "device.status") {
|
||||
state "schedule", label: 'Schedule Set', icon: "http://www.plaidsystems.com/smartthings/st_spruce_leaf_225_t.png"
|
||||
state "finished", label: 'Spruce Finished', icon: "st.Outdoor.outdoor5", backgroundColor: "#46c2e8"
|
||||
state "raintoday", label: 'Rain Today', icon: "st.custom.wuk.nt_chancerain"
|
||||
state "rainy", label: 'Previous Rain', icon: "st.custom.wuk.nt_chancerain"
|
||||
state "raintom", label: 'Rain Tomorrow', icon: "st.custom.wuk.nt_chancerain"
|
||||
state "donewweek", label: 'Spruce Finished', icon: "st.Outdoor.outdoor5", backgroundColor: "#52c435"
|
||||
state "skipping", label: 'Skip Today', icon: "st.Outdoor.outdoor20", backgroundColor: "#36cfe3"
|
||||
state "moisture", label: '', icon: "st.Weather.weather2", backgroundColor: "#36cfe3"
|
||||
state "pause", label: 'PAUSE', icon: "st.contact.contact.open", backgroundColor: "#f2a51f"
|
||||
state "active", label: 'Active', icon: "st.Outdoor.outdoor12", backgroundColor: "#3DC72E"
|
||||
state "season", label: 'Seasonal Adjustment', icon: "st.Outdoor.outdoor17", backgroundColor: "#ffb900"
|
||||
state "disable", label: 'Disabled', icon: "st.secondary.off", backgroundColor: "#888888"
|
||||
state "warning", label: '', icon: "st.categories.damageAndDanger", backgroundColor: "#ffff7f"
|
||||
state "alarm", label: 'Alarm', icon: "st.categories.damageAndDanger", backgroundColor: "#f9240c"
|
||||
multiAttributeTile(name:"switchall", type:"generic", width:6, height:4) {
|
||||
tileAttribute('device.status', key: 'PRIMARY_CONTROL') {
|
||||
attributeState 'schedule', label: 'Ready', icon: 'http://www.plaidsystems.com/smartthings/st_spruce_leaf_225_top.png'
|
||||
attributeState 'finished', label: 'Finished', icon: 'st.Outdoor.outdoor5', backgroundColor: '#46c2e8'
|
||||
attributeState 'raintoday', label: 'Rain Today', icon: 'http://www.plaidsystems.com/smartthings/st_rain.png', backgroundColor: '#d65fe3'
|
||||
attributeState 'rainy', label: 'Rain', icon: 'http://www.plaidsystems.com/smartthings/st_rain.png', backgroundColor: '#d65fe3'
|
||||
attributeState 'raintom', label: 'Rain Tomorrow', icon: 'http://www.plaidsystems.com/smartthings/st_rain.png', backgroundColor: '#d65fe3'
|
||||
attributeState 'donewweek', label: 'Finished', icon: 'st.Outdoor.outdoor5', backgroundColor: '#00A0DC'
|
||||
attributeState 'skipping', label: 'Skip', icon: 'st.Outdoor.outdoor20', backgroundColor: '#46c2e8'
|
||||
attributeState 'moisture', label: 'Ready', icon: 'st.Weather.weather2', backgroundColor: '#46c2e8'
|
||||
attributeState 'pause', label: 'PAUSE', icon: 'st.contact.contact.open', backgroundColor: '#e86d13'
|
||||
attributeState 'delayed', label: 'Delayed', icon: 'st.contact.contact.open', backgroundColor: '#e86d13'
|
||||
attributeState 'active', label: 'Active', icon: 'st.Outdoor.outdoor12', backgroundColor: '#3DC72E'
|
||||
attributeState 'season', label: 'Adjust', icon: 'st.Outdoor.outdoor17', backgroundColor: '#ffb900'
|
||||
attributeState 'disable', label: 'Off', icon: 'st.secondary.off', backgroundColor: '#cccccc'
|
||||
attributeState 'warning', label: 'Warning', icon: 'http://www.plaidsystems.com/smartthings/st_spruce_leaf_225_top_yellow.png'
|
||||
attributeState 'alarm', label: 'Alarm', icon: 'http://www.plaidsystems.com/smartthings/st_spruce_leaf_225_s_red.png', backgroundColor: '#e66565'
|
||||
}
|
||||
|
||||
tileAttribute("device.minutes", key: "VALUE_CONTROL") {
|
||||
attributeState "VALUE_UP", action: "levelUp"
|
||||
attributeState "VALUE_DOWN", action: "levelDown"
|
||||
}
|
||||
|
||||
tileAttribute("device.tileMessage", key: "SECONDARY_CONTROL") {
|
||||
attributeState "tileMessage", label: '${currentValue}'
|
||||
}
|
||||
|
||||
}
|
||||
standardTile("switch", "device.switch") {
|
||||
//state "programOff", label: 'Start Program', action: "programOn", icon: "st.sonos.play-icon", backgroundColor: "#a9a9a9"
|
||||
state "off", label: 'Start Program', action: "programOn", icon: "st.sonos.play-icon", backgroundColor: "#a9a9a9"
|
||||
state "programOn", label: 'Initialize Program', action: "programOff", icon: "st.contact.contact.open", backgroundColor: "#f6e10e"
|
||||
state "on", label: 'Program Running', action: "off", icon: "st.Outdoor.outdoor12", backgroundColor: "#3DC72E"
|
||||
}
|
||||
standardTile("rainsensor", "device.rainsensor") {
|
||||
state "rainSensrooff", label: 'Rain Sensor Clear', icon: "st.Weather.weather14", backgroundColor: "#a9a9a9"
|
||||
state "rainSensoron", label: 'Rain Detected', icon: "st.Weather.weather10", backgroundColor: "#f6e10e"
|
||||
}
|
||||
standardTile("switch1", "device.switch1") {
|
||||
state "z1off", label: '1', action: "z1on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z1on", label: '1', action: "z1off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
}
|
||||
standardTile("switch2", "device.switch2") {
|
||||
state "z2off", label: '2', action: "z2on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z2on", label: '2', action: "z2off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
valueTile('minutes', 'device.minutes'){
|
||||
state 'minutes', label: '${currentValue} min'
|
||||
}
|
||||
valueTile('dummy', 'device.minutes'){
|
||||
state 'minutes', label: ''
|
||||
}
|
||||
standardTile('switch', 'device.switch', width:2, height:2) {
|
||||
state 'off', label: 'Start', action: 'programOn', icon: 'st.Outdoor.outdoor12', backgroundColor: '#a9a9a9'
|
||||
state 'programOn', label: 'Wait', action: 'programOff', icon: 'st.contact.contact.open', backgroundColor: '#f6e10e'
|
||||
state 'programWait', label: 'Wait', action: 'programEnd', icon: 'st.contact.contact.open', backgroundColor: '#f6e10e'
|
||||
state 'on', label: 'Running', action: 'programEnd', icon: 'st.Outdoor.outdoor12', backgroundColor: '#3DC72E'
|
||||
}
|
||||
standardTile("switch3", "device.switch3", inactiveLabel: false) {
|
||||
state "z3off", label: '3', action: "z3on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z3on", label: '3', action: "z3off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
standardTile("rainsensor", "device.rainsensor", decoration: 'flat') {
|
||||
state "rainSensoroff", label: 'sensor', icon: 'http://www.plaidsystems.com/smartthings/st_drop_on.png'
|
||||
state "rainSensoron", label: 'sensor', icon: 'http://www.plaidsystems.com/smartthings/st_drop_on_blue_small.png'
|
||||
state "disable", label: 'sensor', icon: 'http://www.plaidsystems.com/smartthings/st_drop_x_small.png'
|
||||
state "enable", label: 'sensor', icon: 'http://www.plaidsystems.com/smartthings/st_drop_on.png'
|
||||
}
|
||||
standardTile("switch4", "device.switch4", inactiveLabel: false) {
|
||||
state "z4off", label: '4', action: "z4on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z4on", label: '4', action: "z4off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
standardTile('switch1', 'device.switch1', inactiveLabel: false) {
|
||||
state 'z1off', label: '1', action: 'z1on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z1on', label: '1', action: 'z1off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile("switch5", "device.switch5", inactiveLabel: false) {
|
||||
state "z5off", label: '5', action: "z5on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z5on", label: '5', action: "z5off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
}
|
||||
standardTile("switch6", "device.switch6", inactiveLabel: false) {
|
||||
state "z6off", label: '6', action: "z6on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z6on", label: '6', action: "z6off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
}
|
||||
standardTile("switch7", "device.switch7", inactiveLabel: false) {
|
||||
state "z7off", label: '7', action: "z7on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z7on", label: '7', action: "z7off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
}
|
||||
standardTile("switch8", "device.switch8", inactiveLabel: false) {
|
||||
state "z8off", label: '8', action: "z8on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z8on", label: '8', action: "z8off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
}
|
||||
standardTile("switch9", "device.switch9", inactiveLabel: false) {
|
||||
state "z9off", label: '9', action: "z9on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z9on", label: '9', action: "z9off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
}
|
||||
standardTile("switch10", "device.switch10", inactiveLabel: false) {
|
||||
state "z10off", label: '10', action: "z10on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z10on", label: '10', action: "z10off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
standardTile('switch2', 'device.switch2', inactiveLabel: false) {
|
||||
state 'z2off', label: '2', action: 'z2on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z2on', label: '2', action: 'z2off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile("switch11", "device.switch11", inactiveLabel: false) {
|
||||
state "z11off", label: '11', action: "z11on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z11on", label: '11', action: "z11off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
standardTile('switch3', 'device.switch3', inactiveLabel: false) {
|
||||
state 'z3off', label: '3', action: 'z3on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z3on', label: '3', action: 'z3off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile("switch12", "device.switch12", inactiveLabel: false) {
|
||||
state "z12off", label: '12', action: "z12on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z12on", label: '12', action: "z12off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
standardTile('switch4', 'device.switch4', inactiveLabel: false) {
|
||||
state 'z4off', label: '4', action: 'z4on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z4on', label: '4', action: 'z4off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile("switch13", "device.switch13", inactiveLabel: false) {
|
||||
state "z13off", label: '13', action: "z13on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z13on", label: '13', action: "z13off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
standardTile('switch5', 'device.switch5', inactiveLabel: false) {
|
||||
state 'z5off', label: '5', action: 'z5on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z5on', label: '5', action: 'z5off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile("switch14", "device.switch14", inactiveLabel: false) {
|
||||
state "z14off", label: '14', action: "z14on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z14on", label: '14', action: "z14off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
standardTile('switch6', 'device.switch6', inactiveLabel: false) {
|
||||
state 'z6off', label: '6', action: 'z6on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z6on', label: '6', action: 'z6off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile("switch15", "device.switch15", inactiveLabel: false) {
|
||||
state "z15off", label: '15', action: "z15on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z15on", label: '15', action: "z15off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
standardTile('switch7', 'device.switch7', inactiveLabel: false) {
|
||||
state 'z7off', label: '7', action: 'z7on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z7on', label: '7', action: 'z7off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile('switch8', 'device.switch8', inactiveLabel: false) {
|
||||
state 'z8off', label: '8', action: 'z8on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z8on', label: '8', action: 'z8off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile('switch9', 'device.switch9', inactiveLabel: false) {
|
||||
state 'z9off', label: '9', action: 'z9on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z9on', label: '9', action: 'z9off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile('switch10', 'device.switch10', inactiveLabel: false) {
|
||||
state 'z10off', label: '10', action: 'z10on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z10on', label: '10', action: 'z10off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile('switch11', 'device.switch11', inactiveLabel: false) {
|
||||
state 'z11off', label: '11', action: 'z11on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z11on', label: '11', action: 'z11off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile('switch12', 'device.switch12', inactiveLabel: false) {
|
||||
state 'z12off', label: '12', action: 'z12on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z12on', label: '12', action: 'z12off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile('switch13', 'device.switch13', inactiveLabel: false) {
|
||||
state 'z13off', label: '13', action: 'z13on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z13on', label: '13', action: 'z13off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile('switch14', 'device.switch14', inactiveLabel: false) {
|
||||
state 'z14off', label: '14', action: 'z14on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z14on', label: '14', action: 'z14off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile('switch15', 'device.switch15', inactiveLabel: false) {
|
||||
state 'z15off', label: '15', action: 'z15on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z15on', label: '15', action: 'z15off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile("switch16", "device.switch16", inactiveLabel: false) {
|
||||
state "z16off", label: '16', action: "z16on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
state "z16on", label: '16', action: "z16off", icon: "st.valves.water.open", backgroundColor: "#46c2e8"
|
||||
standardTile('switch16', 'device.switch16', inactiveLabel: false) {
|
||||
state 'z16off', label: '16', action: 'z16on', icon: 'st.valves.water.closed', backgroundColor: '#ffffff'
|
||||
state 'z16on', label: '16', action: 'z16off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", action: "refresh", icon:"st.secondary.refresh"
|
||||
standardTile('refresh', 'device.switch', inactiveLabel: false, decoration: 'flat') {
|
||||
state 'default', action: 'refresh', icon:'st.secondary.refresh'//-icon'
|
||||
}
|
||||
standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
|
||||
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
|
||||
}
|
||||
standardTile('configure', 'device.configure', inactiveLabel: false, decoration: 'flat') {
|
||||
state 'configure', label:'', action:'configuration.configure', icon:'http://www.plaidsystems.com/smartthings/st_syncsettings.png'//sync_icon_small.png'
|
||||
}
|
||||
|
||||
main (["status"])
|
||||
details(["status","rainsensor","switch","switch1","switch2","switch3","switch4","switch5","switch6","switch7","switch8","switch9","switch10","switch11","switch12","switch13","switch14","switch15","switch16","refresh","configure"])
|
||||
}
|
||||
main (['switchall'])
|
||||
details(['switchall','minutes','rainsensor','switch1','switch2','switch3','switch4','switch','switch5','switch6','switch7','switch8','switch9','switch10','switch11','switch12','refresh','configure','switch13','switch14','switch15','switch16'])
|
||||
}
|
||||
}
|
||||
|
||||
//used for schedule
|
||||
def programOn(){
|
||||
sendEvent(name: "switch", value: "programOn", descriptionText: "Program turned on")
|
||||
sendEvent(name: 'switch', value: 'programOn', descriptionText: 'Program turned on')
|
||||
}
|
||||
|
||||
def programWait(){
|
||||
sendEvent(name: 'switch', value: 'programWait', descriptionText: "Initializing Schedule")
|
||||
}
|
||||
|
||||
def programEnd(){
|
||||
//sets switch to off and tells schedule switch is off/schedule complete with manaual
|
||||
sendEvent(name: 'switch', value: 'off', descriptionText: 'Program manually turned off')
|
||||
zoff()
|
||||
}
|
||||
|
||||
def programOff(){
|
||||
sendEvent(name: "switch", value: "off", descriptionText: "Program turned off")
|
||||
sendEvent(name: 'switch', value: 'off', descriptionText: 'Program turned off')
|
||||
off()
|
||||
}
|
||||
|
||||
def updated(){
|
||||
log.debug "updated"
|
||||
|
||||
//set minutes
|
||||
def levelUp(){
|
||||
def newvalue = 1
|
||||
if (device.latestValue('minutes') != null) newvalue = device.latestValue('minutes').toInteger()+1
|
||||
if (newvalue >= 60) newvalue = 60
|
||||
def value = newvalue.toString()
|
||||
log.debug value
|
||||
sendEvent(name: 'minutes', value: "${value}", descriptionText: "Manual Time set to ${value}", display: false)
|
||||
}
|
||||
|
||||
def levelDown(){
|
||||
def newvalue = device.latestValue('minutes').toInteger()-1
|
||||
if (newvalue <= 0) newvalue = 1
|
||||
def value = newvalue.toString()
|
||||
log.debug value
|
||||
sendEvent(name: 'minutes', value: "${value}", descriptionText: "Manual Time set to ${value}", display: false)
|
||||
}
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
def parse(String description) {
|
||||
//log.debug "Parse description $description"
|
||||
log.debug "Parse description ${description}"
|
||||
def result = null
|
||||
def map = [:]
|
||||
if (description?.startsWith("read attr -")) {
|
||||
if (description?.startsWith('read attr -')) {
|
||||
def descMap = parseDescriptionAsMap(description)
|
||||
//log.debug "Desc Map: $descMap"
|
||||
//using 000F cluster instead of 0006 (switch) because ST does not differentiate between EPs and processes all as switch
|
||||
if (descMap.cluster == "000F" && descMap.attrId == "0055") {
|
||||
log.debug "Zone"
|
||||
if (descMap.cluster == '000F' && descMap.attrId == '0055') {
|
||||
log.debug 'Zone'
|
||||
map = getZone(descMap)
|
||||
}
|
||||
else if (descMap.cluster == "0009" && descMap.attrId == "0000") {
|
||||
log.debug "Alarm"
|
||||
else if (descMap.cluster == '0009' && descMap.attrId == '0000') {
|
||||
log.debug 'Alarm'
|
||||
map = getAlarm(descMap)
|
||||
}
|
||||
}
|
||||
|
||||
if (map) {
|
||||
result = createEvent(map)
|
||||
}
|
||||
log.debug "Parse returned $map $result"
|
||||
else if (description?.startsWith('catchall: 0104 0009')){
|
||||
log.debug 'Sync settings to controller complete'
|
||||
if (device.latestValue('status') != 'alarm'){
|
||||
def configEvt = createEvent(name: 'status', value: 'schedule', descriptionText: "Sync settings to controller complete")
|
||||
def configMsg = createEvent(name: 'tileMessage', value: 'Sync settings to controller complete', descriptionText: "Sync settings to controller complete", displayed: false)
|
||||
result = [configEvt, configMsg]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
if (map) {
|
||||
result = createEvent(map)
|
||||
//configure after reboot
|
||||
if (map.value == 'warning' || map.value == 'alarm'){
|
||||
def cmds = config()
|
||||
def alarmEvt = createEvent(name: 'tileMessage', value: map.descriptionText, descriptionText: "${map.descriptionText}", displayed: false)
|
||||
result = cmds?.collect { new physicalgraph.device.HubAction(it) } + createEvent(map) + alarmEvt
|
||||
return result
|
||||
}
|
||||
else if (map.name == 'rainsensor'){
|
||||
def rainEvt = createEvent(name: 'tileMessage', value: map.descriptionText, descriptionText: "${map.descriptionText}", displayed: false)
|
||||
result = [createEvent(map), rainEvt]
|
||||
return result
|
||||
}
|
||||
}
|
||||
if (map) log.debug "Parse returned ${map} ${result}"
|
||||
return result
|
||||
}
|
||||
|
||||
def parseDescriptionAsMap(description) {
|
||||
(description - "read attr - ").split(",").inject([:]) { map, param ->
|
||||
def nameAndValue = param.split(":")
|
||||
(description - 'read attr - ').split(',').inject([:]) { map, param ->
|
||||
def nameAndValue = param.split(':')
|
||||
map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
|
||||
}
|
||||
}
|
||||
@@ -270,27 +351,28 @@ def getZone(descMap){
|
||||
def EP = Integer.parseInt(descMap.endpoint.trim(), 16)
|
||||
|
||||
String onoff
|
||||
if(descMap.value == "00"){
|
||||
onoff = "off"
|
||||
if(descMap.value == '00'){
|
||||
onoff = 'off'
|
||||
}
|
||||
else onoff = "on"
|
||||
else onoff = 'on'
|
||||
|
||||
if (EP == 1){
|
||||
map.name = "switch"
|
||||
map.name = 'switch'
|
||||
map.value = onoff
|
||||
map.descriptionText = "${device.displayName} turned sprinkler program $onoff"
|
||||
map.descriptionText = "${device.displayName} turned sprinkler program ${onoff}"
|
||||
}
|
||||
|
||||
else if (EP == 18) {
|
||||
map.name = "rainsensor"
|
||||
map.value = "rainSensor" + onoff
|
||||
map.descriptionText = "${device.displayName} rain sensor is $onoff"
|
||||
map.name = 'rainsensor'
|
||||
log.debug "Rain enable: ${RainEnable}, sensor: ${onoff}"
|
||||
map.value = 'rainSensor' + onoff
|
||||
map.descriptionText = "${device.displayName} rain sensor is ${onoff}"
|
||||
}
|
||||
else {
|
||||
EP -= 1
|
||||
map.name = "switch" + EP
|
||||
map.value = "z" + EP + onoff
|
||||
map.descriptionText = "${device.displayName} turned Zone $EP $onoff"
|
||||
map.name = 'switch' + EP
|
||||
map.value = 'z' + EP + onoff
|
||||
map.descriptionText = "${device.displayName} turned Zone $EP ${onoff}"
|
||||
}
|
||||
|
||||
map.isStateChange = true
|
||||
@@ -300,37 +382,59 @@ def getZone(descMap){
|
||||
|
||||
def getAlarm(descMap){
|
||||
def map = [:]
|
||||
map.name = "status"
|
||||
map.name = 'status'
|
||||
def alarmID = Integer.parseInt(descMap.value.trim(), 16)
|
||||
log.debug "${alarmID}"
|
||||
if(alarmID <= 0) map.descriptionText = "${device.displayName} has rebooted, no other alarms"
|
||||
else map.descriptionText = "${device.displayName} rebooted, reported error on zone ${alarmID - 1}, please check zone is working correctly"
|
||||
map.value = "alarm"
|
||||
map.isStateChange = true
|
||||
map.value = 'alarm'
|
||||
map.displayed = true
|
||||
map.isStateChange = true
|
||||
if(alarmID <= 0){
|
||||
map.descriptionText = "${device.displayName} reboot, no other alarms"
|
||||
map.value = 'warning'
|
||||
//map.isStateChange = false
|
||||
}
|
||||
else map.descriptionText = "${device.displayName} reboot, reported zone ${alarmID - 1} error, please check zone is working correctly, press SYNC SETTINGS button to clear"
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
//status notify and change status
|
||||
def notify(value, text){
|
||||
sendEvent(name:"status", value:"$value", descriptionText:"$text", isStateChange: true, display: false)
|
||||
def notify(String val, String txt){
|
||||
sendEvent(name: 'status', value: val, descriptionText: txt, isStateChange: true, display: false)
|
||||
|
||||
//String txtShort = txt.take(100)
|
||||
sendEvent(name: 'tileMessage', value: txt, descriptionText: "", isStateChange: true, display: false)
|
||||
}
|
||||
|
||||
def updated(){
|
||||
log.debug "updated"
|
||||
|
||||
}
|
||||
|
||||
//prefrences - rain sensor, manual time
|
||||
def rain() {
|
||||
log.debug "Rain $RainEnable"
|
||||
log.debug "Rain sensor: ${RainEnable}"
|
||||
if (RainEnable) sendEvent(name: 'rainsensor', value: 'enable', descriptionText: "${device.displayName} rain sensor is enabled", isStateChange: true)
|
||||
else sendEvent(name: 'rainsensor', value: 'disable', descriptionText: "${device.displayName} rain sensor is disabled", isStateChange: true)
|
||||
|
||||
if (RainEnable) "st wattr 0x${device.deviceNetworkId} 18 0x0F 0x51 0x10 {01}"
|
||||
else "st wattr 0x${device.deviceNetworkId} 18 0x0F 0x51 0x10 {00}"
|
||||
}
|
||||
def manual(){
|
||||
log.debug "Time $ManualTime"
|
||||
def mTime = 10
|
||||
if (ManualTime) mTime = ManualTime
|
||||
def manualTime = hex(mTime)
|
||||
"st wattr 0x${device.deviceNetworkId} 1 6 0x4002 0x21 {00${manualTime}}"
|
||||
|
||||
def manualTime(value){
|
||||
sendEvent(name: 'minutes', value: "${value}", descriptionText: "Manual Time set to ${value}", display: false)
|
||||
}
|
||||
|
||||
def manual(){
|
||||
def newManaul = 10
|
||||
if (device.latestValue('minutes')) newManaul = device.latestValue('minutes').toInteger()
|
||||
log.debug "Manual Zone runtime ${newManaul} mins"
|
||||
def manualTime = hex(newManaul)
|
||||
|
||||
}
|
||||
def sendCmds = []
|
||||
sendCmds.push("st wattr 0x${device.deviceNetworkId} 1 6 0x4002 0x21 {00${manualTime}}")
|
||||
return sendCmds
|
||||
}
|
||||
|
||||
//write switch time settings map
|
||||
def settingsMap(WriteTimes, attrType){
|
||||
@@ -366,13 +470,20 @@ def writeTime(wEP, runTime){
|
||||
|
||||
//set reporting and binding
|
||||
def configure() {
|
||||
|
||||
sendEvent(name: 'status', value: 'schedule', descriptionText: "Syncing settings to controller")
|
||||
sendEvent(name: 'minutes', value: "10", descriptionText: "Manual Time set to 10 mins", display: false)
|
||||
sendEvent(name: 'tileMessage', value: 'Syncing settings to controller', descriptionText: 'Syncing settings to controller')
|
||||
config()
|
||||
}
|
||||
|
||||
def config(){
|
||||
|
||||
String zigbeeId = swapEndianHex(device.hub.zigbeeId)
|
||||
log.debug "Confuguring Reporting and Bindings ${device.deviceNetworkId} ${device.zigbeeId}"
|
||||
sendEvent(name: 'configuration',value: 100, descriptionText: "Configuration initialized")
|
||||
log.debug "Configuring Reporting and Bindings ${device.deviceNetworkId} ${device.zigbeeId}"
|
||||
|
||||
def configCmds = [
|
||||
//program on/off
|
||||
//program on/off
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 6 {${device.zigbeeId}} {}", "delay 1000",
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x09 {${device.zigbeeId}} {}", "delay 1000",
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0F {${device.zigbeeId}} {}", "delay 1000",
|
||||
@@ -458,38 +569,16 @@ def configure() {
|
||||
"zcl global send-me-a-report 0x09 0x00 0x21 1 0 {00}", "delay 500",
|
||||
"send 0x${device.deviceNetworkId} 1 1", "delay 500"
|
||||
]
|
||||
return configCmds + rain() + manual()
|
||||
return configCmds + rain()
|
||||
}
|
||||
|
||||
|
||||
|
||||
private hex(value) {
|
||||
new BigInteger(Math.round(value).toString()).toString(16)
|
||||
}
|
||||
|
||||
private String swapEndianHex(String hex) {
|
||||
reverseArray(hex.decodeHex()).encodeHex()
|
||||
}
|
||||
|
||||
private byte[] reverseArray(byte[] array) {
|
||||
int i = 0;
|
||||
int j = array.length - 1;
|
||||
byte tmp;
|
||||
while (j > i) {
|
||||
tmp = array[j];
|
||||
array[j] = array[i];
|
||||
array[i] = tmp;
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
|
||||
log.debug "refresh"
|
||||
def refreshCmds = [
|
||||
|
||||
log.debug "refresh pressed"
|
||||
sendEvent(name: 'tileMessage', value: 'Refresh', descriptionText: 'Refresh')
|
||||
|
||||
def refreshCmds = [
|
||||
|
||||
"st rattr 0x${device.deviceNetworkId} 1 0x0F 0x55", "delay 500",
|
||||
|
||||
"st rattr 0x${device.deviceNetworkId} 2 0x0F 0x55", "delay 500",
|
||||
@@ -513,64 +602,96 @@ def refresh() {
|
||||
"st rattr 0x${device.deviceNetworkId} 18 0x0F 0x51","delay 500",
|
||||
|
||||
]
|
||||
return refreshCmds + rain() + manual()
|
||||
|
||||
return refreshCmds
|
||||
}
|
||||
|
||||
private hex(value) {
|
||||
new BigInteger(Math.round(value).toString()).toString(16)
|
||||
}
|
||||
|
||||
private String swapEndianHex(String hex) {
|
||||
reverseArray(hex.decodeHex()).encodeHex()
|
||||
}
|
||||
|
||||
private byte[] reverseArray(byte[] array) {
|
||||
int i = 0;
|
||||
int j = array.length - 1;
|
||||
byte tmp;
|
||||
while (j > i) {
|
||||
tmp = array[j];
|
||||
array[j] = array[i];
|
||||
array[i] = tmp;
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
//on & off redefined for Alexa to start manual schedule
|
||||
def on() {
|
||||
log.debug 'Alexa on'
|
||||
//schedule subscribes to programOn
|
||||
sendEvent(name: 'switch', value: 'programOn', descriptionText: 'Alexa turned program on')
|
||||
}
|
||||
def off() {
|
||||
log.debug 'Alexa off'
|
||||
sendEvent(name: 'switch', value: 'off', descriptionText: 'Alexa turned program off')
|
||||
zoff()
|
||||
}
|
||||
|
||||
// Commands to device
|
||||
//zones on - 8
|
||||
def on() {
|
||||
//sendEvent(name:"status", value:"active", descriptionText:"Program Running", isStateChange: true, display: false)
|
||||
log.debug "on"
|
||||
"st cmd 0x${device.deviceNetworkId} 1 6 1 {}"
|
||||
def zon() {
|
||||
"st cmd 0x${device.deviceNetworkId} 1 6 1 {}"
|
||||
}
|
||||
def off() {
|
||||
log.debug "off"
|
||||
"st cmd 0x${device.deviceNetworkId} 1 6 0 {}"
|
||||
def zoff() {
|
||||
"st cmd 0x${device.deviceNetworkId} 1 6 0 {}"
|
||||
}
|
||||
def z1on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 2 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 2 6 1 {}"
|
||||
}
|
||||
def z1off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 2 6 0 {}"
|
||||
}
|
||||
def z2on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 3 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 3 6 1 {}"
|
||||
}
|
||||
def z2off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 3 6 0 {}"
|
||||
}
|
||||
def z3on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 4 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 4 6 1 {}"
|
||||
}
|
||||
def z3off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 4 6 0 {}"
|
||||
}
|
||||
def z4on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 5 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 5 6 1 {}"
|
||||
}
|
||||
def z4off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 5 6 0 {}"
|
||||
}
|
||||
def z5on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 6 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 6 6 1 {}"
|
||||
}
|
||||
def z5off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 6 6 0 {}"
|
||||
}
|
||||
def z6on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 7 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 7 6 1 {}"
|
||||
}
|
||||
def z6off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 7 6 0 {}"
|
||||
}
|
||||
def z7on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 8 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 8 6 1 {}"
|
||||
}
|
||||
def z7off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 8 6 0 {}"
|
||||
}
|
||||
def z8on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 9 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 9 6 1 {}"
|
||||
}
|
||||
def z8off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 9 6 0 {}"
|
||||
@@ -578,50 +699,51 @@ def z8off() {
|
||||
|
||||
//zones 9 - 16
|
||||
def z9on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 10 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 10 6 1 {}"
|
||||
}
|
||||
def z9off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 10 6 0 {}"
|
||||
}
|
||||
def z10on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 11 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 11 6 1 {}"
|
||||
}
|
||||
def z10off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 11 6 0 {}"
|
||||
}
|
||||
def z11on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 12 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 12 6 1 {}"
|
||||
}
|
||||
def z11off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 12 6 0 {}"
|
||||
}
|
||||
def z12on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 13 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 13 6 1 {}"
|
||||
}
|
||||
def z12off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 13 6 0 {}"
|
||||
}
|
||||
def z13on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 14 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 14 6 1 {}"
|
||||
}
|
||||
def z13off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 14 6 0 {}"
|
||||
}
|
||||
def z14on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 15 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 15 6 1 {}"
|
||||
}
|
||||
def z14off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 15 6 0 {}"
|
||||
}
|
||||
def z15on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 16 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 16 6 1 {}"
|
||||
}
|
||||
def z15off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 16 6 0 {}"
|
||||
}
|
||||
def z16on() {
|
||||
"st cmd 0x${device.deviceNetworkId} 17 6 1 {}"
|
||||
return manual() + "st cmd 0x${device.deviceNetworkId} 17 6 1 {}"
|
||||
}
|
||||
def z16off() {
|
||||
"st cmd 0x${device.deviceNetworkId} 17 6 0 {}"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ metadata
|
||||
{
|
||||
standardTile("mainTile", "device.status", width: 1, height: 1, icon: "st.Entertainment.entertainment11")
|
||||
{
|
||||
state "default", label: "Simple Sync", icon: "st.Home.home2", backgroundColor: "#55A7FF"
|
||||
state "default", label: "Simple Sync", icon: "st.Home.home2", backgroundColor: "#00a0dc"
|
||||
}
|
||||
|
||||
def detailTiles = ["mainTile"]
|
||||
|
||||
@@ -47,9 +47,9 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
state "turningOn", label:'${name}', icon:"st.switches.switch.on", backgroundColor:"#79b821"
|
||||
state "turningOn", label:'${name}', icon:"st.switches.switch.on", backgroundColor:"#00A0DC"
|
||||
state "turningOff", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ffffff"
|
||||
}
|
||||
controlTile("levelSliderControl", "device.level", "slider", height: 2, width: 1, inactiveLabel: false) {
|
||||
|
||||
@@ -37,14 +37,14 @@ metadata {
|
||||
tiles {
|
||||
standardTile("button", "device.button", width: 2, height: 2) {
|
||||
state "default", label: "", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffffff"
|
||||
state "button 1 pushed", label: "pushed #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
|
||||
state "button 2 pushed", label: "pushed #2", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
|
||||
state "button 3 pushed", label: "pushed #3", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
|
||||
state "button 4 pushed", label: "pushed #4", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
|
||||
state "button 1 held", label: "held #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
|
||||
state "button 2 held", label: "held #2", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
|
||||
state "button 3 held", label: "held #3", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
|
||||
state "button 4 held", label: "held #4", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
|
||||
state "button 1 pushed", label: "pushed #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#00A0DC"
|
||||
state "button 2 pushed", label: "pushed #2", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#00A0DC"
|
||||
state "button 3 pushed", label: "pushed #3", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#00A0DC"
|
||||
state "button 4 pushed", label: "pushed #4", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#00A0DC"
|
||||
state "button 1 held", label: "held #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#e86d13"
|
||||
state "button 2 held", label: "held #2", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#e86d13"
|
||||
state "button 3 held", label: "held #3", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#e86d13"
|
||||
state "button 4 held", label: "held #4", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#e86d13"
|
||||
}
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
|
||||
@@ -37,9 +37,9 @@ metadata {
|
||||
}
|
||||
|
||||
standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00a0dc", nextState:"turningOff"
|
||||
state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00a0dc", nextState:"turningOff"
|
||||
state "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
standardTile("reset", "device.reset", inactiveLabel: false, decoration: "flat") {
|
||||
|
||||
@@ -82,8 +82,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", inactiveLabel: false, width: 2, height: 2) {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
43
devicetypes/smartthings/aeon-multisensor-gen5.src/README.md
Normal file
43
devicetypes/smartthings/aeon-multisensor-gen5.src/README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Aeon Multisensor Gen5
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [Aeon Labs MultiSensor (Gen 5)](https://www.smartthings.com/works-with-smartthings/sensors/aeon-labs-multisensor-gen-5)
|
||||
|
||||
## 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
|
||||
* **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 (Gen 5) 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 (Gen 5) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206157226-Aeon-Labs-MultiSensor-Gen-5-)
|
||||
@@ -20,10 +20,12 @@ metadata {
|
||||
capability "Configuration"
|
||||
capability "Sensor"
|
||||
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)"
|
||||
}
|
||||
|
||||
simulator {
|
||||
@@ -64,8 +66,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", inactiveLabel: false, width: 2, height: 2) {
|
||||
@@ -98,6 +100,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])
|
||||
}
|
||||
|
||||
def parse(String description)
|
||||
{
|
||||
def result = null
|
||||
@@ -244,6 +256,13 @@ def configureAfterSecure() {
|
||||
secureSequence(request) + ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
def ping() {
|
||||
secure(zwave.batteryV1.batteryGet())
|
||||
}
|
||||
|
||||
def configure() {
|
||||
// log.debug "configure()"
|
||||
//["delay 30000"] + secure(zwave.securityV1.securityCommandsSupportedGet())
|
||||
|
||||
@@ -59,8 +59,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", inactiveLabel: false, width: 2, height: 2) {
|
||||
|
||||
@@ -45,7 +45,7 @@ metadata {
|
||||
// tile definitions
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00a0dc"
|
||||
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
|
||||
}
|
||||
valueTile("energy", "device.energy", decoration: "flat") {
|
||||
|
||||
@@ -53,7 +53,7 @@ metadata {
|
||||
// tile definitions
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
|
||||
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
|
||||
}
|
||||
valueTile("power", "device.power", decoration: "flat") {
|
||||
|
||||
2
devicetypes/smartthings/aeon-siren.src/.st-ignore
Normal file
2
devicetypes/smartthings/aeon-siren.src/.st-ignore
Normal file
@@ -0,0 +1,2 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
37
devicetypes/smartthings/aeon-siren.src/README.md
Normal file
37
devicetypes/smartthings/aeon-siren.src/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Aeon Siren
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [Aeon Labs Siren (Gen 5)](https://www.smartthings.com/works-with-smartthings/aeon-labs/aeon-labs-siren-gen-5)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Actuator** - represents that a Device has commands
|
||||
* **Alarm** - allows for interacting with devices that serve as alarms
|
||||
* **Switch** - can detect state (possible values: on/off)
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
## Device Health
|
||||
|
||||
Aeon Labs Siren (Gen 5) 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 Siren (Gen 5) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/204555240-Aeon-Labs-Siren-Gen-5-)
|
||||
@@ -20,10 +20,11 @@ metadata {
|
||||
capability "Actuator"
|
||||
capability "Alarm"
|
||||
capability "Switch"
|
||||
capability "Health Check"
|
||||
|
||||
command "test"
|
||||
|
||||
fingerprint deviceId: "0x1005", inClusters: "0x5E,0x98"
|
||||
fingerprint deviceId: "0x1005", inClusters: "0x5E,0x98", deviceJoinName: "Aeon Labs Siren (Gen 5)"
|
||||
}
|
||||
|
||||
simulator {
|
||||
@@ -57,7 +58,15 @@ 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])
|
||||
|
||||
if(!state.sound) state.sound = 1
|
||||
if(!state.volume) state.volume = 3
|
||||
|
||||
@@ -148,3 +157,10 @@ def test() {
|
||||
private secure(physicalgraph.zwave.Command cmd) {
|
||||
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
def ping() {
|
||||
secure(zwave.basicV1.basicGet())
|
||||
}
|
||||
@@ -60,7 +60,7 @@ metadata {
|
||||
// tile definitions
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00a0dc"
|
||||
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
|
||||
}
|
||||
valueTile("power", "device.power", decoration: "flat") {
|
||||
@@ -78,7 +78,7 @@ metadata {
|
||||
|
||||
(1..4).each { n ->
|
||||
standardTile("switch$n", "switch$n", canChangeIcon: true) {
|
||||
state "on", label: '${name}', action: "off$n", icon: "st.switches.switch.on", backgroundColor: "#79b821"
|
||||
state "on", label: '${name}', action: "off$n", icon: "st.switches.switch.on", backgroundColor: "#00a0dc"
|
||||
state "off", label: '${name}', action: "on$n", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
|
||||
}
|
||||
valueTile("power$n", "power$n", decoration: "flat") {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2016 SmartThings
|
||||
* 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:
|
||||
@@ -39,7 +39,7 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("presence", "device.presence", width: 2, height: 2, canChangeBackground: true) {
|
||||
state "present", labelIcon:"st.presence.tile.present", backgroundColor:"#53a7c0"
|
||||
state "present", labelIcon:"st.presence.tile.present", backgroundColor:"#00a0dc"
|
||||
state "not present", labelIcon:"st.presence.tile.not-present", backgroundColor:"#ffffff"
|
||||
}
|
||||
standardTile("beep", "device.beep", decoration: "flat") {
|
||||
@@ -59,7 +59,7 @@ def updated() {
|
||||
}
|
||||
|
||||
def configure() {
|
||||
def cmds = zigbee.batteryConfig(20, 20, 0x01)
|
||||
def cmds = zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020) + zigbee.batteryConfig(20, 20, 0x01)
|
||||
log.debug "configure -- cmds: ${cmds}"
|
||||
return cmds
|
||||
}
|
||||
@@ -151,7 +151,7 @@ private handlePresenceEvent(present) {
|
||||
|
||||
private startTimer() {
|
||||
log.debug "Scheduling periodic timer"
|
||||
schedule("0 * * * * ?", checkPresenceCallback)
|
||||
runEvery1Minute("checkPresenceCallback")
|
||||
}
|
||||
|
||||
private stopTimer() {
|
||||
@@ -166,4 +166,4 @@ def checkPresenceCallback() {
|
||||
if (timeSinceLastCheckin >= theCheckInterval) {
|
||||
handlePresenceEvent(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("presence", "device.presence", width: 2, height: 2, canChangeBackground: true) {
|
||||
state "present", labelIcon:"st.presence.tile.present", backgroundColor:"#53a7c0"
|
||||
state "not present", labelIcon:"st.presence.tile.not-present", backgroundColor:"#ebeef2"
|
||||
state "present", labelIcon:"st.presence.tile.present", backgroundColor:"#00a0dc"
|
||||
state "not present", labelIcon:"st.presence.tile.not-present", backgroundColor:"#ffffff"
|
||||
}
|
||||
standardTile("beep", "device.beep", decoration: "flat") {
|
||||
state "beep", label:'', action:"tone.beep", icon:"st.secondary.beep", backgroundColor:"#ffffff"
|
||||
|
||||
@@ -28,6 +28,8 @@ metadata {
|
||||
capability "Refresh"
|
||||
capability "Music Player"
|
||||
capability "Health Check"
|
||||
capability "Sensor"
|
||||
capability "Actuator"
|
||||
|
||||
/**
|
||||
* Define all commands, ie, if you have a custom action not
|
||||
@@ -67,10 +69,10 @@ metadata {
|
||||
}
|
||||
|
||||
standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
|
||||
state "on", label: '${name}', action: "forceOff", icon: "st.Electronics.electronics16", backgroundColor: "#79b821", nextState:"turningOff"
|
||||
state "on", label: '${name}', action: "forceOff", icon: "st.Electronics.electronics16", backgroundColor: "#00a0dc", nextState:"turningOff"
|
||||
state "turningOff", label:'TURNING OFF', icon:"st.Electronics.electronics16", backgroundColor:"#ffffff"
|
||||
state "off", label: '${name}', action: "forceOn", icon: "st.Electronics.electronics16", backgroundColor: "#ffffff", nextState:"turningOn"
|
||||
state "turningOn", label:'TURNING ON', icon:"st.Electronics.electronics16", backgroundColor:"#79b821"
|
||||
state "turningOn", label:'TURNING ON', icon:"st.Electronics.electronics16", backgroundColor:"#00a0dc"
|
||||
}
|
||||
valueTile("1", "device.station1", decoration: "flat", canChangeIcon: false) {
|
||||
state "station1", label:'${currentValue}', action:"preset1"
|
||||
|
||||
@@ -55,13 +55,13 @@ metadata {
|
||||
state "fanOn", label:'${name}', action:"thermostat.setThermostatFanMode"
|
||||
}
|
||||
controlTile("heatSliderControl", "device.heatingSetpoint", "slider", height: 1, width: 2, inactiveLabel: false) {
|
||||
state "setHeatingSetpoint", action:"thermostat.setHeatingSetpoint", backgroundColor:"#d04e00"
|
||||
state "setHeatingSetpoint", action:"thermostat.setHeatingSetpoint", backgroundColor:"#e86d13"
|
||||
}
|
||||
valueTile("heatingSetpoint", "device.heatingSetpoint", inactiveLabel: false, decoration: "flat") {
|
||||
state "heat", label:'${currentValue}° heat', unit:"F", backgroundColor:"#ffffff"
|
||||
}
|
||||
controlTile("coolSliderControl", "device.coolingSetpoint", "slider", height: 1, width: 2, inactiveLabel: false) {
|
||||
state "setCoolingSetpoint", action:"thermostat.setCoolingSetpoint", backgroundColor: "#1e9cbb"
|
||||
state "setCoolingSetpoint", action:"thermostat.setCoolingSetpoint", backgroundColor: "#00a0dc"
|
||||
}
|
||||
valueTile("coolingSetpoint", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
|
||||
state "cool", label:'${currentValue}° cool', unit:"F", backgroundColor:"#ffffff"
|
||||
|
||||
@@ -36,7 +36,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "off", label: '${name}', action: "switch.on", icon: "st.Home.home30", backgroundColor: "#ffffff"
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.Home.home30", backgroundColor: "#79b821"
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.Home.home30", backgroundColor: "#00a0dc"
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings") {
|
||||
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||
|
||||
capability "Actuator"
|
||||
capability "Configuration"
|
||||
@@ -23,6 +23,7 @@ metadata {
|
||||
capability "Switch"
|
||||
capability "Switch Level"
|
||||
capability "Health Check"
|
||||
capability "Light"
|
||||
|
||||
fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0000,0019"
|
||||
}
|
||||
@@ -42,9 +43,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") {
|
||||
|
||||
@@ -81,13 +81,13 @@ metadata {
|
||||
state "fanCirculate", label:'${name}', action:"switchFanMode"
|
||||
}
|
||||
controlTile("heatSliderControl", "device.heatingSetpoint", "slider", height: 1, width: 2, inactiveLabel: false) {
|
||||
state "setHeatingSetpoint", action:"quickSetHeat", backgroundColor:"#d04e00"
|
||||
state "setHeatingSetpoint", action:"quickSetHeat", backgroundColor:"#e86d13"
|
||||
}
|
||||
valueTile("heatingSetpoint", "device.heatingSetpoint", inactiveLabel: false, decoration: "flat") {
|
||||
state "heat", label:'${currentValue}° heat', backgroundColor:"#ffffff"
|
||||
}
|
||||
controlTile("coolSliderControl", "device.coolingSetpoint", "slider", height: 1, width: 2, inactiveLabel: false) {
|
||||
state "setCoolingSetpoint", action:"quickSetCool", backgroundColor: "#1e9cbb"
|
||||
state "setCoolingSetpoint", action:"quickSetCool", backgroundColor: "#00a0dc"
|
||||
}
|
||||
valueTile("coolingSetpoint", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
|
||||
state "cool", label:'${currentValue}° cool', backgroundColor:"#ffffff"
|
||||
|
||||
@@ -33,10 +33,10 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("toggle", "device.lock", width: 2, height: 2) {
|
||||
state "locked", label:'locked', action:"lock.unlock", icon:"st.locks.lock.locked", backgroundColor:"#79b821", nextState:"unlocking"
|
||||
state "locked", label:'locked', action:"lock.unlock", icon:"st.locks.lock.locked", backgroundColor:"#00a0dc", nextState:"unlocking"
|
||||
state "unlocked", label:'unlocked', action:"lock.lock", icon:"st.locks.lock.unlocked", backgroundColor:"#ffffff", nextState:"locking"
|
||||
state "unknown", label:"unknown", action:"lock.lock", icon:"st.locks.lock.unknown", backgroundColor:"#ffffff", nextState:"locking"
|
||||
state "locking", label:'locking', icon:"st.locks.lock.locked", backgroundColor:"#79b821"
|
||||
state "locking", label:'locking', icon:"st.locks.lock.locked", backgroundColor:"#00a0dc"
|
||||
state "unlocking", label:'unlocking', icon:"st.locks.lock.unlocked", backgroundColor:"#ffffff"
|
||||
}
|
||||
standardTile("lock", "device.lock", inactiveLabel: false, decoration: "flat") {
|
||||
|
||||
@@ -7,6 +7,8 @@ Works with:
|
||||
* [GE Z-Wave In-Wall Smart Dimmer (GE 12724)](http://products.z-wavealliance.org/products/1197)
|
||||
* [GE Z-Wave In-Wall Smart Dimmer (Toggle) (GE 12729)](http://products.z-wavealliance.org/products/1201)
|
||||
* [GE Z-Wave Plug-in Smart Dimmer (GE 12718)](http://products.z-wavealliance.org/products/1191)
|
||||
* [GE 1,000-Watt In-Wall Smart Dimmer Switch (GE 12725)](http://products.z-wavealliance.org/products/1198)
|
||||
* [GE In-Wall Smart Fan Control (GE 12730)](http://products.z-wavealliance.org/products/1202)
|
||||
|
||||
## Table of contents
|
||||
|
||||
@@ -27,7 +29,7 @@ Works with:
|
||||
|
||||
## Device Health
|
||||
|
||||
Z-Wave Smart Dimmers (In-Wall, In-Wall(Toggle), Plug-In) are polled by the hub.
|
||||
Z-Wave Smart Dimmers (In-Wall, In-Wall(Toggle), Plug-In), 1000-watt In-Wall Smart Dimmer Switch and In-Wall Smart Fan Control are 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.
|
||||
Check-in interval = 32 mins.
|
||||
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
|
||||
@@ -44,4 +46,6 @@ Instructions related to pairing, resetting and removing the device from SmartThi
|
||||
* [General Z-Wave Dimmer/Switch Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/200955890-Troubleshooting-GE-in-wall-switch-or-dimmer-won-t-respond-to-commands-or-automations-Z-Wave-)
|
||||
* [GE Z-Wave In-Wall Smart Dimmer (GE 12724) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/200902600-GE-In-Wall-Paddle-Dimmer-Switch-GE-12724-Z-Wave-)
|
||||
* [GE Z-Wave In-Wall Smart Dimmer (Toggle) (GE 12729) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/207568463-GE-In-Wall-Smart-Toggle-Dimmer-GE-12729-Z-Wave-)
|
||||
* [GE Z-Wave Plug-in Smart Dimmer (GE 12718) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/202088474-GE-Plug-In-Smart-Dimmer-GE-12718-Z-Wave-)
|
||||
* [GE Z-Wave Plug-in Smart Dimmer (GE 12718) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/202088474-GE-Plug-In-Smart-Dimmer-GE-12718-Z-Wave-)
|
||||
* [GE 1,000-Watt In-Wall Smart Dimmer Switch (GE 12725) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/200879274)
|
||||
* [GE In-Wall Smart Fan Control (GE 12730) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/200879274)
|
||||
@@ -12,7 +12,7 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Dimmer Switch", namespace: "smartthings", author: "SmartThings") {
|
||||
definition (name: "Dimmer Switch", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.switch") {
|
||||
capability "Switch Level"
|
||||
capability "Actuator"
|
||||
capability "Indicator"
|
||||
@@ -21,10 +21,11 @@ metadata {
|
||||
capability "Refresh"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
capability "Light"
|
||||
|
||||
fingerprint mfr:"0063", prod:"4457", deviceJoinName: "GE In-Wall Smart Dimmer "
|
||||
fingerprint mfr:"0063", prod:"4944", deviceJoinName: "GE In-Wall Smart Dimmer "
|
||||
fingerprint mfr:"0063", prod:"5044", deviceJoinName: "GE Plug-In Smart Dimmer "
|
||||
fingerprint mfr:"0063", prod:"4457", deviceJoinName: "GE In-Wall Smart Dimmer"
|
||||
fingerprint mfr:"0063", prod:"4944", deviceJoinName: "GE In-Wall Smart Dimmer"
|
||||
fingerprint mfr:"0063", prod:"5044", deviceJoinName: "GE Plug-In Smart Dimmer"
|
||||
fingerprint mfr:"0063", prod:"4944", model:"3034", deviceJoinName: "GE In-Wall Smart Fan Control"
|
||||
}
|
||||
|
||||
@@ -53,9 +54,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") {
|
||||
@@ -83,6 +84,11 @@ 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])
|
||||
|
||||
@@ -47,8 +47,8 @@ metadata {
|
||||
}
|
||||
|
||||
standardTile("motion", "device.motion") {
|
||||
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
|
||||
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
|
||||
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc")
|
||||
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC")
|
||||
}
|
||||
|
||||
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat") {
|
||||
|
||||
@@ -32,7 +32,7 @@ metadata {
|
||||
command "switchMode"
|
||||
command "switchFanMode"
|
||||
|
||||
attribute "thermostatSetpoint", "number"
|
||||
attribute "displayThermostatSetpoint", "string" // Added to be able to show "Auto"/"Off" keeping attribute thermostatSetpoint a number
|
||||
attribute "thermostatStatus", "string"
|
||||
attribute "maxHeatingSetpoint", "number"
|
||||
attribute "minHeatingSetpoint", "number"
|
||||
@@ -43,8 +43,8 @@ metadata {
|
||||
}
|
||||
|
||||
tiles {
|
||||
valueTile("temperature", "device.temperature", width: 2, height: 2) {
|
||||
state("temperature", label:'${currentValue}°', unit:"F",
|
||||
standardTile("temperature", "device.temperature", width: 2, height: 2, decoration: "flat") {
|
||||
state("temperature", label:'${currentValue}°', unit:"F", icon: "st.thermostat.ac.air-conditioning",
|
||||
backgroundColors:[
|
||||
// Celsius
|
||||
[value: 0, color: "#153591"],
|
||||
@@ -70,7 +70,7 @@ metadata {
|
||||
state "heat", action:"switchMode", nextState: "updating", icon: "st.thermostat.heat"
|
||||
state "cool", action:"switchMode", nextState: "updating", icon: "st.thermostat.cool"
|
||||
state "auto", action:"switchMode", nextState: "updating", icon: "st.thermostat.auto"
|
||||
state "auxHeatOnly", action:"switchMode", icon: "st.thermostat.emergency-heat"
|
||||
state "emergency heat", action:"switchMode", icon: "st.thermostat.emergency-heat" // emergency heat = auxHeatOnly
|
||||
state "updating", label:"Working", icon: "st.secondary.secondary"
|
||||
}
|
||||
standardTile("fanMode", "device.thermostatFanMode", inactiveLabel: false, decoration: "flat") {
|
||||
@@ -81,8 +81,8 @@ metadata {
|
||||
standardTile("upButtonControl", "device.thermostatSetpoint", inactiveLabel: false, decoration: "flat") {
|
||||
state "setpoint", action:"raiseSetpoint", icon:"st.thermostat.thermostat-up"
|
||||
}
|
||||
valueTile("thermostatSetpoint", "device.thermostatSetpoint", width: 1, height: 1, decoration: "flat") {
|
||||
state "thermostatSetpoint", label:'${currentValue}'
|
||||
valueTile("displayThermostatSetpoint", "device.displayThermostatSetpoint", width: 1, height: 1, decoration: "flat") {
|
||||
state "displayThermostatSetpoint", label:'${currentValue}'
|
||||
}
|
||||
valueTile("currentStatus", "device.thermostatStatus", height: 1, width: 2, decoration: "flat") {
|
||||
state "thermostatStatus", label:'${currentValue}', backgroundColor:"#ffffff"
|
||||
@@ -113,7 +113,7 @@ metadata {
|
||||
state "humidity", label:'${currentValue}%'
|
||||
}
|
||||
main "temperature"
|
||||
details(["temperature", "upButtonControl", "thermostatSetpoint", "currentStatus", "downButtonControl", "mode", "fanMode","humidity", "resumeProgram", "refresh"])
|
||||
details(["temperature", "upButtonControl", "displayThermostatSetpoint", "currentStatus", "downButtonControl", "mode", "fanMode","humidity", "resumeProgram", "refresh"])
|
||||
}
|
||||
|
||||
preferences {
|
||||
@@ -185,6 +185,11 @@ def generateEvent(Map results) {
|
||||
isChange = isStateChange(device, name, value.toString())
|
||||
event['isStateChange'] = isChange
|
||||
event['displayed'] = false
|
||||
} else if (name == "thermostatMode") {
|
||||
def mode = value.toString()
|
||||
mode = (mode == "auxHeatOnly") ? "emergency heat" : mode
|
||||
isChange = isStateChange(device, name, mode)
|
||||
event << [value: mode, isStateChange: isChange, displayed: isDisplayed]
|
||||
} else {
|
||||
isChange = isStateChange(device, name, value.toString())
|
||||
isDisplayed = isChange
|
||||
@@ -452,10 +457,10 @@ def emergencyHeat() {
|
||||
}
|
||||
|
||||
def auxHeatOnly() {
|
||||
log.debug "auxHeatOnly"
|
||||
log.debug "auxHeatOnly = emergency heat"
|
||||
def deviceId = device.deviceNetworkId.split(/\./).last()
|
||||
if (parent.setMode ("auxHeatOnly", deviceId))
|
||||
generateModeEvent("auxHeatOnly")
|
||||
generateModeEvent("emergency heat") // emergency heat = auxHeatOnly
|
||||
else {
|
||||
log.debug "Error setting new mode."
|
||||
def currentMode = device.currentState("thermostatMode")?.value
|
||||
@@ -574,17 +579,23 @@ def generateSetpointEvent() {
|
||||
sendEvent("name":"heatingSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale)
|
||||
sendEvent("name":"coolingSetpoint", "value":coolingSetpoint, "unit":location.temperatureScale)
|
||||
|
||||
def averageSetpoint = roundC((heatingSetpoint + coolingSetpoint) / 2)
|
||||
if (mode == "heat") {
|
||||
sendEvent("name":"thermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale)
|
||||
sendEvent("name":"displayThermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale, displayed: false)
|
||||
}
|
||||
else if (mode == "cool") {
|
||||
sendEvent("name":"thermostatSetpoint", "value":coolingSetpoint, "unit":location.temperatureScale)
|
||||
sendEvent("name":"displayThermostatSetpoint", "value":coolingSetpoint, "unit":location.temperatureScale, displayed: false)
|
||||
} else if (mode == "auto") {
|
||||
sendEvent("name":"thermostatSetpoint", "value":"Auto")
|
||||
sendEvent("name":"thermostatSetpoint", "value":averageSetpoint, "unit":location.temperatureScale)
|
||||
sendEvent("name":"displayThermostatSetpoint", "value":"Auto", displayed: false)
|
||||
} else if (mode == "off") {
|
||||
sendEvent("name":"thermostatSetpoint", "value":"Off")
|
||||
} else if (mode == "auxHeatOnly") {
|
||||
sendEvent("name":"thermostatSetpoint", "value":averageSetpoint, "unit":location.temperatureScale)
|
||||
sendEvent("name":"displayThermostatSetpoint", "value":"Off", displayed: false)
|
||||
} else if (mode == "emergency heat") { // emergency heat = auxHeatOnly
|
||||
sendEvent("name":"thermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale)
|
||||
sendEvent("name":"displayThermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale, displayed: false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -621,13 +632,14 @@ void raiseSetpoint() {
|
||||
targetvalue = thermostatSetpoint ? thermostatSetpoint : 0
|
||||
targetvalue = location.temperatureScale == "F"? targetvalue + 1 : targetvalue + 0.5
|
||||
|
||||
if ((mode == "heat" || mode == "auxHeatOnly") && targetvalue > maxHeatingSetpoint) {
|
||||
if ((mode == "heat" || mode == "emergency heat") && targetvalue > maxHeatingSetpoint) { // emergency heat = auxHeatOnly
|
||||
targetvalue = maxHeatingSetpoint
|
||||
} else if (mode == "cool" && targetvalue > maxCoolingSetpoint) {
|
||||
targetvalue = maxCoolingSetpoint
|
||||
}
|
||||
|
||||
sendEvent("name":"thermostatSetpoint", "value":targetvalue, "unit":location.temperatureScale, displayed: false)
|
||||
sendEvent("name":"displayThermostatSetpoint", "value":targetvalue, "unit":location.temperatureScale, displayed: false)
|
||||
log.info "In mode $mode raiseSetpoint() to $targetvalue"
|
||||
|
||||
runIn(3, "alterSetpoint", [data: [value:targetvalue], overwrite: true]) //when user click button this runIn will be overwrite
|
||||
@@ -666,13 +678,14 @@ void lowerSetpoint() {
|
||||
targetvalue = thermostatSetpoint ? thermostatSetpoint : 0
|
||||
targetvalue = location.temperatureScale == "F"? targetvalue - 1 : targetvalue - 0.5
|
||||
|
||||
if ((mode == "heat" || mode == "auxHeatOnly") && targetvalue < minHeatingSetpoint) {
|
||||
if ((mode == "heat" || mode == "emergency heat") && targetvalue < minHeatingSetpoint) { // emergency heat = auxHeatOnly
|
||||
targetvalue = minHeatingSetpoint
|
||||
} else if (mode == "cool" && targetvalue < minCoolingSetpoint) {
|
||||
targetvalue = minCoolingSetpoint
|
||||
}
|
||||
|
||||
sendEvent("name":"thermostatSetpoint", "value":targetvalue, "unit":location.temperatureScale, displayed: false)
|
||||
sendEvent("name":"displayThermostatSetpoint", "value":targetvalue, "unit":location.temperatureScale, displayed: false)
|
||||
log.info "In mode $mode lowerSetpoint() to $targetvalue"
|
||||
|
||||
runIn(3, "alterSetpoint", [data: [value:targetvalue], overwrite: true]) //when user click button this runIn will be overwrite
|
||||
@@ -706,7 +719,7 @@ void alterSetpoint(temp) {
|
||||
}
|
||||
|
||||
//step1: check thermostatMode, enforce limits before sending request to cloud
|
||||
if (mode == "heat" || mode == "auxHeatOnly"){
|
||||
if (mode == "heat" || mode == "emergency heat"){ // emergency heat = auxHeatOnly
|
||||
if (temp.value > coolingSetpoint){
|
||||
targetHeatingSetpoint = temp.value
|
||||
targetCoolingSetpoint = temp.value
|
||||
@@ -735,15 +748,18 @@ void alterSetpoint(temp) {
|
||||
|
||||
if (parent.setHold(heatingValue, coolingValue, deviceId, sendHoldType)) {
|
||||
sendEvent("name": "thermostatSetpoint", "value": temp.value, displayed: false)
|
||||
sendEvent("name": "displayThermostatSetpoint", "value": temp.value, displayed: false)
|
||||
sendEvent("name": "heatingSetpoint", "value": targetHeatingSetpoint, "unit": location.temperatureScale)
|
||||
sendEvent("name": "coolingSetpoint", "value": targetCoolingSetpoint, "unit": location.temperatureScale)
|
||||
log.debug "alterSetpoint in mode $mode succeed change setpoint to= ${temp.value}"
|
||||
} else {
|
||||
log.error "Error alterSetpoint()"
|
||||
if (mode == "heat" || mode == "auxHeatOnly"){
|
||||
if (mode == "heat" || mode == "emergency heat"){ // emergency heat = auxHeatOnly
|
||||
sendEvent("name": "thermostatSetpoint", "value": heatingSetpoint.toString(), displayed: false)
|
||||
sendEvent("name": "displayThermostatSetpoint", "value": heatingSetpoint.toString(), displayed: false)
|
||||
} else if (mode == "cool") {
|
||||
sendEvent("name": "thermostatSetpoint", "value": coolingSetpoint.toString(), displayed: false)
|
||||
sendEvent("name": "displayThermostatSetpoint", "value": heatingSetpoint.toString(), displayed: false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -759,6 +775,7 @@ def generateStatusEvent() {
|
||||
def coolingSetpoint = device.currentValue("coolingSetpoint")
|
||||
def temperature = device.currentValue("temperature")
|
||||
def statusText
|
||||
def operatingState = "idle"
|
||||
|
||||
log.debug "Generate Status Event for Mode = ${mode}"
|
||||
log.debug "Temperature = ${temperature}"
|
||||
@@ -767,20 +784,29 @@ def generateStatusEvent() {
|
||||
log.debug "HVAC Mode = ${mode}"
|
||||
|
||||
if (mode == "heat") {
|
||||
if (temperature >= heatingSetpoint)
|
||||
if (temperature >= heatingSetpoint) {
|
||||
statusText = "Right Now: Idle"
|
||||
else
|
||||
} else {
|
||||
statusText = "Heating to ${heatingSetpoint} ${location.temperatureScale}"
|
||||
operatingState = "heating"
|
||||
}
|
||||
} else if (mode == "cool") {
|
||||
if (temperature <= coolingSetpoint)
|
||||
if (temperature <= coolingSetpoint) {
|
||||
statusText = "Right Now: Idle"
|
||||
else
|
||||
} else {
|
||||
statusText = "Cooling to ${coolingSetpoint} ${location.temperatureScale}"
|
||||
operatingState = "cooling"
|
||||
}
|
||||
} else if (mode == "auto") {
|
||||
statusText = "Right Now: Auto"
|
||||
if (temperature < heatingSetpoint) {
|
||||
operatingState = "heating"
|
||||
} else if (temperature > coolingSetpoint) {
|
||||
operatingState = "cooling"
|
||||
}
|
||||
} else if (mode == "off") {
|
||||
statusText = "Right Now: Off"
|
||||
} else if (mode == "auxHeatOnly") {
|
||||
} else if (mode == "emergency heat") { // emergency heat = auxHeatOnly
|
||||
statusText = "Emergency Heat"
|
||||
} else {
|
||||
statusText = "?"
|
||||
@@ -788,6 +814,7 @@ def generateStatusEvent() {
|
||||
|
||||
log.debug "Generate Status Event = ${statusText}"
|
||||
sendEvent("name":"thermostatStatus", "value":statusText, "description":statusText, displayed: true)
|
||||
sendEvent("name":"thermostatOperatingState", "value":operatingState, "description":operatingState, displayed: false)
|
||||
}
|
||||
|
||||
def generateActivityFeedsEvent(notificationMessage) {
|
||||
|
||||
2
devicetypes/smartthings/econet-vent.src/.st-ignore
Normal file
2
devicetypes/smartthings/econet-vent.src/.st-ignore
Normal file
@@ -0,0 +1,2 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
43
devicetypes/smartthings/econet-vent.src/README.md
Normal file
43
devicetypes/smartthings/econet-vent.src/README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# EcoNet Vent
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [EcoNet Controls Z-Wave Vent](https://www.smartthings.com/works-with-smartthings/econet-controls/econet-controls-z-wave-vent)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Switch Level** - allows for the control of the level attribute of a light
|
||||
* **Actuator** - represents that a Device has commands
|
||||
* **Switch** - allows for the control of a switch device
|
||||
* **Battery** - defines that the device has a battery
|
||||
* **Refresh** - _refresh()_ command for status updates
|
||||
* **Sensor** - detects sensor events
|
||||
* **Polling** - allows for the polling of devices that support it
|
||||
* **Configuration** - allow configuration of devices that support it
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
## Device Health
|
||||
|
||||
EcoNet Controls Z-Wave Vent 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:
|
||||
* [EcoNet Controls Z-Wave Vent Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/204556420-EcoNet-EV100-Vent)
|
||||
@@ -26,11 +26,13 @@ metadata {
|
||||
capability "Sensor"
|
||||
capability "Polling"
|
||||
capability "Configuration"
|
||||
capability "Health Check"
|
||||
|
||||
command "open"
|
||||
command "close"
|
||||
|
||||
fingerprint deviceId: "0x1100", inClusters: "0x26,0x72,0x86,0x77,0x80,0x20"
|
||||
fingerprint mfr:"0157", prod:"0100", model:"0100", deviceJoinName: "EcoNet Controls Z-Wave Vent"
|
||||
}
|
||||
|
||||
simulator {
|
||||
@@ -53,7 +55,7 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", action:"switch.off", icon:"st.vents.vent-open-text", backgroundColor:"#53a7c0"
|
||||
state "on", action:"switch.off", icon:"st.vents.vent-open-text", backgroundColor:"#00a0dc"
|
||||
state "off", action:"switch.on", icon:"st.vents.vent-closed", backgroundColor:"#ffffff"
|
||||
}
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
|
||||
@@ -83,8 +85,15 @@ def parse(String description) {
|
||||
result
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
//send the command to stop polling
|
||||
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("poll stop")
|
||||
}
|
||||
|
||||
@@ -169,6 +178,13 @@ def setLevel(value, duration) {
|
||||
setLevel(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
def ping() {
|
||||
refresh()
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
delayBetween([
|
||||
zwave.switchMultilevelV1.switchMultilevelGet().format(),
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -0,0 +1,40 @@
|
||||
# Everspring Flood Sensor
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [Everspring Water Detector](https://www.smartthings.com/works-with-smartthings/sensors/everspring-water-detector)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Battery](#battery-specification)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Water Sensor** - can detect presence of water (dry or wet)
|
||||
* **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
|
||||
|
||||
Everspring Water Detector is a Z-wave sleepy device and wakes up every 4 hours.
|
||||
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*4*60 + 2)mins = 482 mins.
|
||||
|
||||
* __482min__ checkInterval
|
||||
|
||||
## Battery Specification
|
||||
|
||||
Three AA 1.5V 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:
|
||||
* [Everspring Water Detector Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/202088304-Everspring-Water-Detector)
|
||||
@@ -12,11 +12,12 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Everspring Flood Sensor", namespace: "smartthings", author: "SmartThings") {
|
||||
definition (name: "Everspring Flood Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.moisture") {
|
||||
capability "Water Sensor"
|
||||
capability "Configuration"
|
||||
capability "Sensor"
|
||||
capability "Battery"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint deviceId: "0xA102", inClusters: "0x86,0x72,0x85,0x84,0x80,0x70,0x9C,0x20,0x71"
|
||||
}
|
||||
@@ -28,12 +29,12 @@ metadata {
|
||||
status "battery ${i}%": new physicalgraph.zwave.Zwave().batteryV1.batteryReport(batteryLevel: i).incomingMessage()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"water", type: "generic", width: 6, height: 4){
|
||||
tileAttribute ("device.water", key: "PRIMARY_CONTROL") {
|
||||
attributeState "dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"
|
||||
attributeState "wet", icon:"st.alarm.water.wet", backgroundColor:"#53a7c0"
|
||||
attributeState "wet", icon:"st.alarm.water.wet", backgroundColor:"#00a0dc"
|
||||
}
|
||||
}
|
||||
valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
|
||||
@@ -138,6 +139,8 @@ def zwaveEvent(physicalgraph.zwave.Command cmd)
|
||||
|
||||
def configure()
|
||||
{
|
||||
// Device wakes up every 4 hours, this interval allows us to miss one wakeup notification before marking offline
|
||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
if (!device.currentState("battery")) {
|
||||
sendEvent(name: "battery", value:100, unit:"%", descriptionText:"(Default battery event)", displayed:false)
|
||||
}
|
||||
|
||||
@@ -56,9 +56,9 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00a0dc", nextState:"turningOff"
|
||||
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00a0dc", nextState:"turningOff"
|
||||
state "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -0,0 +1,40 @@
|
||||
# Fibaro Door Window Sensor
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [Fibaro Door/Window Sensor](https://www.smartthings.com/works-with-smartthings/sensors/fibaro-doorwindow-sensor)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Battery](#battery-specification)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Contact Sensor** - can detect contact (possible values: open,closed)
|
||||
* **Sensor** - detects sensor events
|
||||
* **Battery** - defines device uses a battery
|
||||
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
## Device Health
|
||||
|
||||
Fibaro Door/Window Sensor is a Z-wave sleepy device and wakes up every 4 hours.
|
||||
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*4*60 + 2)mins = 482 mins.
|
||||
|
||||
* __482min__ checkInterval
|
||||
|
||||
## Battery Specification
|
||||
|
||||
One 1/2AA 3.6V battery is 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:
|
||||
* [Fibaro Door/Window Sensor Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/204075194-Fibaro-Door-Window-Sensor)
|
||||
@@ -39,7 +39,8 @@
|
||||
capability "Contact Sensor"
|
||||
capability "Sensor"
|
||||
capability "Battery"
|
||||
capability "Configuration"
|
||||
capability "Configuration"
|
||||
capability "Health Check"
|
||||
|
||||
command "resetParams2StDefaults"
|
||||
command "listCurrentParams"
|
||||
@@ -266,6 +267,9 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
|
||||
*/
|
||||
def configure() {
|
||||
log.debug "Configuring Device..."
|
||||
// Device wakes up every 4 hours, this interval allows us to miss one wakeup notification before marking offline
|
||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
def cmds = []
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 1, size: 2).format()
|
||||
// send associate to group 3 to get sensor data reported only to hub
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* Device Type Definition File
|
||||
*
|
||||
* Device Type: Fibaro Flood Sensor
|
||||
* File Name: fibaro-flood-sensor.groovy
|
||||
* Initial Release: 2014-12-10
|
||||
* @author: Todd Wackford
|
||||
* Email: todd@wackford.net
|
||||
* @version: 1.0
|
||||
* Device Type: Fibaro Flood Sensor
|
||||
* File Name: fibaro-flood-sensor.groovy
|
||||
* Initial Release: 2014-12-10
|
||||
* @author: Todd Wackford
|
||||
* Email: todd@wackford.net
|
||||
* @version: 1.0
|
||||
*
|
||||
* Copyright 2014 SmartThings
|
||||
*
|
||||
@@ -26,8 +26,8 @@
|
||||
* not displayed to the user. We do this so we can receive events and display on device
|
||||
* activity. If the user wants to display the tamper tile, adjust the tile display lines
|
||||
* with the following:
|
||||
* main(["water", "temperature", "tamper"])
|
||||
* details(["water", "temperature", "battery", "tamper"])
|
||||
* main(["water", "temperature", "tamper"])
|
||||
* details(["water", "temperature", "battery", "tamper"])
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
@@ -39,13 +39,18 @@ metadata {
|
||||
capability "Temperature Measurement"
|
||||
capability "Configuration"
|
||||
capability "Battery"
|
||||
|
||||
command "resetParams2StDefaults"
|
||||
command "listCurrentParams"
|
||||
command "updateZwaveParam"
|
||||
command "test"
|
||||
|
||||
capability "Health Check"
|
||||
capability "Sensor"
|
||||
|
||||
command "resetParams2StDefaults"
|
||||
command "listCurrentParams"
|
||||
command "updateZwaveParam"
|
||||
command "test"
|
||||
|
||||
fingerprint deviceId: "0xA102", inClusters: "0x30,0x9C,0x60,0x85,0x8E,0x72,0x70,0x86,0x80,0x84"
|
||||
fingerprint mfr:"010F", prod:"0000", model:"2002"
|
||||
fingerprint mfr:"010F", prod:"0000", model:"1002"
|
||||
fingerprint mfr:"010F", prod:"0B00", model:"1001"
|
||||
}
|
||||
|
||||
simulator {
|
||||
@@ -72,7 +77,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("water", "device.water", width: 2, height: 2) {
|
||||
state "dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"
|
||||
state "wet", icon:"st.alarm.water.wet", backgroundColor:"#53a7c0"
|
||||
state "wet", icon:"st.alarm.water.wet", backgroundColor:"#00a0dc"
|
||||
}
|
||||
valueTile("temperature", "device.temperature", inactiveLabel: false) {
|
||||
state "temperature", label:'${currentValue}°',
|
||||
@@ -86,9 +91,9 @@ metadata {
|
||||
[value: 96, color: "#bc2323"]
|
||||
]
|
||||
}
|
||||
standardTile("tamper", "device.tamper") {
|
||||
state("secure", label:"secure", icon:"st.locks.lock.locked", backgroundColor:"#ffffff")
|
||||
state("tampered", label:"tampered", icon:"st.locks.lock.unlocked", backgroundColor:"#53a7c0")
|
||||
standardTile("tamper", "device.tamper") {
|
||||
state("secure", label:"secure", icon:"st.locks.lock.locked", backgroundColor:"#ffffff")
|
||||
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:""
|
||||
@@ -106,26 +111,17 @@ metadata {
|
||||
def parse(String description)
|
||||
{
|
||||
def result = []
|
||||
|
||||
if (description == "updated") {
|
||||
if (!state.MSR) {
|
||||
result << response(zwave.wakeUpV1.wakeUpIntervalSet(seconds: 60*60, nodeid:zwaveHubNodeId))
|
||||
result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
|
||||
}
|
||||
} else {
|
||||
def cmd = zwave.parse(description, [0x31: 2, 0x30: 1, 0x70: 2, 0x71: 1, 0x84: 1, 0x80: 1, 0x9C: 1, 0x72: 2, 0x56: 2, 0x60: 3])
|
||||
|
||||
if (cmd) {
|
||||
result += zwaveEvent(cmd) //createEvent(zwaveEvent(cmd))
|
||||
}
|
||||
}
|
||||
|
||||
result << response(zwave.batteryV1.batteryGet().format())
|
||||
|
||||
if ( result[0] != null ) {
|
||||
|
||||
def cmd = zwave.parse(description, [0x31: 2, 0x30: 1, 0x70: 2, 0x71: 1, 0x84: 1, 0x80: 1, 0x9C: 1, 0x72: 2, 0x56: 2, 0x60: 3])
|
||||
|
||||
if (cmd) {
|
||||
result += zwaveEvent(cmd) //createEvent(zwaveEvent(cmd))
|
||||
}
|
||||
|
||||
if ( result[0] != null ) {
|
||||
log.debug "Parse returned ${result}"
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -142,10 +138,9 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
|
||||
def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
|
||||
if (!isConfigured()) {
|
||||
// we're still in the process of configuring a newly joined device
|
||||
result += lateConfigure(true)
|
||||
result << lateConfigure(true)
|
||||
} else {
|
||||
result += response(zwave.wakeUpV1.wakeUpNoMoreInformation())
|
||||
log.debug "We're done with WakeUp!"
|
||||
result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
|
||||
}
|
||||
result
|
||||
}
|
||||
@@ -153,7 +148,7 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd)
|
||||
{
|
||||
def map = [:]
|
||||
|
||||
|
||||
switch (cmd.sensorType) {
|
||||
case 1:
|
||||
// temperature
|
||||
@@ -184,7 +179,7 @@ def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv1.SensorBinaryReport cm
|
||||
def map = [:]
|
||||
map.value = cmd.sensorValue ? "active" : "inactive"
|
||||
map.name = "acceleration"
|
||||
|
||||
|
||||
if (map.value == "active") {
|
||||
map.descriptionText = "$device.displayName detected vibration"
|
||||
}
|
||||
@@ -199,49 +194,49 @@ def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
|
||||
log.debug "BasicSet with CMD = ${cmd}"
|
||||
|
||||
if (!isConfigured()) {
|
||||
def result = []
|
||||
def map = [:]
|
||||
|
||||
map.name = "water"
|
||||
log.debug "BasicSet with CMD = ${cmd}"
|
||||
|
||||
if (!isConfigured()) {
|
||||
def result = []
|
||||
def map = [:]
|
||||
|
||||
map.name = "water"
|
||||
map.value = cmd.value ? "wet" : "dry"
|
||||
map.descriptionText = "${device.displayName} is ${map.value}"
|
||||
|
||||
// If we are getting a BasicSet, and isConfigured == false, then we are likely NOT properly configured.
|
||||
result += lateConfigure(true)
|
||||
|
||||
result << createEvent(map)
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
// If we are getting a BasicSet, and isConfigured == false, then we are likely NOT properly configured.
|
||||
result += lateConfigure(true)
|
||||
|
||||
result << createEvent(map)
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.sensoralarmv1.SensorAlarmReport cmd)
|
||||
{
|
||||
def map = [:]
|
||||
|
||||
|
||||
if (cmd.sensorType == 0x05) {
|
||||
map.name = "water"
|
||||
map.value = cmd.sensorState ? "wet" : "dry"
|
||||
map.descriptionText = "${device.displayName} is ${map.value}"
|
||||
|
||||
log.debug "CMD = SensorAlarmReport: ${cmd}"
|
||||
setConfigured()
|
||||
} else if ( cmd.sensorType == 0) {
|
||||
map.name = "tamper"
|
||||
map.isStateChange = true
|
||||
map.value = cmd.sensorState ? "tampered" : "secure"
|
||||
map.descriptionText = "${device.displayName} has been tampered with"
|
||||
runIn(30, "resetTamper") //device does not send alarm cancelation
|
||||
|
||||
} else if ( cmd.sensorType == 1) {
|
||||
map.name = "tamper"
|
||||
map.value = cmd.sensorState ? "tampered" : "secure"
|
||||
map.descriptionText = "${device.displayName} has been tampered with"
|
||||
runIn(30, "resetTamper") //device does not send alarm cancelation
|
||||
|
||||
|
||||
log.debug "CMD = SensorAlarmReport: ${cmd}"
|
||||
setConfigured()
|
||||
} else if ( cmd.sensorType == 0) {
|
||||
map.name = "tamper"
|
||||
map.isStateChange = true
|
||||
map.value = cmd.sensorState ? "tampered" : "secure"
|
||||
map.descriptionText = "${device.displayName} has been tampered with"
|
||||
runIn(30, "resetTamper") //device does not send alarm cancelation
|
||||
|
||||
} else if ( cmd.sensorType == 1) {
|
||||
map.name = "tamper"
|
||||
map.value = cmd.sensorState ? "tampered" : "secure"
|
||||
map.descriptionText = "${device.displayName} has been tampered with"
|
||||
runIn(30, "resetTamper") //device does not send alarm cancelation
|
||||
|
||||
} else {
|
||||
map.descriptionText = "${device.displayName}: ${cmd}"
|
||||
}
|
||||
@@ -250,10 +245,10 @@ def zwaveEvent(physicalgraph.zwave.commands.sensoralarmv1.SensorAlarmReport cmd)
|
||||
|
||||
def resetTamper() {
|
||||
def map = [:]
|
||||
map.name = "tamper"
|
||||
map.value = "secure"
|
||||
map.descriptionText = "$device.displayName is secure"
|
||||
sendEvent(map)
|
||||
map.name = "tamper"
|
||||
map.value = "secure"
|
||||
map.descriptionText = "$device.displayName is secure"
|
||||
sendEvent(map)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
@@ -267,10 +262,10 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
|
||||
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
|
||||
log.debug "msr: $msr"
|
||||
device.updateDataValue(["MSR", msr])
|
||||
|
||||
if ( msr == "010F-0B00-2001" ) { //this is the msr and device type for the fibaro flood sensor
|
||||
result += lateConfigure(true)
|
||||
}
|
||||
|
||||
if ( msr == "010F-0B00-2001" ) { //this is the msr and device type for the fibaro flood sensor
|
||||
result += lateConfigure(true)
|
||||
}
|
||||
|
||||
result << createEvent(descriptionText: "$device.displayName MSR: $msr", isStateChange: false)
|
||||
result
|
||||
@@ -282,17 +277,17 @@ def setConfigured() {
|
||||
|
||||
def isConfigured() {
|
||||
Boolean configured = device.getDataValue(["configured"]) as Boolean
|
||||
|
||||
return configured
|
||||
|
||||
return configured
|
||||
}
|
||||
|
||||
def lateConfigure(setConf = False) {
|
||||
def res = response(configure())
|
||||
|
||||
if (setConf)
|
||||
setConfigured()
|
||||
|
||||
return res
|
||||
|
||||
if (setConf)
|
||||
setConfigured()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -304,26 +299,34 @@ def lateConfigure(setConf = False) {
|
||||
*/
|
||||
def configure() {
|
||||
log.debug "Configuring Device..."
|
||||
def cmds = []
|
||||
|
||||
// send associate to group 2 to get alarm data
|
||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
|
||||
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 5, size: 1).format()
|
||||
|
||||
// send associate to group 3 to get sensor data reported only to hub
|
||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
|
||||
// Device wakes up every 4 hours, this interval allows us to miss one wakeup notification before marking offline
|
||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
// temp hysteresis set to .5 degrees celcius
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,50], parameterNumber: 12, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
|
||||
// default initial state
|
||||
sendEvent(name: "water", value: "dry")
|
||||
|
||||
def cmds = []
|
||||
|
||||
// send associate to group 2 to get alarm data
|
||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
|
||||
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 5, size: 1).format()
|
||||
|
||||
// send associate to group 3 to get sensor data reported only to hub
|
||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
|
||||
|
||||
// reporting frequency of temps and battery set to one hour
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,60*60], parameterNumber: 10, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
|
||||
|
||||
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
|
||||
|
||||
// cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
|
||||
|
||||
// temp hysteresis set to .5 degrees celcius
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,50], parameterNumber: 12, size: 2).format()
|
||||
// cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
|
||||
|
||||
cmds << zwave.batteryV1.batteryGet().format()
|
||||
|
||||
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
|
||||
|
||||
delayBetween(cmds, 100)
|
||||
}
|
||||
|
||||
@@ -349,18 +352,18 @@ def test() {
|
||||
* @return none
|
||||
*/
|
||||
def updateZwaveParam(params) {
|
||||
if ( params ) {
|
||||
def pNumber = params.paramNumber
|
||||
def pSize = params.size
|
||||
def pValue = [params.value]
|
||||
log.debug "Make sure device is awake and in recieve mode (triple-click?)"
|
||||
log.debug "Updating ${device.displayName} parameter number '${pNumber}' with value '${pValue}' with size of '${pSize}'"
|
||||
if ( params ) {
|
||||
def pNumber = params.paramNumber
|
||||
def pSize = params.size
|
||||
def pValue = [params.value]
|
||||
log.debug "Make sure device is awake and in recieve mode (triple-click?)"
|
||||
log.debug "Updating ${device.displayName} parameter number '${pNumber}' with value '${pValue}' with size of '${pSize}'"
|
||||
|
||||
def cmds = []
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: pValue, parameterNumber: pNumber, size: pSize).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: pNumber).format()
|
||||
delayBetween(cmds, 1000)
|
||||
}
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: pValue, parameterNumber: pNumber, size: pSize).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: pNumber).format()
|
||||
delayBetween(cmds, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,26 +380,26 @@ def updateZwaveParam(params) {
|
||||
def resetParams2StDefaults() {
|
||||
log.debug "Resetting ${device.displayName} parameters to SmartThings compatible defaults"
|
||||
def cmds = []
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 1, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [3], parameterNumber: 2, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 5, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 7, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 9, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,60*60], parameterNumber: 10, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,50], parameterNumber: 12, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 13, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [5,220], parameterNumber: 50, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [13,172], parameterNumber: 51, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0,0,225], parameterNumber: 61, size: 4).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,255,0,0], parameterNumber: 62, size: 4).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 63, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 73, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 74, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 75, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 76, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 77, size: 1).format()
|
||||
|
||||
delayBetween(cmds, 1200)
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 1, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [3], parameterNumber: 2, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 5, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 7, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 9, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,60*60], parameterNumber: 10, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,50], parameterNumber: 12, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 13, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [5,220], parameterNumber: 50, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [13,172], parameterNumber: 51, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0,0,225], parameterNumber: 61, size: 4).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,255,0,0], parameterNumber: 62, size: 4).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 63, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 73, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 74, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 75, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 76, size: 2).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 77, size: 1).format()
|
||||
|
||||
delayBetween(cmds, 1200)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -413,25 +416,25 @@ def resetParams2StDefaults() {
|
||||
def listCurrentParams() {
|
||||
log.debug "Listing of current parameter settings of ${device.displayName}"
|
||||
def cmds = []
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 2).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 5).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 7).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 9).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 13).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 50).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 51).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 61).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 62).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 63).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 73).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 74).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 75).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 76).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 77).format()
|
||||
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 2).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 5).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 7).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 9).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 13).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 50).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 51).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 61).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 62).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 63).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 73).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 74).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 75).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 76).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 77).format()
|
||||
|
||||
delayBetween(cmds, 1200)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
* 2. 20150125 Todd Wackford
|
||||
* Leaned out parse and moved most device info getting into configuration method.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Sets up metadata, simulator info and tile definition.
|
||||
*
|
||||
@@ -38,7 +38,7 @@
|
||||
* @return none
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Fibaro Motion Sensor", namespace: "smartthings", author: "SmartThings") {
|
||||
definition (name: "Fibaro Motion Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.motion") {
|
||||
capability "Motion Sensor"
|
||||
capability "Temperature Measurement"
|
||||
capability "Acceleration Sensor"
|
||||
@@ -46,7 +46,8 @@
|
||||
capability "Illuminance Measurement"
|
||||
capability "Sensor"
|
||||
capability "Battery"
|
||||
|
||||
capability "Health Check"
|
||||
|
||||
command "resetParams2StDefaults"
|
||||
command "listCurrentParams"
|
||||
command "updateZwaveParam"
|
||||
@@ -81,8 +82,8 @@
|
||||
|
||||
tiles {
|
||||
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"
|
||||
}
|
||||
valueTile("temperature", "device.temperature", inactiveLabel: false) {
|
||||
state "temperature", label:'${currentValue}°',
|
||||
@@ -109,7 +110,7 @@
|
||||
state("active", label:'vibration', icon:"st.motion.acceleration.active", backgroundColor:"#53a7c0")
|
||||
state("inactive", label:'still', icon:"st.motion.acceleration.inactive", backgroundColor:"#ffffff")
|
||||
}
|
||||
|
||||
|
||||
|
||||
main(["motion", "temperature", "acceleration", "illuminance"])
|
||||
details(["motion", "temperature", "acceleration", "battery", "illuminance", "configure"])
|
||||
@@ -125,19 +126,22 @@
|
||||
*/
|
||||
def configure() {
|
||||
log.debug "Configuring Device For SmartThings Use"
|
||||
// Device-Watch simply pings if no device events received for 8 hrs & 2 minutes
|
||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
def cmds = []
|
||||
|
||||
|
||||
// send associate to group 3 to get sensor data reported only to hub
|
||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
|
||||
|
||||
// turn on tamper sensor with active/inactive reports (use it as an acceleration sensor) default is 0, or off
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [4], parameterNumber: 24, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 24).format()
|
||||
|
||||
|
||||
// temperature change report threshold (0-255 = 0.1 to 25.5C) default is 1.0 Celcius, setting to .5 Celcius
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [5], parameterNumber: 60, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 60).format()
|
||||
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 60).format()
|
||||
|
||||
cmds << response(zwave.batteryV1.batteryGet())
|
||||
cmds << response(zwave.versionV1.versionGet().format())
|
||||
cmds << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet().format())
|
||||
@@ -151,20 +155,20 @@ def parse(String description)
|
||||
{
|
||||
def result = []
|
||||
def cmd = zwave.parse(description, [0x72: 2, 0x31: 2, 0x30: 1, 0x84: 1, 0x9C: 1, 0x70: 2, 0x80: 1, 0x86: 1, 0x7A: 1, 0x56: 1])
|
||||
|
||||
|
||||
if (description == "updated") {
|
||||
result << response(zwave.wakeUpV1.wakeUpIntervalSet(seconds: 7200, nodeid:zwaveHubNodeId))
|
||||
result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
|
||||
result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
|
||||
}
|
||||
|
||||
|
||||
if (cmd) {
|
||||
if( cmd.CMD == "8407" ) {
|
||||
if( cmd.CMD == "8407" ) {
|
||||
result << response(zwave.batteryV1.batteryGet().format())
|
||||
result << new physicalgraph.device.HubAction(zwave.wakeUpV1.wakeUpNoMoreInformation().format())
|
||||
result << new physicalgraph.device.HubAction(zwave.wakeUpV1.wakeUpNoMoreInformation().format())
|
||||
}
|
||||
result << createEvent(zwaveEvent(cmd))
|
||||
}
|
||||
|
||||
|
||||
if ( result[0] != null ) {
|
||||
log.debug "Parse returned ${result}"
|
||||
result
|
||||
@@ -185,14 +189,14 @@ def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd)
|
||||
}
|
||||
}
|
||||
|
||||
def createEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd, Map item1) {
|
||||
def createEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd, Map item1) {
|
||||
log.debug "manufacturerId: ${cmd.manufacturerId}"
|
||||
log.debug "manufacturerName: ${cmd.manufacturerName}"
|
||||
log.debug "productId: ${cmd.productId}"
|
||||
log.debug "productTypeId: ${cmd.productTypeId}"
|
||||
}
|
||||
|
||||
def createEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, Map item1) {
|
||||
def createEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, Map item1) {
|
||||
updateDataValue("applicationVersion", "${cmd.applicationVersion}")
|
||||
log.debug "applicationVersion: ${cmd.applicationVersion}"
|
||||
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
|
||||
@@ -201,7 +205,7 @@ def createEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, Map it
|
||||
log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
|
||||
}
|
||||
|
||||
def createEvent(physicalgraph.zwave.commands.firmwareupdatemdv1.FirmwareMdReport cmd, Map item1) {
|
||||
def createEvent(physicalgraph.zwave.commands.firmwareupdatemdv1.FirmwareMdReport cmd, Map item1) {
|
||||
log.debug "checksum: ${cmd.checksum}"
|
||||
log.debug "firmwareId: ${cmd.firmwareId}"
|
||||
log.debug "manufacturerId: ${cmd.manufacturerId}"
|
||||
@@ -300,7 +304,7 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
|
||||
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
|
||||
log.debug "msr: $msr"
|
||||
updateDataValue("MSR", msr)
|
||||
|
||||
|
||||
if ( msr == "010F-0800-2001" ) { //this is the msr and device type for the fibaro motion sensor
|
||||
configure()
|
||||
}
|
||||
@@ -330,7 +334,7 @@ def test() {
|
||||
* @return none
|
||||
*/
|
||||
def updateZwaveParam(params) {
|
||||
if ( params ) {
|
||||
if ( params ) {
|
||||
def pNumber = params.paramNumber
|
||||
def pSize = params.size
|
||||
def pValue = [params.value]
|
||||
@@ -340,7 +344,7 @@ def updateZwaveParam(params) {
|
||||
def cmds = []
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: pValue, parameterNumber: pNumber, size: pSize).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: pNumber).format()
|
||||
delayBetween(cmds, 1000)
|
||||
delayBetween(cmds, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,13 +388,13 @@ def resetParams2StDefaults() {
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [18], parameterNumber: 86, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [28], parameterNumber: 87, size: 1).format()
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 89, size: 1).format()
|
||||
|
||||
|
||||
delayBetween(cmds, 500)
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all of available Fibaro parameters and thier current settings out to the
|
||||
* logging window in the IDE This will be called from the "Fibaro Tweaker" or
|
||||
* Lists all of available Fibaro parameters and thier current settings out to the
|
||||
* logging window in the IDE This will be called from the "Fibaro Tweaker" or
|
||||
* user's own app.
|
||||
*
|
||||
* <p>THIS IS AN ADVANCED OPERATION. USE AT YOUR OWN RISK! READ OEM DOCUMENTATION!
|
||||
@@ -429,7 +433,6 @@ def listCurrentParams() {
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 86).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 87).format()
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: 89).format()
|
||||
|
||||
|
||||
delayBetween(cmds, 500)
|
||||
}
|
||||
|
||||
|
||||
@@ -89,9 +89,9 @@
|
||||
state "whiteLevel", action:"setWhiteLevel", label:'White Level'
|
||||
}
|
||||
standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.illuminance.illuminance.bright", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.illuminance.illuminance.bright", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
state "off", label:'${name}', action:"switch.on", icon:"st.illuminance.illuminance.dark", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
state "turningOn", label:'${name}', icon:"st.illuminance.illuminance.bright", backgroundColor:"#79b821"
|
||||
state "turningOn", label:'${name}', icon:"st.illuminance.illuminance.bright", backgroundColor:"#00A0DC"
|
||||
state "turningOff", label:'${name}', icon:"st.illuminance.illuminance.dark", backgroundColor:"#ffffff"
|
||||
}
|
||||
valueTile("power", "device.power", decoration: "flat") {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
39
devicetypes/smartthings/fortrezz-water-valve.src/README.md
Normal file
39
devicetypes/smartthings/fortrezz-water-valve.src/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# FortrezZ Water Valve
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [FortrezZ Water Valve](https://www.smartthings.com/works-with-smartthings/other/fortrezz-water-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
|
||||
* **Refresh** - _refresh()_ command for status updates
|
||||
* **Sensor** - detects sensor events
|
||||
|
||||
## Device Health
|
||||
|
||||
FortrezZ Water Valve 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:
|
||||
* [FortrezZ Water Valve Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/202088434-FortrezZ-Water-Valve-Shutoff)
|
||||
@@ -14,11 +14,13 @@
|
||||
metadata {
|
||||
definition (name: "Fortrezz Water Valve", namespace: "smartthings", author: "SmartThings") {
|
||||
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"
|
||||
}
|
||||
|
||||
// simulator metadata
|
||||
@@ -34,10 +36,10 @@ 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: "#53a7c0", nextState:"closing"
|
||||
state "closed", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#e86d13", nextState:"opening"
|
||||
state "opening", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#ffe71e"
|
||||
state "closing", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffe71e"
|
||||
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"
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
@@ -48,6 +50,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])
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
log.trace description
|
||||
def result = null
|
||||
@@ -76,6 +88,13 @@ def close() {
|
||||
zwave.switchBinaryV1.switchBinarySet(switchValue: 0xFF).format()
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
def ping() {
|
||||
refresh()
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
zwave.switchBinaryV1.switchBinaryGet().format()
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
standardTile("take", "device.image", width: 1, height: 1, canChangeIcon: false, inactiveLabel: true, canChangeBackground: false) {
|
||||
state "take", label: "Take", action: "Image Capture.take", icon: "st.camera.dropcam", backgroundColor: "#FFFFFF", nextState:"taking"
|
||||
state "taking", label:'Taking', action: "", icon: "st.camera.dropcam", backgroundColor: "#53a7c0"
|
||||
state "taking", label:'Taking', action: "", icon: "st.camera.dropcam", backgroundColor: "#00A0DC"
|
||||
state "image", label: "Take", action: "Image Capture.take", icon: "st.camera.dropcam", backgroundColor: "#FFFFFF", nextState:"taking"
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "GE Link Bulb", namespace: "smartthings", author: "SmartThings") {
|
||||
definition (name: "GE Link Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||
|
||||
capability "Actuator"
|
||||
capability "Configuration"
|
||||
@@ -61,9 +61,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") {
|
||||
|
||||
@@ -31,7 +31,7 @@ metadata {
|
||||
tileAttribute("sessionStatus", key: "PRIMARY_CONTROL") {
|
||||
attributeState "cancelled", action: "timed session.start", icon: "http://f.cl.ly/items/322n181j2K3f281r2s0A/playbutton.png", backgroundColor: "#ffffff", nextState: "running"
|
||||
attributeState "stopped", action: "timed session.start", icon: "http://f.cl.ly/items/322n181j2K3f281r2s0A/playbutton.png", backgroundColor: "#ffffff", nextState: "cancelled"
|
||||
attributeState "running", action: "timed session.stop", icon: "http://f.cl.ly/items/0B3y3p2V3X2l3P3y3W09/stopbutton.png", backgroundColor: "#79b821", nextState: "cancelled"
|
||||
attributeState "running", action: "timed session.stop", icon: "http://f.cl.ly/items/0B3y3p2V3X2l3P3y3W09/stopbutton.png", backgroundColor: "#00A0DC", nextState: "cancelled"
|
||||
}
|
||||
tileAttribute("timeRemaining", key: "SECONDARY_CONTROL") {
|
||||
attributeState "timeRemaining", label:'${currentValue} remaining'
|
||||
@@ -45,7 +45,7 @@ metadata {
|
||||
standardTile("sessionStatusTile", "sessionStatus", width: 1, height: 1, canChangeIcon: true) {
|
||||
state "cancelled", label: "Stopped", action: "timed session.start", backgroundColor: "#ffffff", icon: "http://f.cl.ly/items/1J1g0H2P0S1G1f2O1s1s/icon.png"
|
||||
state "stopped", label: "Stopped", action: "timed session.start", backgroundColor: "#ffffff", icon: "http://f.cl.ly/items/1J1g0H2P0S1G1f2O1s1s/icon.png"
|
||||
state "running", label: "Running", action: "timed session.stop", backgroundColor: "#79b821", icon: "http://f.cl.ly/items/1J1g0H2P0S1G1f2O1s1s/icon.png"
|
||||
state "running", label: "Running", action: "timed session.stop", backgroundColor: "#00A0DC", icon: "http://f.cl.ly/items/1J1g0H2P0S1G1f2O1s1s/icon.png"
|
||||
}
|
||||
|
||||
// duration
|
||||
|
||||
@@ -32,7 +32,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("button", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "off", label: 'Off', action: "switch.on", icon: "st.harmony.harmony-hub-icon", backgroundColor: "#ffffff", nextState: "on"
|
||||
state "on", label: 'On', action: "switch.off", icon: "st.harmony.harmony-hub-icon", backgroundColor: "#79b821", nextState: "off"
|
||||
state "on", label: 'On', action: "switch.off", icon: "st.harmony.harmony-hub-icon", backgroundColor: "#00A0DC", nextState: "off"
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
|
||||
@@ -39,8 +39,8 @@ metadata {
|
||||
|
||||
tiles {
|
||||
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"
|
||||
}
|
||||
valueTile("temperature", "device.temperature", inactiveLabel: false) {
|
||||
state "temperature", label:'${currentValue}°',
|
||||
|
||||
@@ -31,9 +31,9 @@ metadata {
|
||||
tiles (scale: 2){
|
||||
multiAttributeTile(name:"rich-control", 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") {
|
||||
@@ -57,8 +57,18 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
||||
}
|
||||
|
||||
void installed() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}")
|
||||
log.debug "installed()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "updated()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
// parse events into attributes
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
metadata {
|
||||
// Automatically generated. Make future change here.
|
||||
definition (name: "Hue Bridge", namespace: "smartthings", author: "SmartThings") {
|
||||
capability "Bridge"
|
||||
capability "Health Check"
|
||||
|
||||
attribute "networkAddress", "string"
|
||||
@@ -26,7 +27,7 @@ metadata {
|
||||
multiAttributeTile(name:"rich-control"){
|
||||
tileAttribute ("device.status", key: "PRIMARY_CONTROL") {
|
||||
attributeState "Offline", label: '${currentValue}', action: "", icon: "st.Lighting.light99-hue", backgroundColor: "#ffffff"
|
||||
attributeState "Online", label: '${currentValue}', action: "", icon: "st.Lighting.light99-hue", backgroundColor: "#79b821"
|
||||
attributeState "Online", label: '${currentValue}', action: "", icon: "st.Lighting.light99-hue", backgroundColor: "#00A0DC"
|
||||
}
|
||||
}
|
||||
valueTile("doNotRemove", "v", decoration: "flat", height: 2, width: 6, inactiveLabel: false) {
|
||||
@@ -44,8 +45,18 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
||||
}
|
||||
|
||||
void installed() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}")
|
||||
log.debug "installed()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "updated()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
// parse events into attributes
|
||||
|
||||
@@ -32,9 +32,9 @@ metadata {
|
||||
tiles (scale: 2){
|
||||
multiAttributeTile(name:"rich-control", 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") {
|
||||
@@ -66,8 +66,18 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
||||
}
|
||||
|
||||
void installed() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}")
|
||||
log.debug "installed()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "updated()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
// parse events into attributes
|
||||
|
||||
@@ -27,9 +27,9 @@ metadata {
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"rich-control", type: "lighting", 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") {
|
||||
@@ -50,8 +50,17 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
||||
}
|
||||
|
||||
void installed() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}")
|
||||
log.debug "installed()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
initialize()
|
||||
}
|
||||
|
||||
// parse events into attributes
|
||||
|
||||
@@ -28,9 +28,9 @@ metadata {
|
||||
tiles (scale: 2){
|
||||
multiAttributeTile(name:"rich-control", 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") {
|
||||
@@ -55,8 +55,18 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
||||
}
|
||||
|
||||
void installed() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}")
|
||||
log.debug "installed()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "updated()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
// parse events into attributes
|
||||
|
||||
@@ -29,7 +29,7 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("presence", "device.presence", width: 2, height: 2, canChangeBackground: true) {
|
||||
state("present", labelIcon:"st.presence.tile.mobile-present", backgroundColor:"#53a7c0")
|
||||
state("present", labelIcon:"st.presence.tile.mobile-present", backgroundColor:"#00A0DC")
|
||||
state("not present", labelIcon:"st.presence.tile.mobile-not-present", backgroundColor:"#ffffff")
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "LIFX Color Bulb", namespace: "smartthings", author: "LIFX") {
|
||||
definition (name: "LIFX Color Bulb", namespace: "smartthings", author: "LIFX", ocfDeviceType: "oic.d.light") {
|
||||
capability "Actuator"
|
||||
capability "Color Control"
|
||||
capability "Color Temperature"
|
||||
@@ -14,6 +14,7 @@ metadata {
|
||||
capability "Refresh"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
capability "Light"
|
||||
}
|
||||
|
||||
simulator {
|
||||
@@ -23,9 +24,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:"http://hosted.lifx.co/smartthings/v1/196xOn.png", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"http://hosted.lifx.co/smartthings/v1/196xOn.png", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"http://hosted.lifx.co/smartthings/v1/196xOff.png", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'Turning on', action:"switch.off", icon:"http://hosted.lifx.co/smartthings/v1/196xOn.png", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'Turning on', action:"switch.off", icon:"http://hosted.lifx.co/smartthings/v1/196xOn.png", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'Turning off', action:"switch.on", icon:"http://hosted.lifx.co/smartthings/v1/196xOff.png", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
|
||||
@@ -63,8 +64,18 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"cloud\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device?.hub?.hardwareID}\"}", displayed: false)
|
||||
}
|
||||
|
||||
void installed() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"cloud\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device?.hub?.hardwareID}\"}")
|
||||
log.debug "installed()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "updated()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
// handle commands
|
||||
@@ -189,7 +200,7 @@ def off() {
|
||||
|
||||
def refresh() {
|
||||
log.debug "Executing 'refresh'"
|
||||
|
||||
|
||||
def resp = parent.apiGET("/lights/${selector()}")
|
||||
if (resp.status == 404) {
|
||||
state.online = false
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "LIFX White Bulb", namespace: "smartthings", author: "LIFX") {
|
||||
definition (name: "LIFX White Bulb", namespace: "smartthings", author: "LIFX", ocfDeviceType: "oic.d.light") {
|
||||
capability "Actuator"
|
||||
capability "Color Temperature"
|
||||
capability "Switch"
|
||||
@@ -13,6 +13,7 @@ metadata {
|
||||
capability "Refresh"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
capability "Light"
|
||||
}
|
||||
|
||||
simulator {
|
||||
@@ -22,9 +23,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:"http://hosted.lifx.co/smartthings/v1/196xOn.png", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"http://hosted.lifx.co/smartthings/v1/196xOn.png", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"http://hosted.lifx.co/smartthings/v1/196xOff.png", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'Turning on', action:"switch.off", icon:"http://hosted.lifx.co/smartthings/v1/196xOn.png", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'Turning on', action:"switch.off", icon:"http://hosted.lifx.co/smartthings/v1/196xOn.png", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'Turning off', action:"switch.on", icon:"http://hosted.lifx.co/smartthings/v1/196xOff.png", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
|
||||
@@ -54,8 +55,18 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"cloud\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device?.hub?.hardwareID}\"}", displayed: false)
|
||||
}
|
||||
|
||||
void installed() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"cloud\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device?.hub?.hardwareID}\"}")
|
||||
log.debug "installed()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "updated()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
// handle commands
|
||||
@@ -118,7 +129,7 @@ def off() {
|
||||
|
||||
def refresh() {
|
||||
log.debug "Executing 'refresh'"
|
||||
|
||||
|
||||
def resp = parent.apiGET("/lights/${selector()}")
|
||||
if (resp.status == 404) {
|
||||
state.online = false
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import groovy.json.JsonOutput
|
||||
/**
|
||||
* Logitech Harmony Hub
|
||||
*
|
||||
@@ -7,6 +8,7 @@ metadata {
|
||||
definition (name: "Logitech Harmony Hub C2C", namespace: "smartthings", author: "SmartThings") {
|
||||
capability "Media Controller"
|
||||
capability "Refresh"
|
||||
capability "Health Check"
|
||||
|
||||
command "activityoff"
|
||||
command "alloff"
|
||||
@@ -38,6 +40,20 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "cloud", scheme:"untracked"]), displayed: false)
|
||||
}
|
||||
|
||||
def installed() {
|
||||
log.debug "installed()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "updated()"
|
||||
initialize()
|
||||
}
|
||||
|
||||
def startActivity(String activityId) {
|
||||
log.debug "Executing 'Start Activity'"
|
||||
log.trace parent.activity("$device.deviceNetworkId-$activityId","start")
|
||||
@@ -58,6 +74,10 @@ def poll() {
|
||||
log.trace parent.poll()
|
||||
}
|
||||
|
||||
def ping() {
|
||||
refresh()
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
log.debug "Executing 'Refresh'"
|
||||
log.trace parent.poll()
|
||||
|
||||
@@ -36,6 +36,7 @@ metadata {
|
||||
capability "Switch"
|
||||
capability "Refresh"
|
||||
capability "Contact Sensor"
|
||||
capability "Light"
|
||||
|
||||
attribute "powered", "string"
|
||||
|
||||
@@ -53,11 +54,11 @@ metadata {
|
||||
// UI tile definitions
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "doorClosed", label: "Closed", action: "on", icon: "st.doors.garage.garage-closed", backgroundColor: "#79b821"
|
||||
state "doorOpen", label: "Open", action: "on", icon: "st.doors.garage.garage-open", backgroundColor: "#ffa81e"
|
||||
state "doorOpening", label: "Opening", action: "on", icon: "st.doors.garage.garage-opening", backgroundColor: "#ffa81e"
|
||||
state "doorClosing", label: "Closing", action: "on", icon: "st.doors.garage.garage-closing", backgroundColor: "#ffa81e"
|
||||
state "on", label: "Actuate", action: "off", icon: "st.doors.garage.garage-closed", backgroundColor: "#53a7c0"
|
||||
state "doorClosed", label: "Closed", action: "on", icon: "st.doors.garage.garage-closed", backgroundColor: "#00A0DC"
|
||||
state "doorOpen", label: "Open", action: "on", icon: "st.doors.garage.garage-open", backgroundColor: "#e86d13"
|
||||
state "doorOpening", label: "Opening", action: "on", icon: "st.doors.garage.garage-opening", backgroundColor: "#e86d13"
|
||||
state "doorClosing", label: "Closing", action: "on", icon: "st.doors.garage.garage-closing", backgroundColor: "#00A0DC"
|
||||
state "on", label: "Actuate", action: "off", icon: "st.doors.garage.garage-closed", backgroundColor: "#00A0DC"
|
||||
state "off", label: '${name}', action: "on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
|
||||
}
|
||||
standardTile("contact", "device.contact", inactiveLabel: false) {
|
||||
|
||||
@@ -27,8 +27,8 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("presence", "device.presence", width: 2, height: 2, canChangeBackground: true) {
|
||||
state("present", labelIcon:"st.presence.tile.mobile-present", backgroundColor:"#53a7c0")
|
||||
state("not present", labelIcon:"st.presence.tile.mobile-not-present", backgroundColor:"#ebeef2")
|
||||
state("present", labelIcon:"st.presence.tile.mobile-present", backgroundColor:"#00A0DC")
|
||||
state("not present", labelIcon:"st.presence.tile.mobile-not-present", backgroundColor:"#ffffff")
|
||||
}
|
||||
main "presence"
|
||||
details "presence"
|
||||
|
||||
@@ -32,7 +32,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "off", label: 'Push', action: "momentary.push", backgroundColor: "#ffffff", nextState: "on"
|
||||
state "on", label: 'Push', action: "momentary.push", backgroundColor: "#53a7c0"
|
||||
state "on", label: 'Push', action: "momentary.push", backgroundColor: "#00A0DC"
|
||||
}
|
||||
main "switch"
|
||||
details "switch"
|
||||
|
||||
@@ -28,8 +28,8 @@ metadata {
|
||||
// UI tile definitions
|
||||
tiles {
|
||||
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")
|
||||
}
|
||||
|
||||
main "motion"
|
||||
|
||||
@@ -21,6 +21,7 @@ metadata {
|
||||
capability "Configuration"
|
||||
capability "Battery"
|
||||
capability "Refresh"
|
||||
capability "Sensor"
|
||||
|
||||
command "enrollResponse"
|
||||
|
||||
@@ -31,8 +32,8 @@ metadata {
|
||||
|
||||
tiles {
|
||||
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")
|
||||
}
|
||||
|
||||
valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false) {
|
||||
|
||||
@@ -24,6 +24,7 @@ metadata {
|
||||
capability "Contact Sensor"
|
||||
capability "Refresh"
|
||||
capability "Health Check"
|
||||
capability "Sensor"
|
||||
|
||||
command "enrollResponse"
|
||||
|
||||
@@ -41,8 +42,8 @@ metadata {
|
||||
|
||||
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("battery", "device.battery", decoration: "flat", inactiveLabel: false) {
|
||||
|
||||
@@ -31,7 +31,7 @@ metadata {
|
||||
tiles {
|
||||
standardTile("button", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "off", label: 'Off', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "on"
|
||||
state "on", label: 'On', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821", nextState: "off"
|
||||
state "on", label: 'On', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC", nextState: "off"
|
||||
}
|
||||
main "button"
|
||||
details "button"
|
||||
|
||||
@@ -31,7 +31,7 @@ metadata {
|
||||
// UI tile definitions
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true, canChangeBackground: true) {
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
|
||||
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Open/Closed Sensor", namespace: "smartthings", author: "SmartThings") {
|
||||
definition (name: "Open/Closed Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.contact") {
|
||||
capability "Contact Sensor"
|
||||
capability "Sensor"
|
||||
|
||||
@@ -29,8 +29,8 @@ metadata {
|
||||
// UI tile definitions
|
||||
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"
|
||||
}
|
||||
|
||||
main "contact"
|
||||
@@ -44,7 +44,7 @@ def parse(String description) {
|
||||
if (description.startsWith("zone")) {
|
||||
resMap = createEvent(name: "contact", value: zigbee.parseZoneStatus(description).isAlarm1Set() ? "open" : "closed")
|
||||
}
|
||||
|
||||
|
||||
log.debug "Parse returned $resMap"
|
||||
return resMap
|
||||
}
|
||||
|
||||
2
devicetypes/smartthings/plant-link.src/.st-ignore
Normal file
2
devicetypes/smartthings/plant-link.src/.st-ignore
Normal file
@@ -0,0 +1,2 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
35
devicetypes/smartthings/plant-link.src/README.md
Normal file
35
devicetypes/smartthings/plant-link.src/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Plant Link
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [OSO Technologies PlantLink Soil Moisture Sensor](https://www.smartthings.com/works-with-smartthings/oso-technologies/oso-technologies-plantlink-soil-moisture-sensor)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Relative Humidity Measurement** - allows reading the relative humidity from devices that support it
|
||||
* **Sensor** - detects sensor events
|
||||
* **Battery** - defines device uses a battery
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
## Device Health
|
||||
|
||||
Plant Link sensor is a Z-wave sleepy device and checks in every 15 minutes.
|
||||
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
|
||||
|
||||
* __32min__ checkInterval
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the sensor is out of range.
|
||||
Pairing needs to be tried again by placing the sensor closer to the hub.
|
||||
Instructions related to pairing, resetting and removing the different motion sensors from SmartThings can be found in the following links
|
||||
for the different models:
|
||||
* [OSO Technologies PlantLink Soil Moisture Sensor Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206868986-PlantLink-Soil-Moisture-Sensor)
|
||||
@@ -21,8 +21,10 @@ metadata {
|
||||
capability "Relative Humidity Measurement"
|
||||
capability "Battery"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint profileId: "0104", inClusters: "0000,0003,0405,FC08", outClusters: "0003"
|
||||
fingerprint endpoint: "1", profileId: "0104", inClusters: "0000,0001,0003,0B04", outClusters: "0003", manufacturer: "", model: "", deviceJoinName: "OSO Technologies PlantLink Soil Moisture Sensor"
|
||||
}
|
||||
|
||||
tiles {
|
||||
@@ -48,6 +50,11 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def updated() {
|
||||
// Device-Watch allows 2 check-in misses from device
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||
}
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
def parse(String description) {
|
||||
log.debug "Parse description $description"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "RGBW Light", namespace: "smartthings", author: "SmartThings") {
|
||||
definition (name: "RGBW Light", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||
capability "Switch Level"
|
||||
capability "Color Control"
|
||||
capability "Color Temperature"
|
||||
@@ -37,9 +37,9 @@ metadata {
|
||||
}
|
||||
|
||||
standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00a0dc", nextState:"turningOff"
|
||||
state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00a0dc", nextState:"turningOff"
|
||||
state "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
standardTile("reset", "device.reset", inactiveLabel: false, decoration: "flat") {
|
||||
|
||||
@@ -42,9 +42,9 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
state "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 3, inactiveLabel: false) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* Date: 2013-03-05
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "SmartAlert Siren", namespace: "smartthings", author: "SmartThings") {
|
||||
definition (name: "SmartAlert Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.smokedetector") {
|
||||
capability "Actuator"
|
||||
capability "Switch"
|
||||
capability "Sensor"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* Date: 2013-12-04
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "SmartPower Dimming Outlet", namespace: "smartthings", author: "SmartThings") {
|
||||
definition (name: "SmartPower Dimming Outlet", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.smartplug") {
|
||||
capability "Switch"
|
||||
capability "Switch Level"
|
||||
capability "Power Meter"
|
||||
@@ -24,6 +24,7 @@ metadata {
|
||||
capability "Refresh"
|
||||
capability "Actuator"
|
||||
capability "Sensor"
|
||||
capability "Outlet"
|
||||
|
||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "4257050-ZHAC"
|
||||
|
||||
@@ -79,7 +80,8 @@ def parse(String description) {
|
||||
*/
|
||||
event.value = event.value / 10
|
||||
}
|
||||
return event
|
||||
|
||||
return event ? createEvent(event) : event
|
||||
}
|
||||
|
||||
def setLevel(value) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user