mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-09 13:21:53 +00:00
Compare commits
1 Commits
MSA-2113-3
...
MSA-1915-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
508ac203c1 |
18
build.gradle
18
build.gradle
@@ -9,7 +9,7 @@ apply plugin: 'smartthings-slack'
|
||||
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.12"
|
||||
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.11"
|
||||
}
|
||||
repositories {
|
||||
mavenLocal()
|
||||
@@ -19,7 +19,7 @@ buildscript {
|
||||
username smartThingsArtifactoryUserName
|
||||
password smartThingsArtifactoryPassword
|
||||
}
|
||||
url "https://smartthings.jfrog.io/smartthings/libs-release-local"
|
||||
url "https://artifactory.smartthings.com/libs-release-local"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ repositories {
|
||||
username smartThingsArtifactoryUserName
|
||||
password smartThingsArtifactoryPassword
|
||||
}
|
||||
url "https://smartthings.jfrog.io/smartthings/libs-release-local"
|
||||
url "https://artifactory.smartthings.com/libs-release-local"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,10 +51,10 @@ sourceSets {
|
||||
|
||||
dependencies {
|
||||
devicetypesCompile 'org.codehaus.groovy:groovy-all:2.4.7'
|
||||
devicetypesCompile 'smartthings:appengine-z-wave:0.1.3'
|
||||
devicetypesCompile 'smartthings:appengine-zigbee:0.1.12'
|
||||
devicetypesCompile 'smartthings:appengine-z-wave:0.1.2'
|
||||
devicetypesCompile 'smartthings:appengine-zigbee:0.1.11'
|
||||
smartappsCompile 'org.codehaus.groovy:groovy-all:2.4.7'
|
||||
smartappsCompile 'smartthings:appengine-common:0.1.9'
|
||||
smartappsCompile 'smartthings:appengine-common:0.1.8'
|
||||
smartappsCompile 'org.codehaus.groovy.modules.http-builder:http-builder:0.7.1'
|
||||
smartappsCompile 'org.grails:grails-web:2.3.11'
|
||||
smartappsCompile 'org.json:json:20140107'
|
||||
@@ -74,19 +74,19 @@ slackSendMessage {
|
||||
String username
|
||||
switch (branch) {
|
||||
case 'master':
|
||||
username = 'DEV'
|
||||
username = 'Hickory'
|
||||
iconUrl = wolverine
|
||||
color = '#35D0F2'
|
||||
messageText = 'Began deployment of _SmartThingsPublic[master]_ branch to the _Dev_ environments.'
|
||||
break
|
||||
case 'staging':
|
||||
username = 'STG'
|
||||
username = 'Dickory'
|
||||
iconUrl = beach
|
||||
color = '#FFDE20'
|
||||
messageText = 'Began deployment of _SmartThingsPublic[staging]_ branch to the _Staging_ environments.'
|
||||
break
|
||||
case 'production':
|
||||
username = 'PRD'
|
||||
username = 'Dock'
|
||||
iconUrl = drinks
|
||||
color = '#FF1D23'
|
||||
messageText = 'Began deployment of _SmartThingsPublic[production]_ branch to the _Prod_ environments.'
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -1,44 +0,0 @@
|
||||
# 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
|
||||
|
||||
@@ -2,6 +2,27 @@
|
||||
// Motion Sensor - Temperature - Light level - 8 Color Indicator LED - Z-Wave Range Extender - Wall Powered
|
||||
// driver for SmartThings
|
||||
// The EZMultiPli is also known as the HSM200 from HomeSeer.com
|
||||
//
|
||||
// 2017-04-10 - DrZwave (with help from Don Kirker) - changed fingerprint to the new format, lowered the OnTime
|
||||
// and other parameters to be "more in line with ST user expectations", get the luminance in LUX so it reports in lux all the time.
|
||||
// 2016-10-06 - erocm1231 - Added "updated" method to run when configuration options are changed. Depending on model of unit, luminance is being
|
||||
// reported as a relative percentace or as a lux value. Added the option to configure this in the handler.
|
||||
// 2016-01-28 - erocm1231 - Changed the configuration method to use scaledConfiguration so that it properly formatted negative numbers.
|
||||
// Also, added configurationGet and a configurationReport method so that config values can be verified.
|
||||
// 2015-12-04 - erocm1231 - added range value to preferences as suggested by @Dela-Rick.
|
||||
// 2015-11-26 - erocm1231 - Fixed null condition error when adding as a new device.
|
||||
// 2015-11-24 - erocm1231 - Added refresh command. Made a few changes to how the handler maps colors to the LEDs. Fixed
|
||||
// the device not having its on/off status updated when colors are changed.
|
||||
// 2015-11-23 - erocm1231 - Changed the look to match SmartThings v2 devices.
|
||||
// 2015-11-21 - erocm1231 - Made code much more efficient. Also made it compatible when setColor is passed a hex value.
|
||||
// Mapping of special colors: Soft White - Default - Yellow, White - Concentrate - White,
|
||||
// Daylight - Energize - Teal, Warm White - Relax - Yellow
|
||||
// 2015-11-19 - erocm1231 - Fixed a couple incorrect colors, changed setColor to be more compatible with other apps
|
||||
// 2015-11-18 - erocm1231 - Added to setColor for compatibility with Smart Lighting
|
||||
// v0.1.0 - DrZWave - chose better icons, Got color LED to work - first fully functional version
|
||||
// v0.0.9 - jrs - got the temp and luminance to work. Motion works. Debugging the color wheel.
|
||||
// v0.0.8 - DrZWave 2/25/2015 - change the color control to be tiles since there are only 8 colors.
|
||||
// v0.0.7 - jrs - 02/23/2015 - Jim Sulin
|
||||
|
||||
metadata {
|
||||
definition (name: "EZmultiPli", namespace: "DrZWave", author: "Eric Ryherd", oauth: true) {
|
||||
@@ -38,9 +59,9 @@ metadata {
|
||||
tiles (scale: 2){
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL", icon: "st.Lighting.light18") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
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:"#00A0DC"
|
||||
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") {
|
||||
@@ -52,20 +73,20 @@ metadata {
|
||||
}
|
||||
|
||||
standardTile("motion", "device.motion", width: 2, height: 2, canChangeIcon: true, canChangeBackground: true) {
|
||||
state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC"
|
||||
state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc"
|
||||
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: "#153591"], // blue=cold
|
||||
[value: 65, color: "#44b621"], // green
|
||||
[value: 70, color: "#44b621"], // green
|
||||
[value: 75, color: "#f1d801"], // yellow
|
||||
[value: 80, color: "#f1d801"], // yellow
|
||||
[value: 85, color: "#f1d801"], // yellow
|
||||
[value: 90, color: "#d04e00"], // red
|
||||
[value: 95, color: "#bc2323"] // red=hot
|
||||
[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
|
||||
]
|
||||
}
|
||||
|
||||
@@ -110,6 +131,7 @@ metadata {
|
||||
|
||||
} // end metadata
|
||||
|
||||
|
||||
// Parse incoming device messages from device to generate events
|
||||
def parse(String description){
|
||||
//log.debug "==> New Zwave Event: ${description}"
|
||||
@@ -123,7 +145,7 @@ def parse(String description){
|
||||
|
||||
def statusTextmsg = ""
|
||||
if (device.currentState('temperature') != null && device.currentState('illuminance') != null) {
|
||||
statusTextmsg = "${device.currentState('temperature').value} ° - ${device.currentState('illuminance').value} ${(lum == 1) ? "%" : "LUX"}"
|
||||
statusTextmsg = "${device.currentState('temperature').value} ° - ${device.currentState('illuminance').value} ${(lum == "" || lum == null || lum == 1) ? "%" : "LUX"}"
|
||||
sendEvent("name":"statusText", "value":statusTextmsg, displayed:false)
|
||||
}
|
||||
if (result != [null] && result != []) log.debug "Parse returned ${result}"
|
||||
@@ -146,7 +168,7 @@ def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelR
|
||||
break;
|
||||
case 0x03 : // SENSOR_TYPE_LUMINANCE_VERSION_1
|
||||
map.value = cmd.scaledSensorValue.toInteger().toString()
|
||||
if(lum == 1) map.unit = "%"
|
||||
if(lum == "" || lum == null || lum == 1) map.unit = "%"
|
||||
else map.unit = "lux"
|
||||
map.name = "illuminance"
|
||||
log.debug "Luminance report"
|
||||
@@ -181,8 +203,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
|
||||
}
|
||||
|
||||
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")) {
|
||||
if (cmd.value == 0 && device.latestState("color").value != "#ffffff") {
|
||||
sendEvent(name: "color", value: "#ffffff", displayed: true)
|
||||
}
|
||||
[name: "switch", value: cmd.value ? "on" : "off", type: "digital"]
|
||||
@@ -275,12 +296,12 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
// ensure we are passing acceptable param values for LiteMin & TempMin configs
|
||||
def checkLiteTempInput(value) {
|
||||
if (value == null) {
|
||||
value=6
|
||||
value=60
|
||||
}
|
||||
def liteTempVal = value.toInteger()
|
||||
switch (liteTempVal) {
|
||||
case { it < 0 }:
|
||||
return 6 // bad value, set to default
|
||||
return 60 // bad value, set to default
|
||||
break
|
||||
case { it > 127 }:
|
||||
return 127 // bad value, greater then MAX, set to MAX
|
||||
@@ -293,12 +314,12 @@ def checkLiteTempInput(value) {
|
||||
// ensure we are passing acceptable param value for OnTime config
|
||||
def checkOnTimeInput(value) {
|
||||
if (value == null) {
|
||||
value=2
|
||||
value=10
|
||||
}
|
||||
def onTimeVal = value.toInteger()
|
||||
switch (onTimeVal) {
|
||||
case { it < 0 }:
|
||||
return 2 // bad value set to default
|
||||
return 10 // bad value set to default
|
||||
break
|
||||
case { it > 127 }:
|
||||
return 127 // bad value, greater then MAX, set to MAX
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Inovelli 2-Channel Smart Plug
|
||||
*
|
||||
* github: Eric Maycock (erocm123)
|
||||
* Date: 2017-04-27
|
||||
* Copyright Eric Maycock
|
||||
*
|
||||
* Includes all configuration parameters and ease of advanced configuration.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition(name: "Inovelli 2-Channel Smart Plug", namespace: "erocm123", author: "Eric Maycock") {
|
||||
capability "Actuator"
|
||||
capability "Sensor"
|
||||
capability "Switch"
|
||||
capability "Polling"
|
||||
capability "Refresh"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint manufacturer: "015D", prod: "0221", model: "251C", deviceJoinName: "Show Home 2-Channel Smart Plug"
|
||||
fingerprint manufacturer: "0312", prod: "B221", model: "251C", deviceJoinName: "Inovelli 2-Channel Smart Plug"
|
||||
}
|
||||
simulator {}
|
||||
preferences {}
|
||||
tiles {
|
||||
multiAttributeTile(name: "switch", type: "lighting", width: 6, height: 4, canChangeIcon: true) {
|
||||
tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
|
||||
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
|
||||
attributeState "turningOff", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
|
||||
attributeState "turningOn", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
|
||||
}
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label: "", action: "refresh.refresh", icon: "st.secondary.refresh"
|
||||
}
|
||||
main(["switch"])
|
||||
details(["switch",
|
||||
childDeviceTiles("all"), "refresh"
|
||||
])
|
||||
}
|
||||
}
|
||||
def parse(String description) {
|
||||
def result = []
|
||||
def cmd = zwave.parse(description)
|
||||
if (cmd) {
|
||||
result += zwaveEvent(cmd)
|
||||
logging("Parsed ${cmd} to ${result.inspect()}", 1)
|
||||
} else {
|
||||
logging("Non-parsed event: ${description}", 2)
|
||||
}
|
||||
return result
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd, ep = null) {
|
||||
logging("BasicReport ${cmd} - ep ${ep}", 2)
|
||||
if (ep) {
|
||||
def event
|
||||
childDevices.each {
|
||||
childDevice ->
|
||||
if (childDevice.deviceNetworkId == "$device.deviceNetworkId-ep$ep") {
|
||||
childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
|
||||
}
|
||||
}
|
||||
if (cmd.value) {
|
||||
event = [createEvent([name: "switch", value: "on"])]
|
||||
} else {
|
||||
def allOff = true
|
||||
childDevices.each {
|
||||
n ->
|
||||
if (n.currentState("switch").value != "off") allOff = false
|
||||
}
|
||||
if (allOff) {
|
||||
event = [createEvent([name: "switch", value: "off"])]
|
||||
} else {
|
||||
event = [createEvent([name: "switch", value: "on"])]
|
||||
}
|
||||
}
|
||||
return event
|
||||
}
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
|
||||
logging("BasicSet ${cmd}", 2)
|
||||
def result = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "digital")
|
||||
def cmds = []
|
||||
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 1)
|
||||
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
|
||||
return [result, response(commands(cmds))] // returns the result of reponse()
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd, ep = null) {
|
||||
logging("SwitchBinaryReport ${cmd} - ep ${ep}", 2)
|
||||
if (ep) {
|
||||
def event
|
||||
def childDevice = childDevices.find {
|
||||
it.deviceNetworkId == "$device.deviceNetworkId-ep$ep"
|
||||
}
|
||||
if (childDevice) childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
|
||||
if (cmd.value) {
|
||||
event = [createEvent([name: "switch", value: "on"])]
|
||||
} else {
|
||||
def allOff = true
|
||||
childDevices.each {
|
||||
n->
|
||||
if (n.currentState("switch").value != "off") allOff = false
|
||||
}
|
||||
if (allOff) {
|
||||
event = [createEvent([name: "switch", value: "off"])]
|
||||
} else {
|
||||
event = [createEvent([name: "switch", value: "on"])]
|
||||
}
|
||||
}
|
||||
return event
|
||||
} else {
|
||||
def result = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "digital")
|
||||
def cmds = []
|
||||
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 1)
|
||||
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
|
||||
return [result, response(commands(cmds))] // returns the result of reponse()
|
||||
}
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
|
||||
logging("MultiChannelCmdEncap ${cmd}", 2)
|
||||
def encapsulatedCommand = cmd.encapsulatedCommand([0x32: 3, 0x25: 1, 0x20: 1])
|
||||
if (encapsulatedCommand) {
|
||||
zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
|
||||
}
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||
logging("ManufacturerSpecificReport ${cmd}", 2)
|
||||
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
|
||||
logging("msr: $msr", 2)
|
||||
updateDataValue("MSR", msr)
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
// This will capture any commands not handled by other instances of zwaveEvent
|
||||
// and is recommended for development so you can see every command the device sends
|
||||
logging("Unhandled Event: ${cmd}", 2)
|
||||
}
|
||||
def on() {
|
||||
logging("on()", 1)
|
||||
commands([
|
||||
zwave.switchAllV1.switchAllOn(),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
|
||||
])
|
||||
}
|
||||
def off() {
|
||||
logging("off()", 1)
|
||||
commands([
|
||||
zwave.switchAllV1.switchAllOff(),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
|
||||
])
|
||||
}
|
||||
void childOn(String dni) {
|
||||
logging("childOn($dni)", 1)
|
||||
def cmds = []
|
||||
cmds << new physicalgraph.device.HubAction(command(encap(zwave.basicV1.basicSet(value: 0xFF), channelNumber(dni))))
|
||||
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchBinaryV1.switchBinaryGet(), channelNumber(dni))))
|
||||
sendHubCommand(cmds, 1000)
|
||||
}
|
||||
void childOff(String dni) {
|
||||
logging("childOff($dni)", 1)
|
||||
def cmds = []
|
||||
cmds << new physicalgraph.device.HubAction(command(encap(zwave.basicV1.basicSet(value: 0x00), channelNumber(dni))))
|
||||
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchBinaryV1.switchBinaryGet(), channelNumber(dni))))
|
||||
sendHubCommand(cmds, 1000)
|
||||
}
|
||||
void childRefresh(String dni) {
|
||||
logging("childRefresh($dni)", 1)
|
||||
def cmds = []
|
||||
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchBinaryV1.switchBinaryGet(), channelNumber(dni))))
|
||||
sendHubCommand(cmds, 1000)
|
||||
}
|
||||
def poll() {
|
||||
logging("poll()", 1)
|
||||
commands([
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 2),
|
||||
])
|
||||
}
|
||||
def refresh() {
|
||||
logging("refresh()", 1)
|
||||
commands([
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 2),
|
||||
])
|
||||
}
|
||||
def ping() {
|
||||
logging("ping()", 1)
|
||||
refresh()
|
||||
}
|
||||
def installed() {
|
||||
logging("installed()", 1)
|
||||
command(zwave.manufacturerSpecificV1.manufacturerSpecificGet())
|
||||
createChildDevices()
|
||||
}
|
||||
def updated() {
|
||||
logging("updated()", 1)
|
||||
if (!childDevices) {
|
||||
createChildDevices()
|
||||
} else if (device.label != state.oldLabel) {
|
||||
childDevices.each {
|
||||
if (it.label == "${state.oldLabel} (CH${channelNumber(it.deviceNetworkId)})") {
|
||||
def newLabel = "${device.displayName} (CH${channelNumber(it.deviceNetworkId)})"
|
||||
it.setLabel(newLabel)
|
||||
}
|
||||
}
|
||||
state.oldLabel = device.label
|
||||
}
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
sendEvent(name: "needUpdate", value: device.currentValue("needUpdate"), displayed: false, isStateChange: true)
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) {
|
||||
logging("${device.displayName} parameter '${cmd.parameterNumber}' with a byte size of '${cmd.size}' is set to '${cmd2Integer(cmd.configurationValue)}'", 2)
|
||||
}
|
||||
private encap(cmd, endpoint) {
|
||||
if (endpoint) {
|
||||
zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint: endpoint).encapsulate(cmd)
|
||||
} else {
|
||||
cmd
|
||||
}
|
||||
}
|
||||
private command(physicalgraph.zwave.Command cmd) {
|
||||
if (state.sec) {
|
||||
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
|
||||
} else {
|
||||
cmd.format()
|
||||
}
|
||||
}
|
||||
private commands(commands, delay = 1000) {
|
||||
delayBetween(commands.collect {
|
||||
command(it)
|
||||
}, delay)
|
||||
}
|
||||
private channelNumber(String dni) {
|
||||
dni.split("-ep")[-1] as Integer
|
||||
}
|
||||
private void createChildDevices() {
|
||||
state.oldLabel = device.label
|
||||
for (i in 1..2) {
|
||||
addChildDevice("Switch Child Device", "${device.deviceNetworkId}-ep${i}", null, [completedSetup: true, label: "${device.displayName} (CH${i})",
|
||||
isComponent: true, componentName: "ep$i", componentLabel: "Channel $i"
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
private def logging(message, level) {
|
||||
if (logLevel != "0") {
|
||||
switch (logLevel) {
|
||||
case "1":
|
||||
if (level > 1) log.debug "$message"
|
||||
break
|
||||
case "99":
|
||||
log.debug "$message"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/**
|
||||
* Switch Child Device
|
||||
*
|
||||
* Copyright 2017 Eric Maycock
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Switch Child Device", namespace: "erocm123", author: "Eric Maycock") {
|
||||
capability "Switch"
|
||||
capability "Actuator"
|
||||
capability "Sensor"
|
||||
capability "Refresh"
|
||||
}
|
||||
|
||||
tiles {
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 3, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState:"turningOn"
|
||||
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void on() {
|
||||
parent.childOn(device.deviceNetworkId)
|
||||
}
|
||||
|
||||
void off() {
|
||||
parent.childOff(device.deviceNetworkId)
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
parent.childRefresh(device.deviceNetworkId)
|
||||
}
|
||||
@@ -39,8 +39,8 @@ metadata {
|
||||
}
|
||||
|
||||
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
|
||||
attributeState("active", label:'tamper active', backgroundColor:"#00A0DC")
|
||||
attributeState("inactive", label:'tamper inactive', backgroundColor:"#CCCCCC")
|
||||
attributeState("active", label:'tamper active', backgroundColor:"#53a7c0")
|
||||
attributeState("inactive", label:'tamper inactive', backgroundColor:"#ffffff")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ metadata {
|
||||
}
|
||||
|
||||
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
|
||||
attributeState("active", label:'tamper active', backgroundColor:"#00A0DC")
|
||||
attributeState("inactive", label:'tamper inactive', backgroundColor:"#CCCCCC")
|
||||
attributeState("active", label:'tamper active', backgroundColor:"#53a7c0")
|
||||
attributeState("inactive", label:'tamper inactive', backgroundColor:"#ffffff")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ metadata {
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"FGMS", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
|
||||
tileAttribute("device.motion", key:"PRIMARY_CONTROL") {
|
||||
attributeState("inactive", label:"no motion", icon:"st.motion.motion.inactive", backgroundColor:"#cccccc")
|
||||
attributeState("active", label:"motion", icon:"st.motion.motion.active", backgroundColor:"#00A0DC")
|
||||
attributeState("inactive", label:"no motion", icon:"st.motion.motion.inactive", backgroundColor:"#79b821")
|
||||
attributeState("active", label:"motion", icon:"st.motion.motion.active", backgroundColor:"#ffa81e")
|
||||
}
|
||||
|
||||
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
/**
|
||||
* FortrezZ MIMO2+ B-Side
|
||||
*
|
||||
* Copyright 2016 FortrezZ, LLC
|
||||
*
|
||||
* 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: "FortrezZ MIMO2+ B-Side", namespace: "fortrezz", author: "FortrezZ, LLC") {
|
||||
capability "Contact Sensor"
|
||||
capability "Relay Switch"
|
||||
capability "Switch"
|
||||
capability "Voltage Measurement"
|
||||
capability "Refresh"
|
||||
}
|
||||
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2) {
|
||||
state "on", label: "Relay 2 On", action: "off", icon: "http://swiftlet.technology/wp-content/uploads/2016/06/Switch-On-104-edit.png", backgroundColor: "#53a7c0"
|
||||
state "off", label: "Relay 2 Off", action: "on", icon: "http://swiftlet.technology/wp-content/uploads/2016/06/Switch-Off-104-edit.png", backgroundColor: "#ffffff"
|
||||
}
|
||||
standardTile("anaDig1", "device.anaDig1", inactiveLabel: false) {
|
||||
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e"
|
||||
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821"
|
||||
state "val", label:'${currentValue}v', unit:"", defaultState: true
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
standardTile("powered", "device.powered", inactiveLabel: false) {
|
||||
state "powerOn", label: "Power On", icon: "st.switches.switch.on", backgroundColor: "#79b821"
|
||||
state "powerOff", label: "Power Off", icon: "st.switches.switch.off", backgroundColor: "#ffa81e"
|
||||
}
|
||||
standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
|
||||
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
|
||||
}
|
||||
standardTile("blank", "device.blank", inactiveLabel: true, decoration: "flat") {
|
||||
state("blank", label: '')
|
||||
}
|
||||
main (["switch"])
|
||||
details(["switch", "anaDig1", "blank", "blank", "refresh", "powered"])
|
||||
}
|
||||
}
|
||||
|
||||
// parse events into attributes
|
||||
def parse(String description) {
|
||||
log.debug "Parsing '${description}'"
|
||||
// TODO: handle 'contact' attribute
|
||||
// TODO: handle 'switch' attribute
|
||||
// TODO: handle 'switch' attribute
|
||||
// TODO: handle 'voltage' attribute
|
||||
|
||||
}
|
||||
|
||||
def eventParse(evt) {
|
||||
log.debug("Event: ${evt.name}=${evt.value}")
|
||||
switch(evt.name) {
|
||||
case "powered":
|
||||
sendEvent(name: evt.name, value: evt.value)
|
||||
break
|
||||
case "switch2":
|
||||
sendEvent(name: "switch", value: evt.value)
|
||||
break
|
||||
case "contact2":
|
||||
sendEvent(name: "contact", value: evt.value)
|
||||
break
|
||||
case "voltage2":
|
||||
sendEvent(name: "voltage", value: evt.value)
|
||||
break
|
||||
case "relay2":
|
||||
sendEvent(name: evt.name, value: evt.value)
|
||||
break
|
||||
case "anaDig2":
|
||||
sendEvent(name: "anaDig1", value: evt.value)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// handle commands
|
||||
def on() {
|
||||
parent.on2(device.id)
|
||||
log.debug("Executing 'on'")
|
||||
// TODO: Send Event to parent device for "on2"
|
||||
}
|
||||
|
||||
def off() {
|
||||
parent.off2(device.id)
|
||||
log.debug("Executing 'off'")
|
||||
// TODO: Send Event to parent device for "off2"
|
||||
}
|
||||
def refresh() {
|
||||
parent.refresh2(device.id)
|
||||
log.debug("Executing 'refresh'")
|
||||
}
|
||||
@@ -1,379 +0,0 @@
|
||||
/**
|
||||
* MIMO2 Device Handler
|
||||
*
|
||||
* Copyright 2016 FortrezZ, LLC
|
||||
*
|
||||
* 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: "FortrezZ MIMO2+", namespace: "fortrezz", author: "FortrezZ, LLC") {
|
||||
capability "Alarm"
|
||||
capability "Contact Sensor"
|
||||
capability "Switch"
|
||||
capability "Voltage Measurement"
|
||||
capability "Configuration"
|
||||
capability "Refresh"
|
||||
|
||||
attribute "powered", "string"
|
||||
attribute "relay", "string"
|
||||
|
||||
attribute "relay2", "string"
|
||||
attribute "contact2", "string"
|
||||
attribute "voltage2", "string"
|
||||
|
||||
command "on"
|
||||
command "off"
|
||||
command "on2"
|
||||
command "off2"
|
||||
|
||||
fingerprint deviceId: "0x2100", inClusters: "0x5E,0x86,0x72,0x5A,0x59,0x71,0x98,0x7A"
|
||||
}
|
||||
|
||||
preferences {
|
||||
|
||||
input ("RelaySwitchDelay", "decimal", title: "Delay between relay switch on and off in seconds. Only Numbers 0 to 3 allowed. 0 value will remove delay and allow relay to function as a standard switch:\nRelay 1", description: "Numbers 0 to 3.1 allowed.", defaultValue: 0, required: false, displayDuringSetup: true)
|
||||
input ("RelaySwitchDelay2", "decimal", title: "Relay 2", description: "Numbers 0 to 3.1 allowed.", defaultValue: 0, required: false, displayDuringSetup: true)
|
||||
input ("Sig1AD", "bool", title: "Switch off for digital, on for analog:\nSIG1", required: false, displayDuringSetup: true)
|
||||
input ("Sig2AD", "bool", title: "SIG2", required: false, displayDuringSetup: true)
|
||||
} // the range would be 0 to 3.1, but the range value would not accept 3.1, only whole numbers (i tried paranthesis and fractions too. :( )
|
||||
|
||||
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2) {
|
||||
state "on", label: "Relay 1 On", action: "off", icon: "http://swiftlet.technology/wp-content/uploads/2016/06/Switch-On-104-edit.png", backgroundColor: "#53a7c0"
|
||||
state "off", label: "Relay 1 Off", action: "on", icon: "http://swiftlet.technology/wp-content/uploads/2016/06/Switch-Off-104-edit.png", backgroundColor: "#ffffff"
|
||||
|
||||
}
|
||||
standardTile("switch2", "device.switch2", width: 2, height: 2, inactiveLabel: false) {
|
||||
state "on", label: "Relay 2 On", action: "off2", icon: "http://swiftlet.technology/wp-content/uploads/2016/06/Switch-On-104-edit.png", backgroundColor: "#53a7c0"
|
||||
state "off", label: 'Relay 2 Off', action: "on2", icon: "http://swiftlet.technology/wp-content/uploads/2016/06/Switch-Off-104-edit.png", backgroundColor: "#ffffff"
|
||||
}
|
||||
standardTile("anaDig1", "device.anaDig1", inactiveLabel: false) {
|
||||
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e"
|
||||
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821"
|
||||
state "val", label:'${currentValue}v', unit:"", defaultState: true
|
||||
}
|
||||
standardTile("anaDig2", "device.anaDig2", inactiveLabel: false) {
|
||||
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e"
|
||||
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821"
|
||||
state "val", label:'${currentValue}v', unit:"", defaultState: true
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
standardTile("powered", "device.powered", inactiveLabel: false) {
|
||||
state "powerOn", label: "Power On", icon: "st.switches.switch.on", backgroundColor: "#79b821"
|
||||
state "powerOff", label: "Power Off", icon: "st.switches.switch.off", backgroundColor: "#ffa81e"
|
||||
}
|
||||
standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
|
||||
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
|
||||
}
|
||||
standardTile("blank", "device.blank", inactiveLabel: true, decoration: "flat") {
|
||||
state("blank", label: '')
|
||||
}
|
||||
main (["switch"])
|
||||
details(["switch", "anaDig1", "blank", "switch2", "anaDig2", "blank", "configure", "refresh", "powered"])
|
||||
}
|
||||
}
|
||||
|
||||
// parse events into attributes
|
||||
def parse(String description) {
|
||||
def result = null
|
||||
def cmd = zwave.parse(description)
|
||||
|
||||
if (cmd.CMD == "7105") { //Mimo sent a power loss report
|
||||
log.debug "Device lost power"
|
||||
sendEvent(name: "powered", value: "powerOff", descriptionText: "$device.displayName lost power")
|
||||
} else {
|
||||
sendEvent(name: "powered", value: "powerOn", descriptionText: "$device.displayName regained power")
|
||||
}
|
||||
if (cmd) {
|
||||
def eventReturn = zwaveEvent(cmd)
|
||||
if(eventReturn in physicalgraph.device.HubMultiAction) {
|
||||
result = eventReturn
|
||||
}
|
||||
else {
|
||||
result = createEvent(eventReturn)
|
||||
}
|
||||
}
|
||||
log.debug "Parse returned ${result} $cmd.CMD"
|
||||
return result
|
||||
}
|
||||
|
||||
def updated() { // neat built-in smartThings function which automatically runs whenever any setting inputs are changed in the preferences menu of the device handler
|
||||
|
||||
if (state.count == 1) // this bit with state keeps the function from running twice ( which it always seems to want to do) (( oh, and state.count is a variable which is nonVolatile and doesn't change per every parse request.
|
||||
{
|
||||
state.count = 0
|
||||
log.debug "Settings Updated..."
|
||||
return response(delayBetween([
|
||||
configure(), // the response() function is used for sending commands in reponse to an event, without it, no zWave commands will work for contained function
|
||||
refresh()
|
||||
], 200))
|
||||
}
|
||||
else {state.count = 1}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) // basic set is essentially our digital sensor for SIG1 and SIG2 - it doesn't use an endpoint so we are having it send a multilevelGet() for SIG1 and SIG2 to see which one triggered.
|
||||
{
|
||||
log.debug "sent a BasicSet command"
|
||||
return response(refresh())
|
||||
}
|
||||
|
||||
def zwaveEvent(int endPoint, physicalgraph.zwave.commands.sensorbinaryv1.SensorBinaryReport cmd) // event to get the state of the digital sensor SIG1 and SIG2
|
||||
{
|
||||
log.debug "sent a sensorBinaryReport command"
|
||||
return response(refresh())
|
||||
}
|
||||
|
||||
def zwaveEvent(int endPoint, physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) // event for seeing the states of relay 1 and relay 2
|
||||
{
|
||||
def map = [:] // map for containing the name and state fo the specified relay
|
||||
if (endPoint == 3)
|
||||
{
|
||||
if (cmd.value) // possible values are 255 and 0 (0 is false)
|
||||
{map.value = "on"}
|
||||
else
|
||||
{map.value = "off"}
|
||||
map.name = "switch"
|
||||
log.debug "sent a SwitchBinary command $map.name $map.value" // the map is only used for debug messages. not for the return command to the device
|
||||
return [name: "switch", value: cmd.value ? "on" : "off"]
|
||||
}
|
||||
else if (endPoint == 4)
|
||||
{
|
||||
if (cmd.value)
|
||||
{map.value = "on"}
|
||||
else
|
||||
{map.value = "off"}
|
||||
map.name = "switch2"
|
||||
sendEvent(name: "relay2", value: "$map.value")
|
||||
log.debug "sent a SwitchBinary command $map.name $map.value" // the map is only used for debug messages. not for the return command to the device
|
||||
return [name: "switch2", value: cmd.value ? "on" : "off"]
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent (int endPoint, physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd) // sensorMultilevelReport is used to report the value of the analog voltage for SIG1
|
||||
{
|
||||
def map = [:]
|
||||
def stdEvent = [:]
|
||||
def voltageVal = CalculateVoltage(cmd.scaledSensorValue) // saving the scaled Sensor Value used to enter into a large formula to determine actual voltage value
|
||||
if (endPoint == 1) //endPoint 1 is for SIG1
|
||||
{
|
||||
if (state.AD1 == false) // state.AD1 is to determine which state the anaDig1 tile should be in (either analogue or digital mode)
|
||||
{
|
||||
map.name = "anaDig1"
|
||||
stdEvent.name = "contact"
|
||||
if (voltageVal < 2) { // DK changed to 2v to follow LED behavior
|
||||
map.value = "closed"
|
||||
stdEvent.value = "closed"
|
||||
}
|
||||
else
|
||||
{
|
||||
map.value = "open"
|
||||
stdEvent.value = "open"
|
||||
}
|
||||
}
|
||||
else //or state.AD1 is true for analogue mode
|
||||
{
|
||||
map.name = "anaDig1"
|
||||
stdEvent.name = "voltage"
|
||||
map.value = voltageVal
|
||||
stdEvent.value = voltageVal
|
||||
map.unit = "v"
|
||||
stdEvent.unit = "v"
|
||||
}
|
||||
}
|
||||
else if (endPoint == 2) // endpoint 2 is for SIG2
|
||||
{
|
||||
if (state.AD2 == false)
|
||||
{
|
||||
map.name = "anaDig2"
|
||||
stdEvent.name = "contact2"
|
||||
if (voltageVal < 2) {
|
||||
map.value = "closed"
|
||||
stdEvent.value = "closed"
|
||||
}
|
||||
else
|
||||
{
|
||||
map.value = "open"
|
||||
stdEvent.value = "open"
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
map.name = "anaDig2"
|
||||
stdEvent.name = "voltage2"
|
||||
map.value = voltageVal
|
||||
stdEvent.value = voltageVal
|
||||
map.unit = "v"
|
||||
stdEvent.unit = "v"
|
||||
}
|
||||
}
|
||||
log.debug "sent a SensorMultilevelReport $map.name $map.value"
|
||||
sendEvent(stdEvent)
|
||||
return map
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) { //standard security encapsulation event code (should be the same on all device handlers)
|
||||
def encapsulatedCommand = cmd.encapsulatedCommand()
|
||||
// can specify command class versions here like in zwave.parse
|
||||
if (encapsulatedCommand) {
|
||||
return zwaveEvent(encapsulatedCommand)
|
||||
}
|
||||
}
|
||||
|
||||
// MultiChannelCmdEncap and MultiInstanceCmdEncap are ways that devices
|
||||
// can indicate that a message is coming from one of multiple subdevices
|
||||
// or "endpoints" that would otherwise be indistinguishable
|
||||
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
|
||||
def encapsulatedCommand = cmd.encapsulatedCommand()
|
||||
log.debug ("Command from endpoint ${cmd.sourceEndPoint}: ${encapsulatedCommand}")
|
||||
|
||||
if (encapsulatedCommand) {
|
||||
return zwaveEvent(cmd.sourceEndPoint, encapsulatedCommand)
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(int endPoint, physicalgraph.zwave.commands.multichannelassociationv2.MultiChannelAssociationReport cmd) {
|
||||
|
||||
log.debug "sent an Association Report"
|
||||
log.debug " ${cmd.groupingIdentifier}"
|
||||
//return [:]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
// Handles all Z-Wave commands we aren't interested in
|
||||
log.debug("Un-parsed Z-Wave message ${cmd}")
|
||||
return [:]
|
||||
}
|
||||
|
||||
def CalculateVoltage(ADCvalue) // used to calculate the voltage based on the collected Scaled sensor value of the multilevel sensor event
|
||||
{
|
||||
def volt = (((2.396*(10**-17))*(ADCvalue**5)) - ((1.817*(10**-13))*(ADCvalue**4)) + ((5.087*(10**-10))*(ADCvalue**3)) - ((5.868*(10**-7))*(ADCvalue**2)) + ((9.967*(10**-4))*(ADCvalue)) - (1.367*(10**-2)))
|
||||
return volt.round(1)
|
||||
}
|
||||
|
||||
|
||||
def configure() {
|
||||
log.debug "Configuring...."
|
||||
def sig1
|
||||
def sig2
|
||||
if (Sig1AD == true)
|
||||
{ sig1 = 0x01
|
||||
state.AD1 = true}
|
||||
else if (Sig1AD == false)
|
||||
{ sig1 = 0x40
|
||||
state.AD1 = false}
|
||||
if (Sig2AD == true)
|
||||
{ sig2 = 0x01
|
||||
state.AD2 = true}
|
||||
else if (Sig2AD == false)
|
||||
{ sig2 = 0x40
|
||||
state.AD2 = false}
|
||||
|
||||
def delay = (RelaySwitchDelay*10).toInteger() // the input which we get from the user is a string and is in seconds while the MIMO2 configuration requires it in 100ms so - change to integer and multiply by 10
|
||||
def delay2 = (RelaySwitchDelay2*10).toInteger() // the input which we get from the user is a string and is in seconds while the MIMO2 configuration requires it in 100ms so - change to integer and multiply by 10
|
||||
if (delay > 31)
|
||||
{
|
||||
log.debug "Relay 1 input ${delay / 10} set too high. Max value is 3.1"
|
||||
delay = 31
|
||||
}
|
||||
if (delay < 0)
|
||||
{
|
||||
log.debug "Relay 1 input ${delay / 10} set too low. Min value is 0"
|
||||
delay = 0
|
||||
}
|
||||
if (delay2 > 31)
|
||||
{
|
||||
log.debug "Relay 2 input ${delay2 / 10} set too high. Max value is 3.1"
|
||||
delay2 = 31
|
||||
}
|
||||
if (delay2 < 0)
|
||||
{
|
||||
log.debug "Relay 2 input ${delay2 / 10} set too low. Min value is 0"
|
||||
delay = 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
return delayBetween([
|
||||
encap(zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]), 0),
|
||||
encap(zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]), 0),
|
||||
|
||||
encap(zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]), 1),
|
||||
encap(zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]), 2),
|
||||
encap(zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]), 3),
|
||||
encap(zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]), 4),
|
||||
|
||||
secure(zwave.configurationV1.configurationSet(configurationValue: [sig1], parameterNumber: 3, size: 1)), // sends a multiLevelSensor report every 30 seconds for SIG1
|
||||
secure(zwave.configurationV1.configurationSet(configurationValue: [sig2], parameterNumber: 9, size: 1)), // sends a multiLevelSensor report every 30 seconds for SIG2
|
||||
secure(zwave.configurationV1.configurationSet(configurationValue: [delay], parameterNumber: 1, size: 1)), // configurationValue for parameterNumber means how many 100ms do you want the relay
|
||||
// to wait before it cycles again / size should just be 1 (for 1 byte.)
|
||||
secure(zwave.configurationV1.configurationSet(configurationValue: [delay2], parameterNumber: 2, size: 1)),
|
||||
|
||||
], 200)
|
||||
}
|
||||
|
||||
def on() {
|
||||
return encap(zwave.basicV1.basicSet(value: 0xff), 3) // physically changes the relay from on to off and requests a report of the relay
|
||||
// oddly, smartThings automatically sends a switchBinaryGet() command whenever the above basicSet command is sent, so we don't need to send one here.
|
||||
}
|
||||
|
||||
def off() {
|
||||
return encap(zwave.basicV1.basicSet(value: 0x00), 3) // physically changes the relay from on to off and requests a report of the relay
|
||||
// oddly, smartThings automatically sends a switchBinaryGet() command whenever the above basicSet command is sent, so we don't need to send one here.
|
||||
}
|
||||
|
||||
def on2() {
|
||||
return encap(zwave.basicV1.basicSet(value: 0xff), 4)
|
||||
// oddly, smartThings automatically sends a switchBinaryGet() command whenever the above basicSet command is sent, so we don't need to send one here.
|
||||
}
|
||||
|
||||
def off2() {
|
||||
return encap(zwave.basicV1.basicSet(value: 0x00), 4)
|
||||
// oddly, smartThings automatically sends a switchBinaryGet() command whenever the above basicSet command is sent, so we don't need to send one here.
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
log.debug "Refresh"
|
||||
return delayBetween([
|
||||
encap(zwave.sensorMultilevelV5.sensorMultilevelGet(), 1),// requests a report of the anologue input voltage for SIG1
|
||||
encap(zwave.sensorMultilevelV5.sensorMultilevelGet(), 2),// requests a report of the anologue input voltage for SIG2
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 3), //requests a report of the relay to make sure that it changed for Relay 1
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 4), //requests a report of the relay to make sure that it changed for Relay 2
|
||||
],200)
|
||||
}
|
||||
|
||||
def refreshZWave() {
|
||||
log.debug "Refresh (Z-Wave Response)"
|
||||
return delayBetween([
|
||||
encap(zwave.sensorMultilevelV5.sensorMultilevelGet(), 1),// requests a report of the anologue input voltage for SIG1
|
||||
encap(zwave.sensorMultilevelV5.sensorMultilevelGet(), 2),// requests a report of the anologue input voltage for SIG2
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 3), //requests a report of the relay to make sure that it changed for Relay 1
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 4) //requests a report of the relay to make sure that it changed for Relay 2
|
||||
],200)
|
||||
}
|
||||
|
||||
private secureSequence(commands, delay=200) { // decided not to use this
|
||||
return delayBetween(commands.collect{ secure(it) }, delay)
|
||||
}
|
||||
|
||||
private secure(physicalgraph.zwave.Command cmd) { //take multiChannel message and securely encrypts the message so the device can read it
|
||||
return zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
|
||||
}
|
||||
|
||||
private encap(cmd, endpoint) { // takes desired command and encapsulates it by multiChannel and then sends it to secure() to be wrapped with another encapsulation for secure encryption
|
||||
if (endpoint) {
|
||||
return secure(zwave.multiChannelV3.multiChannelCmdEncap(bitAddress: false, sourceEndPoint:0, destinationEndPoint: endpoint).encapsulate(cmd))
|
||||
} else {
|
||||
return secure(cmd)
|
||||
}
|
||||
}
|
||||
@@ -95,12 +95,12 @@ metadata {
|
||||
multiAttributeTile(name:"doorCtrl", type:"generic", width:6, height:4) {tileAttribute("device.doorState", key: "PRIMARY_CONTROL")
|
||||
{
|
||||
attributeState "unknown", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", nextState:"Sent"
|
||||
attributeState "open", label: '${name}', action:"closeDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#00A0DC" , nextState:"Sent"
|
||||
attributeState "opening", label: '${name}', action:"closeDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#00A0DC"
|
||||
attributeState "closed", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ffffff", nextState:"Sent"
|
||||
attributeState "closing", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ffffff"
|
||||
attributeState "jammed", label: '${name}', action:"closeDoorHiI", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff0000", nextState:"Sent"
|
||||
attributeState "forced close", label: 'forced\rclose', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff8000", nextState:"Sent"
|
||||
attributeState "open", label: '${name}', action:"closeDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#0000ff" , nextState:"Sent"
|
||||
attributeState "opening", label: '${name}', action:"closeDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ffa81e"
|
||||
attributeState "closed", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#79b821", nextState:"Sent"
|
||||
attributeState "closing", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ffa81e"
|
||||
attributeState "jammed", label: '${name}', action:"closeDoorHiI", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff0000", nextState:"Sent"
|
||||
attributeState "forced close", label: 'forced\rclose', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff8000", nextState:"Sent"
|
||||
attributeState "fault", label: 'FAULT', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff0000", nextState:"Sent"
|
||||
attributeState "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
||||
}
|
||||
@@ -135,13 +135,13 @@ metadata {
|
||||
}
|
||||
|
||||
standardTile("autoClose", "device.autoCloseEnable", width: 2, height: 2){
|
||||
state "on", label: 'Auto', action:"autoCloseOff", icon: "st.doors.garage.garage-closing", backgroundColor: "#00A0DC", nextState:"Sent"
|
||||
state "on", label: 'Auto', action:"autoCloseOff", icon: "st.doors.garage.garage-closing", backgroundColor: "#79b821", nextState:"Sent"
|
||||
state "off", label: 'Auto', action:"autoCloseOn", icon: "st.doors.garage.garage-closing", nextState:"Sent"
|
||||
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
||||
}
|
||||
|
||||
standardTile("autoOpen", "device.autoOpenEnable", width: 2, height: 2){
|
||||
state "on", label: 'Auto', action:"autoOpenOff", icon: "st.doors.garage.garage-opening", backgroundColor: "#00A0DC", nextState:"Sent"
|
||||
state "on", label: 'Auto', action:"autoOpenOff", icon: "st.doors.garage.garage-opening", backgroundColor: "#79b821", nextState:"Sent"
|
||||
state "off", label: 'Auto', action:"autoOpenOn", icon: "st.doors.garage.garage-opening", nextState:"Sent"
|
||||
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
||||
}
|
||||
@@ -189,13 +189,13 @@ metadata {
|
||||
|
||||
standardTile("aux1", "device.Aux1", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "off", label:'Aux 1', action:"Aux1On", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"Sent"
|
||||
state "on", label:'Aux 1', action:"Aux1Off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"Sent"
|
||||
state "on", label:'Aux 1', action:"Aux1Off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"Sent"
|
||||
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
||||
}
|
||||
|
||||
standardTile("aux2", "device.Aux2", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "off", label:'Aux 2', action:"Aux2On", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"Sent"
|
||||
state "on", label:'Aux 2', action:"Aux2Off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"Sent"
|
||||
state "on", label:'Aux 2', action:"Aux2Off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"Sent"
|
||||
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -1,33 +0,0 @@
|
||||
# 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,7 +24,6 @@ import groovy.json.JsonBuilder
|
||||
metadata {
|
||||
definition (name: "PlantLink", namespace: "OsoTech", author: "Oso Technologies") {
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
|
||||
command "setStatusIcon"
|
||||
command "setPlantFuelLevel"
|
||||
@@ -71,16 +70,6 @@ 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 status = ''
|
||||
switch (value) {
|
||||
@@ -172,4 +161,4 @@ def parseDescriptionAsMap(description) {
|
||||
map += []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Spruce Sensor -updated with SLP model number 5/2017
|
||||
* Spruce Sensor -Pre-release V2 10/8/2015
|
||||
*
|
||||
* Copyright 2014 Plaid Systems
|
||||
*
|
||||
@@ -14,33 +14,25 @@
|
||||
*
|
||||
-------10/20/2015 Updates--------
|
||||
-Fix/add battery reporting interval to update
|
||||
-remove polling and/or refresh
|
||||
|
||||
-------5/2017 Updates--------
|
||||
-Add fingerprints for SLP
|
||||
-add device health, check every 60mins + 2mins
|
||||
-remove polling and/or refresh(?)
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "Spruce Sensor", namespace: "plaidsystems", author: "Plaid Systems") {
|
||||
definition (name: "Spruce Sensor", namespace: "plaidsystems", author: "NCauffman") {
|
||||
|
||||
capability "Configuration"
|
||||
capability "Battery"
|
||||
capability "Relative Humidity Measurement"
|
||||
capability "Temperature Measurement"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
//capability "Polling"
|
||||
|
||||
attribute "maxHum", "string"
|
||||
attribute "minHum", "string"
|
||||
|
||||
|
||||
command "resetHumidity"
|
||||
command "refresh"
|
||||
|
||||
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0402,0405", outClusters: "0003, 0019", manufacturer: "PLAID SYSTEMS", model: "PS-SPRZMS-01", deviceJoinName: "Spruce Sensor"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0402,0405", outClusters: "0003, 0019", manufacturer: "PLAID SYSTEMS", model: "PS-SPRZMS-SLP1", deviceJoinName: "Spruce Sensor"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0402,0405", outClusters: "0003, 0019", manufacturer: "PLAID SYSTEMS", model: "PS-SPRZMS-01"
|
||||
}
|
||||
|
||||
preferences {
|
||||
@@ -301,11 +293,6 @@ def setConfig(){
|
||||
sendEvent(name: 'configuration',value: configInterval, descriptionText: "Configuration initialized")
|
||||
}
|
||||
|
||||
def installed(){
|
||||
//check every 1 hour + 2mins
|
||||
sendEvent(name: "checkInterval", value: 1 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||
}
|
||||
|
||||
//when device preferences are changed
|
||||
def updated(){
|
||||
log.debug "device updated"
|
||||
@@ -316,8 +303,6 @@ def updated(){
|
||||
sendEvent(name: 'configuration',value: 0, descriptionText: "Settings changed and will update at next report. Measure interval set to ${interval} mins")
|
||||
}
|
||||
}
|
||||
//check every 1 hour + 2mins
|
||||
sendEvent(name: "checkInterval", value: 1 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||
}
|
||||
|
||||
//poll
|
||||
@@ -410,4 +395,4 @@ private byte[] reverseArray(byte[] array) {
|
||||
i++;
|
||||
}
|
||||
return array
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -1,34 +0,0 @@
|
||||
# Aeon Labs Key Fob
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [Aeon Labs Key Fob](http://aeotec.com/z-wave-key-fob-remote-control)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Actuator** - represents device has commands
|
||||
* **Button** - represents a device with one or more buttons
|
||||
* **Holdable Button** - represents a device with one or more holdable buttons
|
||||
* **Configuration** - allows for configuration of devices
|
||||
* **Sensor** - detects sensor events
|
||||
* **Battery** - defines device uses a battery
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
## Device Health
|
||||
|
||||
Aeon Key Fob is a ZWave totally sleepy device and is marked offline only in the case when Hub is offline.
|
||||
|
||||
## 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 Aeon Labs Key Fob from SmartThings can be found in the following link:
|
||||
* [Aeotec Key Fob Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/202294120-Aeon-Labs-Key-Fob)
|
||||
@@ -1,4 +1,3 @@
|
||||
import groovy.json.JsonOutput
|
||||
/**
|
||||
* Copyright 2015 SmartThings
|
||||
*
|
||||
@@ -20,10 +19,8 @@ metadata {
|
||||
capability "Configuration"
|
||||
capability "Sensor"
|
||||
capability "Battery"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint deviceId: "0x0101", inClusters: "0x86,0x72,0x70,0x80,0x84,0x85"
|
||||
fingerprint mfr: "0086", prod: "0001", model: "0026", deviceJoinName: "Aeon Panic Button"
|
||||
}
|
||||
|
||||
simulator {
|
||||
@@ -133,15 +130,5 @@ def updated() {
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
// Arrival sensors only goes OFFLINE when Hub is off
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "zigbee", scheme:"untracked"]), displayed: false)
|
||||
|
||||
def zwMap = getZwaveInfo()
|
||||
def buttons = 4 // Default for Key Fob
|
||||
|
||||
// Only one button for Aeon Panic Button
|
||||
if (zwMap && zwMap.mfr == "0086" && zwMap.prod == "0001" && zwMap.model == "0026") {
|
||||
buttons = 1
|
||||
}
|
||||
sendEvent(name: "numberOfButtons", value: buttons)
|
||||
sendEvent(name: "numberOfButtons", value: 4)
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -1,33 +0,0 @@
|
||||
# Aeon Minimote
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [Aeotec Minimote](http://aeotec.com/small-z-wave-remote-control)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Actuator** - represents device has commands
|
||||
* **Button** - represents a device with one or more buttons
|
||||
* **Holdable Button** - represents a device with one or more holdable buttons
|
||||
* **Configuration** - allows for configuration of devices
|
||||
* **Sensor** - detects sensor events
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
## Device Health
|
||||
|
||||
Aeon Minimote is a ZWave totally sleepy device and is marked offline only in the case when Hub is offline.
|
||||
|
||||
## 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 Aeotec Minimote from SmartThings can be found in the following link:
|
||||
* [Aeotec Minimote Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/202087904-Aeotec-Minimote)
|
||||
@@ -1,4 +1,3 @@
|
||||
import groovy.json.JsonOutput
|
||||
/**
|
||||
* Copyright 2015 SmartThings
|
||||
*
|
||||
@@ -19,7 +18,6 @@ metadata {
|
||||
capability "Holdable Button"
|
||||
capability "Configuration"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint deviceId: "0x0101", inClusters: "0x86,0x72,0x70,0x9B", outClusters: "0x26,0x2B"
|
||||
fingerprint deviceId: "0x0101", inClusters: "0x86,0x72,0x70,0x9B,0x85,0x84", outClusters: "0x26" // old style with numbered buttons
|
||||
@@ -121,7 +119,5 @@ def updated() {
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
// Arrival sensors only goes OFFLINE when Hub is off
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "zigbee", scheme:"untracked"]), displayed: false)
|
||||
sendEvent(name: "numberOfButtons", value: 4)
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -1,39 +0,0 @@
|
||||
# Aeon Multisensor 6
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [Aeon Labs MultiSensor 6](https://www.smartthings.com/products/aeon-labs-multisensor-6)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Motion Sensor** - can detect motion
|
||||
* **Temperature Measurement** - defines device measures current temperature
|
||||
* **Relative Humidity Measurement** - allow reading the relative humidity from devices that support it
|
||||
* **Illuminance Measurement** - gives the illuminance reading from devices that support it
|
||||
* **Ultraviolet Index** - gives the ability to get the ultraviolet index from devices that report it
|
||||
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
|
||||
* **Sensor** - detects sensor events
|
||||
* **Battery** - defines device uses a battery
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
## Device Health
|
||||
|
||||
Aeon Labs MultiSensor 6 is polled by the hub.
|
||||
Aeon MultiSensor reports in once every hour.
|
||||
|
||||
* __122min__ checkInterval
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
|
||||
Pairing needs to be tried again by placing the device closer to the hub.
|
||||
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
|
||||
* [Aeon Labs MultiSensor 6 Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206157226)
|
||||
@@ -22,7 +22,6 @@ metadata {
|
||||
capability "Configuration"
|
||||
capability "Sensor"
|
||||
capability "Battery"
|
||||
capability "Health Check"
|
||||
|
||||
attribute "tamper", "enum", ["detected", "clear"]
|
||||
attribute "batteryStatus", "string"
|
||||
@@ -30,7 +29,6 @@ metadata {
|
||||
|
||||
fingerprint deviceId: "0x2101", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x7A", outClusters: "0x5A"
|
||||
fingerprint deviceId: "0x2101", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x7A,0x5A"
|
||||
fingerprint mfr:"0086", prod:"0102", model:"0064", deviceJoinName: "Aeon Labs MultiSensor 6"
|
||||
}
|
||||
|
||||
simulator {
|
||||
@@ -105,7 +103,7 @@ metadata {
|
||||
}
|
||||
|
||||
valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "illuminance", label:'${currentValue} lux', unit:""
|
||||
state "illuminance", label:'${currentValue} ${unit}', unit:"lux"
|
||||
}
|
||||
|
||||
valueTile("ultravioletIndex", "device.ultravioletIndex", inactiveLabel: false, width: 2, height: 2) {
|
||||
@@ -129,14 +127,7 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def installed(){
|
||||
// Device-Watch simply pings if no device events received for 122min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 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 122min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
log.debug "Updated with settings: ${settings}"
|
||||
log.debug "${device.displayName} is now ${device.latestValue("powerSupply")}"
|
||||
|
||||
@@ -335,13 +326,6 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
createEvent(descriptionText: cmd.toString(), isStateChange: false)
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
def ping() {
|
||||
secure(zwave.batteryV1.batteryGet())
|
||||
}
|
||||
|
||||
def configure() {
|
||||
// This sensor joins as a secure device if you double-click the button to include it
|
||||
log.debug "${device.displayName} is configuring its settings"
|
||||
@@ -426,4 +410,4 @@ private command(physicalgraph.zwave.Command cmd) {
|
||||
private commands(commands, delay=200) {
|
||||
log.info "sending commands: ${commands}"
|
||||
delayBetween(commands.collect{ command(it) }, delay)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ metadata {
|
||||
capability "Battery"
|
||||
capability "Health Check"
|
||||
|
||||
command "configureAfterSecure"
|
||||
|
||||
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x98,0x7A", outClusters:"0x5A"
|
||||
fingerprint mfr:"0086", prod:"0102", model:"004A", deviceJoinName: "Aeon Labs MultiSensor (Gen 5)"
|
||||
}
|
||||
@@ -84,17 +86,17 @@ metadata {
|
||||
state "humidity", label:'${currentValue}% humidity', unit:""
|
||||
}
|
||||
valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "luminosity", label:'${currentValue} lux', unit:""
|
||||
state "luminosity", label:'${currentValue} ${unit}', unit:"lux"
|
||||
}
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
}
|
||||
standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "configure", label:'', action:"configure", icon:"st.secondary.configure"
|
||||
standardTile("configureAfterSecure", "device.configure", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "configure", label:'', action:"configureAfterSecure", icon:"st.secondary.configure"
|
||||
}
|
||||
|
||||
main(["motion", "temperature", "humidity", "illuminance"])
|
||||
details(["motion", "temperature", "humidity", "illuminance", "battery", "configure"])
|
||||
details(["motion", "temperature", "humidity", "illuminance", "battery", "configureAfterSecure"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,8 +131,8 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
|
||||
|
||||
if (!isConfigured()) {
|
||||
// we're still in the process of configuring a newly joined device
|
||||
log.debug("not sending wakeUpNoMoreInformation yet: late configure")
|
||||
result += response(configure())
|
||||
log.debug("not sending wakeUpNoMoreInformation yet")
|
||||
result += response(configureAfterSecure())
|
||||
} else {
|
||||
result += response(zwave.wakeUpV1.wakeUpNoMoreInformation())
|
||||
}
|
||||
@@ -148,6 +150,11 @@ def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulat
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityCommandsSupportedReport cmd) {
|
||||
// log.debug "Received SecurityCommandsSupportedReport"
|
||||
response(configureAfterSecure())
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
||||
def map = [ name: "battery", unit: "%" ]
|
||||
if (cmd.batteryLevel == 0xFF) {
|
||||
@@ -219,6 +226,36 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
createEvent(descriptionText: cmd.toString(), isStateChange: false)
|
||||
}
|
||||
|
||||
def configureAfterSecure() {
|
||||
// log.debug "configureAfterSecure()"
|
||||
|
||||
def request = [
|
||||
// send temperature, humidity, and illuminance every 8 minutes
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 128|64|32),
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 8*60),
|
||||
|
||||
// send battery every 20 hours
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 1),
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 20*60*60),
|
||||
|
||||
// send no-motion report 60 seconds after motion stops
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 60),
|
||||
|
||||
// send binary sensor report instead of basic set for motion
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: 2),
|
||||
|
||||
// disable notification-style motion events
|
||||
zwave.notificationV3.notificationSet(notificationType: 7, notificationStatus: 0),
|
||||
|
||||
zwave.batteryV1.batteryGet(),
|
||||
zwave.sensorBinaryV2.sensorBinaryGet(sensorType:0x0C)
|
||||
]
|
||||
|
||||
setConfigured()
|
||||
|
||||
secureSequence(request) + ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
@@ -228,36 +265,7 @@ def ping() {
|
||||
|
||||
def configure() {
|
||||
// log.debug "configure()"
|
||||
def request = []
|
||||
// send temperature, humidity, and illuminance every 8 minutes
|
||||
request << zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 128|64|32)
|
||||
request << zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 8*60)
|
||||
|
||||
// send battery every 20 hours
|
||||
request << zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 1)
|
||||
request << zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 20*60*60)
|
||||
|
||||
// send no-motion report 60 seconds after motion stops
|
||||
request << zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 60)
|
||||
|
||||
// send binary sensor report instead of basic set for motion
|
||||
request << zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: 2)
|
||||
|
||||
// Turn on the Multisensor Gen5 PIR sensor
|
||||
request << zwave.configurationV1.configurationSet(parameterNumber: 4, size: 1, scaledConfigurationValue: 1)
|
||||
|
||||
// disable notification-style motion events
|
||||
request << zwave.notificationV3.notificationSet(notificationType: 7, notificationStatus: 0)
|
||||
|
||||
request << zwave.batteryV1.batteryGet()
|
||||
request << zwave.sensorBinaryV2.sensorBinaryGet(sensorType: 0x0C) //motion
|
||||
request << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x01) //temperature
|
||||
request << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x03) //illuminance
|
||||
request << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x05) //humidity
|
||||
|
||||
setConfigured()
|
||||
|
||||
secureSequence(request) + ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
|
||||
//["delay 30000"] + secure(zwave.securityV1.securityCommandsSupportedGet())
|
||||
}
|
||||
|
||||
private setConfigured() {
|
||||
@@ -274,4 +282,5 @@ private secure(physicalgraph.zwave.Command cmd) {
|
||||
|
||||
private secureSequence(commands, delay=200) {
|
||||
delayBetween(commands.collect{ secure(it) }, delay)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -1,48 +0,0 @@
|
||||
# Aeon Multisensor
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [Aeotec MultiSensor (DSB05-ZWUS)](https://www.smartthings.com/products/aeotec-multisensor-5)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Battery](#battery-specification)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Motion Sensor** - can detect motion
|
||||
* **Temperature Measurement** - defines device measures current temperature
|
||||
* **Relative Humidity Measurement** - allow reading the relative humidity from devices that support it
|
||||
* **Illuminance Measurement** - gives the illuminance reading from devices that support it
|
||||
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
|
||||
* **Sensor** - detects sensor events
|
||||
* **Battery** - defines device uses a battery
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
|
||||
## Device Health
|
||||
|
||||
Aeon Labs MultiSensor is polled by the hub.
|
||||
As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed.
|
||||
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
|
||||
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
|
||||
the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row,
|
||||
it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time.
|
||||
|
||||
* __32min__ checkInterval
|
||||
|
||||
## Battery Specification
|
||||
|
||||
Four AAA batteries are required.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
|
||||
Pairing needs to be tried again by placing the device closer to the hub.
|
||||
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
|
||||
* [Aeon MultiSensor Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206157226-How-to-connect-Aeon-Labs-MultiSensors)
|
||||
@@ -20,7 +20,6 @@ metadata {
|
||||
capability "Illuminance Measurement"
|
||||
capability "Sensor"
|
||||
capability "Battery"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint deviceId: "0x2001", inClusters: "0x30,0x31,0x80,0x84,0x70,0x85,0x72,0x86"
|
||||
}
|
||||
@@ -80,7 +79,7 @@ metadata {
|
||||
state "humidity", label:'${currentValue}% humidity', unit:""
|
||||
}
|
||||
valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "luminosity", label:'${currentValue} lux', unit:""
|
||||
state "luminosity", label:'${currentValue} ${unit}', unit:"lux"
|
||||
}
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
@@ -94,16 +93,6 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def installed(){
|
||||
// Device-Watch simply pings if no device events received for 32min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
}
|
||||
|
||||
def updated(){
|
||||
// Device-Watch simply pings if no device events received for 32min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
}
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
def parse(String description)
|
||||
{
|
||||
@@ -190,13 +179,6 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
[:]
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
def ping() {
|
||||
secure(zwave.batteryV1.batteryGet())
|
||||
}
|
||||
|
||||
def configure() {
|
||||
delayBetween([
|
||||
// send binary sensor report instead of basic set for motion
|
||||
@@ -211,4 +193,4 @@ def configure() {
|
||||
// set data reporting period to 5 minutes
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 300).format()
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* Date: 2014-07-15
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Aeon Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.smoke") {
|
||||
definition (name: "Aeon Siren", namespace: "smartthings", author: "SmartThings") {
|
||||
capability "Actuator"
|
||||
capability "Alarm"
|
||||
capability "Switch"
|
||||
@@ -61,8 +61,6 @@ metadata {
|
||||
def installed() {
|
||||
// Device-Watch simply pings if no device events received for 32min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
response(secure(zwave.basicV1.basicGet()))
|
||||
}
|
||||
|
||||
def updated() {
|
||||
@@ -165,4 +163,4 @@ private secure(physicalgraph.zwave.Command cmd) {
|
||||
* */
|
||||
def ping() {
|
||||
secure(zwave.basicV1.basicGet())
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -1,50 +0,0 @@
|
||||
# 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,3 @@
|
||||
import groovy.json.JsonOutput
|
||||
|
||||
/**
|
||||
* Copyright 2017 SmartThings
|
||||
*
|
||||
@@ -21,7 +19,6 @@ metadata {
|
||||
capability "Sensor"
|
||||
capability "Battery"
|
||||
capability "Configuration"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint inClusters: "0000,0001,0003,000F,0020", outClusters: "0003,0019",
|
||||
manufacturer: "SmartThings", model: "tagv4", deviceJoinName: "Arrival Sensor"
|
||||
@@ -61,11 +58,6 @@ def updated() {
|
||||
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 cmds = zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020) + zigbee.batteryConfig(20, 20, 0x01)
|
||||
log.debug "configure -- cmds: ${cmds}"
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -1,49 +0,0 @@
|
||||
# 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,5 +1,3 @@
|
||||
import groovy.json.JsonOutput
|
||||
|
||||
/**
|
||||
* Copyright 2015 SmartThings
|
||||
*
|
||||
@@ -21,7 +19,6 @@ metadata {
|
||||
capability "Presence Sensor"
|
||||
capability "Sensor"
|
||||
capability "Battery"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint profileId: "FC01", deviceId: "019A"
|
||||
fingerprint profileId: "FC01", deviceId: "0131", inClusters: "0000,0003", outClusters: "0003"
|
||||
@@ -114,11 +111,6 @@ 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 results
|
||||
if (isBatteryMessage(description)) {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
|
||||
|
||||
/**
|
||||
* Bose SoundTouch
|
||||
*
|
||||
|
||||
@@ -9,7 +9,6 @@ metadata {
|
||||
capability "Configuration"
|
||||
capability "Refresh"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
|
||||
attribute "thermostatFanState", "string"
|
||||
|
||||
@@ -19,7 +18,6 @@ metadata {
|
||||
command "quickSetHeat"
|
||||
|
||||
fingerprint deviceId: "0x08", inClusters: "0x43,0x40,0x44,0x31,0x80,0x85,0x60"
|
||||
fingerprint mfr:"0098", prod:"6401", model:"0107", deviceJoinName: "2Gig CT100 Programmable Thermostat"
|
||||
}
|
||||
|
||||
// simulator metadata
|
||||
@@ -108,16 +106,6 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
def updated() {
|
||||
// Device-Watch simply pings if no device events received for 32min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
}
|
||||
|
||||
def installed() {
|
||||
// Device-Watch simply pings if no device events received for 32min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
}
|
||||
|
||||
def parse(String description)
|
||||
{
|
||||
def result = []
|
||||
@@ -451,14 +439,6 @@ def setCoolingSetpoint(Double degrees, Integer delay = 30000) {
|
||||
], delay)
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
def ping() {
|
||||
log.debug "ping() called"
|
||||
refresh()
|
||||
}
|
||||
|
||||
def configure() {
|
||||
delayBetween([
|
||||
zwave.thermostatModeV2.thermostatModeSupportedGet().format(),
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Dimmer Switch", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||
definition (name: "Dimmer Switch", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.switch") {
|
||||
capability "Switch Level"
|
||||
capability "Actuator"
|
||||
capability "Indicator"
|
||||
@@ -108,20 +108,11 @@ def updated(){
|
||||
}
|
||||
}
|
||||
|
||||
def getCommandClassVersions() {
|
||||
[
|
||||
0x20: 1, // Basic
|
||||
0x26: 1, // SwitchMultilevel
|
||||
0x56: 1, // Crc16Encap
|
||||
0x70: 1, // Configuration
|
||||
]
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
def result = null
|
||||
if (description != "updated") {
|
||||
log.debug "parse() >> zwave.parse($description)"
|
||||
def cmd = zwave.parse(description, commandClassVersions)
|
||||
def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
|
||||
if (cmd) {
|
||||
result = zwaveEvent(cmd)
|
||||
}
|
||||
@@ -188,16 +179,6 @@ def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelS
|
||||
[createEvent(name:"switch", value:"on"), response(zwave.switchMultilevelV1.switchMultilevelGet().format())]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
|
||||
def versions = commandClassVersions
|
||||
def version = versions[cmd.commandClass as Integer]
|
||||
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
|
||||
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
|
||||
if (encapsulatedCommand) {
|
||||
zwaveEvent(encapsulatedCommand)
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
// Handles all Z-Wave commands we aren't interested in
|
||||
[:]
|
||||
|
||||
@@ -70,7 +70,7 @@ metadata {
|
||||
state "heat", action:"switchMode", nextState: "updating", icon: "st.thermostat.heat"
|
||||
state "cool", action:"switchMode", nextState: "updating", icon: "st.thermostat.cool"
|
||||
state "auto", action:"switchMode", nextState: "updating", icon: "st.thermostat.auto"
|
||||
state "auxheatonly", action:"switchMode", icon: "st.thermostat.emergency-heat"
|
||||
state "emergency heat", action:"switchMode", icon: "st.thermostat.emergency-heat" // emergency heat = auxHeatOnly
|
||||
state "updating", label:"Working", icon: "st.secondary.secondary"
|
||||
}
|
||||
standardTile("fanMode", "device.thermostatFanMode", inactiveLabel: false, decoration: "flat") {
|
||||
@@ -156,49 +156,47 @@ void poll() {
|
||||
def generateEvent(Map results) {
|
||||
log.debug "parsing data $results"
|
||||
if(results) {
|
||||
results.each { name, value ->
|
||||
|
||||
def linkText = getLinkText(device)
|
||||
def supportedThermostatModes = ["off"]
|
||||
def thermostatMode = null
|
||||
|
||||
results.each { name, value ->
|
||||
def isChange = false
|
||||
def isDisplayed = true
|
||||
def event = [name: name, linkText: linkText, descriptionText: getThermostatDescriptionText(name, value, linkText),
|
||||
handlerName: name]
|
||||
|
||||
if (name=="temperature" || name=="heatingSetpoint" || name=="coolingSetpoint" ) {
|
||||
def sendValue = location.temperatureScale == "C"? roundC(convertFtoC(value.toDouble())) : value.toInteger()
|
||||
event << [value: sendValue, unit: temperatureScale]
|
||||
isChange = isTemperatureStateChange(device, name, value.toString())
|
||||
isDisplayed = isChange
|
||||
event << [value: sendValue, unit: temperatureScale, isStateChange: isChange, displayed: isDisplayed]
|
||||
} else if (name=="maxCoolingSetpoint" || name=="minCoolingSetpoint" || name=="maxHeatingSetpoint" || name=="minHeatingSetpoint") {
|
||||
def sendValue = location.temperatureScale == "C"? roundC(convertFtoC(value.toDouble())) : value.toInteger()
|
||||
event << [value: sendValue, unit: temperatureScale, displayed: false]
|
||||
} else if (name=="heatMode" || name=="coolMode" || name=="autoMode" || name=="auxHeatMode"){
|
||||
if (value == true) {
|
||||
supportedThermostatModes << ((name == "auxHeatMode") ? "auxheatonly" : name - "Mode")
|
||||
}
|
||||
return // as we don't want to send this event here, proceed to next name/value pair
|
||||
isChange = isStateChange(device, name, value.toString())
|
||||
event << [value: value.toString(), isStateChange: isChange, displayed: false]
|
||||
} else if (name=="thermostatFanMode"){
|
||||
sendEvent(name: "supportedThermostatFanModes", value: fanModes(), displayed: false)
|
||||
event << [value: value.toString(), data:[supportedThermostatFanModes: fanModes()]]
|
||||
isChange = isStateChange(device, name, value.toString())
|
||||
event << [value: value.toString(), isStateChange: isChange, displayed: false]
|
||||
} else if (name=="humidity") {
|
||||
event << [value: value.toString(), displayed: false, unit: "%"]
|
||||
isChange = isStateChange(device, name, value.toString())
|
||||
event << [value: value.toString(), isStateChange: isChange, displayed: false, unit: "%"]
|
||||
} else if (name == "deviceAlive") {
|
||||
isChange = isStateChange(device, name, value.toString())
|
||||
event['isStateChange'] = isChange
|
||||
event['displayed'] = false
|
||||
} else if (name == "thermostatMode") {
|
||||
thermostatMode = value.toLowerCase()
|
||||
return // as we don't want to send this event here, proceed to next name/value pair
|
||||
def mode = value.toString()
|
||||
mode = (mode == "auxHeatOnly") ? "emergency heat" : mode
|
||||
isChange = isStateChange(device, name, mode)
|
||||
event << [value: mode, isStateChange: isChange, displayed: isDisplayed]
|
||||
} else {
|
||||
event << [value: value.toString()]
|
||||
isChange = isStateChange(device, name, value.toString())
|
||||
isDisplayed = isChange
|
||||
event << [value: value.toString(), isStateChange: isChange, displayed: isDisplayed]
|
||||
}
|
||||
sendEvent(event)
|
||||
}
|
||||
if (state.supportedThermostatModes != supportedThermostatModes) {
|
||||
state.supportedThermostatModes = supportedThermostatModes
|
||||
sendEvent(name: "supportedThermostatModes", value: supportedThermostatModes, displayed: false)
|
||||
}
|
||||
if (thermostatMode) {
|
||||
sendEvent(name: "thermostatMode", value: thermostatMode, data:[supportedThermostatModes:state.supportedThermostatModes], linkText: linkText,
|
||||
descriptionText: getThermostatDescriptionText("thermostatMode", thermostatMode, linkText), handlerName: "thermostatMode")
|
||||
}
|
||||
generateSetpointEvent ()
|
||||
generateStatusEvent ()
|
||||
}
|
||||
@@ -324,7 +322,15 @@ void resumeProgram() {
|
||||
}
|
||||
|
||||
def modes() {
|
||||
return state.supportedThermostatModes
|
||||
if (state.modes) {
|
||||
log.debug "Modes = ${state.modes}"
|
||||
return state.modes
|
||||
}
|
||||
else {
|
||||
state.modes = parent.availableModes(this)
|
||||
log.debug "Modes = ${state.modes}"
|
||||
return state.modes
|
||||
}
|
||||
}
|
||||
|
||||
def fanModes() {
|
||||
@@ -407,13 +413,11 @@ def setThermostatFanMode(String mode) {
|
||||
}
|
||||
|
||||
def generateModeEvent(mode) {
|
||||
sendEvent(name: "thermostatMode", value: mode, data:[supportedThermostatModes: state.supportedThermostatModes],
|
||||
descriptionText: "$device.displayName is in ${mode} mode")
|
||||
sendEvent(name: "thermostatMode", value: mode, descriptionText: "$device.displayName is in ${mode} mode", displayed: true)
|
||||
}
|
||||
|
||||
def generateFanModeEvent(fanMode) {
|
||||
sendEvent(name: "thermostatFanMode", value: fanMode, data:[supportedThermostatFanModes: fanModes()],
|
||||
descriptionText: "$device.displayName fan is in ${fanMode} mode")
|
||||
sendEvent(name: "thermostatFanMode", value: fanMode, descriptionText: "$device.displayName fan is in ${fanMode} mode", displayed: true)
|
||||
}
|
||||
|
||||
def generateOperatingStateEvent(operatingState) {
|
||||
@@ -449,14 +453,14 @@ def heat() {
|
||||
}
|
||||
|
||||
def emergencyHeat() {
|
||||
auxheatonly()
|
||||
auxHeatOnly()
|
||||
}
|
||||
|
||||
def auxheatonly() {
|
||||
log.debug "auxheatonly()"
|
||||
def auxHeatOnly() {
|
||||
log.debug "auxHeatOnly = emergency heat"
|
||||
def deviceId = device.deviceNetworkId.split(/\./).last()
|
||||
if (parent.setMode ("auxHeatOnly", deviceId))
|
||||
generateModeEvent("auxheatonly")
|
||||
generateModeEvent("emergency heat") // emergency heat = auxHeatOnly
|
||||
else {
|
||||
log.debug "Error setting new mode."
|
||||
def currentMode = device.currentState("thermostatMode")?.value
|
||||
@@ -589,7 +593,7 @@ def generateSetpointEvent() {
|
||||
} else if (mode == "off") {
|
||||
sendEvent("name":"thermostatSetpoint", "value":averageSetpoint, "unit":location.temperatureScale)
|
||||
sendEvent("name":"displayThermostatSetpoint", "value":"Off", displayed: false)
|
||||
} else if (mode == "auxheatonly") {
|
||||
} else if (mode == "emergency heat") { // emergency heat = auxHeatOnly
|
||||
sendEvent("name":"thermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale)
|
||||
sendEvent("name":"displayThermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale, displayed: false)
|
||||
}
|
||||
@@ -628,7 +632,7 @@ void raiseSetpoint() {
|
||||
targetvalue = thermostatSetpoint ? thermostatSetpoint : 0
|
||||
targetvalue = location.temperatureScale == "F"? targetvalue + 1 : targetvalue + 0.5
|
||||
|
||||
if ((mode == "heat" || mode == "auxheatonly") && targetvalue > maxHeatingSetpoint) {
|
||||
if ((mode == "heat" || mode == "emergency heat") && targetvalue > maxHeatingSetpoint) { // emergency heat = auxHeatOnly
|
||||
targetvalue = maxHeatingSetpoint
|
||||
} else if (mode == "cool" && targetvalue > maxCoolingSetpoint) {
|
||||
targetvalue = maxCoolingSetpoint
|
||||
@@ -674,7 +678,7 @@ void lowerSetpoint() {
|
||||
targetvalue = thermostatSetpoint ? thermostatSetpoint : 0
|
||||
targetvalue = location.temperatureScale == "F"? targetvalue - 1 : targetvalue - 0.5
|
||||
|
||||
if ((mode == "heat" || mode == "auxheatonly") && targetvalue < minHeatingSetpoint) {
|
||||
if ((mode == "heat" || mode == "emergency heat") && targetvalue < minHeatingSetpoint) { // emergency heat = auxHeatOnly
|
||||
targetvalue = minHeatingSetpoint
|
||||
} else if (mode == "cool" && targetvalue < minCoolingSetpoint) {
|
||||
targetvalue = minCoolingSetpoint
|
||||
@@ -715,7 +719,7 @@ void alterSetpoint(temp) {
|
||||
}
|
||||
|
||||
//step1: check thermostatMode, enforce limits before sending request to cloud
|
||||
if (mode == "heat" || mode == "auxheatonly"){
|
||||
if (mode == "heat" || mode == "emergency heat"){ // emergency heat = auxHeatOnly
|
||||
if (temp.value > coolingSetpoint){
|
||||
targetHeatingSetpoint = temp.value
|
||||
targetCoolingSetpoint = temp.value
|
||||
@@ -750,7 +754,7 @@ void alterSetpoint(temp) {
|
||||
log.debug "alterSetpoint in mode $mode succeed change setpoint to= ${temp.value}"
|
||||
} else {
|
||||
log.error "Error alterSetpoint()"
|
||||
if (mode == "heat" || mode == "auxheatonly"){
|
||||
if (mode == "heat" || mode == "emergency heat"){ // emergency heat = auxHeatOnly
|
||||
sendEvent("name": "thermostatSetpoint", "value": heatingSetpoint.toString(), displayed: false)
|
||||
sendEvent("name": "displayThermostatSetpoint", "value": heatingSetpoint.toString(), displayed: false)
|
||||
} else if (mode == "cool") {
|
||||
@@ -779,7 +783,7 @@ def generateStatusEvent() {
|
||||
log.debug "Cooling set point = ${coolingSetpoint}"
|
||||
log.debug "HVAC Mode = ${mode}"
|
||||
|
||||
if (mode == "heat" || mode == "auxheatonly") {
|
||||
if (mode == "heat") {
|
||||
if (temperature >= heatingSetpoint) {
|
||||
statusText = "Right Now: Idle"
|
||||
} else {
|
||||
@@ -802,6 +806,8 @@ def generateStatusEvent() {
|
||||
}
|
||||
} else if (mode == "off") {
|
||||
statusText = "Right Now: Off"
|
||||
} else if (mode == "emergency heat") { // emergency heat = auxHeatOnly
|
||||
statusText = "Emergency Heat"
|
||||
} else {
|
||||
statusText = "?"
|
||||
}
|
||||
|
||||
@@ -1,163 +0,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.
|
||||
*
|
||||
* Everspring ST815 Illuminance Sensor
|
||||
*
|
||||
* Author: SmartThings
|
||||
* Date: 2017-3-4
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "Everspring Illuminance Sensor", namespace: "smartthings", author: "SmartThings") {
|
||||
capability "Illuminance Measurement"
|
||||
capability "Battery"
|
||||
capability "Configuration"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint mfr:"0060", prod:"0007", model:"0001"
|
||||
}
|
||||
|
||||
simulator {
|
||||
for( int i = 0; i <= 100; i += 20 ) {
|
||||
status "illuminace ${i} lux": new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(
|
||||
scaledSensorValue: i, precision: 0, sensorType: 3, scale: 1).incomingMessage()
|
||||
}
|
||||
|
||||
for( int i = 0; i <= 100; i += 20 ) {
|
||||
status "battery ${i}%": new physicalgraph.zwave.Zwave().batteryV1.batteryReport(
|
||||
batteryLevel: i).incomingMessage()
|
||||
}
|
||||
|
||||
status "wakeup": "command: 8407, payload: "
|
||||
}
|
||||
|
||||
tiles(scale: 2) {
|
||||
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "temperature", label:'${currentValue}°',
|
||||
backgroundColors:[
|
||||
[value: 32, color: "#153591"],
|
||||
[value: 44, color: "#1e9cbb"],
|
||||
[value: 59, color: "#90d2a7"],
|
||||
[value: 74, color: "#44b621"],
|
||||
[value: 84, color: "#f1d801"],
|
||||
[value: 92, color: "#d04e00"],
|
||||
[value: 98, color: "#bc2323"]
|
||||
]
|
||||
}
|
||||
valueTile("humidity", "device.humidity", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "humidity", label:'${currentValue}% humidity', unit:""
|
||||
}
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
}
|
||||
|
||||
main( ["temperature", "humidity"] )
|
||||
details( ["temperature", "humidity", "battery"] )
|
||||
}
|
||||
}
|
||||
|
||||
def updated() {
|
||||
state.configured = false
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
def result = []
|
||||
|
||||
def cmd = zwave.parse(description, [0x20: 1, 0x31: 2, 0x70: 1, 0x71: 1, 0x80: 1, 0x84: 2, 0x85: 2])
|
||||
|
||||
if (cmd) {
|
||||
result = zwaveEvent(cmd)
|
||||
}
|
||||
|
||||
if (result instanceof List) {
|
||||
log.debug "Parsed '$description' to ${result.collect { it.respondsTo("toHubAction") ? it.toHubAction() : it }}"
|
||||
} else {
|
||||
log.debug "Parsed '$description' to ${result}"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
|
||||
def result = [
|
||||
createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)
|
||||
]
|
||||
if (state.configured) {
|
||||
result << response(zwave.batteryV1.batteryGet())
|
||||
} else {
|
||||
result << response(configure())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.alarmv1.AlarmReport cmd) {
|
||||
if (cmd.alarmType == 1 && cmd.alarmType == 0xFF) {
|
||||
return createEvent(descriptionText: "${device.displayName} battery is low", isStateChange: true)
|
||||
} else if (cmd.alarmType == 2 && cmd.alarmLevel == 1) {
|
||||
return createEvent(descriptionText: "${device.displayName} powered up", isStateChange: false)
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd) {
|
||||
|
||||
def map = [:]
|
||||
switch( cmd.sensorType ) {
|
||||
case 3:
|
||||
// luminance
|
||||
map.value = cmd.scaledSensorValue.toInteger().toString()
|
||||
map.unit = "lux"
|
||||
map.name = "illuminance"
|
||||
break;
|
||||
}
|
||||
|
||||
return createEvent(map)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
||||
def map = [ name: "battery", unit: "%" ]
|
||||
if (cmd.batteryLevel == 0xFF) {
|
||||
map.value = 1
|
||||
map.descriptionText = "${device.displayName} has a low battery"
|
||||
map.isStateChange = true
|
||||
} else {
|
||||
map.value = cmd.batteryLevel
|
||||
}
|
||||
|
||||
def response_cmds = []
|
||||
if (!currentTemperature) {
|
||||
response_cmds << zwave.sensorMultilevelV2.sensorMultilevelGet().format()
|
||||
response_cmds << "delay 1000"
|
||||
}
|
||||
response_cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
|
||||
|
||||
return [createEvent(map), response(response_cmds)]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
log.debug "Unhandled: ${cmd.toString()}"
|
||||
return [:]
|
||||
}
|
||||
|
||||
def configure() {
|
||||
state.configured = true
|
||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
delayBetween([
|
||||
// Auto report time interval in minutes
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 5, size: 2, scaledConfigurationValue: 20).format(),
|
||||
|
||||
// Auto report lux change threshold
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 6, size: 2, scaledConfigurationValue: 30).format(),
|
||||
|
||||
// Get battery – report triggers WakeUpNMI
|
||||
zwave.batteryV1.batteryGet().format()
|
||||
])
|
||||
}
|
||||
@@ -1,188 +0,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.
|
||||
*
|
||||
* Everspring ST814 Temperature/Humidity Sensor
|
||||
*
|
||||
* Author: SmartThings
|
||||
* Date: 2017-3-4
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "Everspring ST814", namespace: "smartthings", author: "SmartThings") {
|
||||
capability "Temperature Measurement"
|
||||
capability "Relative Humidity Measurement"
|
||||
capability "Battery"
|
||||
capability "Configuration"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
|
||||
fingerprint mfr:"0060", prod:"0006", model:"0001"
|
||||
}
|
||||
|
||||
simulator {
|
||||
for( int i = 0; i <= 100; i += 20 ) {
|
||||
status "temperature ${i}F": new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(
|
||||
scaledSensorValue: i, precision: 1, sensorType: 1, scale: 1).incomingMessage()
|
||||
}
|
||||
|
||||
for( int i = 0; i <= 100; i += 20 ) {
|
||||
status "humidity ${i}%": new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(
|
||||
scaledSensorValue: i, precision: 0, sensorType: 5).incomingMessage()
|
||||
}
|
||||
|
||||
for( int i = 0; i <= 100; i += 20 ) {
|
||||
status "battery ${i}%": new physicalgraph.zwave.Zwave().batteryV1.batteryReport(
|
||||
batteryLevel: i).incomingMessage()
|
||||
}
|
||||
status "wakeup": "command: 8407, payload: "
|
||||
}
|
||||
|
||||
tiles(scale: 2) {
|
||||
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "temperature", label:'${currentValue}°',
|
||||
backgroundColors:[
|
||||
[value: 32, color: "#153591"],
|
||||
[value: 44, color: "#1e9cbb"],
|
||||
[value: 59, color: "#90d2a7"],
|
||||
[value: 74, color: "#44b621"],
|
||||
[value: 84, color: "#f1d801"],
|
||||
[value: 92, color: "#d04e00"],
|
||||
[value: 98, color: "#bc2323"]
|
||||
]
|
||||
}
|
||||
valueTile("humidity", "device.humidity", inactiveLabel: false, width: 2, height: 2) {
|
||||
state "humidity", label:'${currentValue}% humidity', unit:""
|
||||
}
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
}
|
||||
|
||||
main( ["temperature", "humidity"] )
|
||||
details( ["temperature", "humidity", "battery"] )
|
||||
}
|
||||
}
|
||||
|
||||
def updated() {
|
||||
state.configured = false
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
def result = []
|
||||
|
||||
def cmd = zwave.parse(description, [0x20: 1, 0x31: 2, 0x70: 1, 0x71: 1, 0x80: 1, 0x84: 2, 0x85: 2])
|
||||
|
||||
if (cmd) {
|
||||
result = zwaveEvent(cmd)
|
||||
}
|
||||
|
||||
if (result instanceof List) {
|
||||
log.debug "Parsed '$description' to ${result.collect { it.respondsTo("toHubAction") ? it.toHubAction() : it }}"
|
||||
} else {
|
||||
log.debug "Parsed '$description' to ${result}"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
|
||||
def result = [
|
||||
createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)
|
||||
]
|
||||
if (state.configured) {
|
||||
result << response(zwave.batteryV1.batteryGet())
|
||||
} else {
|
||||
result << response(configure())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.alarmv1.AlarmReport cmd) {
|
||||
if (cmd.alarmType == 1 && cmd.alarmType == 0xFF) {
|
||||
return createEvent(descriptionText: "${device.displayName} battery is low", isStateChange: true)
|
||||
} else if (cmd.alarmType == 2 && cmd.alarmLevel == 1) {
|
||||
return createEvent(descriptionText: "${device.displayName} powered up", isStateChange: false)
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd) {
|
||||
|
||||
def map = [:]
|
||||
switch( cmd.sensorType ) {
|
||||
case 1:
|
||||
/* temperature */
|
||||
def cmdScale = cmd.scale == 1 ? "F" : "C"
|
||||
map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
|
||||
map.unit = getTemperatureScale()
|
||||
map.name = "temperature"
|
||||
break
|
||||
case 5:
|
||||
/* humidity */
|
||||
map.value = cmd.scaledSensorValue.toInteger().toString()
|
||||
map.unit = "%"
|
||||
map.name = "humidity"
|
||||
break
|
||||
}
|
||||
|
||||
return createEvent(map)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
||||
def map = [ name: "battery", unit: "%" ]
|
||||
if (cmd.batteryLevel == 0xFF) {
|
||||
map.value = 1
|
||||
map.descriptionText = "${device.displayName} has a low battery"
|
||||
map.isStateChange = true
|
||||
} else {
|
||||
map.value = cmd.batteryLevel
|
||||
}
|
||||
|
||||
def response_cmds = []
|
||||
if (!currentTemperature) {
|
||||
response_cmds << zwave.sensorMultilevelV2.sensorMultilevelGet().format()
|
||||
response_cmds << "delay 1000"
|
||||
}
|
||||
response_cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
|
||||
|
||||
return [createEvent(map), response(response_cmds)]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
|
||||
def result = null
|
||||
def encapsulatedCommand = cmd.encapsulatedCommand([0x20: 1, 0x31: 2, 0x70: 1, 0x71: 1, 0x80: 1, 0x84: 2, 0x85: 2])
|
||||
log.debug ("Command from endpoint ${cmd.sourceEndPoint}: ${encapsulatedCommand}")
|
||||
if (encapsulatedCommand) {
|
||||
result = zwaveEvent(encapsulatedCommand)
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
log.debug "Unhandled: ${cmd.toString()}"
|
||||
return [:]
|
||||
}
|
||||
|
||||
def configure() {
|
||||
state.configured = true
|
||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
delayBetween([
|
||||
// Auto report time interval in minutes
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 6, size: 2, scaledConfigurationValue: 20).format(),
|
||||
|
||||
// Auto report temperature change threshold
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 7, size: 1, scaledConfigurationValue: 2).format(),
|
||||
|
||||
// Auto report humidity change threshold
|
||||
zwave.configurationV1.configurationSet(parameterNumber: 8, size: 1, scaledConfigurationValue: 5).format(),
|
||||
|
||||
// Get battery – report triggers WakeUpNMI
|
||||
zwave.batteryV1.batteryGet().format()
|
||||
])
|
||||
}
|
||||
@@ -68,8 +68,8 @@
|
||||
|
||||
tiles {
|
||||
standardTile("contact", "device.contact", width: 2, height: 2) {
|
||||
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13"
|
||||
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#00A0DC"
|
||||
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e"
|
||||
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821"
|
||||
}
|
||||
valueTile("temperature", "device.temperature", inactiveLabel: false) {
|
||||
state "temperature", label:'${currentValue}°',
|
||||
@@ -86,7 +86,7 @@
|
||||
}
|
||||
standardTile("tamper", "device.alarm") {
|
||||
state("secure", label:'secure', icon:"st.locks.lock.locked", backgroundColor:"#ffffff")
|
||||
state("tampered", label:'tampered', icon:"st.locks.lock.unlocked", backgroundColor:"#00a0dc")
|
||||
state("tampered", label:'tampered', icon:"st.locks.lock.unlocked", backgroundColor:"#53a7c0")
|
||||
}
|
||||
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
|
||||
state "battery", label:'${currentValue}% battery', unit:""
|
||||
|
||||
@@ -107,8 +107,8 @@
|
||||
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
|
||||
}
|
||||
standardTile("acceleration", "device.acceleration") {
|
||||
state("active", label:'vibration', icon:"st.motion.acceleration.active", backgroundColor:"#00a0dc")
|
||||
state("inactive", label:'still', icon:"st.motion.acceleration.inactive", backgroundColor:"#cccccc")
|
||||
state("active", label:'vibration', icon:"st.motion.acceleration.active", backgroundColor:"#53a7c0")
|
||||
state("inactive", label:'still', icon:"st.motion.acceleration.inactive", backgroundColor:"#ffffff")
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -300,21 +300,15 @@ def setColor(value) {
|
||||
value.hex = "#${hex(value.red)}${hex(value.green)}${hex(value.blue)}"
|
||||
}
|
||||
|
||||
if(value.hue) {
|
||||
sendEvent(name: "hue", value: value.hue, displayed: false)
|
||||
}
|
||||
if(value.saturation) {
|
||||
sendEvent(name: "saturation", value: value.saturation, displayed: false)
|
||||
}
|
||||
if(value.hex?.trim()) {
|
||||
sendEvent(name: "color", value: value.hex, displayed: false)
|
||||
}
|
||||
if (value.level) {
|
||||
sendEvent(name: "level", value: value.level)
|
||||
}
|
||||
if (value.switch?.trim()) {
|
||||
sendEvent(name: "switch", value: value.switch)
|
||||
}
|
||||
sendEvent(name: "hue", value: value.hue, displayed: false)
|
||||
sendEvent(name: "saturation", value: value.saturation, displayed: false)
|
||||
sendEvent(name: "color", value: value.hex, displayed: false)
|
||||
if (value.level) {
|
||||
sendEvent(name: "level", value: value.level)
|
||||
}
|
||||
if (value.switch) {
|
||||
sendEvent(name: "switch", value: value.switch)
|
||||
}
|
||||
|
||||
sendRGB(value.rh, value.gh, value.bh)
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Fortrezz Water Valve", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.watervalve") {
|
||||
definition (name: "Fortrezz Water Valve", namespace: "smartthings", author: "SmartThings") {
|
||||
capability "Actuator"
|
||||
capability "Health Check"
|
||||
capability "Valve"
|
||||
capability "Refresh"
|
||||
capability "Sensor"
|
||||
|
||||
|
||||
fingerprint deviceId: "0x1000", inClusters: "0x25,0x72,0x86,0x71,0x22,0x70"
|
||||
fingerprint mfr:"0084", prod:"0213", model:"0215", deviceJoinName: "FortrezZ Water Valve"
|
||||
}
|
||||
@@ -34,17 +34,14 @@ metadata {
|
||||
}
|
||||
|
||||
// tile definitions
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"contact", type: "generic", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.contact", key: "PRIMARY_CONTROL") {
|
||||
attributeState "open", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC", nextState:"closing"
|
||||
attributeState "closed", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff", nextState:"opening"
|
||||
attributeState "opening", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC"
|
||||
attributeState "closing", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
}
|
||||
tiles {
|
||||
standardTile("contact", "device.contact", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "open", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC", nextState:"closing"
|
||||
state "closed", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff", nextState:"opening"
|
||||
state "opening", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC"
|
||||
state "closing", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff"
|
||||
}
|
||||
|
||||
standardTile("refresh", "device.valve", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
|
||||
@@ -56,8 +53,6 @@ metadata {
|
||||
def installed(){
|
||||
// Device-Watch simply pings if no device events received for 32min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
response(refresh())
|
||||
}
|
||||
|
||||
def updated(){
|
||||
@@ -67,37 +62,30 @@ def updated(){
|
||||
|
||||
def parse(String description) {
|
||||
log.trace description
|
||||
def result = null
|
||||
def cmd = zwave.parse(description)
|
||||
if (cmd) {
|
||||
return zwaveEvent(cmd)
|
||||
result = createEvent(zwaveEvent(cmd))
|
||||
}
|
||||
log.debug "Could not parse message"
|
||||
return null
|
||||
log.debug "Parse returned ${result?.descriptionText}"
|
||||
return result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
|
||||
def value = cmd.value ? "closed" : "open"
|
||||
|
||||
return [createEventWithDebug([name: "contact", value: value, descriptionText: "$device.displayName valve is $value"]),
|
||||
createEventWithDebug([name: "valve", value: value, descriptionText: "$device.displayName valve is $value"])]
|
||||
[name: "contact", value: value, descriptionText: "$device.displayName valve is $value"]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
return createEvent([:]) // Handles all Z-Wave commands we aren't interested in
|
||||
[:] // Handles all Z-Wave commands we aren't interested in
|
||||
}
|
||||
|
||||
def open() {
|
||||
delayBetween([
|
||||
zwave.switchBinaryV1.switchBinarySet(switchValue: 0x00).format(),
|
||||
zwave.switchBinaryV1.switchBinaryGet().format()
|
||||
], 500)
|
||||
zwave.switchBinaryV1.switchBinarySet(switchValue: 0x00).format()
|
||||
}
|
||||
|
||||
def close() {
|
||||
delayBetween([
|
||||
zwave.switchBinaryV1.switchBinarySet(switchValue: 0xFF).format(),
|
||||
zwave.switchBinaryV1.switchBinaryGet().format()
|
||||
], 500)
|
||||
zwave.switchBinaryV1.switchBinarySet(switchValue: 0xFF).format()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,9 +98,3 @@ def ping() {
|
||||
def refresh() {
|
||||
zwave.switchBinaryV1.switchBinaryGet().format()
|
||||
}
|
||||
|
||||
def createEventWithDebug(eventMap) {
|
||||
def event = createEvent(eventMap)
|
||||
log.debug "Event created with ${event?.name}:${event?.value} - ${event?.descriptionText}"
|
||||
return event
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
|
||||
|
||||
/**
|
||||
* Hue Bloom
|
||||
*
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
|
||||
|
||||
/**
|
||||
* Hue Bridge
|
||||
*
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
|
||||
|
||||
/**
|
||||
* Hue Bulb
|
||||
*
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
|
||||
|
||||
/**
|
||||
* Hue Lux Bulb
|
||||
*
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
|
||||
|
||||
/**
|
||||
* Hue White Ambiance Bulb
|
||||
*
|
||||
|
||||
@@ -62,8 +62,8 @@ metadata {
|
||||
state "off", label: '${name}', action: "on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
|
||||
}
|
||||
standardTile("contact", "device.contact", inactiveLabel: false) {
|
||||
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13"
|
||||
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#00A0DC"
|
||||
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e"
|
||||
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821"
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
|
||||
@@ -21,7 +21,7 @@ Works with:
|
||||
|
||||
## Device Health
|
||||
|
||||
Plant Link sensor is a ZigBee sleepy device and checks in every 15 minutes.
|
||||
Plant Link sensor is a Z-wave sleepy device and checks in every 15 minutes.
|
||||
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
|
||||
|
||||
* __32min__ checkInterval
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -1,39 +0,0 @@
|
||||
# Smartalert Siren
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [FortrezZ Siren Strobe Alarm](https://www.smartthings.com/products/fortrezz-siren-strobe-alarm)
|
||||
|
||||
## 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,17 +16,15 @@
|
||||
* Date: 2013-03-05
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "SmartAlert Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.smoke") {
|
||||
definition (name: "SmartAlert Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.smokedetector") {
|
||||
capability "Actuator"
|
||||
capability "Switch"
|
||||
capability "Sensor"
|
||||
capability "Alarm"
|
||||
capability "Health Check"
|
||||
|
||||
command "test"
|
||||
|
||||
fingerprint deviceId: "0x1100", inClusters: "0x26,0x71"
|
||||
fingerprint mfr:"0084", prod:"0313", model:"010B", deviceJoinName: "FortrezZ Siren Strobe Alarm"
|
||||
}
|
||||
|
||||
simulator {
|
||||
@@ -70,16 +68,6 @@ 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() {
|
||||
[
|
||||
zwave.basicV1.basicSet(value: 0xFF).format(),
|
||||
@@ -161,10 +149,3 @@ def createEvents(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
|
||||
def zwaveEvent(physicalgraph.zwave.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())
|
||||
}
|
||||
@@ -44,9 +44,9 @@ metadata {
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
||||
|
||||
@@ -23,12 +23,12 @@ metadata {
|
||||
capability "Refresh"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
capability "Light"
|
||||
capability "Outlet"
|
||||
|
||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3200", deviceJoinName: "Outlet"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3200-Sgb", deviceJoinName: "Outlet"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "4257050-RZHAC", deviceJoinName: "Outlet"
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 000F, 0B04", outClusters: "0019", manufacturer: "SmartThings", model: "outletv4", deviceJoinName: "Outlet"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019"
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ metadata {
|
||||
state("closing", label:'${name}', icon:"st.doors.garage.garage-closing", backgroundColor:"#00A0DC")
|
||||
}
|
||||
standardTile("contact", "device.contact") {
|
||||
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13")
|
||||
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00A0DC")
|
||||
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
|
||||
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
|
||||
}
|
||||
standardTile("acceleration", "device.acceleration", decoration: "flat") {
|
||||
state("active", label:'${name}', icon:"st.motion.acceleration.active", backgroundColor:"#00A0DC")
|
||||
|
||||
@@ -105,8 +105,6 @@ def parse(String description) {
|
||||
} else {
|
||||
log.warn "TEMP REPORTING CONFIG FAILED- error code: ${descMap.data[0]}"
|
||||
}
|
||||
} else if (descMap?.clusterInt == zigbee.IAS_ZONE_CLUSTER && descMap.attrInt == zigbee.ATTRIBUTE_IAS_ZONE_STATUS && descMap?.value) {
|
||||
map = translateZoneStatus(new ZoneStatus(zigbee.convertToInt(descMap?.value)))
|
||||
}
|
||||
}
|
||||
} else if (map.name == "temperature") {
|
||||
@@ -131,10 +129,6 @@ def parse(String description) {
|
||||
private Map parseIasMessage(String description) {
|
||||
ZoneStatus zs = zigbee.parseZoneStatus(description)
|
||||
|
||||
translateZoneStatus(zs)
|
||||
}
|
||||
|
||||
private Map translateZoneStatus(ZoneStatus zs) {
|
||||
return zs.isAlarm1Set() ? getMoistureResult('wet') : getMoistureResult('dry')
|
||||
}
|
||||
|
||||
@@ -203,8 +197,7 @@ def ping() {
|
||||
def refresh() {
|
||||
log.debug "Refreshing Temperature and Battery"
|
||||
def refreshCmds = zigbee.readAttribute(zigbee.TEMPERATURE_MEASUREMENT_CLUSTER, 0x0000) +
|
||||
zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020) +
|
||||
zigbee.readAttribute(zigbee.IAS_ZONE_CLUSTER, zigbee.ATTRIBUTE_IAS_ZONE_STATUS)
|
||||
zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020)
|
||||
|
||||
return refreshCmds + zigbee.enrollResponse()
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ metadata {
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name: "motion", type: "generic", width: 6, height: 4) {
|
||||
tileAttribute("device.motion", key: "PRIMARY_CONTROL") {
|
||||
attributeState "active", label: 'motion', icon: "st.motion.motion.active", backgroundColor: "#00A0DC"
|
||||
attributeState "inactive", label: 'no motion', icon: "st.motion.motion.inactive", backgroundColor: "#cccccc"
|
||||
attributeState "active", label: 'motion', icon: "st.motion.motion.active", backgroundColor: "#53a7c0"
|
||||
attributeState "inactive", label: 'no motion', icon: "st.motion.motion.inactive", backgroundColor: "#ffffff"
|
||||
}
|
||||
}
|
||||
valueTile("temperature", "device.temperature", width: 2, height: 2) {
|
||||
@@ -111,8 +111,6 @@ def parse(String description) {
|
||||
def value = descMap.value.endsWith("01") ? "active" : "inactive"
|
||||
log.debug "Doing a read attr motion event"
|
||||
map = getMotionResult(value)
|
||||
} else if (descMap?.clusterInt == zigbee.IAS_ZONE_CLUSTER && descMap.attrInt == zigbee.ATTRIBUTE_IAS_ZONE_STATUS && descMap?.value) {
|
||||
map = translateZoneStatus(new ZoneStatus(zigbee.convertToInt(descMap?.value)))
|
||||
}
|
||||
}
|
||||
} else if (map.name == "temperature") {
|
||||
@@ -137,10 +135,6 @@ def parse(String description) {
|
||||
private Map parseIasMessage(String description) {
|
||||
ZoneStatus zs = zigbee.parseZoneStatus(description)
|
||||
|
||||
translateZoneStatus(zs)
|
||||
}
|
||||
|
||||
private Map translateZoneStatus(ZoneStatus zs) {
|
||||
// Some sensor models that use this DTH use alarm1 and some use alarm2 to signify motion
|
||||
return (zs.isAlarm1Set() || zs.isAlarm2Set()) ? getMotionResult('active') : getMotionResult('inactive')
|
||||
}
|
||||
@@ -171,8 +165,8 @@ private Map getBatteryResult(rawValue) {
|
||||
def pct = batteryMap[volts]
|
||||
result.value = pct
|
||||
} else {
|
||||
def minVolts = 2.4
|
||||
def maxVolts = 2.7
|
||||
def minVolts = 2.1
|
||||
def maxVolts = 3.0
|
||||
def pct = (volts - minVolts) / (maxVolts - minVolts)
|
||||
def roundedPct = Math.round(pct * 100)
|
||||
if (roundedPct <= 0)
|
||||
@@ -206,8 +200,7 @@ def refresh() {
|
||||
log.debug "refresh called"
|
||||
|
||||
def refreshCmds = zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020) +
|
||||
zigbee.readAttribute(zigbee.TEMPERATURE_MEASUREMENT_CLUSTER, 0x0000) +
|
||||
zigbee.readAttribute(zigbee.IAS_ZONE_CLUSTER, zigbee.ATTRIBUTE_IAS_ZONE_STATUS)
|
||||
zigbee.readAttribute(zigbee.TEMPERATURE_MEASUREMENT_CLUSTER, 0x0000)
|
||||
|
||||
return refreshCmds + zigbee.enrollResponse()
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ 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: "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,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"
|
||||
|
||||
attribute "status", "string"
|
||||
@@ -87,8 +88,8 @@ metadata {
|
||||
state("closed", label: 'Closed', icon: "st.contact.contact.closed", backgroundColor: "#00a0dc")
|
||||
}
|
||||
standardTile("acceleration", "device.acceleration", width: 2, height: 2) {
|
||||
state("active", label: 'Active', icon: "st.motion.acceleration.active", backgroundColor: "#00a0dc")
|
||||
state("inactive", label: 'Inactive', icon: "st.motion.acceleration.inactive", backgroundColor: "#cccccc")
|
||||
state("active", label: 'Active', icon: "st.motion.acceleration.active", backgroundColor: "#53a7c0")
|
||||
state("inactive", label: 'Inactive', icon: "st.motion.acceleration.inactive", backgroundColor: "#ffffff")
|
||||
}
|
||||
valueTile("temperature", "device.temperature", width: 2, height: 2) {
|
||||
state("temperature", label: '${currentValue}°',
|
||||
@@ -134,9 +135,8 @@ def parse(String description) {
|
||||
} else {
|
||||
log.warn "TEMP REPORTING CONFIG FAILED- error code: ${descMap.data[0]}"
|
||||
}
|
||||
} else if (descMap?.clusterInt == zigbee.IAS_ZONE_CLUSTER && descMap.attrInt == zigbee.ATTRIBUTE_IAS_ZONE_STATUS && descMap?.value) {
|
||||
maps += translateZoneStatus(new ZoneStatus(zigbee.convertToInt(descMap?.value)))
|
||||
} else {
|
||||
|
||||
maps += handleAcceleration(descMap)
|
||||
}
|
||||
}
|
||||
@@ -179,7 +179,7 @@ private List<Map> handleAcceleration(descMap) {
|
||||
result += parseAxis(descMap.additionalAttrs)
|
||||
}
|
||||
} else if (descMap.clusterInt == 0xFC02 && descMap.attrInt == 0x0012) {
|
||||
def addAttrs = descMap.additionalAttrs ?: []
|
||||
def addAttrs = descMap.additionalAttrs
|
||||
addAttrs << ["attrInt": descMap.attrInt, "value": descMap.value]
|
||||
result += parseAxis(addAttrs)
|
||||
}
|
||||
@@ -192,10 +192,6 @@ private List<Map> parseAxis(List<Map> attrData) {
|
||||
def y = hexToSignedInt(attrData.find { it.attrInt == 0x0013 }?.value)
|
||||
def z = hexToSignedInt(attrData.find { it.attrInt == 0x0014 }?.value)
|
||||
|
||||
if ([x, y ,z].any { it == null }) {
|
||||
return []
|
||||
}
|
||||
|
||||
def xyzResults = [:]
|
||||
if (device.getDataValue("manufacturer") == "SmartThings") {
|
||||
// This mapping matches the current behavior of the Device Handler for the Centralite sensors
|
||||
@@ -230,11 +226,6 @@ private List<Map> parseAxis(List<Map> attrData) {
|
||||
|
||||
private List<Map> parseIasMessage(String description) {
|
||||
ZoneStatus zs = zigbee.parseZoneStatus(description)
|
||||
|
||||
translateZoneStatus(zs)
|
||||
}
|
||||
|
||||
private List<Map> translateZoneStatus(ZoneStatus zs) {
|
||||
List<Map> results = []
|
||||
|
||||
if (garageSensor != "Yes") {
|
||||
@@ -274,7 +265,7 @@ private Map getBatteryResult(rawValue) {
|
||||
result.value = pct
|
||||
} else {
|
||||
def minVolts = 2.1
|
||||
def maxVolts = 2.7
|
||||
def maxVolts = 3.0
|
||||
def pct = (volts - minVolts) / (maxVolts - minVolts)
|
||||
def roundedPct = Math.round(pct * 100)
|
||||
if (roundedPct <= 0)
|
||||
@@ -319,7 +310,7 @@ def refresh() {
|
||||
def refreshCmds = zigbee.readAttribute(zigbee.TEMPERATURE_MEASUREMENT_CLUSTER, 0x0000) +
|
||||
zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020) +
|
||||
zigbee.readAttribute(0xFC02, 0x0010, [mfgCode: manufacturerCode]) +
|
||||
zigbee.readAttribute(zigbee.IAS_ZONE_CLUSTER, zigbee.ATTRIBUTE_IAS_ZONE_STATUS) + zigbee.enrollResponse()
|
||||
zigbee.enrollResponse()
|
||||
|
||||
return refreshCmds
|
||||
}
|
||||
@@ -381,10 +372,6 @@ def updated() {
|
||||
}
|
||||
|
||||
private hexToSignedInt(hexVal) {
|
||||
if (!hexVal) {
|
||||
return null
|
||||
}
|
||||
|
||||
def unsignedVal = hexToInt(hexVal)
|
||||
unsignedVal > 32767 ? unsignedVal - 65536 : unsignedVal
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ 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"
|
||||
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 {
|
||||
|
||||
@@ -49,6 +49,6 @@ def arrived() {
|
||||
|
||||
|
||||
def departed() {
|
||||
log.trace "Executing 'departed'"
|
||||
log.trace "Executing 'arrived'"
|
||||
sendEvent(name: "presence", value: "not present")
|
||||
}
|
||||
|
||||
@@ -22,16 +22,16 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("contact", "device.contact", width: 2, height: 2) {
|
||||
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00A0DC", action: "open")
|
||||
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13", action: "close")
|
||||
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:"#00A0DC")
|
||||
state("open", label:'Freezer', icon:"st.contact.contact.open", backgroundColor:"#e86d13")
|
||||
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:"#00A0DC")
|
||||
state("open", label:'Fridge', icon:"st.contact.contact.open", backgroundColor:"#e86d13")
|
||||
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")
|
||||
|
||||
@@ -25,8 +25,8 @@ metadata {
|
||||
|
||||
tiles(scale: 2) {
|
||||
standardTile("contact", "device.contact", width: 4, height: 4) {
|
||||
state("closed", label:'${name}', icon:"st.fridge.fridge-closed", backgroundColor:"#00A0DC")
|
||||
state("open", label:'${name}', icon:"st.fridge.fridge-open", backgroundColor:"#e86d13")
|
||||
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")
|
||||
|
||||
@@ -27,7 +27,7 @@ metadata {
|
||||
tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ metadata {
|
||||
tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'${name}', backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
tileAttribute("device.level", key: "SECONDARY_CONTROL") {
|
||||
@@ -59,7 +59,7 @@ metadata {
|
||||
tileAttribute("device.switch", key: "SECONDARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'…', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'…', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'…', action:"switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
tileAttribute("device.level", key: "VALUE_CONTROL") {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
|
||||
|
||||
/**
|
||||
* Copyright 2015 SmartThings
|
||||
*
|
||||
@@ -42,11 +40,11 @@ metadata {
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"rich-control", type: "switch", canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "offline", label:'${name}', icon:"st.Home.home30", backgroundColor:"#cccccc"
|
||||
attributeState "offline", label:'${name}', icon:"st.Home.home30", backgroundColor:"#ff0000"
|
||||
}
|
||||
tileAttribute ("currentIP", key: "SECONDARY_CONTROL") {
|
||||
attributeState "currentIP", label: ''
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
|
||||
|
||||
/**
|
||||
* Copyright 2015 SmartThings
|
||||
*
|
||||
@@ -48,8 +46,8 @@
|
||||
}
|
||||
|
||||
standardTile("motion", "device.motion", width: 2, height: 2) {
|
||||
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC")
|
||||
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#CCCCCC")
|
||||
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
|
||||
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
|
||||
state("offline", label:'${name}', icon:"st.motion.motion.inactive", backgroundColor:"#ff0000")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//DEPRECATED. INTEGRATION MOVED TO SUPER LAN CONNECT
|
||||
|
||||
/**
|
||||
* Copyright 2015 SmartThings
|
||||
*
|
||||
@@ -40,11 +38,11 @@
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"rich-control", type: "switch", canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "offline", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#cccccc"
|
||||
attributeState "offline", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ff0000"
|
||||
}
|
||||
tileAttribute ("currentIP", key: "SECONDARY_CONTROL") {
|
||||
attributeState "currentIP", label: ''
|
||||
@@ -52,11 +50,11 @@
|
||||
}
|
||||
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
state "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
state "offline", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#cccccc"
|
||||
state "offline", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ff0000"
|
||||
}
|
||||
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, height: 2, width: 2, decoration: "flat") {
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
.st-ignore
|
||||
README.md
|
||||
@@ -1,42 +0,0 @@
|
||||
# ZigBee Button
|
||||
|
||||
Cloud Execution
|
||||
|
||||
Works with:
|
||||
|
||||
* [OSRAM LIGHTIFY Dimming Switch](https://support.smartthings.com/hc/en-us/articles/115000236823-SYLVANIA-Dimming-Switch)
|
||||
* [Iris Smart Button](https://support.smartthings.com/hc/en-us/articles/115000190186-Iris-Smart-Button)
|
||||
* [Iris KeyFob](https://support.smartthings.com/hc/en-us/articles/217409686-Iris-Smart-Fob)
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
* [Health](#device-health)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Capabilities
|
||||
|
||||
* **Actuator** - It represents that a device has commands.
|
||||
* **Battery** - It defines that the device has a battery
|
||||
* **Button** - It defines that a device has one or more buttons
|
||||
* **Holdable Button** - It defines that a device has one or more holdable buttons
|
||||
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
|
||||
* **Refresh** - _refresh()_ command for status updates
|
||||
* **Sensor** - it represents that a Device has attributes.
|
||||
* **Health Check** - indicates ability to get device health notifications
|
||||
|
||||
|
||||
## Device Health
|
||||
|
||||
ZigBee Button is marked offline only in the case when Hub is offline.
|
||||
|
||||
|
||||
## 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.
|
||||
It may also happen that you need to reset the device.
|
||||
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
|
||||
* [OSRAM LIGHTIFY Dimming Switch Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/115000236823-SYLVANIA-Dimming-Switch)
|
||||
* [Iris Smart Button Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/115000190186-Iris-Smart-Button)
|
||||
* [Iris KeyFob Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/217409686-Iris-Smart-Fob)
|
||||
@@ -13,8 +13,6 @@
|
||||
* for the specific language governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import groovy.json.JsonOutput
|
||||
import physicalgraph.zigbee.zcl.DataType
|
||||
|
||||
metadata {
|
||||
@@ -26,7 +24,6 @@ metadata {
|
||||
capability "Configuration"
|
||||
capability "Refresh"
|
||||
capability "Sensor"
|
||||
capability "Health Check"
|
||||
|
||||
command "enrollResponse"
|
||||
|
||||
@@ -252,8 +249,6 @@ def updated() {
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
// Arrival sensors only goes OFFLINE when Hub is off
|
||||
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "zigbee", scheme:"untracked"]), displayed: false)
|
||||
if ((device.getDataValue("manufacturer") == "OSRAM") && (device.getDataValue("model") == "LIGHTIFY Dimming Switch")) {
|
||||
sendEvent(name: "numberOfButtons", value: 2)
|
||||
}
|
||||
|
||||
@@ -70,27 +70,19 @@ def parse(String description) {
|
||||
else {
|
||||
sendEvent(event)
|
||||
}
|
||||
} else {
|
||||
def descMap = zigbee.parseDescriptionAsMap(description)
|
||||
if (descMap && descMap.clusterInt == 0x0006 && descMap.commandInt == 0x07) {
|
||||
if (descMap.data[0] == "00") {
|
||||
}
|
||||
else {
|
||||
def cluster = zigbee.parse(description)
|
||||
if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) {
|
||||
if (cluster.data[0] == 0x00){
|
||||
log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster
|
||||
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
|
||||
}
|
||||
} else if (device.getDataValue("manufacturer") == "sengled" && descMap && descMap.clusterInt == 0x0008 && descMap.attrInt == 0x0000) {
|
||||
// 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 {
|
||||
}
|
||||
else {
|
||||
log.warn "DID NOT PARSE MESSAGE for description : $description"
|
||||
log.debug zigbee.parseDescriptionAsMap(description)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ metadata {
|
||||
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008"
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY A19 ON/OFF/DIM", deviceJoinName: "SYLVANIA Smart A19 Soft White"
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY A19 ON/OFF/DIM 10 Year", deviceJoinName: "SYLVANIA Smart 10-Year A19"
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, FF00", outClusters: "0019", manufacturer: "MRVL", model: "MZ100", deviceJoinName: "Wemo Bulb"
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B05", outClusters: "0019", manufacturer: "OSRAM SYLVANIA", model: "iQBR30", deviceJoinName: "Sylvania Ultra iQ"
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY PAR38 ON/OFF/DIM", deviceJoinName: "SYLVANIA Smart PAR38 Soft White"
|
||||
@@ -66,29 +65,22 @@ def parse(String description) {
|
||||
else {
|
||||
sendEvent(event)
|
||||
}
|
||||
} else {
|
||||
def descMap = zigbee.parseDescriptionAsMap(description)
|
||||
if (descMap && descMap.clusterInt == 0x0006 && descMap.commandInt == 0x07) {
|
||||
if (descMap.data[0] == "00") {
|
||||
}
|
||||
else {
|
||||
def cluster = zigbee.parse(description)
|
||||
|
||||
if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) {
|
||||
if (cluster.data[0] == 0x00) {
|
||||
log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster
|
||||
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
|
||||
}
|
||||
} else if (device.getDataValue("manufacturer") == "sengled" && descMap && descMap.clusterInt == 0x0008 && descMap.attrInt == 0x0000) {
|
||||
// This is being done because the sengled element touch/classic incorrectly uses the value 0xFF for the max level.
|
||||
// Per the ZCL spec for the UINT8 data type 0xFF is an invalid value, and 0xFE should be the max. Here we
|
||||
// manually handle the invalid attribute value since it will be ignored by getEvent as an invalid value.
|
||||
// We also set the level of the bulb to 0xFE so future level reports will be 0xFE until it is changed by
|
||||
// something else.
|
||||
if (descMap.value.toUpperCase() == "FF") {
|
||||
descMap.value = "FE"
|
||||
}
|
||||
sendHubCommand(zigbee.command(zigbee.LEVEL_CONTROL_CLUSTER, 0x00, "FE0000").collect { new physicalgraph.device.HubAction(it) }, 0)
|
||||
sendEvent(zigbee.getEventFromAttrData(descMap.clusterInt, descMap.attrInt, descMap.encoding, descMap.value))
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
log.warn "DID NOT PARSE MESSAGE for description : $description"
|
||||
log.debug "${descMap}"
|
||||
log.debug "${cluster}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import physicalgraph.zigbee.zcl.DataType
|
||||
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,000A,0101,0020", outClusters: "000A,0019", manufacturer: "Yale", model: "YRD210 PB DB", deviceJoinName: "Yale Push Button Deadbolt Lock"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,000A,0101,0020", outClusters: "000A,0019", manufacturer: "Yale", model: "YRD220/240 TSDB", deviceJoinName: "Yale Touch Screen Deadbolt Lock"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,000A,0101,0020", outClusters: "000A,0019", manufacturer: "Yale", model: "YRL210 PB LL", deviceJoinName: "Yale Push Button Lever Lock"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,000A,0101,0020", outClusters: "000A,0019", manufacturer: "Yale", model: "YRD226/246 TSDB", deviceJoinName: "Yale Touch Screen Deadbolt Lock"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,000A,0101,0020", outClusters: "000A,0019", manufacturer: "Yale", model: "YRD226/246 TSDB", deviceJoinName: "Yale Touch Screen Deadbolt Lock"
|
||||
}
|
||||
|
||||
tiles(scale: 2) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2017 SmartThings
|
||||
* Copyright 2016 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:
|
||||
@@ -64,7 +64,6 @@ private getATTRIBUTE_HUE() { 0x0000 }
|
||||
private getATTRIBUTE_SATURATION() { 0x0001 }
|
||||
private getHUE_COMMAND() { 0x00 }
|
||||
private getSATURATION_COMMAND() { 0x03 }
|
||||
private getMOVE_TO_HUE_AND_SATURATION_COMMAND() { 0x06 }
|
||||
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
@@ -85,11 +84,11 @@ def parse(String description) {
|
||||
|
||||
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
|
||||
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
|
||||
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
|
||||
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
|
||||
sendEvent(name: "hue", value: hueValue, descriptionText: "Color has changed")
|
||||
}
|
||||
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
|
||||
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
|
||||
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
|
||||
sendEvent(name: "saturation", value: saturationValue, descriptionText: "Color has changed", displayed: false)
|
||||
}
|
||||
}
|
||||
@@ -124,12 +123,7 @@ def ping() {
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
zigbee.onOffRefresh() +
|
||||
zigbee.levelRefresh() +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) +
|
||||
zigbee.onOffConfig(0, 300) +
|
||||
zigbee.levelConfig()
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) + zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, DataType.UINT8, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, DataType.UINT8, 1, 3600, 0x01)
|
||||
}
|
||||
|
||||
def configure() {
|
||||
@@ -139,38 +133,26 @@ def configure() {
|
||||
sendEvent(name: "checkInterval", value: 3 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
// OnOff minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no activity
|
||||
refresh()
|
||||
zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, DataType.UINT8, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, DataType.UINT8, 1, 3600, 0x01) + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
}
|
||||
|
||||
def setLevel(value) {
|
||||
zigbee.setLevel(value)
|
||||
}
|
||||
|
||||
private getScaledHue(value) {
|
||||
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
}
|
||||
|
||||
private getScaledSaturation(value) {
|
||||
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
}
|
||||
|
||||
def setColor(value){
|
||||
log.trace "setColor($value)"
|
||||
zigbee.on() +
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
|
||||
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
zigbee.on() + setHue(value.hue) + "delay 500" + setSaturation(value.saturation)
|
||||
}
|
||||
|
||||
def setHue(value) {
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, getScaledHue(value), "00", "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
|
||||
def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5)
|
||||
}
|
||||
|
||||
def setSaturation(value) {
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, getScaledSaturation(value), "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") + "delay 1000" + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
}
|
||||
|
||||
def installed() {
|
||||
@@ -179,4 +161,4 @@ def installed() {
|
||||
sendEvent(name: "level", value: 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2017 SmartThings
|
||||
* Copyright 2016 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:
|
||||
@@ -46,9 +46,9 @@ metadata {
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
||||
@@ -78,7 +78,6 @@ private getATTRIBUTE_HUE() { 0x0000 }
|
||||
private getATTRIBUTE_SATURATION() { 0x0001 }
|
||||
private getHUE_COMMAND() { 0x00 }
|
||||
private getSATURATION_COMMAND() { 0x03 }
|
||||
private getMOVE_TO_HUE_AND_SATURATION_COMMAND() { 0x06 }
|
||||
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
|
||||
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
|
||||
|
||||
@@ -103,12 +102,12 @@ def parse(String description) {
|
||||
|
||||
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
|
||||
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
|
||||
state.hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
|
||||
runIn(5, updateColor, [overwrite: true])
|
||||
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
|
||||
sendEvent(name: "hue", value: hueValue, descriptionText: "Color has changed")
|
||||
}
|
||||
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
|
||||
state.saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
|
||||
runIn(5, updateColor, [overwrite: true])
|
||||
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
|
||||
sendEvent(name: "saturation", value: saturationValue, descriptionText: "Color has changed", displayed: false)
|
||||
}
|
||||
}
|
||||
else if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) {
|
||||
@@ -127,11 +126,6 @@ def parse(String description) {
|
||||
}
|
||||
}
|
||||
|
||||
def updateColor() {
|
||||
sendEvent(name: "hue", value: state.hueValue, descriptionText: "Color has changed")
|
||||
sendEvent(name: "saturation", value: state.saturationValue, descriptionText: "Color has changed", displayed: false)
|
||||
}
|
||||
|
||||
def on() {
|
||||
zigbee.on()
|
||||
}
|
||||
@@ -147,13 +141,7 @@ def ping() {
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
zigbee.onOffRefresh() +
|
||||
zigbee.levelRefresh() +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE) +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) +
|
||||
zigbee.onOffConfig(0, 300) +
|
||||
zigbee.levelConfig()
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) + zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, DataType.UINT8, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, DataType.UINT8, 1, 3600, 0x01)
|
||||
}
|
||||
|
||||
def configure() {
|
||||
@@ -168,12 +156,7 @@ def configure() {
|
||||
|
||||
def setColorTemperature(value) {
|
||||
setGenericName(value)
|
||||
value = value as Integer
|
||||
def tempInMired = (1000000 / value) as Integer
|
||||
def finalHex = zigbee.swapEndianHex(zigbee.convertToHexString(tempInMired, 4))
|
||||
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, 0x0A, "$finalHex 0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE)
|
||||
zigbee.setColorTemperature(value)
|
||||
}
|
||||
|
||||
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
|
||||
@@ -197,31 +180,19 @@ def setLevel(value) {
|
||||
zigbee.setLevel(value)
|
||||
}
|
||||
|
||||
private getScaledHue(value) {
|
||||
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
}
|
||||
|
||||
private getScaledSaturation(value) {
|
||||
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
}
|
||||
|
||||
def setColor(value){
|
||||
log.trace "setColor($value)"
|
||||
zigbee.on() +
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
|
||||
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
|
||||
zigbee.on() + setHue(value.hue) + "delay 300" + setSaturation(value.saturation)
|
||||
}
|
||||
|
||||
def setHue(value) {
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, getScaledHue(value), "00", "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
|
||||
def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5)
|
||||
}
|
||||
|
||||
def setSaturation(value) {
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, getScaledSaturation(value), "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") + "delay 1000" + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
}
|
||||
|
||||
def installed() {
|
||||
@@ -230,4 +201,4 @@ def installed() {
|
||||
sendEvent(name: "level", value: 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ metadata {
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702"
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702, 0B05", outClusters: "0003, 000A, 0019", manufacturer: "Jasco Products", model: "45853", deviceJoinName: "GE ZigBee Plug-In Switch"
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702, 0B05", outClusters: "000A, 0019", manufacturer: "Jasco Products", model: "45856", deviceJoinName: "GE ZigBee In-Wall Switch"
|
||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 000F, 0B04", outClusters: "0019", manufacturer: "SmartThings", model: "outletv4", deviceJoinName: "Outlet"
|
||||
}
|
||||
|
||||
tiles(scale: 2) {
|
||||
|
||||
@@ -41,9 +41,9 @@ metadata {
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
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}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ metadata {
|
||||
}
|
||||
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"contact", type: "generic", width: 6, height: 4, canChangeIcon: true){
|
||||
multiAttributeTile(name:"valve", type: "generic", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.contact", key: "PRIMARY_CONTROL") {
|
||||
attributeState "open", label: '${name}', action: "valve.close", icon: "st.valves.water.open", backgroundColor: "#00A0DC", nextState:"closing"
|
||||
attributeState "closed", label: '${name}', action: "valve.open", icon: "st.valves.water.closed", backgroundColor: "#ffffff", nextState:"opening"
|
||||
@@ -58,8 +58,8 @@ metadata {
|
||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
|
||||
main(["contact"])
|
||||
details(["contact", "battery", "refresh"])
|
||||
main(["valve"])
|
||||
details(["valve", "battery", "refresh"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,9 +83,6 @@ def parse(String description) {
|
||||
}
|
||||
}
|
||||
sendEvent(event)
|
||||
//handle valve attribute
|
||||
event.name = "valve"
|
||||
sendEvent(event)
|
||||
}
|
||||
else {
|
||||
def descMap = zigbee.parseDescriptionAsMap(description)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2017 SmartThings
|
||||
* Copyright 2015 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:
|
||||
@@ -45,9 +45,9 @@ metadata {
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
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}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
||||
@@ -71,11 +71,6 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
// Globals
|
||||
private getMOVE_TO_COLOR_TEMPERATURE_COMMAND() { 0x0A }
|
||||
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
|
||||
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
def parse(String description) {
|
||||
log.debug "description is $description"
|
||||
@@ -128,11 +123,7 @@ def ping() {
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
zigbee.onOffRefresh() +
|
||||
zigbee.levelRefresh() +
|
||||
zigbee.colorTemperatureRefresh() +
|
||||
zigbee.onOffConfig(0, 300) +
|
||||
zigbee.levelConfig()
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
|
||||
}
|
||||
|
||||
def configure() {
|
||||
@@ -147,12 +138,7 @@ def configure() {
|
||||
|
||||
def setColorTemperature(value) {
|
||||
setGenericName(value)
|
||||
value = value as Integer
|
||||
def tempInMired = (1000000 / value) as Integer
|
||||
def finalHex = zigbee.swapEndianHex(zigbee.convertToHexString(tempInMired, 4))
|
||||
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_COLOR_TEMPERATURE_COMMAND, "$finalHex 0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE)
|
||||
zigbee.setColorTemperature(value)
|
||||
}
|
||||
|
||||
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
|
||||
|
||||
@@ -49,9 +49,9 @@ metadata {
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
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}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2017 SmartThings
|
||||
* Copyright 2016 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:
|
||||
@@ -55,7 +55,6 @@ private getATTRIBUTE_HUE() { 0x0000 }
|
||||
private getATTRIBUTE_SATURATION() { 0x0001 }
|
||||
private getHUE_COMMAND() { 0x00 }
|
||||
private getSATURATION_COMMAND() { 0x03 }
|
||||
private getMOVE_TO_HUE_AND_SATURATION_COMMAND() { 0x06 }
|
||||
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
@@ -73,11 +72,11 @@ def parse(String description) {
|
||||
|
||||
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
|
||||
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
|
||||
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
|
||||
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 360)
|
||||
sendEvent(name: "hue", value: hueValue, displayed:false)
|
||||
}
|
||||
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
|
||||
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
|
||||
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
|
||||
sendEvent(name: "saturation", value: saturationValue, displayed:false)
|
||||
}
|
||||
}
|
||||
@@ -109,46 +108,28 @@ def configure() {
|
||||
}
|
||||
|
||||
def configureAttributes() {
|
||||
zigbee.onOffConfig() +
|
||||
zigbee.levelConfig()
|
||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, DataType.UINT8, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, DataType.UINT8, 1, 3600, 0x01)
|
||||
}
|
||||
|
||||
def refreshAttributes() {
|
||||
zigbee.onOffRefresh() +
|
||||
zigbee.levelRefresh() +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
}
|
||||
|
||||
def setLevel(value) {
|
||||
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
|
||||
}
|
||||
|
||||
private getScaledHue(value) {
|
||||
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
}
|
||||
|
||||
private getScaledSaturation(value) {
|
||||
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
}
|
||||
|
||||
def setColor(value){
|
||||
log.trace "setColor($value)"
|
||||
zigbee.on() +
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
|
||||
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
zigbee.on() + setHue(value.hue) + ["delay 300"] + setSaturation(value.saturation) + ["delay 2000"] + refreshAttributes()
|
||||
}
|
||||
|
||||
def setHue(value) {
|
||||
//payload-> hue value, direction (00-> shortest distance), transition time (1/10th second)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, getScaledHue(value), "00", "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
|
||||
def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") + ["delay 1500"] + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5)
|
||||
}
|
||||
|
||||
def setSaturation(value) {
|
||||
//payload-> sat value, transition time
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, getScaledSaturation(value), "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") + ["delay 1500"] + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) //payload-> sat value, transition time
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2017 SmartThings
|
||||
* Copyright 2016 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:
|
||||
@@ -70,7 +70,6 @@ private getATTRIBUTE_HUE() { 0x0000 }
|
||||
private getATTRIBUTE_SATURATION() { 0x0001 }
|
||||
private getHUE_COMMAND() { 0x00 }
|
||||
private getSATURATION_COMMAND() { 0x03 }
|
||||
private getMOVE_TO_HUE_AND_SATURATION_COMMAND() { 0x06 }
|
||||
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
|
||||
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
|
||||
|
||||
@@ -89,11 +88,11 @@ def parse(String description) {
|
||||
|
||||
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
|
||||
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
|
||||
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
|
||||
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 360)
|
||||
sendEvent(name: "hue", value: hueValue, displayed:false)
|
||||
}
|
||||
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
|
||||
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
|
||||
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
|
||||
sendEvent(name: "saturation", value: saturationValue, displayed:false)
|
||||
}
|
||||
}
|
||||
@@ -125,16 +124,11 @@ def configure() {
|
||||
}
|
||||
|
||||
def configureAttributes() {
|
||||
zigbee.onOffConfig() +
|
||||
zigbee.levelConfig()
|
||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, DataType.UINT8, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, DataType.UINT8, 1, 3600, 0x01)
|
||||
}
|
||||
|
||||
def refreshAttributes() {
|
||||
zigbee.onOffRefresh() +
|
||||
zigbee.levelRefresh() +
|
||||
zigbee.colorTemperatureRefresh() +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
}
|
||||
|
||||
def setColorTemperature(value) {
|
||||
@@ -145,32 +139,17 @@ def setLevel(value) {
|
||||
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
|
||||
}
|
||||
|
||||
private getScaledHue(value) {
|
||||
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
}
|
||||
|
||||
private getScaledSaturation(value) {
|
||||
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
}
|
||||
|
||||
def setColor(value){
|
||||
log.trace "setColor($value)"
|
||||
zigbee.on() +
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
|
||||
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
|
||||
zigbee.onOffRefresh() +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
zigbee.on() + setHue(value.hue) + ["delay 300"] + setSaturation(value.saturation) + ["delay 2000"] + refreshAttributes()
|
||||
}
|
||||
|
||||
def setHue(value) {
|
||||
//payload-> hue value, direction (00-> shortest distance), transition time (1/10th second)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, getScaledHue(value), "00", "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
|
||||
def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") + ["delay 1500"] + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5)
|
||||
}
|
||||
|
||||
def setSaturation(value) {
|
||||
//payload-> sat value, transition time
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, getScaledSaturation(value), "0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
|
||||
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") + ["delay 1500"] + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) //payload-> sat value, transition time
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2017 SmartThings
|
||||
* Copyright 2016 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:
|
||||
@@ -66,11 +66,6 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
// Globals
|
||||
private getMOVE_TO_COLOR_TEMPERATURE_COMMAND() { 0x0A }
|
||||
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
|
||||
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
def parse(String description) {
|
||||
log.debug "description is $description"
|
||||
@@ -100,14 +95,14 @@ def setLevel(value) {
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
def cmds = zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
||||
def cmds = zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
||||
|
||||
// Do NOT config if the device is the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, and maybe other weird things with the others
|
||||
// Do NOT config if the device is the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, and maybe other weird things with the others
|
||||
if (!((device.getDataValue("manufacturer") == "Eaton") && (device.getDataValue("model") == "Halo_LT01"))) {
|
||||
cmds += zigbee.onOffConfig() + zigbee.levelConfig()
|
||||
cmds = cmds + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
|
||||
}
|
||||
|
||||
cmds
|
||||
cmds
|
||||
}
|
||||
|
||||
def poll() {
|
||||
@@ -143,7 +138,7 @@ def configure() {
|
||||
log.debug "configure()"
|
||||
configureHealthCheck()
|
||||
// Implementation note: for the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, so be sure this is before the call to onOffRefresh
|
||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
@@ -153,12 +148,7 @@ def updated() {
|
||||
|
||||
def setColorTemperature(value) {
|
||||
setGenericName(value)
|
||||
value = value as Integer
|
||||
def tempInMired = (1000000 / value) as Integer
|
||||
def finalHex = zigbee.swapEndianHex(zigbee.convertToHexString(tempInMired, 4))
|
||||
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_COLOR_TEMPERATURE_COMMAND, "$finalHex 0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE)
|
||||
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
|
||||
}
|
||||
|
||||
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2017 SmartThings
|
||||
* Copyright 2016 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:
|
||||
@@ -68,11 +68,6 @@ metadata {
|
||||
}
|
||||
}
|
||||
|
||||
// Globals
|
||||
private getMOVE_TO_COLOR_TEMPERATURE_COMMAND() { 0x0A }
|
||||
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
|
||||
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
def parse(String description) {
|
||||
log.debug "description is $description"
|
||||
@@ -99,11 +94,7 @@ def setLevel(value) {
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
zigbee.onOffRefresh() +
|
||||
zigbee.levelRefresh() +
|
||||
zigbee.colorTemperatureRefresh() +
|
||||
zigbee.onOffConfig() +
|
||||
zigbee.levelConfig()
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
|
||||
}
|
||||
|
||||
def poll() {
|
||||
@@ -138,7 +129,8 @@ def configureHealthCheck() {
|
||||
def configure() {
|
||||
log.debug "configure()"
|
||||
configureHealthCheck()
|
||||
refresh()
|
||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
||||
|
||||
}
|
||||
|
||||
def updated() {
|
||||
@@ -148,12 +140,7 @@ def updated() {
|
||||
|
||||
def setColorTemperature(value) {
|
||||
setGenericName(value)
|
||||
value = value as Integer
|
||||
def tempInMired = (1000000 / value) as Integer
|
||||
def finalHex = zigbee.swapEndianHex(zigbee.convertToHexString(tempInMired, 4))
|
||||
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_COLOR_TEMPERATURE_COMMAND, "$finalHex 0000") +
|
||||
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE)
|
||||
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
|
||||
}
|
||||
|
||||
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
|
||||
|
||||
@@ -75,10 +75,6 @@ def parse(String description) {
|
||||
return result
|
||||
}
|
||||
|
||||
def uninstalled() {
|
||||
sendEvent(name: "epEvent", value: "delete all", isStateChange: true, displayed: false, descriptionText: "Delete endpoint devices")
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
|
||||
[ createEvent(descriptionText: "${device.displayName} woke up", isStateChange:true),
|
||||
response(["delay 2000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]) ]
|
||||
|
||||
@@ -88,20 +88,11 @@ def updated(){
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
}
|
||||
|
||||
def getCommandClassVersions() {
|
||||
[
|
||||
0x20: 1, // Basic
|
||||
0x26: 1, // SwitchMultilevel
|
||||
0x56: 1, // Crc16Encap
|
||||
0x70: 1, // Configuration
|
||||
]
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
def result = null
|
||||
if (description != "updated") {
|
||||
log.debug "parse() >> zwave.parse($description)"
|
||||
def cmd = zwave.parse(description, commandClassVersions)
|
||||
def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
|
||||
if (cmd) {
|
||||
result = zwaveEvent(cmd)
|
||||
}
|
||||
@@ -168,16 +159,6 @@ def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelS
|
||||
[createEvent(name:"switch", value:"on"), response(zwave.switchMultilevelV1.switchMultilevelGet().format())]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
|
||||
def versions = commandClassVersions
|
||||
def version = versions[cmd.commandClass as Integer]
|
||||
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
|
||||
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
|
||||
if (encapsulatedCommand) {
|
||||
zwaveEvent(encapsulatedCommand)
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
// Handles all Z-Wave commands we aren't interested in
|
||||
[:]
|
||||
|
||||
@@ -30,15 +30,9 @@ metadata {
|
||||
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x98", outClusters: "0x5A,0x82"
|
||||
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x80,0x71,0x85,0x70,0x72,0x86,0x30,0x31,0x84,0x59,0x73,0x5A,0x8F,0x98,0x7A", outClusters:"0x20" // Philio multi+
|
||||
fingerprint mfr:"0086", prod:"0002", model:"001D", deviceJoinName: "Aeon Labs Door/Window Sensor (Gen 5)"
|
||||
fingerprint mfr:"0086", prod:"0102", model:"0070", deviceJoinName: "Aeon Labs Door/Window Sensor 6"
|
||||
fingerprint mfr:"0086", prod:"0102", model:"0059", deviceJoinName: "Aeon Labs Recessed Door Sensor"
|
||||
fingerprint mfr:"014A", prod:"0001", model:"0002", deviceJoinName: "Ecolink Door/Window Sensor"
|
||||
fingerprint mfr:"014A", prod:"0001", model:"0003", deviceJoinName: "Ecolink Tilt Sensor"
|
||||
fingerprint mfr:"0086", prod:"0102", model:"0070", deviceJoinName: "Aeon Labs Door/Window Sensor 6"
|
||||
fingerprint mfr:"011A", prod:"0601", model:"0903", deviceJoinName: "Enerwave Magnetic Door/Window Sensor"
|
||||
fingerprint mfr:"014F", prod:"2001", model:"0102", deviceJoinName: "Nortek GoControl Door/Window Sensor"
|
||||
fingerprint mfr:"0063", prod:"4953", model:"3031", deviceJoinName: "Jasco Hinge Pin Door Sensor"
|
||||
fingerprint mfr:"019A", prod:"0003", model:"0003", deviceJoinName: "Sensative Strips"
|
||||
|
||||
}
|
||||
|
||||
// simulator metadata
|
||||
@@ -113,9 +107,9 @@ def updated() {
|
||||
|
||||
def configure() {
|
||||
commands([
|
||||
zwave.sensorBinaryV2.sensorBinaryGet(sensorType: zwave.sensorBinaryV2.SENSOR_TYPE_DOOR_WINDOW),
|
||||
zwave.manufacturerSpecificV2.manufacturerSpecificGet()
|
||||
], 1000)
|
||||
zwave.manufacturerSpecificV2.manufacturerSpecificGet(),
|
||||
zwave.batteryV1.batteryGet()
|
||||
], 6000)
|
||||
}
|
||||
|
||||
def sensorValueEvent(value) {
|
||||
@@ -190,17 +184,11 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
|
||||
cmds << command(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
|
||||
cmds << "delay 1200"
|
||||
}
|
||||
|
||||
if (device.currentValue("contact") == null) { // Incase our initial request didn't make it
|
||||
cmds << command(zwave.sensorBinaryV2.sensorBinaryGet(sensorType: zwave.sensorBinaryV2.SENSOR_TYPE_DOOR_WINDOW))
|
||||
}
|
||||
|
||||
if (!state.lastbat || now() - state.lastbat > 53*60*60*1000) {
|
||||
cmds << command(zwave.batteryV1.batteryGet())
|
||||
} else { // If we check the battery state we will send NoMoreInfo in the handler for BatteryReport so that we definitely get the report
|
||||
} else {
|
||||
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
|
||||
}
|
||||
|
||||
[event, response(cmds)]
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Z-Wave Lock
|
||||
# Z-Wave Switch
|
||||
|
||||
Cloud Execution
|
||||
|
||||
@@ -6,6 +6,7 @@ Works with:
|
||||
|
||||
* [Yale Key Free Touchscreen Deadbolt (YRD240)](https://www.smartthings.com/works-with-smartthings/yale/yale-key-free-touchscreen-deadbolt-yrd240)
|
||||
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Capabilities](#capabilities)
|
||||
@@ -40,3 +41,5 @@ If the device doesn't pair when trying from the SmartThings mobile app, it is po
|
||||
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:
|
||||
* [General Z-Wave/ZigBee Yale Lock Troubleshooting](https://support.smartthings.com/hc/en-us/articles/205138400-How-to-connect-Yale-locks)
|
||||
|
||||
|
||||
|
||||
@@ -26,24 +26,7 @@ metadata {
|
||||
|
||||
fingerprint deviceId: "0x4003", inClusters: "0x98"
|
||||
fingerprint deviceId: "0x4004", inClusters: "0x98"
|
||||
fingerprint mfr:"0090", prod:"0001", model:"0236", deviceJoinName: "KwikSet SmartCode 910 Deadbolt Door Lock"
|
||||
fingerprint mfr:"0090", prod:"0003", model:"0238", deviceJoinName: "KwikSet SmartCode 910 Deadbolt Door Lock"
|
||||
fingerprint mfr:"0090", prod:"0001", model:"0001", deviceJoinName: "KwikSet SmartCode 910 Contemporary Deadbolt Door Lock"
|
||||
fingerprint mfr:"0090", prod:"0003", model:"0339", deviceJoinName: "KwikSet SmartCode 912 Lever Door Lock"
|
||||
fingerprint mfr:"0090", prod:"0003", model:"4006", deviceJoinName: "KwikSet SmartCode 914 Deadbolt Door Lock" //backlit version
|
||||
fingerprint mfr:"0090", prod:"0003", model:"0440", deviceJoinName: "KwikSet SmartCode 914 Deadbolt Door Lock"
|
||||
fingerprint mfr:"0090", prod:"0001", model:"0642", deviceJoinName: "KwikSet SmartCode 916 Touchscreen Deadbolt Door Lock"
|
||||
fingerprint mfr:"0090", prod:"0003", model:"0642", deviceJoinName: "KwikSet SmartCode 916 Touchscreen Deadbolt Door Lock"
|
||||
fingerprint mfr:"003B", prod:"6341", model:"0544", deviceJoinName: "Schlage Camelot Touchscreen Deadbolt Door Lock"
|
||||
fingerprint mfr:"003B", prod:"6341", model:"5044", deviceJoinName: "Schlage Century Touchscreen Deadbolt Door Lock"
|
||||
fingerprint mfr:"003B", prod:"634B", model:"504C", deviceJoinName: "Schlage Connected Keypad Lever Door Lock"
|
||||
fingerprint mfr:"0129", prod:"0002", model:"0800", deviceJoinName: "Yale Touchscreen Deadbolt Door Lock" // YRD120
|
||||
fingerprint mfr:"0129", prod:"0002", model:"0000", deviceJoinName: "Yale Touchscreen Deadbolt Door Lock" // YRD220, YRD240
|
||||
fingerprint mfr:"0129", prod:"0002", model:"FFFF", deviceJoinName: "Yale Touchscreen Lever Door Lock" // YRD220
|
||||
fingerprint mfr:"0129", prod:"0004", model:"0800", deviceJoinName: "Yale Push Button Deadbolt Door Lock" // YRD110
|
||||
fingerprint mfr:"0129", prod:"0004", model:"0000", deviceJoinName: "Yale Push Button Deadbolt Door Lock" // YRD210
|
||||
fingerprint mfr:"0129", prod:"0001", model:"0000", deviceJoinName: "Yale Push Button Lever Door Lock" // YRD210
|
||||
fingerprint mfr:"0129", prod:"8002", model:"0600", deviceJoinName: "Yale Assure Lock with Bluetooth"
|
||||
fingerprint mfr:"0129", prod:"0002", model:"0000", deviceJoinName: "Yale Key Free Touchscreen Deadbolt"
|
||||
}
|
||||
|
||||
simulator {
|
||||
@@ -86,13 +69,13 @@ import physicalgraph.zwave.commands.doorlockv1.*
|
||||
import physicalgraph.zwave.commands.usercodev1.*
|
||||
|
||||
def installed() {
|
||||
// Device-Watch pings if no device events received for 1 hour (checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 1 * 60 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
// 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 pings if no device events received for 1 hour (checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 1 * 60 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
// 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])
|
||||
try {
|
||||
if (!state.init) {
|
||||
state.init = true
|
||||
@@ -152,10 +135,6 @@ def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityCommandsSupported
|
||||
|
||||
def zwaveEvent(DoorLockOperationReport cmd) {
|
||||
def result = []
|
||||
|
||||
unschedule("followupStateCheck")
|
||||
unschedule("stateCheck")
|
||||
|
||||
def map = [ name: "lock" ]
|
||||
if (cmd.doorLockMode == 0xFF) {
|
||||
map.value = "locked"
|
||||
@@ -369,7 +348,7 @@ def zwaveEvent(UserCodeReport cmd) {
|
||||
code = state["set$name"] ?: decrypt(state[name]) ?: "****"
|
||||
state.remove("set$name".toString())
|
||||
} else {
|
||||
map = [ name: "codeReport", value: cmd.userIdentifier, data: [ code: code ], isStateChange: true ]
|
||||
map = [ name: "codeReport", value: cmd.userIdentifier, data: [ code: code ] ]
|
||||
map.descriptionText = "$device.displayName code $cmd.userIdentifier is set"
|
||||
map.displayed = (cmd.userIdentifier != state.requestCode && cmd.userIdentifier != state.pollCode)
|
||||
map.isStateChange = true
|
||||
@@ -460,12 +439,11 @@ def zwaveEvent(physicalgraph.zwave.commands.timev1.TimeGet cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
|
||||
// The old Schlage locks use group 1 for basic control - we don't want that, so unsubscribe from group 1
|
||||
def result = [ createEvent(name: "lock", value: cmd.value ? "unlocked" : "locked") ]
|
||||
def cmds = [
|
||||
zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId).format(),
|
||||
"delay 1200",
|
||||
zwave.associationV1.associationGet(groupingIdentifier:2).format()
|
||||
]
|
||||
[result, response(cmds)]
|
||||
result << response(zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId))
|
||||
if (state.assoc != zwaveHubNodeId) {
|
||||
result << response(zwave.associationV1.associationGet(groupingIdentifier:2))
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
||||
@@ -535,18 +513,11 @@ def unlockwtimeout() {
|
||||
lockAndCheck(DoorLockOperationSet.DOOR_LOCK_MODE_DOOR_UNSECURED_WITH_TIMEOUT)
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
def ping() {
|
||||
runIn(30, followupStateCheck)
|
||||
secure(zwave.doorLockV1.doorLockOperationGet())
|
||||
}
|
||||
|
||||
def followupStateCheck() {
|
||||
runEvery1Hour(stateCheck)
|
||||
stateCheck()
|
||||
}
|
||||
|
||||
def stateCheck() {
|
||||
sendHubCommand(new physicalgraph.device.HubAction(secure(zwave.doorLockV1.doorLockOperationGet())))
|
||||
refresh()
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Z-Wave Metering Dimmer", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
|
||||
definition (name: "Z-Wave Metering Dimmer", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.switch") {
|
||||
capability "Switch"
|
||||
capability "Polling"
|
||||
capability "Power Meter"
|
||||
@@ -85,21 +85,11 @@ metadata {
|
||||
details(["switch", "power", "energy", "levelSliderControl", "refresh", "reset"])
|
||||
}
|
||||
|
||||
def getCommandClassVersions() {
|
||||
[
|
||||
0x20: 1, // Basic
|
||||
0x26: 3, // SwitchMultilevel
|
||||
0x56: 1, // Crc16Encap
|
||||
0x70: 1, // Configuration
|
||||
0x32: 3, // Meter
|
||||
]
|
||||
}
|
||||
|
||||
// parse events into attributes
|
||||
def parse(String description) {
|
||||
def result = null
|
||||
if (description != "updated") {
|
||||
def cmd = zwave.parse(description, commandClassVersions)
|
||||
def cmd = zwave.parse(description, [0x20: 1, 0x26: 3, 0x70: 1, 0x32:3])
|
||||
if (cmd) {
|
||||
result = zwaveEvent(cmd)
|
||||
log.debug("'$description' parsed to $result")
|
||||
@@ -134,21 +124,6 @@ def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelR
|
||||
dimmerEvents(cmd)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
|
||||
def versions = commandClassVersions
|
||||
def version = versions[cmd.commandClass as Integer]
|
||||
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
|
||||
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
|
||||
if (encapsulatedCommand) {
|
||||
zwaveEvent(encapsulatedCommand)
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
// Handles all Z-Wave commands we aren't interested in
|
||||
[:]
|
||||
}
|
||||
|
||||
def dimmerEvents(physicalgraph.zwave.Command cmd) {
|
||||
def result = []
|
||||
def value = (cmd.value ? "on" : "off")
|
||||
|
||||
@@ -89,19 +89,10 @@ def updated() {
|
||||
} catch (e) { log.debug e }
|
||||
}
|
||||
|
||||
def getCommandClassVersions() {
|
||||
[
|
||||
0x20: 1, // Basic
|
||||
0x32: 1, // SwitchMultilevel
|
||||
0x56: 1, // Crc16Encap
|
||||
0x72: 2, // ManufacturerSpecific
|
||||
]
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
def result = null
|
||||
if(description == "updated") return
|
||||
def cmd = zwave.parse(description, commandClassVersions)
|
||||
def cmd = zwave.parse(description, [0x20: 1, 0x32: 1, 0x72: 2])
|
||||
if (cmd) {
|
||||
result = zwaveEvent(cmd)
|
||||
}
|
||||
@@ -166,16 +157,6 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
|
||||
result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
|
||||
def versions = commandClassVersions
|
||||
def version = versions[cmd.commandClass as Integer]
|
||||
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
|
||||
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
|
||||
if (encapsulatedCommand) {
|
||||
zwaveEvent(encapsulatedCommand)
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
log.debug "$device.displayName: Unhandled: $cmd"
|
||||
[:]
|
||||
|
||||
@@ -29,7 +29,7 @@ metadata {
|
||||
fingerprint mfr: "0060", prod: "0001", model: "0002", deviceJoinName: "Everspring Motion Sensor" // Everspring SP814
|
||||
fingerprint mfr: "0060", prod: "0001", model: "0003", deviceJoinName: "Everspring Motion Sensor" // Everspring HSP02
|
||||
fingerprint mfr: "011A", prod: "0601", model: "0901", deviceJoinName: "Enerwave Motion Sensor" // Enerwave ZWN-BPC
|
||||
fingerprint mfr: "0063", prod: "4953", model: "3133", deviceJoinName: "GE Portable Smart Motion Sensor"
|
||||
fingerprint mfr: "0063", prod: "4953", model: "3133", deviceJoinName: "GE Smart Motion Sensor"
|
||||
}
|
||||
|
||||
simulator {
|
||||
|
||||
@@ -37,8 +37,8 @@ metadata {
|
||||
|
||||
tiles {
|
||||
standardTile("motion", "device.motion", width: 3, height: 2) {
|
||||
state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC"
|
||||
state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#CCCCCC"
|
||||
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", inactiveLabel: false) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* Date: 2014-07-15
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Z-Wave Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.smoke") {
|
||||
definition (name: "Z-Wave Siren", namespace: "smartthings", author: "SmartThings") {
|
||||
capability "Actuator"
|
||||
capability "Alarm"
|
||||
capability "Battery"
|
||||
|
||||
@@ -22,7 +22,6 @@ metadata {
|
||||
attribute "alarmState", "string"
|
||||
|
||||
fingerprint deviceId: "0xA100", inClusters: "0x20,0x80,0x70,0x85,0x71,0x72,0x86"
|
||||
fingerprint mfr:"0138", prod:"0001", model:"0001", deviceJoinName: "First Alert Smoke Detector"
|
||||
fingerprint mfr:"0138", prod:"0001", model:"0002", deviceJoinName: "First Alert Smoke Detector and Carbon Monoxide Alarm (ZCOMBO)"
|
||||
}
|
||||
|
||||
|
||||
@@ -71,17 +71,9 @@ def updated(){
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
}
|
||||
|
||||
def getCommandClassVersions() {
|
||||
[
|
||||
0x20: 1, // Basic
|
||||
0x56: 1, // Crc16Encap
|
||||
0x70: 1, // Configuration
|
||||
]
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
def result = null
|
||||
def cmd = zwave.parse(description, commandClassVersions)
|
||||
def cmd = zwave.parse(description, [0x20: 1, 0x70: 1])
|
||||
if (cmd) {
|
||||
result = createEvent(zwaveEvent(cmd))
|
||||
}
|
||||
@@ -128,15 +120,6 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
|
||||
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
|
||||
def versions = commandClassVersions
|
||||
def version = versions[cmd.commandClass as Integer]
|
||||
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
|
||||
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
|
||||
if (encapsulatedCommand) {
|
||||
zwaveEvent(encapsulatedCommand)
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
// Handles all Z-Wave commands we aren't interested in
|
||||
|
||||
@@ -89,17 +89,9 @@ def updated(){
|
||||
}
|
||||
}
|
||||
|
||||
def getCommandClassVersions() {
|
||||
[
|
||||
0x20: 1, // Basic
|
||||
0x56: 1, // Crc16Encap
|
||||
0x70: 1, // Configuration
|
||||
]
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
def result = null
|
||||
def cmd = zwave.parse(description, commandClassVersions)
|
||||
def cmd = zwave.parse(description, [0x20: 1, 0x70: 1])
|
||||
if (cmd) {
|
||||
result = createEvent(zwaveEvent(cmd))
|
||||
}
|
||||
@@ -146,16 +138,6 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
|
||||
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
|
||||
def versions = commandClassVersions
|
||||
def version = versions[cmd.commandClass as Integer]
|
||||
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
|
||||
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
|
||||
if (encapsulatedCommand) {
|
||||
zwaveEvent(encapsulatedCommand)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
// Handles all Z-Wave commands we aren't interested in
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user