mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-16 21:03:28 +00:00
Compare commits
195 Commits
PROD_2017.
...
MSA-1925-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90d8534b46 | ||
|
|
7e8baeeb0b | ||
|
|
62991f8d23 | ||
|
|
ad824a9dd8 | ||
|
|
11f2775568 | ||
|
|
83b65c0d87 | ||
|
|
e641759a47 | ||
|
|
7820b39b2b | ||
|
|
6a76a8ee39 | ||
|
|
980bef6879 | ||
|
|
120935f14e | ||
|
|
c864fc521e | ||
|
|
032f4a92d4 | ||
|
|
6d528683e6 | ||
|
|
8bcbe7b924 | ||
|
|
69dd13f333 | ||
|
|
016425b7c8 | ||
|
|
c164b201ca | ||
|
|
030dd47b69 | ||
|
|
cc68534b47 | ||
|
|
5e07494dff | ||
|
|
573630232f | ||
|
|
29c7049d60 | ||
|
|
03a79b8bb5 | ||
|
|
d91fc1c9d1 | ||
|
|
db7288f245 | ||
|
|
b59d979fbf | ||
|
|
fc32031555 | ||
|
|
f445ffc67c | ||
|
|
5b39a9f840 | ||
|
|
95c383a2ea | ||
|
|
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 | ||
|
|
bcfece27c4 | ||
|
|
26f9690190 | ||
|
|
640f9413c3 | ||
|
|
1c52f80eae | ||
|
|
de4d52a28b | ||
|
|
6892965cf1 | ||
|
|
b36a985d92 | ||
|
|
8a3c9edf0a | ||
|
|
f734c5490b | ||
|
|
4dac7b5379 | ||
|
|
a79d56e467 | ||
|
|
0a4d56be04 | ||
|
|
1326881142 | ||
|
|
d30494172f | ||
|
|
be0c16c76d | ||
|
|
16cb20685c | ||
|
|
7a7a08ea6e | ||
|
|
950a33dc74 | ||
|
|
ef8611d2ea | ||
|
|
648dee90b6 |
2
devicetypes/drzwave/ezmultipli.src/.st-ignore
Normal file
2
devicetypes/drzwave/ezmultipli.src/.st-ignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.st-ignore
|
||||||
|
README.md
|
||||||
44
devicetypes/drzwave/ezmultipli.src/README.md
Normal file
44
devicetypes/drzwave/ezmultipli.src/README.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Express Controls EZMultiPli
|
||||||
|
|
||||||
|
Works with:
|
||||||
|
|
||||||
|
* [Express Controls EZMultiPli](https://www.smartthings.com/works-with-smartthings/)
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
* [Release Notes](#release-notes)
|
||||||
|
* [Capabilities](#capabilities)
|
||||||
|
* [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
## Release Notes
|
||||||
|
|
||||||
|
* **2017-04-19** - _dkirker_ - Update default config values in config value range check functions, use lux if lum option is null, fix NullPointerException on initial pairing when color data has not been set (and set the default color data!)
|
||||||
|
* **2017-04-10** - _DrZwave_ (with help from Donald 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
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
* **Actuator** - represents that a Device has commands
|
||||||
|
* **Sensor** - detects sensor events
|
||||||
|
* **Motion Sensor** - can detect motion
|
||||||
|
* **Temperature Measurement** - defines device measures current temperature
|
||||||
|
* **Illuminance Measurement** - gives the illuminance reading from devices that support it
|
||||||
|
* **Switch** - can detect state (possible values: on/off)
|
||||||
|
* **Color Control** - represents that the color attributes of a device can be controlled (hue, saturation, color value
|
||||||
|
* **Configuration** - configure() command called when device is installed or device preferences updated
|
||||||
|
* **Refresh** - refresh() command for status updates
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
405
devicetypes/drzwave/ezmultipli.src/ezmultipli.groovy
Normal file
405
devicetypes/drzwave/ezmultipli.src/ezmultipli.groovy
Normal file
@@ -0,0 +1,405 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
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 == 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 == 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) {
|
||||||
|
// The EZMultiPli sets the color back to #ffffff on "off" or at init, so update the ST device to reflect this.
|
||||||
|
if (device.latestState("color") == null || (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=6
|
||||||
|
}
|
||||||
|
def liteTempVal = value.toInteger()
|
||||||
|
switch (liteTempVal) {
|
||||||
|
case { it < 0 }:
|
||||||
|
return 6 // 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=2
|
||||||
|
}
|
||||||
|
def onTimeVal = value.toInteger()
|
||||||
|
switch (onTimeVal) {
|
||||||
|
case { it < 0 }:
|
||||||
|
return 2 // 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
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
metadata {
|
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 "Battery"
|
||||||
capability "Contact Sensor"
|
capability "Contact Sensor"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
|
|||||||
@@ -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,12 +14,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
metadata {
|
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 "Battery"
|
||||||
capability "Contact Sensor"
|
capability "Contact Sensor"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Tamper Alert"
|
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: ""
|
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: ""
|
||||||
}
|
}
|
||||||
@@ -199,6 +200,8 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
|
|||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "Executing '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 = []
|
def cmds = []
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
metadata {
|
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 "Battery"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
@@ -34,13 +34,13 @@ metadata {
|
|||||||
tiles(scale: 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
|
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") {
|
tileAttribute("device.water", key:"PRIMARY_CONTROL") {
|
||||||
attributeState("dry", icon:"st.alarm.water.dry", backgroundColor:"#00a0dc")
|
attributeState("dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff")
|
||||||
attributeState("wet", icon:"st.alarm.water.wet", backgroundColor:"#e86d13")
|
attributeState("wet", icon:"st.alarm.water.wet", backgroundColor:"#00a0dc")
|
||||||
}
|
}
|
||||||
|
|
||||||
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
|
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
|
||||||
attributeState("active", label:'tamper active', backgroundColor:"#00a0dc")
|
attributeState("active", label:'tamper active', backgroundColor:"#cccccc")
|
||||||
attributeState("inactive", label:'tamper inactive', backgroundColor:"#cccccc")
|
attributeState("inactive", label:'tamper inactive', backgroundColor:"#00A0DC")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
metadata {
|
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 "Battery"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Illuminance Measurement"
|
capability "Illuminance Measurement"
|
||||||
|
|||||||
@@ -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 "Sensor"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
command "getLevel"
|
command "getLevel"
|
||||||
command "getOnOff"
|
command "getOnOff"
|
||||||
@@ -20,10 +21,7 @@ metadata {
|
|||||||
command "setZigBeeIdTile"
|
command "setZigBeeIdTile"
|
||||||
command "clearObstruction"
|
command "clearObstruction"
|
||||||
|
|
||||||
fingerprint endpoint: "1",
|
fingerprint endpoint: "1", profileId: "0104", inClusters: "0000,0001,0003,0004,0005,0006,0008,0020,0402,0403,0B05,FC01,FC02", outClusters: "0019"
|
||||||
profileId: "0104",
|
|
||||||
inClusters: "0000,0001,0003,0004,0005,0006,0008,0020,0402,0403,0B05,FC01,FC02",
|
|
||||||
outClusters: "0019"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulator metadata
|
// simulator metadata
|
||||||
@@ -466,15 +464,27 @@ def refresh() {
|
|||||||
getBattery()
|
getBattery()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PING is used by Device-Watch in attempt to reach the Device
|
||||||
|
* */
|
||||||
|
def ping() {
|
||||||
|
return refresh()
|
||||||
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "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
|
// get ZigBee ID by hidden tile because that's the only way we can do it
|
||||||
setZigBeeIdTile()
|
setZigBeeIdTile()
|
||||||
|
|
||||||
def configCmds = [
|
def configCmds = [
|
||||||
// bind reporting clusters to hub
|
// 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 0x0008 {${device.zigbeeId}} {}", "delay 500",
|
||||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0402 {${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",
|
"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",
|
// "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
|
||||||
]
|
]
|
||||||
|
|
||||||
return configCmds + refresh()
|
return configCmds + zigbee.onOffConfig() + refresh()
|
||||||
}
|
}
|
||||||
|
|||||||
2
devicetypes/osotech/plantlink.src/.st-ignore
Normal file
2
devicetypes/osotech/plantlink.src/.st-ignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.st-ignore
|
||||||
|
README.md
|
||||||
33
devicetypes/osotech/plantlink.src/README.md
Normal file
33
devicetypes/osotech/plantlink.src/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Osotech 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
|
||||||
|
|
||||||
|
* **Sensor** - detects sensor events
|
||||||
|
* **Health Check** - indicates ability to get device health notifications
|
||||||
|
|
||||||
|
## Device Health
|
||||||
|
|
||||||
|
Plant Link sensor is a ZigBee 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)
|
||||||
@@ -24,6 +24,7 @@ import groovy.json.JsonBuilder
|
|||||||
metadata {
|
metadata {
|
||||||
definition (name: "PlantLink", namespace: "OsoTech", author: "Oso Technologies") {
|
definition (name: "PlantLink", namespace: "OsoTech", author: "Oso Technologies") {
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
command "setStatusIcon"
|
command "setStatusIcon"
|
||||||
command "setPlantFuelLevel"
|
command "setPlantFuelLevel"
|
||||||
@@ -70,6 +71,16 @@ 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])
|
||||||
|
}
|
||||||
|
|
||||||
|
def installed() {
|
||||||
|
// 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])
|
||||||
|
}
|
||||||
|
|
||||||
def setStatusIcon(value){
|
def setStatusIcon(value){
|
||||||
def status = ''
|
def status = ''
|
||||||
switch (value) {
|
switch (value) {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Spruce Controller - Pre Release V2 10/11/2015
|
* Spruce Controller V2_4 Big Tiles *
|
||||||
*
|
|
||||||
* Copyright 2015 Plaid Systems
|
* Copyright 2015 Plaid Systems
|
||||||
*
|
*
|
||||||
* Author: NC
|
* Author: NC
|
||||||
@@ -21,82 +20,96 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "Spruce Controller", namespace: "plaidsystems", author: "NCauffman") {
|
definition (name: 'Spruce Controller', namespace: 'plaidsystems', author: 'Plaid Systems') {
|
||||||
capability "Switch"
|
capability 'Switch'
|
||||||
capability "Configuration"
|
capability 'Configuration'
|
||||||
capability "Refresh"
|
capability 'Refresh'
|
||||||
capability "Actuator"
|
capability 'Actuator'
|
||||||
capability "Valve"
|
capability 'Valve'
|
||||||
|
|
||||||
attribute "switch", "string"
|
attribute 'switch', 'string'
|
||||||
attribute "switch1", "string"
|
attribute 'switch1', 'string'
|
||||||
attribute "switch2", "string"
|
attribute 'switch2', 'string'
|
||||||
attribute "switch8", "string"
|
attribute 'switch8', 'string'
|
||||||
attribute "switch5", "string"
|
attribute 'switch5', 'string'
|
||||||
attribute "switch3", "string"
|
attribute 'switch3', 'string'
|
||||||
attribute "switch4", "string"
|
attribute 'switch4', 'string'
|
||||||
attribute "switch6", "string"
|
attribute 'switch6', 'string'
|
||||||
attribute "switch7", "string"
|
attribute 'switch7', 'string'
|
||||||
attribute "switch9", "string"
|
attribute 'switch9', 'string'
|
||||||
attribute "switch10", "string"
|
attribute 'switch10', 'string'
|
||||||
attribute "switch11", "string"
|
attribute 'switch11', 'string'
|
||||||
attribute "switch12", "string"
|
attribute 'switch12', 'string'
|
||||||
attribute "switch13", "string"
|
attribute 'switch13', 'string'
|
||||||
attribute "switch14", "string"
|
attribute 'switch14', 'string'
|
||||||
attribute "switch15", "string"
|
attribute 'switch15', 'string'
|
||||||
attribute "switch16", "string"
|
attribute 'switch16', 'string'
|
||||||
attribute "status", "string"
|
attribute 'rainsensor', 'string'
|
||||||
|
attribute 'status', 'string'
|
||||||
|
attribute 'tileMessage', 'string'
|
||||||
|
attribute 'minutes', 'string'
|
||||||
|
attribute 'VALUE_UP', 'string'
|
||||||
|
attribute 'VALUE_DOWN', 'string'
|
||||||
|
|
||||||
command "programOn"
|
command 'levelUp'
|
||||||
command "programOff"
|
command 'levelDown'
|
||||||
command "on"
|
command 'programOn'
|
||||||
command "off"
|
command 'programOff'
|
||||||
command "z1on"
|
command 'programWait'
|
||||||
command "z1off"
|
command 'programEnd'
|
||||||
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 "refresh"
|
command 'on'
|
||||||
command "rain"
|
command 'off'
|
||||||
command "manual"
|
command 'zon'
|
||||||
command "setDisplay"
|
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 'config'
|
||||||
command "writeTime"
|
command 'refresh'
|
||||||
command "writeType"
|
command 'rain'
|
||||||
command "notify"
|
command 'manual'
|
||||||
command "updated"
|
command 'manualTime'
|
||||||
|
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"
|
//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"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,161 +118,229 @@ metadata {
|
|||||||
// status messages
|
// status messages
|
||||||
|
|
||||||
// reply messages
|
// reply messages
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
preferences {
|
preferences {
|
||||||
input description: "Press Configure button after making changes to these preferences", displayDuringSetup: true, type: "paragraph", element: "paragraph", title: ""
|
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 "RainEnable", "bool", title: "Rain Sensor Attached?", required: false, displayDuringSetup: true
|
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 "ManualTime", "number", title: "Automatic shutoff time when a zone is turned on manually?", required: false, displayDuringSetup: true
|
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
|
// UI tile definitions
|
||||||
tiles {
|
tiles {
|
||||||
|
|
||||||
standardTile("status", "device.status") {
|
multiAttributeTile(name:"switchall", type:"generic", width:6, height:4) {
|
||||||
state "schedule", label: 'Schedule Set', icon: "http://www.plaidsystems.com/smartthings/st_spruce_leaf_225_t.png"
|
tileAttribute('device.status', key: 'PRIMARY_CONTROL') {
|
||||||
state "finished", label: 'Spruce Finished', icon: "st.Outdoor.outdoor5", backgroundColor: "#46c2e8"
|
attributeState 'schedule', label: 'Ready', icon: 'http://www.plaidsystems.com/smartthings/st_spruce_leaf_225_top.png'
|
||||||
state "raintoday", label: 'Rain Today', icon: "st.custom.wuk.nt_chancerain"
|
attributeState 'finished', label: 'Finished', icon: 'st.Outdoor.outdoor5', backgroundColor: '#46c2e8'
|
||||||
state "rainy", label: 'Previous Rain', icon: "st.custom.wuk.nt_chancerain"
|
attributeState 'raintoday', label: 'Rain Today', icon: 'http://www.plaidsystems.com/smartthings/st_rain.png', backgroundColor: '#d65fe3'
|
||||||
state "raintom", label: 'Rain Tomorrow', icon: "st.custom.wuk.nt_chancerain"
|
attributeState 'rainy', label: 'Rain', icon: 'http://www.plaidsystems.com/smartthings/st_rain.png', backgroundColor: '#d65fe3'
|
||||||
state "donewweek", label: 'Spruce Finished', icon: "st.Outdoor.outdoor5", backgroundColor: "#00A0DC"
|
attributeState 'raintom', label: 'Rain Tomorrow', icon: 'http://www.plaidsystems.com/smartthings/st_rain.png', backgroundColor: '#d65fe3'
|
||||||
state "skipping", label: 'Skip Today', icon: "st.Outdoor.outdoor20", backgroundColor: "#36cfe3"
|
attributeState 'donewweek', label: 'Finished', icon: 'st.Outdoor.outdoor5', backgroundColor: '#00A0DC'
|
||||||
state "moisture", label: '', icon: "st.Weather.weather2", backgroundColor: "#36cfe3"
|
attributeState 'skipping', label: 'Skip', icon: 'st.Outdoor.outdoor20', backgroundColor: '#46c2e8'
|
||||||
state "pause", label: 'PAUSE', icon: "st.contact.contact.open", backgroundColor: "#e86d13"
|
attributeState 'moisture', label: 'Ready', icon: 'st.Weather.weather2', backgroundColor: '#46c2e8'
|
||||||
state "active", label: 'Active', icon: "st.Outdoor.outdoor12", backgroundColor: "#3DC72E"
|
attributeState 'pause', label: 'PAUSE', icon: 'st.contact.contact.open', backgroundColor: '#e86d13'
|
||||||
state "season", label: 'Seasonal Adjustment', icon: "st.Outdoor.outdoor17", backgroundColor: "#ffb900"
|
attributeState 'delayed', label: 'Delayed', icon: 'st.contact.contact.open', backgroundColor: '#e86d13'
|
||||||
state "disable", label: 'Disabled', icon: "st.secondary.off", backgroundColor: "#cccccc"
|
attributeState 'active', label: 'Active', icon: 'st.Outdoor.outdoor12', backgroundColor: '#3DC72E'
|
||||||
state "warning", label: '', icon: "st.categories.damageAndDanger", backgroundColor: "#ffff7f"
|
attributeState 'season', label: 'Adjust', icon: 'st.Outdoor.outdoor17', backgroundColor: '#ffb900'
|
||||||
state "alarm", label: 'Alarm', icon: "st.categories.damageAndDanger", backgroundColor: "#f9240c"
|
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") {
|
valueTile('minutes', 'device.minutes'){
|
||||||
//state "programOff", label: 'Start Program', action: "programOn", icon: "st.sonos.play-icon", backgroundColor: "#a9a9a9"
|
state 'minutes', label: '${currentValue} min'
|
||||||
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"
|
valueTile('dummy', 'device.minutes'){
|
||||||
state "on", label: 'Program Running', action: "off", icon: "st.Outdoor.outdoor12", backgroundColor: "#3DC72E"
|
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("rainsensor", "device.rainsensor") {
|
standardTile("rainsensor", "device.rainsensor", decoration: 'flat') {
|
||||||
state "rainSensrooff", label: 'Rain Sensor Clear', icon: "st.Weather.weather14", backgroundColor: "#a9a9a9"
|
state "rainSensoroff", label: 'sensor', icon: 'http://www.plaidsystems.com/smartthings/st_drop_on.png'
|
||||||
state "rainSensoron", label: 'Rain Detected', icon: "st.Weather.weather10", backgroundColor: "#f6e10e"
|
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("switch1", "device.switch1") {
|
standardTile('switch1', 'device.switch1', inactiveLabel: false) {
|
||||||
state "z1off", label: '1', action: "z1on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z1on', label: '1', action: 'z1off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch2", "device.switch2") {
|
standardTile('switch2', 'device.switch2', inactiveLabel: false) {
|
||||||
state "z2off", label: '2', action: "z2on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z2on', label: '2', action: 'z2off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch3", "device.switch3", inactiveLabel: false) {
|
standardTile('switch3', 'device.switch3', inactiveLabel: false) {
|
||||||
state "z3off", label: '3', action: "z3on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z3on', label: '3', action: 'z3off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch4", "device.switch4", inactiveLabel: false) {
|
standardTile('switch4', 'device.switch4', inactiveLabel: false) {
|
||||||
state "z4off", label: '4', action: "z4on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z4on', label: '4', action: 'z4off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch5", "device.switch5", inactiveLabel: false) {
|
standardTile('switch5', 'device.switch5', inactiveLabel: false) {
|
||||||
state "z5off", label: '5', action: "z5on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z5on', label: '5', action: 'z5off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch6", "device.switch6", inactiveLabel: false) {
|
standardTile('switch6', 'device.switch6', inactiveLabel: false) {
|
||||||
state "z6off", label: '6', action: "z6on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z6on', label: '6', action: 'z6off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch7", "device.switch7", inactiveLabel: false) {
|
standardTile('switch7', 'device.switch7', inactiveLabel: false) {
|
||||||
state "z7off", label: '7', action: "z7on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z7on', label: '7', action: 'z7off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch8", "device.switch8", inactiveLabel: false) {
|
standardTile('switch8', 'device.switch8', inactiveLabel: false) {
|
||||||
state "z8off", label: '8', action: "z8on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z8on', label: '8', action: 'z8off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch9", "device.switch9", inactiveLabel: false) {
|
standardTile('switch9', 'device.switch9', inactiveLabel: false) {
|
||||||
state "z9off", label: '9', action: "z9on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z9on', label: '9', action: 'z9off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch10", "device.switch10", inactiveLabel: false) {
|
standardTile('switch10', 'device.switch10', inactiveLabel: false) {
|
||||||
state "z10off", label: '10', action: "z10on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z10on', label: '10', action: 'z10off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch11", "device.switch11", inactiveLabel: false) {
|
standardTile('switch11', 'device.switch11', inactiveLabel: false) {
|
||||||
state "z11off", label: '11', action: "z11on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z11on', label: '11', action: 'z11off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch12", "device.switch12", inactiveLabel: false) {
|
standardTile('switch12', 'device.switch12', inactiveLabel: false) {
|
||||||
state "z12off", label: '12', action: "z12on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z12on', label: '12', action: 'z12off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch13", "device.switch13", inactiveLabel: false) {
|
standardTile('switch13', 'device.switch13', inactiveLabel: false) {
|
||||||
state "z13off", label: '13', action: "z13on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z13on', label: '13', action: 'z13off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch14", "device.switch14", inactiveLabel: false) {
|
standardTile('switch14', 'device.switch14', inactiveLabel: false) {
|
||||||
state "z14off", label: '14', action: "z14on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z14on', label: '14', action: 'z14off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch15", "device.switch15", inactiveLabel: false) {
|
standardTile('switch15', 'device.switch15', inactiveLabel: false) {
|
||||||
state "z15off", label: '15', action: "z15on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z15on', label: '15', action: 'z15off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("switch16", "device.switch16", inactiveLabel: false) {
|
standardTile('switch16', 'device.switch16', inactiveLabel: false) {
|
||||||
state "z16off", label: '16', action: "z16on", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
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"
|
state 'z16on', label: '16', action: 'z16off', icon: 'st.valves.water.open', backgroundColor: '#00A0DC'
|
||||||
}
|
}
|
||||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
standardTile('refresh', 'device.switch', inactiveLabel: false, decoration: 'flat') {
|
||||||
state "default", action: "refresh", icon:"st.secondary.refresh"
|
state 'default', action: 'refresh', icon:'st.secondary.refresh'//-icon'
|
||||||
}
|
}
|
||||||
standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
|
standardTile('configure', 'device.configure', inactiveLabel: false, decoration: 'flat') {
|
||||||
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
|
state 'configure', label:'', action:'configuration.configure', icon:'http://www.plaidsystems.com/smartthings/st_syncsettings.png'//sync_icon_small.png'
|
||||||
}
|
}
|
||||||
|
|
||||||
main (["status"])
|
main (['switchall'])
|
||||||
details(["status","rainsensor","switch","switch1","switch2","switch3","switch4","switch5","switch6","switch7","switch8","switch9","switch10","switch11","switch12","switch13","switch14","switch15","switch16","refresh","configure"])
|
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(){
|
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(){
|
def programOff(){
|
||||||
sendEvent(name: "switch", value: "off", descriptionText: "Program turned off")
|
sendEvent(name: 'switch', value: 'off', descriptionText: 'Program turned off')
|
||||||
off()
|
off()
|
||||||
}
|
}
|
||||||
|
|
||||||
def updated(){
|
//set minutes
|
||||||
log.debug "updated"
|
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
|
// Parse incoming device messages to generate events
|
||||||
def parse(String description) {
|
def parse(String description) {
|
||||||
//log.debug "Parse description $description"
|
log.debug "Parse description ${description}"
|
||||||
def result = null
|
def result = null
|
||||||
def map = [:]
|
def map = [:]
|
||||||
if (description?.startsWith("read attr -")) {
|
if (description?.startsWith('read attr -')) {
|
||||||
def descMap = parseDescriptionAsMap(description)
|
def descMap = parseDescriptionAsMap(description)
|
||||||
//log.debug "Desc Map: $descMap"
|
//log.debug "Desc Map: $descMap"
|
||||||
//using 000F cluster instead of 0006 (switch) because ST does not differentiate between EPs and processes all as switch
|
//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") {
|
if (descMap.cluster == '000F' && descMap.attrId == '0055') {
|
||||||
log.debug "Zone"
|
log.debug 'Zone'
|
||||||
map = getZone(descMap)
|
map = getZone(descMap)
|
||||||
}
|
}
|
||||||
else if (descMap.cluster == "0009" && descMap.attrId == "0000") {
|
else if (descMap.cluster == '0009' && descMap.attrId == '0000') {
|
||||||
log.debug "Alarm"
|
log.debug 'Alarm'
|
||||||
map = getAlarm(descMap)
|
map = getAlarm(descMap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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) {
|
if (map) {
|
||||||
result = createEvent(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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
log.debug "Parse returned $map $result"
|
if (map) log.debug "Parse returned ${map} ${result}"
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
def parseDescriptionAsMap(description) {
|
def parseDescriptionAsMap(description) {
|
||||||
(description - "read attr - ").split(",").inject([:]) { map, param ->
|
(description - 'read attr - ').split(',').inject([:]) { map, param ->
|
||||||
def nameAndValue = param.split(":")
|
def nameAndValue = param.split(':')
|
||||||
map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
|
map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,27 +351,28 @@ def getZone(descMap){
|
|||||||
def EP = Integer.parseInt(descMap.endpoint.trim(), 16)
|
def EP = Integer.parseInt(descMap.endpoint.trim(), 16)
|
||||||
|
|
||||||
String onoff
|
String onoff
|
||||||
if(descMap.value == "00"){
|
if(descMap.value == '00'){
|
||||||
onoff = "off"
|
onoff = 'off'
|
||||||
}
|
}
|
||||||
else onoff = "on"
|
else onoff = 'on'
|
||||||
|
|
||||||
if (EP == 1){
|
if (EP == 1){
|
||||||
map.name = "switch"
|
map.name = 'switch'
|
||||||
map.value = onoff
|
map.value = onoff
|
||||||
map.descriptionText = "${device.displayName} turned sprinkler program $onoff"
|
map.descriptionText = "${device.displayName} turned sprinkler program ${onoff}"
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (EP == 18) {
|
else if (EP == 18) {
|
||||||
map.name = "rainsensor"
|
map.name = 'rainsensor'
|
||||||
map.value = "rainSensor" + onoff
|
log.debug "Rain enable: ${RainEnable}, sensor: ${onoff}"
|
||||||
map.descriptionText = "${device.displayName} rain sensor is $onoff"
|
map.value = 'rainSensor' + onoff
|
||||||
|
map.descriptionText = "${device.displayName} rain sensor is ${onoff}"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EP -= 1
|
EP -= 1
|
||||||
map.name = "switch" + EP
|
map.name = 'switch' + EP
|
||||||
map.value = "z" + EP + onoff
|
map.value = 'z' + EP + onoff
|
||||||
map.descriptionText = "${device.displayName} turned Zone $EP $onoff"
|
map.descriptionText = "${device.displayName} turned Zone $EP ${onoff}"
|
||||||
}
|
}
|
||||||
|
|
||||||
map.isStateChange = true
|
map.isStateChange = true
|
||||||
@@ -300,37 +382,59 @@ def getZone(descMap){
|
|||||||
|
|
||||||
def getAlarm(descMap){
|
def getAlarm(descMap){
|
||||||
def map = [:]
|
def map = [:]
|
||||||
map.name = "status"
|
map.name = 'status'
|
||||||
def alarmID = Integer.parseInt(descMap.value.trim(), 16)
|
def alarmID = Integer.parseInt(descMap.value.trim(), 16)
|
||||||
log.debug "${alarmID}"
|
log.debug "${alarmID}"
|
||||||
if(alarmID <= 0) map.descriptionText = "${device.displayName} has rebooted, no other alarms"
|
map.value = 'alarm'
|
||||||
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.displayed = true
|
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
|
return map
|
||||||
}
|
}
|
||||||
|
|
||||||
//status notify and change status
|
//status notify and change status
|
||||||
def notify(value, text){
|
def notify(String val, String txt){
|
||||||
sendEvent(name:"status", value:"$value", descriptionText:"$text", isStateChange: true, display: false)
|
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
|
//prefrences - rain sensor, manual time
|
||||||
def rain() {
|
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}"
|
if (RainEnable) "st wattr 0x${device.deviceNetworkId} 18 0x0F 0x51 0x10 {01}"
|
||||||
else "st wattr 0x${device.deviceNetworkId} 18 0x0F 0x51 0x10 {00}"
|
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
|
//write switch time settings map
|
||||||
def settingsMap(WriteTimes, attrType){
|
def settingsMap(WriteTimes, attrType){
|
||||||
@@ -367,9 +471,16 @@ def writeTime(wEP, runTime){
|
|||||||
//set reporting and binding
|
//set reporting and binding
|
||||||
def configure() {
|
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)
|
String zigbeeId = swapEndianHex(device.hub.zigbeeId)
|
||||||
log.debug "Confuguring Reporting and Bindings ${device.deviceNetworkId} ${device.zigbeeId}"
|
log.debug "Configuring Reporting and Bindings ${device.deviceNetworkId} ${device.zigbeeId}"
|
||||||
sendEvent(name: 'configuration',value: 100, descriptionText: "Configuration initialized")
|
|
||||||
|
|
||||||
def configCmds = [
|
def configCmds = [
|
||||||
//program on/off
|
//program on/off
|
||||||
@@ -458,36 +569,14 @@ def configure() {
|
|||||||
"zcl global send-me-a-report 0x09 0x00 0x21 1 0 {00}", "delay 500",
|
"zcl global send-me-a-report 0x09 0x00 0x21 1 0 {00}", "delay 500",
|
||||||
"send 0x${device.deviceNetworkId} 1 1", "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() {
|
def refresh() {
|
||||||
|
|
||||||
log.debug "refresh"
|
log.debug "refresh pressed"
|
||||||
|
sendEvent(name: 'tileMessage', value: 'Refresh', descriptionText: 'Refresh')
|
||||||
|
|
||||||
def refreshCmds = [
|
def refreshCmds = [
|
||||||
|
|
||||||
"st rattr 0x${device.deviceNetworkId} 1 0x0F 0x55", "delay 500",
|
"st rattr 0x${device.deviceNetworkId} 1 0x0F 0x55", "delay 500",
|
||||||
@@ -513,64 +602,96 @@ def refresh() {
|
|||||||
"st rattr 0x${device.deviceNetworkId} 18 0x0F 0x51","delay 500",
|
"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
|
// Commands to device
|
||||||
//zones on - 8
|
//zones on - 8
|
||||||
def on() {
|
def zon() {
|
||||||
//sendEvent(name:"status", value:"active", descriptionText:"Program Running", isStateChange: true, display: false)
|
"st cmd 0x${device.deviceNetworkId} 1 6 1 {}"
|
||||||
log.debug "on"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 1 6 1 {}"
|
|
||||||
}
|
}
|
||||||
def off() {
|
def zoff() {
|
||||||
log.debug "off"
|
"st cmd 0x${device.deviceNetworkId} 1 6 0 {}"
|
||||||
"st cmd 0x${device.deviceNetworkId} 1 6 0 {}"
|
|
||||||
}
|
}
|
||||||
def z1on() {
|
def z1on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 2 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 2 6 1 {}"
|
||||||
}
|
}
|
||||||
def z1off() {
|
def z1off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 2 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 2 6 0 {}"
|
||||||
}
|
}
|
||||||
def z2on() {
|
def z2on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 3 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 3 6 1 {}"
|
||||||
}
|
}
|
||||||
def z2off() {
|
def z2off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 3 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 3 6 0 {}"
|
||||||
}
|
}
|
||||||
def z3on() {
|
def z3on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 4 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 4 6 1 {}"
|
||||||
}
|
}
|
||||||
def z3off() {
|
def z3off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 4 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 4 6 0 {}"
|
||||||
}
|
}
|
||||||
def z4on() {
|
def z4on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 5 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 5 6 1 {}"
|
||||||
}
|
}
|
||||||
def z4off() {
|
def z4off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 5 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 5 6 0 {}"
|
||||||
}
|
}
|
||||||
def z5on() {
|
def z5on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 6 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 6 6 1 {}"
|
||||||
}
|
}
|
||||||
def z5off() {
|
def z5off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 6 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 6 6 0 {}"
|
||||||
}
|
}
|
||||||
def z6on() {
|
def z6on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 7 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 7 6 1 {}"
|
||||||
}
|
}
|
||||||
def z6off() {
|
def z6off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 7 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 7 6 0 {}"
|
||||||
}
|
}
|
||||||
def z7on() {
|
def z7on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 8 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 8 6 1 {}"
|
||||||
}
|
}
|
||||||
def z7off() {
|
def z7off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 8 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 8 6 0 {}"
|
||||||
}
|
}
|
||||||
def z8on() {
|
def z8on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 9 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 9 6 1 {}"
|
||||||
}
|
}
|
||||||
def z8off() {
|
def z8off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 9 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 9 6 0 {}"
|
||||||
@@ -578,50 +699,51 @@ def z8off() {
|
|||||||
|
|
||||||
//zones 9 - 16
|
//zones 9 - 16
|
||||||
def z9on() {
|
def z9on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 10 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 10 6 1 {}"
|
||||||
}
|
}
|
||||||
def z9off() {
|
def z9off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 10 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 10 6 0 {}"
|
||||||
}
|
}
|
||||||
def z10on() {
|
def z10on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 11 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 11 6 1 {}"
|
||||||
}
|
}
|
||||||
def z10off() {
|
def z10off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 11 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 11 6 0 {}"
|
||||||
}
|
}
|
||||||
def z11on() {
|
def z11on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 12 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 12 6 1 {}"
|
||||||
}
|
}
|
||||||
def z11off() {
|
def z11off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 12 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 12 6 0 {}"
|
||||||
}
|
}
|
||||||
def z12on() {
|
def z12on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 13 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 13 6 1 {}"
|
||||||
}
|
}
|
||||||
def z12off() {
|
def z12off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 13 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 13 6 0 {}"
|
||||||
}
|
}
|
||||||
def z13on() {
|
def z13on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 14 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 14 6 1 {}"
|
||||||
}
|
}
|
||||||
def z13off() {
|
def z13off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 14 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 14 6 0 {}"
|
||||||
}
|
}
|
||||||
def z14on() {
|
def z14on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 15 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 15 6 1 {}"
|
||||||
}
|
}
|
||||||
def z14off() {
|
def z14off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 15 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 15 6 0 {}"
|
||||||
}
|
}
|
||||||
def z15on() {
|
def z15on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 16 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 16 6 1 {}"
|
||||||
}
|
}
|
||||||
def z15off() {
|
def z15off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 16 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 16 6 0 {}"
|
||||||
}
|
}
|
||||||
def z16on() {
|
def z16on() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 17 6 1 {}"
|
return manual() + "st cmd 0x${device.deviceNetworkId} 17 6 1 {}"
|
||||||
}
|
}
|
||||||
def z16off() {
|
def z16off() {
|
||||||
"st cmd 0x${device.deviceNetworkId} 17 6 0 {}"
|
"st cmd 0x${device.deviceNetworkId} 17 6 0 {}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,182 @@
|
|||||||
|
/**
|
||||||
|
* SmartSense Open/Closed Sensor
|
||||||
|
*
|
||||||
|
* Copyright 2014 SmartThings
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||||
|
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import physicalgraph.zigbee.clusters.iaszone.ZoneStatus
|
||||||
|
|
||||||
|
metadata {
|
||||||
|
definition(name: "Sensative ZB Strips", namespace: "sensative", author: "SmartThings") {
|
||||||
|
capability "Battery"
|
||||||
|
capability "Configuration"
|
||||||
|
capability "Contact Sensor"
|
||||||
|
capability "Refresh"
|
||||||
|
capability "Temperature Measurement"
|
||||||
|
capability "Health Check"
|
||||||
|
capability "Sensor"
|
||||||
|
|
||||||
|
command "enrollResponse"
|
||||||
|
|
||||||
|
|
||||||
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "Sensative", model: "Strips-001"
|
||||||
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "Sensative", model: "Strips-001"
|
||||||
|
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "Sensativee", model: "Strips-001", deviceJoinName: "Sensative ZB Strips"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
simulator {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
preferences {
|
||||||
|
input title: "Temperature Offset", description: "This feature allows you to correct any temperature variations by selecting an offset. Ex: If your sensor consistently reports a temp that's 5 degrees too warm, you'd enter \"-5\". If 3 degrees too cold, enter \"+3\".", displayDuringSetup: false, type: "paragraph", element: "paragraph"
|
||||||
|
input "tempOffset", "number", title: "Degrees", description: "Adjust temperature by this many degrees", range: "*..*", displayDuringSetup: false
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles(scale: 2) {
|
||||||
|
multiAttributeTile(name: "contact", type: "generic", width: 6, height: 4) {
|
||||||
|
tileAttribute("device.contact", key: "PRIMARY_CONTROL") {
|
||||||
|
attributeState "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13"
|
||||||
|
attributeState "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#00A0DC"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
|
||||||
|
state "temperature", label: '${currentValue}°F',
|
||||||
|
backgroundColors: [
|
||||||
|
[value: 31, color: "#153591"],
|
||||||
|
[value: 44, color: "#1e9cbb"],
|
||||||
|
[value: 59, color: "#90d2a7"],
|
||||||
|
[value: 74, color: "#44b621"],
|
||||||
|
[value: 84, color: "#f1d801"],
|
||||||
|
[value: 95, color: "#d04e00"],
|
||||||
|
[value: 96, color: "#bc2323"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
|
||||||
|
state "battery", label: 'Battery\n${currentValue}%', unit: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||||
|
state "default", action: "refresh.refresh", icon: "st.secondary.refresh"
|
||||||
|
}
|
||||||
|
|
||||||
|
main(["contact"])
|
||||||
|
details(["contact", "battery", "temperature", "refresh"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def parse(String description) {
|
||||||
|
log.debug "description: $description"
|
||||||
|
|
||||||
|
Map map = zigbee.getEvent(description)
|
||||||
|
if (!map) {
|
||||||
|
if (description?.startsWith('zone status')) {
|
||||||
|
map = parseIasMessage(description)
|
||||||
|
} else {
|
||||||
|
Map descMap = zigbee.parseDescriptionAsMap(description)
|
||||||
|
if (descMap?.clusterInt == 0x0001 && descMap.commandInt != 0x07 && descMap?.value) {
|
||||||
|
map = getBatteryResult(Integer.parseInt(descMap.value, 16))
|
||||||
|
} else if (descMap?.clusterInt == zigbee.TEMPERATURE_MEASUREMENT_CLUSTER && descMap.commandInt == 0x07) {
|
||||||
|
if (descMap.data[0] == "00") {
|
||||||
|
log.debug "TEMP REPORTING CONFIG RESPONSE: $descMap"
|
||||||
|
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||||
|
} else {
|
||||||
|
log.warn "TEMP REPORTING CONFIG FAILED- error code: ${descMap.data[0]}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (map.name == "temperature") {
|
||||||
|
if (tempOffset) {
|
||||||
|
map.value = (int) map.value + (int) tempOffset
|
||||||
|
}
|
||||||
|
map.descriptionText = temperatureScale == 'C' ? '{{ device.displayName }} was {{ value }}°C' : '{{ device.displayName }} was {{ value }}°F'
|
||||||
|
map.translatable = true
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug "Parse returned $map"
|
||||||
|
def result = map ? createEvent(map) : [:]
|
||||||
|
|
||||||
|
if (description?.startsWith('enroll request')) {
|
||||||
|
List cmds = zigbee.enrollResponse()
|
||||||
|
log.debug "enroll response: ${cmds}"
|
||||||
|
result = cmds?.collect { new physicalgraph.device.HubAction(it) }
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Map parseIasMessage(String description) {
|
||||||
|
ZoneStatus zs = zigbee.parseZoneStatus(description)
|
||||||
|
return zs.isAlarm1Set() ? getContactResult('open') : getContactResult('closed')
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map getBatteryResult(rawValue) {
|
||||||
|
log.debug 'Battery'
|
||||||
|
def linkText = getLinkText(device)
|
||||||
|
|
||||||
|
def result = [:]
|
||||||
|
|
||||||
|
def volts = rawValue / 10
|
||||||
|
if (!(rawValue == 0 || rawValue == 255)) {
|
||||||
|
def minVolts = 2.1
|
||||||
|
def maxVolts = 3.0
|
||||||
|
def pct = (volts - minVolts) / (maxVolts - minVolts)
|
||||||
|
def roundedPct = Math.round(pct * 100)
|
||||||
|
if (roundedPct <= 0)
|
||||||
|
roundedPct = 1
|
||||||
|
result.value = Math.min(100, roundedPct)
|
||||||
|
result.descriptionText = "${linkText} battery was ${result.value}%"
|
||||||
|
result.name = 'battery'
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map getContactResult(value) {
|
||||||
|
log.debug 'Contact Status'
|
||||||
|
def linkText = getLinkText(device)
|
||||||
|
def descriptionText = "${linkText} was ${value == 'open' ? 'opened' : 'closed'}"
|
||||||
|
return [
|
||||||
|
name : 'contact',
|
||||||
|
value : value,
|
||||||
|
descriptionText: descriptionText
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PING is used by Device-Watch in attempt to reach the Device
|
||||||
|
* */
|
||||||
|
def ping() {
|
||||||
|
return zigbee.readAttribute(0x001, 0x0020) // Read the Battery Level
|
||||||
|
}
|
||||||
|
|
||||||
|
def refresh() {
|
||||||
|
log.debug "Refreshing Temperature and Battery"
|
||||||
|
def refreshCmds = zigbee.readAttribute(zigbee.TEMPERATURE_MEASUREMENT_CLUSTER, 0x0000) +
|
||||||
|
zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020)
|
||||||
|
|
||||||
|
return refreshCmds + zigbee.enrollResponse()
|
||||||
|
}
|
||||||
|
|
||||||
|
def 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 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||||
|
|
||||||
|
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
||||||
|
|
||||||
|
// temperature minReportTime 30 seconds, maxReportTime 5 min. Reporting interval if no activity
|
||||||
|
// battery minReport 30 seconds, maxReportTime 6 hrs by default
|
||||||
|
return refresh() + zigbee.batteryConfig() + zigbee.temperatureConfig(30, 300) // send refresh cmds as part of config
|
||||||
|
}
|
||||||
@@ -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 "Configuration"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
command "configureAfterSecure"
|
command "configureAfterSecure"
|
||||||
|
|
||||||
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x98,0x7A", outClusters:"0x5A"
|
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 {
|
simulator {
|
||||||
@@ -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 parse(String description)
|
||||||
{
|
{
|
||||||
def result = null
|
def result = null
|
||||||
@@ -244,6 +256,13 @@ def configureAfterSecure() {
|
|||||||
secureSequence(request) + ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
|
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() {
|
def configure() {
|
||||||
// log.debug "configure()"
|
// log.debug "configure()"
|
||||||
//["delay 30000"] + secure(zwave.securityV1.securityCommandsSupportedGet())
|
//["delay 30000"] + secure(zwave.securityV1.securityCommandsSupportedGet())
|
||||||
|
|||||||
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 "Actuator"
|
||||||
capability "Alarm"
|
capability "Alarm"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
command "test"
|
command "test"
|
||||||
|
|
||||||
fingerprint deviceId: "0x1005", inClusters: "0x5E,0x98"
|
fingerprint deviceId: "0x1005", inClusters: "0x5E,0x98", deviceJoinName: "Aeon Labs Siren (Gen 5)"
|
||||||
}
|
}
|
||||||
|
|
||||||
simulator {
|
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() {
|
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.sound) state.sound = 1
|
||||||
if(!state.volume) state.volume = 3
|
if(!state.volume) state.volume = 3
|
||||||
|
|
||||||
@@ -148,3 +157,10 @@ def test() {
|
|||||||
private secure(physicalgraph.zwave.Command cmd) {
|
private secure(physicalgraph.zwave.Command cmd) {
|
||||||
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
|
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PING is used by Device-Watch in attempt to reach the Device
|
||||||
|
* */
|
||||||
|
def ping() {
|
||||||
|
secure(zwave.basicV1.basicGet())
|
||||||
|
}
|
||||||
2
devicetypes/smartthings/arrival-sensor-ha.src/.st-ignore
Normal file
2
devicetypes/smartthings/arrival-sensor-ha.src/.st-ignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.st-ignore
|
||||||
|
README.md
|
||||||
50
devicetypes/smartthings/arrival-sensor-ha.src/README.md
Normal file
50
devicetypes/smartthings/arrival-sensor-ha.src/README.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Arrival Sensor HA (2016+ Model)
|
||||||
|
|
||||||
|
Cloud Execution
|
||||||
|
|
||||||
|
Works with:
|
||||||
|
|
||||||
|
* [Samsung SmartThings Arrival Sensor](https://support.smartthings.com/hc/en-us/articles/212417083-Samsung-SmartThings-Arrival-Sensor)
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
* [Capabilities](#capabilities)
|
||||||
|
* [Health](#device-health)
|
||||||
|
* [Battery](#battery)
|
||||||
|
* [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
* **Tone** - beep command to allow an audible tone
|
||||||
|
* **Actuator** - device has commands
|
||||||
|
* **Presence Sensor** - device tells presence with enum - {present, not present}
|
||||||
|
* **Sensor** - device has attributes
|
||||||
|
* **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
|
||||||
|
|
||||||
|
Arrival Sensor ZigBee is an untracked device. Sends broadcast of battery level every 20 seconds.
|
||||||
|
Disconnects when Hub goes OFFLINE.
|
||||||
|
|
||||||
|
|
||||||
|
## Battery
|
||||||
|
|
||||||
|
Uses 1 CR2032 Battery
|
||||||
|
|
||||||
|
* [Changing the Battery](https://support.smartthings.com/hc/en-us/articles/200907400-How-to-change-the-battery-in-the-SmartSense-Presence-Sensor-and-Samsung-SmartThings-Arrival-Sensor)
|
||||||
|
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the arrival sensor is out of range.
|
||||||
|
Pairing needs to be tried again by placing the sensor closer to the hub.
|
||||||
|
|
||||||
|
* [Samsung SmartThings Arrival Sensor Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/205382134-Samsung-SmartThings-Arrival-Sensor-2015-model-)
|
||||||
|
|
||||||
|
If the arrival sensor doesn't update its status, here are a few things you can try to debug.
|
||||||
|
|
||||||
|
* [Troubleshooting: Samsung SmartThings Arrival Sensor won't update its status](https://support.smartthings.com/hc/en-us/articles/200846514-Troubleshooting-Samsung-SmartThings-Arrival-Sensor-won-t-update-its-status)
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import groovy.json.JsonOutput
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright 2016 SmartThings
|
* Copyright 2017 SmartThings
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
* 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:
|
* in compliance with the License. You may obtain a copy of the License at:
|
||||||
@@ -19,6 +21,7 @@ metadata {
|
|||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
fingerprint inClusters: "0000,0001,0003,000F,0020", outClusters: "0003,0019",
|
fingerprint inClusters: "0000,0001,0003,000F,0020", outClusters: "0003,0019",
|
||||||
manufacturer: "SmartThings", model: "tagv4", deviceJoinName: "Arrival Sensor"
|
manufacturer: "SmartThings", model: "tagv4", deviceJoinName: "Arrival Sensor"
|
||||||
@@ -58,8 +61,13 @@ def updated() {
|
|||||||
startTimer()
|
startTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def installed() {
|
||||||
|
// Arrival sensors only goes OFFLINE when Hub is off
|
||||||
|
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "zigbee", scheme:"untracked"]), displayed: false)
|
||||||
|
}
|
||||||
|
|
||||||
def configure() {
|
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}"
|
log.debug "configure -- cmds: ${cmds}"
|
||||||
return cmds
|
return cmds
|
||||||
}
|
}
|
||||||
|
|||||||
2
devicetypes/smartthings/arrival-sensor.src/.st-ignore
Normal file
2
devicetypes/smartthings/arrival-sensor.src/.st-ignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.st-ignore
|
||||||
|
README.md
|
||||||
49
devicetypes/smartthings/arrival-sensor.src/README.md
Normal file
49
devicetypes/smartthings/arrival-sensor.src/README.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# Arrival Sensor (2015 Model)
|
||||||
|
|
||||||
|
Cloud Execution
|
||||||
|
|
||||||
|
Works with:
|
||||||
|
|
||||||
|
* [Arrival Sensor](https://www.smartthings.com/products/samsung-smartthings-arrival-sensor)
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
* [Capabilities](#capabilities)
|
||||||
|
* [Health](#device-health)
|
||||||
|
* [Battery](#battery)
|
||||||
|
* [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
* **Tone** - beep command to allow an audible tone
|
||||||
|
* **Actuator** - device has commands
|
||||||
|
* **Signal Strength** - device can read the strength of signal- lqi: Link Quality Indication, rssi: Received Signal Strength Indication
|
||||||
|
* **Presence Sensor** - device tells presence with enum - {present, not present}
|
||||||
|
* **Sensor** - device has attributes
|
||||||
|
* **Battery** - defines device uses a battery
|
||||||
|
* **Health Check** - indicates ability to get device health notifications
|
||||||
|
|
||||||
|
|
||||||
|
## Device Health
|
||||||
|
|
||||||
|
Arrival Sensor ZigBee is an untracked device. Disconnects when Hub goes OFFLINE.
|
||||||
|
|
||||||
|
|
||||||
|
## Battery
|
||||||
|
|
||||||
|
Uses 1 CR2032 Battery
|
||||||
|
|
||||||
|
* [Changing the Battery](https://support.smartthings.com/hc/en-us/articles/200907400-How-to-change-the-battery-in-the-SmartSense-Presence-Sensor-and-Samsung-SmartThings-Arrival-Sensor)
|
||||||
|
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the arrival sensor is out of range.
|
||||||
|
Pairing needs to be tried again by placing the sensor closer to the hub.
|
||||||
|
|
||||||
|
* [Samsung SmartThings Arrival Sensor Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/205382134-Samsung-SmartThings-Arrival-Sensor-2015-model-)
|
||||||
|
|
||||||
|
If the arrival sensor doesn't update its status, here are a few things you can try to debug.
|
||||||
|
|
||||||
|
* [Troubleshooting: Samsung SmartThings Arrival Sensor won't update its status](https://support.smartthings.com/hc/en-us/articles/200846514-Troubleshooting-Samsung-SmartThings-Arrival-Sensor-won-t-update-its-status)
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import groovy.json.JsonOutput
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright 2015 SmartThings
|
* Copyright 2015 SmartThings
|
||||||
*
|
*
|
||||||
@@ -19,6 +21,7 @@ metadata {
|
|||||||
capability "Presence Sensor"
|
capability "Presence Sensor"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
fingerprint profileId: "FC01", deviceId: "019A"
|
fingerprint profileId: "FC01", deviceId: "019A"
|
||||||
fingerprint profileId: "FC01", deviceId: "0131", inClusters: "0000,0003", outClusters: "0003"
|
fingerprint profileId: "FC01", deviceId: "0131", inClusters: "0000,0003", outClusters: "0003"
|
||||||
@@ -111,6 +114,11 @@ def beep() {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def installed() {
|
||||||
|
// Arrival sensors only goes OFFLINE when Hub is off
|
||||||
|
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "zigbee", scheme:"untracked"]), displayed: false)
|
||||||
|
}
|
||||||
|
|
||||||
def parse(String description) {
|
def parse(String description) {
|
||||||
def results
|
def results
|
||||||
if (isBatteryMessage(description)) {
|
if (isBatteryMessage(description)) {
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ metadata {
|
|||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Music Player"
|
capability "Music Player"
|
||||||
capability "Health Check"
|
capability "Health Check"
|
||||||
|
capability "Sensor"
|
||||||
|
capability "Actuator"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define all commands, ie, if you have a custom action not
|
* Define all commands, ie, if you have a custom action not
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
|
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "Dimmer Switch", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "Dimmer Switch", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
capability "Switch Level"
|
capability "Switch Level"
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Indicator"
|
capability "Indicator"
|
||||||
@@ -23,9 +23,9 @@ metadata {
|
|||||||
capability "Health Check"
|
capability "Health Check"
|
||||||
capability "Light"
|
capability "Light"
|
||||||
|
|
||||||
fingerprint mfr:"0063", prod:"4457", deviceJoinName: "GE In-Wall 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:"4944", deviceJoinName: "GE In-Wall Smart Dimmer"
|
||||||
fingerprint mfr:"0063", prod:"5044", deviceJoinName: "GE Plug-In 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"
|
fingerprint mfr:"0063", prod:"4944", model:"3034", deviceJoinName: "GE In-Wall Smart Fan Control"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,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(){
|
def updated(){
|
||||||
// Device-Watch simply pings if no device events received for 32min(checkInterval)
|
// 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])
|
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ metadata {
|
|||||||
command "switchMode"
|
command "switchMode"
|
||||||
command "switchFanMode"
|
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 "thermostatStatus", "string"
|
||||||
attribute "maxHeatingSetpoint", "number"
|
attribute "maxHeatingSetpoint", "number"
|
||||||
attribute "minHeatingSetpoint", "number"
|
attribute "minHeatingSetpoint", "number"
|
||||||
@@ -43,8 +43,8 @@ metadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tiles {
|
tiles {
|
||||||
valueTile("temperature", "device.temperature", width: 2, height: 2) {
|
standardTile("temperature", "device.temperature", width: 2, height: 2, decoration: "flat") {
|
||||||
state("temperature", label:'${currentValue}°', unit:"F",
|
state("temperature", label:'${currentValue}°', unit:"F", icon: "st.thermostat.ac.air-conditioning",
|
||||||
backgroundColors:[
|
backgroundColors:[
|
||||||
// Celsius
|
// Celsius
|
||||||
[value: 0, color: "#153591"],
|
[value: 0, color: "#153591"],
|
||||||
@@ -70,7 +70,7 @@ metadata {
|
|||||||
state "heat", action:"switchMode", nextState: "updating", icon: "st.thermostat.heat"
|
state "heat", action:"switchMode", nextState: "updating", icon: "st.thermostat.heat"
|
||||||
state "cool", action:"switchMode", nextState: "updating", icon: "st.thermostat.cool"
|
state "cool", action:"switchMode", nextState: "updating", icon: "st.thermostat.cool"
|
||||||
state "auto", action:"switchMode", nextState: "updating", icon: "st.thermostat.auto"
|
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"
|
state "updating", label:"Working", icon: "st.secondary.secondary"
|
||||||
}
|
}
|
||||||
standardTile("fanMode", "device.thermostatFanMode", inactiveLabel: false, decoration: "flat") {
|
standardTile("fanMode", "device.thermostatFanMode", inactiveLabel: false, decoration: "flat") {
|
||||||
@@ -81,8 +81,8 @@ metadata {
|
|||||||
standardTile("upButtonControl", "device.thermostatSetpoint", inactiveLabel: false, decoration: "flat") {
|
standardTile("upButtonControl", "device.thermostatSetpoint", inactiveLabel: false, decoration: "flat") {
|
||||||
state "setpoint", action:"raiseSetpoint", icon:"st.thermostat.thermostat-up"
|
state "setpoint", action:"raiseSetpoint", icon:"st.thermostat.thermostat-up"
|
||||||
}
|
}
|
||||||
valueTile("thermostatSetpoint", "device.thermostatSetpoint", width: 1, height: 1, decoration: "flat") {
|
valueTile("displayThermostatSetpoint", "device.displayThermostatSetpoint", width: 1, height: 1, decoration: "flat") {
|
||||||
state "thermostatSetpoint", label:'${currentValue}'
|
state "displayThermostatSetpoint", label:'${currentValue}'
|
||||||
}
|
}
|
||||||
valueTile("currentStatus", "device.thermostatStatus", height: 1, width: 2, decoration: "flat") {
|
valueTile("currentStatus", "device.thermostatStatus", height: 1, width: 2, decoration: "flat") {
|
||||||
state "thermostatStatus", label:'${currentValue}', backgroundColor:"#ffffff"
|
state "thermostatStatus", label:'${currentValue}', backgroundColor:"#ffffff"
|
||||||
@@ -113,7 +113,7 @@ metadata {
|
|||||||
state "humidity", label:'${currentValue}%'
|
state "humidity", label:'${currentValue}%'
|
||||||
}
|
}
|
||||||
main "temperature"
|
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 {
|
preferences {
|
||||||
@@ -185,6 +185,11 @@ def generateEvent(Map results) {
|
|||||||
isChange = isStateChange(device, name, value.toString())
|
isChange = isStateChange(device, name, value.toString())
|
||||||
event['isStateChange'] = isChange
|
event['isStateChange'] = isChange
|
||||||
event['displayed'] = false
|
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 {
|
} else {
|
||||||
isChange = isStateChange(device, name, value.toString())
|
isChange = isStateChange(device, name, value.toString())
|
||||||
isDisplayed = isChange
|
isDisplayed = isChange
|
||||||
@@ -452,10 +457,10 @@ def emergencyHeat() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def auxHeatOnly() {
|
def auxHeatOnly() {
|
||||||
log.debug "auxHeatOnly"
|
log.debug "auxHeatOnly = emergency heat"
|
||||||
def deviceId = device.deviceNetworkId.split(/\./).last()
|
def deviceId = device.deviceNetworkId.split(/\./).last()
|
||||||
if (parent.setMode ("auxHeatOnly", deviceId))
|
if (parent.setMode ("auxHeatOnly", deviceId))
|
||||||
generateModeEvent("auxHeatOnly")
|
generateModeEvent("emergency heat") // emergency heat = auxHeatOnly
|
||||||
else {
|
else {
|
||||||
log.debug "Error setting new mode."
|
log.debug "Error setting new mode."
|
||||||
def currentMode = device.currentState("thermostatMode")?.value
|
def currentMode = device.currentState("thermostatMode")?.value
|
||||||
@@ -574,17 +579,23 @@ def generateSetpointEvent() {
|
|||||||
sendEvent("name":"heatingSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale)
|
sendEvent("name":"heatingSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale)
|
||||||
sendEvent("name":"coolingSetpoint", "value":coolingSetpoint, "unit":location.temperatureScale)
|
sendEvent("name":"coolingSetpoint", "value":coolingSetpoint, "unit":location.temperatureScale)
|
||||||
|
|
||||||
|
def averageSetpoint = roundC((heatingSetpoint + coolingSetpoint) / 2)
|
||||||
if (mode == "heat") {
|
if (mode == "heat") {
|
||||||
sendEvent("name":"thermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale)
|
sendEvent("name":"thermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale)
|
||||||
|
sendEvent("name":"displayThermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale, displayed: false)
|
||||||
}
|
}
|
||||||
else if (mode == "cool") {
|
else if (mode == "cool") {
|
||||||
sendEvent("name":"thermostatSetpoint", "value":coolingSetpoint, "unit":location.temperatureScale)
|
sendEvent("name":"thermostatSetpoint", "value":coolingSetpoint, "unit":location.temperatureScale)
|
||||||
|
sendEvent("name":"displayThermostatSetpoint", "value":coolingSetpoint, "unit":location.temperatureScale, displayed: false)
|
||||||
} else if (mode == "auto") {
|
} 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") {
|
} else if (mode == "off") {
|
||||||
sendEvent("name":"thermostatSetpoint", "value":"Off")
|
sendEvent("name":"thermostatSetpoint", "value":averageSetpoint, "unit":location.temperatureScale)
|
||||||
} else if (mode == "auxHeatOnly") {
|
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":"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 = thermostatSetpoint ? thermostatSetpoint : 0
|
||||||
targetvalue = location.temperatureScale == "F"? targetvalue + 1 : targetvalue + 0.5
|
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
|
targetvalue = maxHeatingSetpoint
|
||||||
} else if (mode == "cool" && targetvalue > maxCoolingSetpoint) {
|
} else if (mode == "cool" && targetvalue > maxCoolingSetpoint) {
|
||||||
targetvalue = maxCoolingSetpoint
|
targetvalue = maxCoolingSetpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
sendEvent("name":"thermostatSetpoint", "value":targetvalue, "unit":location.temperatureScale, displayed: false)
|
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"
|
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
|
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 = thermostatSetpoint ? thermostatSetpoint : 0
|
||||||
targetvalue = location.temperatureScale == "F"? targetvalue - 1 : targetvalue - 0.5
|
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
|
targetvalue = minHeatingSetpoint
|
||||||
} else if (mode == "cool" && targetvalue < minCoolingSetpoint) {
|
} else if (mode == "cool" && targetvalue < minCoolingSetpoint) {
|
||||||
targetvalue = minCoolingSetpoint
|
targetvalue = minCoolingSetpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
sendEvent("name":"thermostatSetpoint", "value":targetvalue, "unit":location.temperatureScale, displayed: false)
|
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"
|
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
|
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
|
//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){
|
if (temp.value > coolingSetpoint){
|
||||||
targetHeatingSetpoint = temp.value
|
targetHeatingSetpoint = temp.value
|
||||||
targetCoolingSetpoint = temp.value
|
targetCoolingSetpoint = temp.value
|
||||||
@@ -735,15 +748,18 @@ void alterSetpoint(temp) {
|
|||||||
|
|
||||||
if (parent.setHold(heatingValue, coolingValue, deviceId, sendHoldType)) {
|
if (parent.setHold(heatingValue, coolingValue, deviceId, sendHoldType)) {
|
||||||
sendEvent("name": "thermostatSetpoint", "value": temp.value, displayed: false)
|
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": "heatingSetpoint", "value": targetHeatingSetpoint, "unit": location.temperatureScale)
|
||||||
sendEvent("name": "coolingSetpoint", "value": targetCoolingSetpoint, "unit": location.temperatureScale)
|
sendEvent("name": "coolingSetpoint", "value": targetCoolingSetpoint, "unit": location.temperatureScale)
|
||||||
log.debug "alterSetpoint in mode $mode succeed change setpoint to= ${temp.value}"
|
log.debug "alterSetpoint in mode $mode succeed change setpoint to= ${temp.value}"
|
||||||
} else {
|
} else {
|
||||||
log.error "Error alterSetpoint()"
|
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": "thermostatSetpoint", "value": heatingSetpoint.toString(), displayed: false)
|
||||||
|
sendEvent("name": "displayThermostatSetpoint", "value": heatingSetpoint.toString(), displayed: false)
|
||||||
} else if (mode == "cool") {
|
} else if (mode == "cool") {
|
||||||
sendEvent("name": "thermostatSetpoint", "value": coolingSetpoint.toString(), displayed: false)
|
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 coolingSetpoint = device.currentValue("coolingSetpoint")
|
||||||
def temperature = device.currentValue("temperature")
|
def temperature = device.currentValue("temperature")
|
||||||
def statusText
|
def statusText
|
||||||
|
def operatingState = "idle"
|
||||||
|
|
||||||
log.debug "Generate Status Event for Mode = ${mode}"
|
log.debug "Generate Status Event for Mode = ${mode}"
|
||||||
log.debug "Temperature = ${temperature}"
|
log.debug "Temperature = ${temperature}"
|
||||||
@@ -767,20 +784,29 @@ def generateStatusEvent() {
|
|||||||
log.debug "HVAC Mode = ${mode}"
|
log.debug "HVAC Mode = ${mode}"
|
||||||
|
|
||||||
if (mode == "heat") {
|
if (mode == "heat") {
|
||||||
if (temperature >= heatingSetpoint)
|
if (temperature >= heatingSetpoint) {
|
||||||
statusText = "Right Now: Idle"
|
statusText = "Right Now: Idle"
|
||||||
else
|
} else {
|
||||||
statusText = "Heating to ${heatingSetpoint} ${location.temperatureScale}"
|
statusText = "Heating to ${heatingSetpoint} ${location.temperatureScale}"
|
||||||
|
operatingState = "heating"
|
||||||
|
}
|
||||||
} else if (mode == "cool") {
|
} else if (mode == "cool") {
|
||||||
if (temperature <= coolingSetpoint)
|
if (temperature <= coolingSetpoint) {
|
||||||
statusText = "Right Now: Idle"
|
statusText = "Right Now: Idle"
|
||||||
else
|
} else {
|
||||||
statusText = "Cooling to ${coolingSetpoint} ${location.temperatureScale}"
|
statusText = "Cooling to ${coolingSetpoint} ${location.temperatureScale}"
|
||||||
|
operatingState = "cooling"
|
||||||
|
}
|
||||||
} else if (mode == "auto") {
|
} else if (mode == "auto") {
|
||||||
statusText = "Right Now: Auto"
|
statusText = "Right Now: Auto"
|
||||||
|
if (temperature < heatingSetpoint) {
|
||||||
|
operatingState = "heating"
|
||||||
|
} else if (temperature > coolingSetpoint) {
|
||||||
|
operatingState = "cooling"
|
||||||
|
}
|
||||||
} else if (mode == "off") {
|
} else if (mode == "off") {
|
||||||
statusText = "Right Now: Off"
|
statusText = "Right Now: Off"
|
||||||
} else if (mode == "auxHeatOnly") {
|
} else if (mode == "emergency heat") { // emergency heat = auxHeatOnly
|
||||||
statusText = "Emergency Heat"
|
statusText = "Emergency Heat"
|
||||||
} else {
|
} else {
|
||||||
statusText = "?"
|
statusText = "?"
|
||||||
@@ -788,6 +814,7 @@ def generateStatusEvent() {
|
|||||||
|
|
||||||
log.debug "Generate Status Event = ${statusText}"
|
log.debug "Generate Status Event = ${statusText}"
|
||||||
sendEvent("name":"thermostatStatus", "value":statusText, "description":statusText, displayed: true)
|
sendEvent("name":"thermostatStatus", "value":statusText, "description":statusText, displayed: true)
|
||||||
|
sendEvent("name":"thermostatOperatingState", "value":operatingState, "description":operatingState, displayed: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
def generateActivityFeedsEvent(notificationMessage) {
|
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 "Sensor"
|
||||||
capability "Polling"
|
capability "Polling"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
command "open"
|
command "open"
|
||||||
command "close"
|
command "close"
|
||||||
|
|
||||||
fingerprint deviceId: "0x1100", inClusters: "0x26,0x72,0x86,0x77,0x80,0x20"
|
fingerprint deviceId: "0x1100", inClusters: "0x26,0x72,0x86,0x77,0x80,0x20"
|
||||||
|
fingerprint mfr:"0157", prod:"0100", model:"0100", deviceJoinName: "EcoNet Controls Z-Wave Vent"
|
||||||
}
|
}
|
||||||
|
|
||||||
simulator {
|
simulator {
|
||||||
@@ -83,8 +85,15 @@ def parse(String description) {
|
|||||||
result
|
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
|
//send the command to stop polling
|
||||||
def updated() {
|
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")
|
response("poll stop")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +178,13 @@ def setLevel(value, duration) {
|
|||||||
setLevel(value)
|
setLevel(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PING is used by Device-Watch in attempt to reach the Device
|
||||||
|
* */
|
||||||
|
def ping() {
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
|
||||||
def refresh() {
|
def refresh() {
|
||||||
delayBetween([
|
delayBetween([
|
||||||
zwave.switchMultilevelV1.switchMultilevelGet().format(),
|
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 {
|
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 "Water Sensor"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
fingerprint deviceId: "0xA102", inClusters: "0x86,0x72,0x85,0x84,0x80,0x70,0x9C,0x20,0x71"
|
fingerprint deviceId: "0xA102", inClusters: "0x86,0x72,0x85,0x84,0x80,0x70,0x9C,0x20,0x71"
|
||||||
}
|
}
|
||||||
@@ -138,6 +139,8 @@ def zwaveEvent(physicalgraph.zwave.Command cmd)
|
|||||||
|
|
||||||
def configure()
|
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")) {
|
if (!device.currentState("battery")) {
|
||||||
sendEvent(name: "battery", value:100, unit:"%", descriptionText:"(Default battery event)", displayed:false)
|
sendEvent(name: "battery", value:100, unit:"%", descriptionText:"(Default battery event)", displayed:false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 "Contact Sensor"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
command "resetParams2StDefaults"
|
command "resetParams2StDefaults"
|
||||||
command "listCurrentParams"
|
command "listCurrentParams"
|
||||||
@@ -266,6 +267,9 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
|
|||||||
*/
|
*/
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "Configuring Device..."
|
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 = []
|
def cmds = []
|
||||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 1, size: 2).format()
|
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
|
// send associate to group 3 to get sensor data reported only to hub
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
* @return none
|
* @return none
|
||||||
*/
|
*/
|
||||||
metadata {
|
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 "Motion Sensor"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Acceleration Sensor"
|
capability "Acceleration Sensor"
|
||||||
@@ -436,4 +436,3 @@ def listCurrentParams() {
|
|||||||
|
|
||||||
delayBetween(cmds, 500)
|
delayBetween(cmds, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
metadata {
|
||||||
definition (name: "Fortrezz Water Valve", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "Fortrezz Water Valve", namespace: "smartthings", author: "SmartThings") {
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
|
capability "Health Check"
|
||||||
capability "Valve"
|
capability "Valve"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
|
|
||||||
fingerprint deviceId: "0x1000", inClusters: "0x25,0x72,0x86,0x71,0x22,0x70"
|
fingerprint deviceId: "0x1000", inClusters: "0x25,0x72,0x86,0x71,0x22,0x70"
|
||||||
|
fingerprint mfr:"0084", prod:"0213", model:"0215", deviceJoinName: "FortrezZ Water Valve"
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulator metadata
|
// simulator metadata
|
||||||
@@ -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) {
|
def parse(String description) {
|
||||||
log.trace description
|
log.trace description
|
||||||
def result = null
|
def result = null
|
||||||
@@ -76,6 +88,13 @@ def close() {
|
|||||||
zwave.switchBinaryV1.switchBinarySet(switchValue: 0xFF).format()
|
zwave.switchBinaryV1.switchBinarySet(switchValue: 0xFF).format()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PING is used by Device-Watch in attempt to reach the Device
|
||||||
|
* */
|
||||||
|
def ping() {
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
|
||||||
def refresh() {
|
def refresh() {
|
||||||
zwave.switchBinaryV1.switchBinaryGet().format()
|
zwave.switchBinaryV1.switchBinaryGet().format()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
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 "Actuator"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
|
|||||||
@@ -57,10 +57,20 @@ metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void installed() {
|
def initialize() {
|
||||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void installed() {
|
||||||
|
log.debug "installed()"
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
def updated() {
|
||||||
|
log.debug "updated()"
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
// parse events into attributes
|
// parse events into attributes
|
||||||
def parse(description) {
|
def parse(description) {
|
||||||
log.debug "parse() - $description"
|
log.debug "parse() - $description"
|
||||||
|
|||||||
@@ -45,10 +45,20 @@ metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void installed() {
|
def initialize() {
|
||||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void installed() {
|
||||||
|
log.debug "installed()"
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
def updated() {
|
||||||
|
log.debug "updated()"
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
// parse events into attributes
|
// parse events into attributes
|
||||||
def parse(description) {
|
def parse(description) {
|
||||||
log.debug "Parsing '${description}'"
|
log.debug "Parsing '${description}'"
|
||||||
|
|||||||
@@ -66,10 +66,20 @@ metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void installed() {
|
def initialize() {
|
||||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void installed() {
|
||||||
|
log.debug "installed()"
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
def updated() {
|
||||||
|
log.debug "updated()"
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
// parse events into attributes
|
// parse events into attributes
|
||||||
def parse(description) {
|
def parse(description) {
|
||||||
log.debug "parse() - $description"
|
log.debug "parse() - $description"
|
||||||
|
|||||||
@@ -50,10 +50,19 @@ metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void installed() {
|
def initialize() {
|
||||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void installed() {
|
||||||
|
log.debug "installed()"
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
def updated() {
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
// parse events into attributes
|
// parse events into attributes
|
||||||
def parse(description) {
|
def parse(description) {
|
||||||
log.debug "parse() - $description"
|
log.debug "parse() - $description"
|
||||||
|
|||||||
@@ -55,10 +55,20 @@ metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void installed() {
|
def initialize() {
|
||||||
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void installed() {
|
||||||
|
log.debug "installed()"
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
def updated() {
|
||||||
|
log.debug "updated()"
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
// parse events into attributes
|
// parse events into attributes
|
||||||
def parse(description) {
|
def parse(description) {
|
||||||
log.debug "parse() - $description"
|
log.debug "parse() - $description"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
metadata {
|
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 "Actuator"
|
||||||
capability "Color Control"
|
capability "Color Control"
|
||||||
capability "Color Temperature"
|
capability "Color Temperature"
|
||||||
@@ -64,8 +64,18 @@ metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def initialize() {
|
||||||
|
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"cloud\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device?.hub?.hardwareID}\"}", displayed: false)
|
||||||
|
}
|
||||||
|
|
||||||
void installed() {
|
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
|
// handle commands
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
metadata {
|
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 "Actuator"
|
||||||
capability "Color Temperature"
|
capability "Color Temperature"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
@@ -55,8 +55,18 @@ metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def initialize() {
|
||||||
|
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"cloud\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device?.hub?.hardwareID}\"}", displayed: false)
|
||||||
|
}
|
||||||
|
|
||||||
void installed() {
|
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
|
// handle commands
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import groovy.json.JsonOutput
|
||||||
/**
|
/**
|
||||||
* Logitech Harmony Hub
|
* Logitech Harmony Hub
|
||||||
*
|
*
|
||||||
@@ -7,6 +8,7 @@ metadata {
|
|||||||
definition (name: "Logitech Harmony Hub C2C", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "Logitech Harmony Hub C2C", namespace: "smartthings", author: "SmartThings") {
|
||||||
capability "Media Controller"
|
capability "Media Controller"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
command "activityoff"
|
command "activityoff"
|
||||||
command "alloff"
|
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) {
|
def startActivity(String activityId) {
|
||||||
log.debug "Executing 'Start Activity'"
|
log.debug "Executing 'Start Activity'"
|
||||||
log.trace parent.activity("$device.deviceNetworkId-$activityId","start")
|
log.trace parent.activity("$device.deviceNetworkId-$activityId","start")
|
||||||
@@ -58,6 +74,10 @@ def poll() {
|
|||||||
log.trace parent.poll()
|
log.trace parent.poll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def ping() {
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
|
||||||
def refresh() {
|
def refresh() {
|
||||||
log.debug "Executing 'Refresh'"
|
log.debug "Executing 'Refresh'"
|
||||||
log.trace parent.poll()
|
log.trace parent.poll()
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
metadata {
|
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 "Contact Sensor"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
|
|
||||||
|
|||||||
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 ZigBee 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 "Relative Humidity Measurement"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
fingerprint profileId: "0104", inClusters: "0000,0003,0405,FC08", outClusters: "0003"
|
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 {
|
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
|
// Parse incoming device messages to generate events
|
||||||
def parse(String description) {
|
def parse(String description) {
|
||||||
log.debug "Parse description $description"
|
log.debug "Parse description $description"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
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 "Switch Level"
|
||||||
capability "Color Control"
|
capability "Color Control"
|
||||||
capability "Color Temperature"
|
capability "Color Temperature"
|
||||||
|
|||||||
2
devicetypes/smartthings/smartalert-siren.src/.st-ignore
Normal file
2
devicetypes/smartthings/smartalert-siren.src/.st-ignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.st-ignore
|
||||||
|
README.md
|
||||||
39
devicetypes/smartthings/smartalert-siren.src/README.md
Normal file
39
devicetypes/smartthings/smartalert-siren.src/README.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Smartalert Siren
|
||||||
|
|
||||||
|
Cloud Execution
|
||||||
|
|
||||||
|
Works with:
|
||||||
|
|
||||||
|
* [FortrezZ Siren Strobe Alarm](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
|
||||||
|
* **Switch** - can detect state (possible values: on/off)
|
||||||
|
* **Sensor** - detects sensor events
|
||||||
|
* **Alarm** - allows for interacting with devices that serve as alarms
|
||||||
|
* **Health Check** - indicates ability to get device health notifications
|
||||||
|
|
||||||
|
## Device Health
|
||||||
|
|
||||||
|
FortrezZ Siren Strobe Alarm 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 Siren Strobe Alarm Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/202294760-FortrezZ-Siren-Strobe-Alarm)
|
||||||
@@ -16,15 +16,17 @@
|
|||||||
* Date: 2013-03-05
|
* Date: 2013-03-05
|
||||||
*/
|
*/
|
||||||
metadata {
|
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 "Actuator"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Alarm"
|
capability "Alarm"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
command "test"
|
command "test"
|
||||||
|
|
||||||
fingerprint deviceId: "0x1100", inClusters: "0x26,0x71"
|
fingerprint deviceId: "0x1100", inClusters: "0x26,0x71"
|
||||||
|
fingerprint mfr:"0084", prod:"0313", model:"010B", deviceJoinName: "FortrezZ Siren Strobe Alarm"
|
||||||
}
|
}
|
||||||
|
|
||||||
simulator {
|
simulator {
|
||||||
@@ -68,6 +70,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 on() {
|
def on() {
|
||||||
[
|
[
|
||||||
zwave.basicV1.basicSet(value: 0xFF).format(),
|
zwave.basicV1.basicSet(value: 0xFF).format(),
|
||||||
@@ -149,3 +161,10 @@ def createEvents(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
|
|||||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||||
log.warn "UNEXPECTED COMMAND: $cmd"
|
log.warn "UNEXPECTED COMMAND: $cmd"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PING is used by Device-Watch in attempt to reach the Device
|
||||||
|
* */
|
||||||
|
def ping() {
|
||||||
|
secure(zwave.basicV1.basicGet())
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
* Date: 2013-12-04
|
* Date: 2013-12-04
|
||||||
*/
|
*/
|
||||||
metadata {
|
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"
|
||||||
capability "Switch Level"
|
capability "Switch Level"
|
||||||
capability "Power Meter"
|
capability "Power Meter"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
metadata {
|
metadata {
|
||||||
// Automatically generated. Make future change here.
|
// Automatically generated. Make future change here.
|
||||||
definition(name: "SmartPower Outlet", namespace: "smartthings", author: "SmartThings") {
|
definition(name: "SmartPower Outlet", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.smartplug") {
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
capability "Power Meter"
|
capability "Power Meter"
|
||||||
|
|||||||
@@ -107,6 +107,12 @@ def parse(String description) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (map.name == "temperature") {
|
||||||
|
if (tempOffset) {
|
||||||
|
map.value = (int) map.value + (int) tempOffset
|
||||||
|
}
|
||||||
|
map.descriptionText = temperatureScale == 'C' ? '{{ device.displayName }} was {{ value }}°C' : '{{ device.displayName }} was {{ value }}°F'
|
||||||
|
map.translatable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug "Parse returned $map"
|
log.debug "Parse returned $map"
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
.st-ignore
|
||||||
|
README.md
|
||||||
36
devicetypes/smartthings/smartsense-moisture.src/README.md
Normal file
36
devicetypes/smartthings/smartsense-moisture.src/README.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Smartsense Moisture
|
||||||
|
|
||||||
|
Cloud Execution
|
||||||
|
|
||||||
|
Works with:
|
||||||
|
|
||||||
|
* [FortrezZ Moisture Sensor](https://www.smartthings.com/works-with-smartthings/fortrezz/fortrezz-moisture-sensor)
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
* [Capabilities](#capabilities)
|
||||||
|
* [Health](#device-health)
|
||||||
|
* [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
* **Water Sensor** - can detect presence of water (dry or wet)
|
||||||
|
* **Sensor** - detects sensor events
|
||||||
|
* **Battery** - defines device uses a battery
|
||||||
|
* **Temperature Measurement** - represents capability to measure temperature
|
||||||
|
* **Health Check** - indicates ability to get device health notifications
|
||||||
|
|
||||||
|
## Device Health
|
||||||
|
|
||||||
|
Smartsense Moisture is a Z-wave sleepy device type and checks in 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
|
||||||
|
|
||||||
|
## 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:
|
||||||
|
* [FortrezZ Moisture Sensor Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/200930740-FortrezZ-Moisture-Sensor)
|
||||||
@@ -17,9 +17,11 @@ metadata {
|
|||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
fingerprint deviceId: "0x2001", inClusters: "0x30,0x9C,0x9D,0x85,0x80,0x72,0x31,0x84,0x86"
|
fingerprint deviceId: "0x2001", inClusters: "0x30,0x9C,0x9D,0x85,0x80,0x72,0x31,0x84,0x86"
|
||||||
fingerprint deviceId: "0x2101", inClusters: "0x71,0x70,0x85,0x80,0x72,0x31,0x84,0x86"
|
fingerprint deviceId: "0x2101", inClusters: "0x71,0x70,0x85,0x80,0x72,0x31,0x84,0x86"
|
||||||
|
fingerprint mfr:"0084", prod:"0063", model:"010C", deviceJoinName: "FortrezZ Moisture Sensor"
|
||||||
}
|
}
|
||||||
|
|
||||||
simulator {
|
simulator {
|
||||||
@@ -89,6 +91,16 @@ def parse(String description) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def installed() {
|
||||||
|
// Device-Watch simply pings if no device events received for 482min(checkInterval)
|
||||||
|
sendEvent(name: "checkInterval", value: 2 * 4 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||||
|
}
|
||||||
|
|
||||||
|
def updated() {
|
||||||
|
// Device-Watch simply pings if no device events received for 482min(checkInterval)
|
||||||
|
sendEvent(name: "checkInterval", value: 2 * 4 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||||
|
}
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
|
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
|
||||||
{
|
{
|
||||||
[descriptionText: "${device.displayName} woke up", isStateChange: false]
|
[descriptionText: "${device.displayName} woke up", isStateChange: false]
|
||||||
|
|||||||
@@ -113,6 +113,12 @@ def parse(String description) {
|
|||||||
map = getMotionResult(value)
|
map = getMotionResult(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (map.name == "temperature") {
|
||||||
|
if (tempOffset) {
|
||||||
|
map.value = (int) map.value + (int) tempOffset
|
||||||
|
}
|
||||||
|
map.descriptionText = temperatureScale == 'C' ? '{{ device.displayName }} was {{ value }}°C' : '{{ device.displayName }} was {{ value }}°F'
|
||||||
|
map.translatable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug "Parse returned $map"
|
log.debug "Parse returned $map"
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ metadata {
|
|||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3320"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3320"
|
||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321"
|
||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321-S", deviceJoinName: "Multipurpose Sensor"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321-S", deviceJoinName: "Multipurpose Sensor"
|
||||||
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3323-G", deviceJoinName: "Centralite Micro Door Sensor"
|
|
||||||
fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500,FC02", outClusters: "0019", manufacturer: "SmartThings", model: "multiv4", deviceJoinName: "Multipurpose Sensor"
|
fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500,FC02", outClusters: "0019", manufacturer: "SmartThings", model: "multiv4", deviceJoinName: "Multipurpose Sensor"
|
||||||
|
|
||||||
attribute "status", "string"
|
attribute "status", "string"
|
||||||
@@ -192,6 +191,10 @@ private List<Map> parseAxis(List<Map> attrData) {
|
|||||||
def y = hexToSignedInt(attrData.find { it.attrInt == 0x0013 }?.value)
|
def y = hexToSignedInt(attrData.find { it.attrInt == 0x0013 }?.value)
|
||||||
def z = hexToSignedInt(attrData.find { it.attrInt == 0x0014 }?.value)
|
def z = hexToSignedInt(attrData.find { it.attrInt == 0x0014 }?.value)
|
||||||
|
|
||||||
|
if ([x, y ,z].any { it == null }) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
def xyzResults = [:]
|
def xyzResults = [:]
|
||||||
if (device.getDataValue("manufacturer") == "SmartThings") {
|
if (device.getDataValue("manufacturer") == "SmartThings") {
|
||||||
// This mapping matches the current behavior of the Device Handler for the Centralite sensors
|
// This mapping matches the current behavior of the Device Handler for the Centralite sensors
|
||||||
@@ -372,6 +375,10 @@ def updated() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private hexToSignedInt(hexVal) {
|
private hexToSignedInt(hexVal) {
|
||||||
|
if (!hexVal) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
def unsignedVal = hexToInt(hexVal)
|
def unsignedVal = hexToInt(hexVal)
|
||||||
unsignedVal > 32767 ? unsignedVal - 65536 : unsignedVal
|
unsignedVal > 32767 ? unsignedVal - 65536 : unsignedVal
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ metadata {
|
|||||||
tiles(scale: 2) {
|
tiles(scale: 2) {
|
||||||
multiAttributeTile(name:"contact", type: "generic", width: 6, height: 4){
|
multiAttributeTile(name:"contact", type: "generic", width: 6, height: 4){
|
||||||
tileAttribute ("device.contact", key: "PRIMARY_CONTROL") {
|
tileAttribute ("device.contact", key: "PRIMARY_CONTROL") {
|
||||||
attributeState "open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"##e86d13"
|
attributeState "open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13"
|
||||||
attributeState "closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00a0dc"
|
attributeState "closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00a0dc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ metadata {
|
|||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3300-S"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3300-S"
|
||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3300"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3300"
|
||||||
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3320-L", deviceJoinName: "Iris Contact Sensor"
|
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3320-L", deviceJoinName: "Iris Contact Sensor"
|
||||||
|
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3323-G", deviceJoinName: "Centralite Micro Door Sensor"
|
||||||
}
|
}
|
||||||
|
|
||||||
simulator {
|
simulator {
|
||||||
@@ -95,6 +96,12 @@ def parse(String description) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (map.name == "temperature") {
|
||||||
|
if (tempOffset) {
|
||||||
|
map.value = (int) map.value + (int) tempOffset
|
||||||
|
}
|
||||||
|
map.descriptionText = temperatureScale == 'C' ? '{{ device.displayName }} was {{ value }}°C' : '{{ device.displayName }} was {{ value }}°F'
|
||||||
|
map.translatable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug "Parse returned $map"
|
log.debug "Parse returned $map"
|
||||||
|
|||||||
@@ -88,6 +88,12 @@ def parse(String description) {
|
|||||||
log.warn "TEMP REPORTING CONFIG FAILED- error code: ${descMap.data[0]}"
|
log.warn "TEMP REPORTING CONFIG FAILED- error code: ${descMap.data[0]}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (map.name == "temperature") {
|
||||||
|
if (tempOffset) {
|
||||||
|
map.value = (int) map.value + (int) tempOffset
|
||||||
|
}
|
||||||
|
map.descriptionText = temperatureScale == 'C' ? '{{ device.displayName }} was {{ value }}°C' : '{{ device.displayName }} was {{ value }}°F'
|
||||||
|
map.translatable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug "Parse returned $map"
|
log.debug "Parse returned $map"
|
||||||
@@ -129,10 +135,7 @@ def refresh() {
|
|||||||
return zigbee.readAttribute(0xFC45, 0x0000, ["mfgCode": 0x104E]) + // New firmware
|
return zigbee.readAttribute(0xFC45, 0x0000, ["mfgCode": 0x104E]) + // New firmware
|
||||||
zigbee.readAttribute(0xFC45, 0x0000, ["mfgCode": 0xC2DF]) + // Original firmware
|
zigbee.readAttribute(0xFC45, 0x0000, ["mfgCode": 0xC2DF]) + // Original firmware
|
||||||
zigbee.readAttribute(zigbee.TEMPERATURE_MEASUREMENT_CLUSTER, 0x0000) +
|
zigbee.readAttribute(zigbee.TEMPERATURE_MEASUREMENT_CLUSTER, 0x0000) +
|
||||||
zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020) +
|
zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020)
|
||||||
zigbee.configureReporting(0xFC45, 0x0000, DataType.INT16, 30, 3600, 100) +
|
|
||||||
zigbee.batteryConfig() +
|
|
||||||
zigbee.temperatureConfig(30, 300)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
@@ -144,5 +147,10 @@ def configure() {
|
|||||||
|
|
||||||
// temperature minReportTime 30 seconds, maxReportTime 5 min. Reporting interval if no activity
|
// temperature minReportTime 30 seconds, maxReportTime 5 min. Reporting interval if no activity
|
||||||
// battery minReport 30 seconds, maxReportTime 6 hrs by default
|
// battery minReport 30 seconds, maxReportTime 6 hrs by default
|
||||||
return refresh()
|
return refresh() +
|
||||||
|
zigbee.configureReporting(0xFC45, 0x0000, DataType.UINT16, 30, 3600, 100, ["mfgCode": 0x104E]) + // New firmware
|
||||||
|
zigbee.configureReporting(0xFC45, 0x0000, DataType.UINT16, 30, 3600, 100, ["mfgCode": 0xC2DF]) + // Original firmware
|
||||||
|
zigbee.batteryConfig() +
|
||||||
|
zigbee.temperatureConfig(30, 300)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
//DEPRECATED - Using the generic DTH for this device. Users need to be moved before deleting this DTH
|
//DEPRECATED - Using the generic DTH for this device. Users need to be moved before deleting this DTH
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "Sylvania Ultra iQ", namespace:"smartthings", author: "SmartThings") {
|
definition (name: "Sylvania Ultra iQ", namespace:"smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
capability "Switch Level"
|
capability "Switch Level"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2017 SmartThings
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||||
|
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
metadata {
|
||||||
|
definition (name: "Simulated Refrigerator Door", namespace: "smartthings/testing", author: "SmartThings") {
|
||||||
|
capability "Contact Sensor"
|
||||||
|
capability "Sensor"
|
||||||
|
|
||||||
|
command "open"
|
||||||
|
command "close"
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles {
|
||||||
|
standardTile("contact", "device.contact", width: 2, height: 2) {
|
||||||
|
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821", action: "open")
|
||||||
|
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e", action: "close")
|
||||||
|
}
|
||||||
|
standardTile("freezerDoor", "device.contact", width: 2, height: 2, decoration: "flat") {
|
||||||
|
state("closed", label:'Freezer', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
|
||||||
|
state("open", label:'Freezer', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
|
||||||
|
}
|
||||||
|
standardTile("mainDoor", "device.contact", width: 2, height: 2, decoration: "flat") {
|
||||||
|
state("closed", label:'Fridge', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
|
||||||
|
state("open", label:'Fridge', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
|
||||||
|
}
|
||||||
|
standardTile("control", "device.contact", width: 1, height: 1, decoration: "flat") {
|
||||||
|
state("closed", label:'${name}', icon:"st.contact.contact.closed", action: "open")
|
||||||
|
state("open", label:'${name}', icon:"st.contact.contact.open", action: "close")
|
||||||
|
}
|
||||||
|
main "contact"
|
||||||
|
details "contact"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def installed() {
|
||||||
|
sendEvent(name: "contact", value: "closed")
|
||||||
|
}
|
||||||
|
|
||||||
|
def open() {
|
||||||
|
sendEvent(name: "contact", value: "open")
|
||||||
|
parent.doorOpen(device.deviceNetworkId)
|
||||||
|
}
|
||||||
|
|
||||||
|
def close() {
|
||||||
|
sendEvent(name: "contact", value: "closed")
|
||||||
|
parent.doorClosed(device.deviceNetworkId)
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* Simulated Refrigerator Temperature Control
|
||||||
|
*
|
||||||
|
* Copyright 2017 SmartThings
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||||
|
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
metadata {
|
||||||
|
definition (name: "Simulated Refrigerator Temperature Control", namespace: "smartthings/testing", author: "SmartThings") {
|
||||||
|
capability "Temperature Measurement"
|
||||||
|
capability "Thermostat Cooling Setpoint"
|
||||||
|
|
||||||
|
command "tempUp"
|
||||||
|
command "tempDown"
|
||||||
|
command "setpointUp"
|
||||||
|
command "setpointDown"
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles {
|
||||||
|
valueTile("refrigerator", "device.temperature", width: 2, height: 2, canChangeBackground: true) {
|
||||||
|
state("temperature", label:'${currentValue}°', unit:"F",
|
||||||
|
backgroundColors:[
|
||||||
|
[value: 0, color: "#153591"],
|
||||||
|
[value: 40, color: "#1e9cbb"],
|
||||||
|
[value: 45, color: "#f1d801"]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
valueTile("freezer", "device.temperature", width: 2, height: 2, canChangeBackground: true) {
|
||||||
|
state("temperature", label:'${currentValue}°', unit:"F",
|
||||||
|
backgroundColors:[
|
||||||
|
[value: 0, color: "#153591"],
|
||||||
|
[value: 5, color: "#1e9cbb"],
|
||||||
|
[value: 15, color: "#f1d801"]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
valueTile("freezerSetpoint", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
|
||||||
|
state "setpoint", label:'Freezer Set: ${currentValue}°', unit:"F"
|
||||||
|
}
|
||||||
|
valueTile("refrigeratorSetpoint", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
|
||||||
|
state "heat", label:'Fridge Set: ${currentValue}°', unit:"F"
|
||||||
|
}
|
||||||
|
standardTile("tempUp", "device.temperature", inactiveLabel: false, decoration: "flat") {
|
||||||
|
state "default", action:"tempUp", icon:"st.thermostat.thermostat-up"
|
||||||
|
}
|
||||||
|
standardTile("tempDown", "device.temperature", inactiveLabel: false, decoration: "flat") {
|
||||||
|
state "default", action:"tempDown", icon:"st.thermostat.thermostat-down"
|
||||||
|
}
|
||||||
|
standardTile("setpointUp", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
|
||||||
|
state "default", action:"setpointUp", icon:"st.thermostat.thermostat-up"
|
||||||
|
}
|
||||||
|
standardTile("setpointDown", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
|
||||||
|
state "default", action:"setpointDown", icon:"st.thermostat.thermostat-down"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def installed() {
|
||||||
|
sendEvent(name: "temperature", value: device.componentName == "freezer" ? 2 : 40)
|
||||||
|
sendEvent(name: "coolingSetpoint", value: device.componentName == "freezer" ? 2 : 40)
|
||||||
|
}
|
||||||
|
|
||||||
|
def updated() {
|
||||||
|
installed()
|
||||||
|
}
|
||||||
|
|
||||||
|
void tempUp() {
|
||||||
|
def value = device.currentValue("temperature") as Integer
|
||||||
|
sendEvent(name: "temperature", value: value + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
void tempDown() {
|
||||||
|
def value = device.currentValue("temperature") as Integer
|
||||||
|
sendEvent(name: "temperature", value: value - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
void setpointUp() {
|
||||||
|
def value = device.currentValue("coolingSetpoint") as Integer
|
||||||
|
sendEvent(name: "coolingSetpoint", value: value + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
void setpointDown() {
|
||||||
|
def value = device.currentValue("coolingSetpoint") as Integer
|
||||||
|
sendEvent(name: "coolingSetpoint", value: value - 1)
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
* Simulated Refrigerator
|
||||||
|
*
|
||||||
|
* Example composite device handler that simulates a refrigerator with a freezer compartment and a main compartment.
|
||||||
|
* Each of these compartments has its own door, temperature, and temperature setpoint. Each compartment modeled
|
||||||
|
* as a child device of the main refrigerator device so that temperature-based SmartApps can be used with each
|
||||||
|
* compartment
|
||||||
|
*
|
||||||
|
* Copyright 2017 SmartThings
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||||
|
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
metadata {
|
||||||
|
definition (name: "Simulated Refrigerator", namespace: "smartthings/testing", author: "SmartThings") {
|
||||||
|
capability "Contact Sensor"
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles(scale: 2) {
|
||||||
|
standardTile("contact", "device.contact", width: 4, height: 4) {
|
||||||
|
state("closed", label:'${name}', icon:"st.fridge.fridge-closed", backgroundColor:"#79b821")
|
||||||
|
state("open", label:'${name}', icon:"st.fridge.fridge-open", backgroundColor:"#ffa81e")
|
||||||
|
}
|
||||||
|
childDeviceTile("freezerDoor", "freezerDoor", height: 2, width: 2, childTileName: "freezerDoor")
|
||||||
|
childDeviceTile("mainDoor", "mainDoor", height: 2, width: 2, childTileName: "mainDoor")
|
||||||
|
childDeviceTile("freezer", "freezer", height: 2, width: 2, childTileName: "freezer")
|
||||||
|
childDeviceTile("refrigerator", "refrigerator", height: 2, width: 2, childTileName: "refrigerator")
|
||||||
|
childDeviceTile("freezerSetpoint", "freezer", height: 1, width: 2, childTileName: "freezerSetpoint")
|
||||||
|
childDeviceTile("refrigeratorSetpoint", "refrigerator", height: 1, width: 2, childTileName: "refrigeratorSetpoint")
|
||||||
|
|
||||||
|
// for simulator
|
||||||
|
childDeviceTile("freezerUp", "freezer", height: 1, width: 1, childTileName: "tempUp")
|
||||||
|
childDeviceTile("freezerDown", "freezer", height: 1, width: 1, childTileName: "tempDown")
|
||||||
|
childDeviceTile("refrigeratorUp", "refrigerator", height: 1, width: 1, childTileName: "tempUp")
|
||||||
|
childDeviceTile("refrigeratorDown", "refrigerator", height: 1, width: 1, childTileName: "tempDown")
|
||||||
|
childDeviceTile("freezerDoorControl", "freezerDoor", height: 1, width: 1, childTileName: "control")
|
||||||
|
childDeviceTile("mainDoorControl", "mainDoor", height: 1, width: 1, childTileName: "control")
|
||||||
|
childDeviceTile("freezerSetpointUp", "freezer", height: 1, width: 1, childTileName: "setpointUp")
|
||||||
|
childDeviceTile("freezerSetpointDown", "freezer", height: 1, width: 1, childTileName: "setpointDown")
|
||||||
|
childDeviceTile("refrigeratorSetpointUp", "refrigerator", height: 1, width: 1, childTileName: "setpointUp")
|
||||||
|
childDeviceTile("refrigeratorSetpointDown", "refrigerator", height: 1, width: 1, childTileName: "setpointDown")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def installed() {
|
||||||
|
state.counter = state.counter ? state.counter + 1 : 1
|
||||||
|
if (state.counter == 1) {
|
||||||
|
addChildDevice(
|
||||||
|
"Simulated Refrigerator Door",
|
||||||
|
"${device.deviceNetworkId}.1",
|
||||||
|
null,
|
||||||
|
[completedSetup: true, label: "${device.label} (Freezer Door)", componentName: "freezerDoor", componentLabel: "Freezer Door"])
|
||||||
|
|
||||||
|
addChildDevice(
|
||||||
|
"Simulated Refrigerator Door",
|
||||||
|
"${device.deviceNetworkId}.2",
|
||||||
|
null,
|
||||||
|
[completedSetup: true, label: "${device.label} (Main Door)", componentName: "mainDoor", componentLabel: "Main Door"])
|
||||||
|
|
||||||
|
addChildDevice(
|
||||||
|
"Simulated Refrigerator Temperature Control",
|
||||||
|
"${device.deviceNetworkId}.3",
|
||||||
|
null,
|
||||||
|
[completedSetup: true, label: "${device.label} (Freezer)", componentName: "freezer", componentLabel: "Freezer"])
|
||||||
|
|
||||||
|
addChildDevice(
|
||||||
|
"Simulated Refrigerator Temperature Control",
|
||||||
|
"${device.deviceNetworkId}.3",
|
||||||
|
null,
|
||||||
|
[completedSetup: true, label: "${device.label} (Fridge)", componentName: "refrigerator", componentLabel: "Fridge"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def doorOpen(dni) {
|
||||||
|
// If any door opens, then the refrigerator is considered to be open
|
||||||
|
sendEvent(name: "contact", value: "open")
|
||||||
|
}
|
||||||
|
|
||||||
|
def doorClosed(dni) {
|
||||||
|
// Both doors must be closed for the refrigerator to be considered closed
|
||||||
|
if (!childDevices.find{it.deviceNetworkId != dni && it.currentValue("contact") == "open"}) {
|
||||||
|
sendEvent(name: "contact", value: "closed")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ metadata {
|
|||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Health Check"
|
capability "Health Check"
|
||||||
|
capability "Sensor"
|
||||||
|
|
||||||
command "enrollResponse"
|
command "enrollResponse"
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ metadata {
|
|||||||
definition(name: "Wattvision", namespace: "smartthings", author: "Steve Vlaminck") {
|
definition(name: "Wattvision", namespace: "smartthings", author: "Steve Vlaminck") {
|
||||||
capability "Power Meter"
|
capability "Power Meter"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
|
capability "Sensor"
|
||||||
attribute "powerContent", "string"
|
attribute "powerContent", "string"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
//DEPRECATED - Using the generic DTH for this device. Users need to be moved before deleting this DTH
|
//DEPRECATED - Using the generic DTH for this device. Users need to be moved before deleting this DTH
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "WeMo Bulb", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "WeMo Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
|
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "Wemo Light Switch", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "Wemo Light Switch", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.switch") {
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
capability "Polling"
|
capability "Polling"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
* Date: 2015-10-11
|
* Date: 2015-10-11
|
||||||
*/
|
*/
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "Wemo Switch", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "Wemo Switch", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.smartplug") {
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
capability "Polling"
|
capability "Polling"
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ metadata {
|
|||||||
command "enrollResponse"
|
command "enrollResponse"
|
||||||
|
|
||||||
fingerprint inClusters: "0000, 0001, 0003, 0020, 0402, 0B05", outClusters: "0003, 0006, 0008, 0019", manufacturer: "OSRAM", model: "LIGHTIFY Dimming Switch", deviceJoinName: "OSRAM LIGHTIFY Dimming Switch"
|
fingerprint inClusters: "0000, 0001, 0003, 0020, 0402, 0B05", outClusters: "0003, 0006, 0008, 0019", manufacturer: "OSRAM", model: "LIGHTIFY Dimming Switch", deviceJoinName: "OSRAM LIGHTIFY Dimming Switch"
|
||||||
|
fingerprint inClusters: "0000, 0001, 0003, 0020, 0402, 0B05", outClusters: "0003, 0006, 0008, 0019", manufacturer: "CentraLite", model: "3130", deviceJoinName: "Centralite Zigbee Smart Switch"
|
||||||
//fingerprint inClusters: "0000, 0001, 0003, 0020, 0500", outClusters: "0003,0019", manufacturer: "CentraLite", model: "3455-L", deviceJoinName: "Iris Care Pendant"
|
//fingerprint inClusters: "0000, 0001, 0003, 0020, 0500", outClusters: "0003,0019", manufacturer: "CentraLite", model: "3455-L", deviceJoinName: "Iris Care Pendant"
|
||||||
fingerprint inClusters: "0000, 0001, 0003, 0007, 0020, 0402, 0B05", outClusters: "0003, 0006, 0019", manufacturer: "CentraLite", model: "3460-L", deviceJoinName: "Iris Smart Button"
|
fingerprint inClusters: "0000, 0001, 0003, 0007, 0020, 0402, 0B05", outClusters: "0003, 0006, 0019", manufacturer: "CentraLite", model: "3460-L", deviceJoinName: "Iris Smart Button"
|
||||||
fingerprint inClusters: "0000, 0001, 0003, 0007, 0020, 0B05", outClusters: "0003, 0006, 0019", manufacturer: "CentraLite", model:"3450-L", deviceJoinName: "Iris KeyFob"
|
fingerprint inClusters: "0000, 0001, 0003, 0007, 0020, 0B05", outClusters: "0003, 0006, 0019", manufacturer: "CentraLite", model:"3450-L", deviceJoinName: "Iris KeyFob"
|
||||||
@@ -251,12 +252,19 @@ def initialize() {
|
|||||||
if ((device.getDataValue("manufacturer") == "OSRAM") && (device.getDataValue("model") == "LIGHTIFY Dimming Switch")) {
|
if ((device.getDataValue("manufacturer") == "OSRAM") && (device.getDataValue("model") == "LIGHTIFY Dimming Switch")) {
|
||||||
sendEvent(name: "numberOfButtons", value: 2)
|
sendEvent(name: "numberOfButtons", value: 2)
|
||||||
}
|
}
|
||||||
else if ((device.getDataValue("manufacturer") == "CentraLite") &&
|
else if (device.getDataValue("manufacturer") == "CentraLite") {
|
||||||
((device.getDataValue("model") == "3455-L") || (device.getDataValue("model") == "3460-L"))) {
|
if (device.getDataValue("model") == "3130") {
|
||||||
sendEvent(name: "numberOfButtons", value: 1)
|
sendEvent(name: "numberOfButtons", value: 2)
|
||||||
}
|
}
|
||||||
else if ((device.getDataValue("manufacturer") == "CentraLite") && (device.getDataValue("model") == "3450-L")) {
|
else if ((device.getDataValue("model") == "3455-L") || (device.getDataValue("model") == "3460-L")) {
|
||||||
sendEvent(name: "numberOfButtons", value: 4)
|
sendEvent(name: "numberOfButtons", value: 1)
|
||||||
|
}
|
||||||
|
else if (device.getDataValue("model") == "3450-L") {
|
||||||
|
sendEvent(name: "numberOfButtons", value: 4)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sendEvent(name: "numberOfButtons", value: 4) //default case. can be changed later.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//default. can be changed
|
//default. can be changed
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "ZigBee Dimmer Power", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "ZigBee Dimmer Power", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
@@ -70,19 +70,27 @@ def parse(String description) {
|
|||||||
else {
|
else {
|
||||||
sendEvent(event)
|
sendEvent(event)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
def descMap = zigbee.parseDescriptionAsMap(description)
|
||||||
def cluster = zigbee.parse(description)
|
if (descMap && descMap.clusterInt == 0x0006 && descMap.commandInt == 0x07) {
|
||||||
if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) {
|
if (descMap.data[0] == "00") {
|
||||||
if (cluster.data[0] == 0x00){
|
|
||||||
log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster
|
log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster
|
||||||
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
|
log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
|
||||||
}
|
}
|
||||||
}
|
} else if (device.getDataValue("manufacturer") == "sengled" && descMap && descMap.clusterInt == 0x0008 && descMap.attrInt == 0x0000) {
|
||||||
else {
|
// This is being done because the sengled element touch incorrectly uses the value 0xFF for the max level.
|
||||||
|
// Per the ZCL spec for the UINT8 data type 0xFF is an invalid value, and 0xFE should be the max. Here we
|
||||||
|
// manually handle the invalid attribute value since it will be ignored by getEvent as an invalid value.
|
||||||
|
// We also set the level of the bulb to 0xFE so future level reports will be 0xFE until it is changed by
|
||||||
|
// something else.
|
||||||
|
if (descMap.value.toUpperCase() == "FF") {
|
||||||
|
descMap.value = "FE"
|
||||||
|
}
|
||||||
|
sendHubCommand(zigbee.command(zigbee.LEVEL_CONTROL_CLUSTER, 0x00, "FE0000").collect { new physicalgraph.device.HubAction(it) }, 0)
|
||||||
|
sendEvent(zigbee.getEventFromAttrData(descMap.clusterInt, descMap.attrInt, descMap.encoding, descMap.value))
|
||||||
|
} else {
|
||||||
log.warn "DID NOT PARSE MESSAGE for description : $description"
|
log.warn "DID NOT PARSE MESSAGE for description : $description"
|
||||||
log.debug zigbee.parseDescriptionAsMap(description)
|
log.debug zigbee.parseDescriptionAsMap(description)
|
||||||
}
|
}
|
||||||
@@ -114,9 +122,17 @@ def refresh() {
|
|||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "Configuring Reporting and Bindings."
|
log.debug "Configuring Reporting and Bindings."
|
||||||
|
def cmds = []
|
||||||
|
if (device.getDataValue("manufacturer") == "sengled") {
|
||||||
|
def startLevel = 0xFE
|
||||||
|
if ((device.currentState("level")?.value != null)) {
|
||||||
|
startLevel = Math.round(Integer.parseInt(device.currentState("level").value) * 0xFE / 100)
|
||||||
|
}
|
||||||
|
// Level Control Cluster, command Move to Level, level start level, transition time 0
|
||||||
|
cmds << zigbee.command(zigbee.LEVEL_CONTROL_CLUSTER, 0x00, sprintf("%02X0000", startLevel))
|
||||||
|
}
|
||||||
// Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time)
|
// 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
|
// enrolls with default periodic reporting until newer 5 min interval is confirmed
|
||||||
sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||||
refresh()
|
cmds + refresh()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "ZigBee Dimmer", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "ZigBee Dimmer", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
|
|||||||
2
devicetypes/smartthings/zigbee-lock.src/.st-ignore
Normal file
2
devicetypes/smartthings/zigbee-lock.src/.st-ignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.st-ignore
|
||||||
|
README.md
|
||||||
46
devicetypes/smartthings/zigbee-lock.src/README.md
Normal file
46
devicetypes/smartthings/zigbee-lock.src/README.md
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Zigbee Lock
|
||||||
|
|
||||||
|
Cloud Execution
|
||||||
|
|
||||||
|
Works with:
|
||||||
|
|
||||||
|
* [Yale Push Button Deadbolt (YRD210-HA)](https://www.smartthings.com/works-with-smartthings/door-locks/yale-push-button-deadbolt-yrd210)
|
||||||
|
* [Yale Touchscreen Lever (YRL220-ZB)](https://www.smartthings.com/works-with-smartthings/door-locks/yale-touchscreen-lever-yrl220)
|
||||||
|
* [Yale Touchscreen Deadbolt (YRD220-HA))](https://www.smartthings.com/works-with-smartthings/door-locks/yale-touchscreen-deadbolt-yrd220)
|
||||||
|
* [Yale Key Free Touchscreen Deadbolt (YRD240-HA)](https://www.smartthings.com/works-with-smartthings/door-locks/yale-key-free-touchscreen-deadbolt-yrd240)
|
||||||
|
* [Yale Push Button Lever Lock (YRL210-HA)](https://www.smartthings.com/works-with-smartthings/door-locks/yale-push-button-lever-lock-yrl210)
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
* [Capabilities](#capabilities)
|
||||||
|
* [Health](#device-health)
|
||||||
|
* [Battery](#battery-specification)
|
||||||
|
* [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
* **Actuator** - represents that a Device has commands
|
||||||
|
* **Lock** - allows for the control of a lock device
|
||||||
|
* **Refresh** - _refresh()_ command for status updates
|
||||||
|
* **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
|
||||||
|
|
||||||
|
Yale Push Button Deadbolt (YRD210-HA) is a Zigbee device and checks in every 1 hour.
|
||||||
|
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*60 + 2)mins = 122 mins.
|
||||||
|
|
||||||
|
* __122min__ checkInterval
|
||||||
|
|
||||||
|
## Battery Specification
|
||||||
|
|
||||||
|
Four 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 sensor from SmartThings can be found in the following link:
|
||||||
|
* [Yale Locks Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/205138400)
|
||||||
@@ -24,6 +24,7 @@ import physicalgraph.zigbee.zcl.DataType
|
|||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0004,0005,0009,0020,0101,0402,0B05,FDBD", outClusters: "000A,0019", manufacturer: "Kwikset", model: "SMARTCODE_DEADBOLT_5", deviceJoinName: "Kwikset 5-Button Deadbolt"
|
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0004,0005,0009,0020,0101,0402,0B05,FDBD", outClusters: "000A,0019", manufacturer: "Kwikset", model: "SMARTCODE_DEADBOLT_5", deviceJoinName: "Kwikset 5-Button Deadbolt"
|
||||||
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0004,0005,0009,0020,0101,0402,0B05,FDBD", outClusters: "000A,0019", manufacturer: "Kwikset", model: "SMARTCODE_LEVER_5", deviceJoinName: "Kwikset 5-Button Lever"
|
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0004,0005,0009,0020,0101,0402,0B05,FDBD", outClusters: "000A,0019", manufacturer: "Kwikset", model: "SMARTCODE_LEVER_5", deviceJoinName: "Kwikset 5-Button Lever"
|
||||||
@@ -83,6 +84,9 @@ def uninstalled() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
|
// Device-Watch allows 2 check-in misses from device + ping (plus 2 min lag time)
|
||||||
|
sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||||
|
|
||||||
def cmds =
|
def cmds =
|
||||||
zigbee.configureReporting(CLUSTER_DOORLOCK, DOORLOCK_ATTR_LOCKSTATE,
|
zigbee.configureReporting(CLUSTER_DOORLOCK, DOORLOCK_ATTR_LOCKSTATE,
|
||||||
DataType.ENUM8, 0, 3600, null) +
|
DataType.ENUM8, 0, 3600, null) +
|
||||||
@@ -92,6 +96,13 @@ def configure() {
|
|||||||
return refresh() + cmds // send refresh cmds as part of config
|
return refresh() + cmds // send refresh cmds as part of config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PING is used by Device-Watch in attempt to reach the Device
|
||||||
|
* */
|
||||||
|
def ping() {
|
||||||
|
zigbee.readAttribute(CLUSTER_DOORLOCK, DOORLOCK_ATTR_LOCKSTATE)
|
||||||
|
}
|
||||||
|
|
||||||
def refresh() {
|
def refresh() {
|
||||||
def cmds =
|
def cmds =
|
||||||
zigbee.readAttribute(CLUSTER_DOORLOCK, DOORLOCK_ATTR_LOCKSTATE) +
|
zigbee.readAttribute(CLUSTER_DOORLOCK, DOORLOCK_ATTR_LOCKSTATE) +
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "ZigBee Switch Power", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "ZigBee Switch Power", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.switch") {
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
|
|||||||
2
devicetypes/smartthings/zigbee-switch.src/.st-ignore
Normal file
2
devicetypes/smartthings/zigbee-switch.src/.st-ignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.st-ignore
|
||||||
|
README.md
|
||||||
35
devicetypes/smartthings/zigbee-switch.src/README.md
Normal file
35
devicetypes/smartthings/zigbee-switch.src/README.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Leviton Switch (ZigBee)
|
||||||
|
|
||||||
|
Cloud Execution
|
||||||
|
|
||||||
|
Works with:
|
||||||
|
|
||||||
|
* [Leviton Switch (ZigBee)](https://www.smartthings.com/works-with-smartthings/leviton/leviton-switch)
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
* [Capabilities](#capabilities)
|
||||||
|
* [Health](#device-health)
|
||||||
|
* [Troubleshooting](#Troubleshooting)
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
* **Actuator** - represents that a Device has commands
|
||||||
|
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
|
||||||
|
* **Refresh** - _refresh()_ command for status updates
|
||||||
|
* **Switch** - can detect state (possible values: on/off)
|
||||||
|
* **Health Check** - indicates ability to get device health notifications
|
||||||
|
|
||||||
|
## Device Health
|
||||||
|
|
||||||
|
A Zigbee Switch 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 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:
|
||||||
|
* [Leviton Switch Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/209686003-How-to-connect-Leviton-ZigBee-devices)
|
||||||
@@ -13,11 +13,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "ZigBee Switch", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "ZigBee Switch", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.switch") {
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
|
capability "Health Check"
|
||||||
|
|
||||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006"
|
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006"
|
||||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0006", outClusters: "0003, 0006, 0019, 0406", manufacturer: "Leviton", model: "ZSS-10", deviceJoinName: "Leviton Switch"
|
fingerprint profileId: "0104", inClusters: "0000, 0003, 0006", outClusters: "0003, 0006, 0019, 0406", manufacturer: "Leviton", model: "ZSS-10", deviceJoinName: "Leviton Switch"
|
||||||
@@ -75,11 +76,20 @@ def on() {
|
|||||||
zigbee.on()
|
zigbee.on()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PING is used by Device-Watch in attempt to reach the Device
|
||||||
|
* */
|
||||||
|
def ping() {
|
||||||
|
return refresh()
|
||||||
|
}
|
||||||
|
|
||||||
def refresh() {
|
def refresh() {
|
||||||
zigbee.onOffRefresh() + zigbee.onOffConfig()
|
zigbee.onOffRefresh() + zigbee.onOffConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
|
// Device-Watch allows 2 check-in misses from device + ping (plus 2 min lag time)
|
||||||
|
sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||||
log.debug "Configuring Reporting and Bindings."
|
log.debug "Configuring Reporting and Bindings."
|
||||||
zigbee.onOffRefresh() + zigbee.onOffConfig()
|
zigbee.onOffRefresh() + zigbee.onOffConfig()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import groovy.transform.Field
|
|||||||
@Field Boolean hasConfiguredHealthCheck = false
|
@Field Boolean hasConfiguredHealthCheck = false
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "ZLL Dimmer Bulb", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "ZLL Dimmer Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
|
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
import physicalgraph.zigbee.zcl.DataType
|
import physicalgraph.zigbee.zcl.DataType
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "ZLL RGB Bulb", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "ZLL RGB Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
|
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Color Control"
|
capability "Color Control"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
import physicalgraph.zigbee.zcl.DataType
|
import physicalgraph.zigbee.zcl.DataType
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "ZLL RGBW Bulb", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "ZLL RGBW Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
|
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Color Control"
|
capability "Color Control"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import groovy.transform.Field
|
|||||||
@Field Boolean hasConfiguredHealthCheck = false
|
@Field Boolean hasConfiguredHealthCheck = false
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "ZLL White Color Temperature Bulb 5000K", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "ZLL White Color Temperature Bulb 5000K", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
|
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Color Temperature"
|
capability "Color Temperature"
|
||||||
@@ -30,7 +30,7 @@ metadata {
|
|||||||
attribute "colorName", "string"
|
attribute "colorName", "string"
|
||||||
command "setGenericName"
|
command "setGenericName"
|
||||||
|
|
||||||
fingerprint profileId: "C05E", deviceId: "0220", inClusters: "0000, 0004, 0003, 0006, 0008, 0005, 0300", outClusters: "0019", manufacturer: "Eaton", model: "Halo_LT01", deviceJoinName: "Halo RL56 Wireless"
|
fingerprint profileId: "C05E", deviceId: "0220", inClusters: "0000, 0004, 0003, 0006, 0008, 0005, 0300", outClusters: "0019", manufacturer: "Eaton", model: "Halo_RL5601", deviceJoinName: "Halo RL56"
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI tile definitions
|
// UI tile definitions
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import groovy.transform.Field
|
|||||||
@Field Boolean hasConfiguredHealthCheck = false
|
@Field Boolean hasConfiguredHealthCheck = false
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "ZLL White Color Temperature Bulb", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "ZLL White Color Temperature Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||||
|
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Color Temperature"
|
capability "Color Temperature"
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Zooz Power Strip Outlet
|
||||||
|
*
|
||||||
|
* Copyright 2017 SmartThings
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||||
|
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
metadata {
|
||||||
|
definition (name: "Zooz Power Strip Outlet", namespace: "smartthings", author: "SmartThings") {
|
||||||
|
capability "Switch"
|
||||||
|
capability "Actuator"
|
||||||
|
capability "Sensor"
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles {
|
||||||
|
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||||
|
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||||
|
attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState:"turningOn"
|
||||||
|
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC", nextState:"turningOff"
|
||||||
|
attributeState "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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on() {
|
||||||
|
parent.childOn(device.deviceNetworkId)
|
||||||
|
}
|
||||||
|
|
||||||
|
void off() {
|
||||||
|
parent.childOff(device.deviceNetworkId)
|
||||||
|
}
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
/**
|
||||||
|
* Zooz ZEN20 Power Strip Outlet
|
||||||
|
*
|
||||||
|
* Implementation of the Zooz ZEN20 power strip that uses the new composite device capabilities to provide individual
|
||||||
|
* control of each outlet from SmartApps as well as the mobile app. Incorporates contributions from:
|
||||||
|
*
|
||||||
|
* Eric Maycock (https://github.com/erocm123/SmartThingsPublic/blob/master/devicetypes/erocm123/zooz-power-strip.src/zooz-power-strip.groovy)
|
||||||
|
* Robert Vandervoort (https://github.com/robertvandervoort/SmartThings/blob/master/zooZ-Strip-ZEN20/device_type-zooZ-strip-ZEN20_v1.0)
|
||||||
|
*
|
||||||
|
* Copyright 2017 SmartThings
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||||
|
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
metadata {
|
||||||
|
definition (name: "Zooz Power Strip", namespace: "smartthings", author: "SmartThings") {
|
||||||
|
capability "Switch"
|
||||||
|
capability "Refresh"
|
||||||
|
capability "Actuator"
|
||||||
|
capability "Sensor"
|
||||||
|
capability "Configuration"
|
||||||
|
|
||||||
|
fingerprint manufacturer: "015D", prod: "0651", model: "F51C", deviceJoinName: "Zooz ZEN 20 Power Strip"
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles {
|
||||||
|
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||||
|
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||||
|
attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState:"turningOn"
|
||||||
|
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC", nextState:"turningOff"
|
||||||
|
attributeState "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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
childDeviceTiles("outlets")
|
||||||
|
standardTile("refresh", "device.switch", width: 1, height: 1, inactiveLabel: false, decoration: "flat") {
|
||||||
|
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// Installation and update //
|
||||||
|
/////////////////////////////
|
||||||
|
def installed() {
|
||||||
|
createChildDevices()
|
||||||
|
}
|
||||||
|
|
||||||
|
def updated() {
|
||||||
|
if (!childDevices) {
|
||||||
|
createChildDevices()
|
||||||
|
}
|
||||||
|
else if (device.label != state.oldLabel) {
|
||||||
|
childDevices.each {
|
||||||
|
def newLabel = "${device.displayName} (CH${channelNumber(it.deviceNetworkId)})"
|
||||||
|
it.setLabel(newLabel)
|
||||||
|
}
|
||||||
|
state.oldLabel = device.label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def configure() {
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// Event Generation //
|
||||||
|
//////////////////////
|
||||||
|
def parse(String description) {
|
||||||
|
trace "parse('$description')"
|
||||||
|
def result = []
|
||||||
|
if (description.startsWith("Err")) {
|
||||||
|
result = createEvent(descriptionText:description, isStateChange:true)
|
||||||
|
} else if (description != "updated") {
|
||||||
|
def cmd = zwave.parse(description, [0x60: 3, 0x32: 3, 0x25: 1, 0x20: 1])
|
||||||
|
if (cmd) {
|
||||||
|
result += zwaveEvent(cmd, 1)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.warn "Unparsed description $description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd, ep) {
|
||||||
|
def encapsulatedCommand = cmd.encapsulatedCommand([0x32: 3, 0x25: 1, 0x20: 1])
|
||||||
|
if (encapsulatedCommand) {
|
||||||
|
zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd, endpoint) {
|
||||||
|
trace "zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport $cmd, $endpoint)"
|
||||||
|
zwaveBinaryEvent(cmd, endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd, endpoint) {
|
||||||
|
trace "zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport $cmd, $endpoint)"
|
||||||
|
zwaveBinaryEvent(cmd, endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveBinaryEvent(cmd, endpoint) {
|
||||||
|
def result = []
|
||||||
|
def children = childDevices
|
||||||
|
def childDevice = children.find{it.deviceNetworkId.endsWith("$endpoint")}
|
||||||
|
if (childDevice) {
|
||||||
|
childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
|
||||||
|
|
||||||
|
if (cmd.value) {
|
||||||
|
// One on and the strip is on
|
||||||
|
result << createEvent(name: "switch", value: "on")
|
||||||
|
} else {
|
||||||
|
// All off and the strip is off
|
||||||
|
if (!children.any { it.currentValue("switch") == "on" }) {
|
||||||
|
result << createEvent(name: "switch", value: "off")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd, ep) {
|
||||||
|
updateDataValue("MSR", String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId))
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, ep) {
|
||||||
|
trace "applicationVersion $cmd.applicationVersion"
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.Command cmd, ep) {
|
||||||
|
log.warn("${device.displayName}: Unhandled ${cmd}" + (ep ? " from endpoint $ep" : ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// Installation and update //
|
||||||
|
/////////////////////////////
|
||||||
|
def on() {
|
||||||
|
def cmds = []
|
||||||
|
def cmd = zwave.switchBinaryV1.switchBinarySet(switchValue: 0xFF)
|
||||||
|
cmds << zwave.multiChannelV3.multiChannelCmdEncap(bitAddress: true, destinationEndPoint:0x1F).encapsulate(cmd).format()
|
||||||
|
cmds << "delay 400"
|
||||||
|
cmds.addAll(refresh())
|
||||||
|
return cmds
|
||||||
|
}
|
||||||
|
|
||||||
|
def off() {
|
||||||
|
def cmds = []
|
||||||
|
def cmd = zwave.switchBinaryV1.switchBinarySet(switchValue: 0x00)
|
||||||
|
cmds << zwave.multiChannelV3.multiChannelCmdEncap(bitAddress: true, destinationEndPoint:0x1F).encapsulate(cmd).format()
|
||||||
|
cmds << "delay 400"
|
||||||
|
cmds.addAll(refresh())
|
||||||
|
return cmds
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// Child Device API //
|
||||||
|
//////////////////////
|
||||||
|
void childOn(String dni) {
|
||||||
|
onOffCmd(0xFF, channelNumber(dni))
|
||||||
|
}
|
||||||
|
|
||||||
|
void childOff(String dni) {
|
||||||
|
onOffCmd(0, channelNumber(dni))
|
||||||
|
}
|
||||||
|
|
||||||
|
def refresh() {
|
||||||
|
def cmds = (1..5).collect { endpoint ->
|
||||||
|
encap(zwave.switchBinaryV1.switchBinaryGet(), endpoint)
|
||||||
|
}
|
||||||
|
delayBetween(cmds, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// Local Methods //
|
||||||
|
///////////////////
|
||||||
|
private channelNumber(String dni) {
|
||||||
|
dni.split("-ep")[-1] as Integer
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onOffCmd(value, endpoint = null) {
|
||||||
|
def actions = [
|
||||||
|
new physicalgraph.device.HubAction(encap(zwave.basicV1.basicSet(value: value), endpoint)),
|
||||||
|
new physicalgraph.device.HubAction(encap(zwave.switchBinaryV1.switchBinaryGet(), endpoint)),
|
||||||
|
]
|
||||||
|
sendHubCommand(actions, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createChildDevices() {
|
||||||
|
state.oldLabel = device.label
|
||||||
|
for (i in 1..5) {
|
||||||
|
addChildDevice("Zooz Power Strip Outlet", "${device.deviceNetworkId}-ep${i}", null,
|
||||||
|
[completedSetup: true, label: "${device.displayName} (CH${i})",
|
||||||
|
isComponent: true, componentName: "ch$i", componentLabel: "Channel $i"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private encap(cmd, endpoint) {
|
||||||
|
if (endpoint) {
|
||||||
|
zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint:endpoint).encapsulate(cmd).format()
|
||||||
|
} else {
|
||||||
|
cmd.format()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private trace(msg) {
|
||||||
|
//log.trace(msg)
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user