Compare commits

...

59 Commits

Author SHA1 Message Date
Vinay Rao
bd0ccd0c21 Merge pull request #903 from SmartThingsCommunity/staging
Rolling up staging to production Deploy May 17
2016-05-17 09:58:29 -07:00
Vinay Rao
d34508c19d Merge pull request #901 from dsainteclaire/DVCSMP-1739-revert-untested-code
Undo DVCSMP-1739 Revert "make sure reformat the storeGraphData"
2016-05-16 17:28:04 -07:00
David Sainte-Claire
a8e118fe83 Revert "make sure reformat the storeGraphData"
This reverts commit e1de599668.

Revert "make descriptive comment and add space in else condition"

This reverts commit 0e01cbed06.

Revert "null zwave event check in storeGraphData"

This reverts commit 8821c68e9c.
2016-05-16 17:20:43 -07:00
Vinay Rao
072cc066b6 Merge pull request #900 from workingmonk/bug/cree_remove_fingerprint
DPROT-94 removing cree fingerprint from zll dimmer until the fix in trim
2016-05-16 14:59:22 -07:00
Vinay Rao
17562c96ae removing cree fingerprint from zll dimmer until the fix in trim for deviceJoinName 2016-05-16 14:54:09 -07:00
Vinay Rao
3b56fb4a2f Merge pull request #891 from workingmonk/bug/hotfix_cree_fingerprint
DPROT-94 moving the cree specific generic fingerprint back to cree dth
2016-05-16 11:30:50 -07:00
Vinay Rao
cca1eccce6 moving the cree specific generic fingerprint back to cree dth because of cree manufacturerInfo spacing issue 2016-05-12 16:10:05 -07:00
tslagle13
f1e54c8a5c Merge pull request #872 from tslagle13/fix-vacation-lighting-director-exception
fix exception caused by typo
2016-05-11 18:59:00 -07:00
tslagle13
a4a48fddd2 fix exception caused by typo
added paren to end of "someoneIsHome" check on accident.
2016-05-11 12:07:03 -07:00
Vinay Rao
2bd18859b9 Merge pull request #870 from SmartThingsCommunity/master
Rolling up master to staging for next week's release
2016-05-10 15:44:41 -07:00
Dwight Liu
32f8d2d944 Merge pull request #863 from dwightatsmartthings/DVCSMP-1719-aeon-home-energy-meter-c3-npe-fix
null zwave event check in storeGraphData
2016-05-10 14:29:02 -07:00
Dwight Liu
e1de599668 make sure reformat the storeGraphData 2016-05-10 14:23:46 -07:00
Dwight Liu
0e01cbed06 make descriptive comment and add space in else condition 2016-05-10 13:40:52 -07:00
Vinay Rao
566425c531 Merge pull request #869 from SmartThingsCommunity/staging
Rolling up staging to production 05-10
2016-05-10 13:40:49 -07:00
Jim Anderson
bf476940e9 Merge pull request #857 from jimmyjames/fix-generic-tile
fix parse signature for generic multiattribute example tile
2016-05-09 12:28:27 -05:00
Jack Chi
a219f37035 Merge pull request #835 from jackchi/add-healthcheck-smartsense
[CHF-131] Add checkInterval values to SmartSense DTHs
2016-05-07 20:29:55 +08:00
Dwight Liu
8821c68e9c null zwave event check in storeGraphData 2016-05-06 12:50:02 -07:00
Tom Manley
7571c1b980 Merge pull request #858 from tpmanley/feature/ge_fingerprints
DVCSMP-1370: Added fingerprints for GE Link Daylight and SoftWhite bulbs
2016-05-05 23:01:52 -05:00
Tom Manley
bb65c4ce14 Added fingerprints for GE Link Daylight and SoftWhite bulbs
Resolves:
    https://smartthings.atlassian.net/browse/DVCSMP-1370
2016-05-05 22:54:30 -05:00
Jim Anderson
69ae9973da fix parse signature for generic multiattribute example tile 2016-05-05 15:36:08 -05:00
rohandesai
36c0af82fe Merge pull request #843 from rohandesai/rohan/PENG-157
Fixing the security issue in the IFTTT SmartApp
2016-05-04 16:52:47 -07:00
Rohan Desai
eba1f16ee1 added changes to address security loophole in the IFTTT app
addressed comments

PENG-157 IFTTT should not allow undefined commands
- added changes to address security loophole in the IFTTT app
- addressed comments
- removed an extra whitespace
2016-05-04 11:54:08 -07:00
Vinay Rao
f397691fdb Merge pull request #856 from workingmonk/bug/unnecessary_logs
DVCSMP-1748 Remove unncessary changelog from the file header
2016-05-04 11:52:51 -07:00
Vinay Rao
9a5be2c5db remove unncessary changelog from the file header 2016-05-04 11:49:59 -07:00
Vinay Rao
39ac9f9a8c Merge pull request #854 from workingmonk/feature/osram_fingerprint
INTL-532 Adding additional osram fingerprint
2016-05-04 10:19:03 -07:00
Vinay Rao
c353eeae17 adding additional osram fingerprint 2016-05-04 09:52:07 -07:00
Vinay Rao
467c6ff055 Merge pull request #852 from workingmonk/feature/zll_dth
DVCSMP-1743 INTL-532 Add zll dth equivalent
2016-05-03 21:56:44 -07:00
Vinay Rao
5beacf0ef2 add zll dth equivalent 2016-05-03 21:52:32 -07:00
Vinay Rao
e7448e7908 Merge pull request #848 from SmartThingsCommunity/master
Rolling up master to staging
2016-05-03 10:59:58 -07:00
Vinay Rao
973c16f088 Merge pull request #842 from SmartThingsCommunity/staging
Rolling up changes to production from staging 2016-05-03 Release
2016-05-03 10:20:53 -07:00
Luke Bredeson
77f880af6e Merge pull request #841 from lbredeso/hue-connect-updated-failure
SHARD-174: Hue (Connect) updated() calls can fail in certain situations
2016-04-28 13:28:07 -05:00
Luke Bredeson
1c4386a67b SHARD-174: Hue (Connect) updated() calls can fail in certain situations 2016-04-28 11:09:52 -05:00
Matt Pennig
88dd510e72 Merge pull request #832 from SmartThingsCommunity/two-line-multiattribute-controls
Adding test cases for multi-line controls in multiattribute tiles
2016-04-26 13:49:57 -05:00
Vinay Rao
e278a3b57d Merge pull request #838 from SmartThingsCommunity/master
Rolling up master to staging
2016-04-26 11:34:03 -07:00
Vinay Rao
7786df3262 Merge pull request #837 from SmartThingsCommunity/staging
Rolling down staging hotfix to master
2016-04-26 11:25:59 -07:00
Matt Pennig
5ac08e5a92 adding multi-line text for standard and value tiles 2016-04-26 13:13:20 -05:00
Vinay Rao
b05d956d95 Merge pull request #830 from SmartThingsCommunity/staging
Rolling up changes to production from staging 2016-04-26 Release
2016-04-26 10:59:05 -07:00
Donald C. Kirker
6cdb80db1f Merge pull request #836 from mckeed/staging
Add auto-retyping for Astralink sensors SING-44
2016-04-25 17:41:32 -07:00
Duncan McKee
4db99824af Add Astralink sensors to zw door/window retypeBasedOnMSR 2016-04-25 16:40:47 -04:00
jackchi
d9f224fa6e [CHF-131] Add checkInterval values to SmartSense DTHs 2016-04-25 13:21:28 -07:00
Vinay Rao
72b51d50bc Merge pull request #834 from SmartThingsCommunity/staging
Rolling down hotfix for deploy tool to master
2016-04-25 12:33:13 -07:00
Vinay Rao
b2e245bd85 Merge pull request #833 from SmartThingsCommunity/production
Rolling down hotfix for deploy tool to staging
2016-04-25 12:28:55 -07:00
Vinay Rao
9a9854cf92 Merge pull request #831 from jord98716/DEVTOOLS-636-a
DEVTOOLS-636: Increment version of executable-deployment-scripts
2016-04-25 12:27:42 -07:00
Matt Pennig
1e27ff5d4a Adding test cases for multi-line controls in multiattribute tiles 2016-04-25 11:58:18 -05:00
Jordan Howe
37f1726ee6 DEVTOOLS-636: Increment version of executable-deployment-scripts 2016-04-25 09:57:53 -05:00
Jack Chi
c7e8079ff1 Merge pull request #757 from jackchi/add-healthcheck-smartsense
[CHF-112] Add Health Check capability to SmartThings SmartSense products
2016-04-22 11:11:59 -07:00
jackchi
481d13a571 [CHF-112] Add Health Check capability to SmartThings SmartSense products 2016-04-22 11:10:48 -07:00
Luke Bredeson
9d83b850ca Merge pull request #813 from lbredeso/updated-settings-state-fix
SHARD-159: Wemo (Connect) updated() fails in certain IP change scenarios
2016-04-20 16:31:36 -05:00
Luke Bredeson
84de336a1a SHARD-159: Wemo (Connect) updated() fails in certain IP change scenarios 2016-04-20 16:07:11 -05:00
Lars Finander
8b465b03b4 Merge pull request #808 from larsfinander/DVCSMP-1716_Philips_Hue_Invalid_parameter
DVCSMP-1716 Philips Hue: Invalid hue parameter used in setColor
2016-04-20 11:11:39 -07:00
Vinay Rao
2f81964479 Merge pull request #775 from motley74/nyce_hinge
Added fingerprint for NYCE door hinge sensor
2016-04-20 10:29:06 -07:00
Vinay Rao
d5ea735df7 Merge pull request #810 from SmartThingsCommunity/master
Rolling up master to staging
2016-04-19 15:50:22 -07:00
Vinay Rao
6428719c79 Merge pull request #809 from SmartThingsCommunity/staging
Rolling down staging hotfix to master
2016-04-19 15:41:56 -07:00
Lars Finander
327f8dfb00 DVCSMP-1716 Philips Hue: Invalid hue parameter used in setColor
-Replaced transition with transitiontime according to Hue API
2016-04-19 15:05:21 -07:00
Yaima
33ef75091b Merge pull request #783 from Yaima/master
Fixes broken htmlTile
2016-04-14 16:05:55 -07:00
Yaima Valdivia
1bcad614ec Fixes broken htmlTile 2016-04-14 16:03:58 -07:00
Luke Bredeson
3ab83350f3 Merge pull request #761 from lbredeso/hue-event-subscription-improvements
EX-3: Improve Hue (Connect) event subscriptions
2016-04-14 16:58:01 -05:00
Michael Hudson
235e3f5507 Added fingerprint for NYCE door hinge sensor 2016-04-12 18:23:28 -06:00
Luke Bredeson
237d6a79e9 EX-3: Improve Hue (Connect) event subscriptions 2016-04-05 13:28:45 -05:00
31 changed files with 730 additions and 223 deletions

View File

@@ -9,7 +9,7 @@ apply plugin: 'smartthings-slack'
buildscript {
dependencies {
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.7"
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.8"
}
repositories {
mavenLocal()

View File

@@ -12,16 +12,6 @@
*
*/
/*
* Purpose: Arrival Sensor HA DTH File
*
* Filename: Arrival-Sensor-HA.src/Arrival-Sensor-HA.groovy
*
* Change History:
* 1. 20160115 TW - Update/Edit to support i18n translations
* 2. 20160121 TW - Update to V4 battery calcs, added pref's page title translations
*/
metadata {
definition (name: "Arrival Sensor HA", namespace: "smartthings", author: "SmartThings") {
capability "Tone"

View File

@@ -1,4 +1,3 @@
#==============================================================================
# Copyright 2016 SmartThings
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -12,15 +11,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#==============================================================================
# Purpose: Arrival Sensor HA i18n Translation File
#
# Filename: Arrival-Sensor-HA.src/i18n/messages.properties
#
# Change History:
# 1. 20160115 TW Initial release with informal Korean translation.
# 2. 20160121 TW Added def preference section titles.
#==============================================================================
# Korean (ko)
# Device Preferences
'''Give your device a name'''.ko=기기 이름 설정

View File

@@ -13,12 +13,13 @@
* for the specific language governing permissions and limitations under the License.
*
*/
metadata {
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings") {
capability "Actuator"
capability "Configuration"
capability "Polling"
capability "Refresh"
capability "Switch"
capability "Switch Level"
@@ -88,6 +89,10 @@ def refresh() {
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.onOffConfig() + zigbee.levelConfig()
}
def poll() {
zigbee.onOffRefresh() + zigbee.levelRefresh()
}
def configure() {
log.debug "Configuring Reporting and Bindings."
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()

View File

@@ -1,7 +1,7 @@
/**
* GE Link Bulb
*
* Copyright 2014 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:
@@ -53,6 +53,8 @@ metadata {
capability "Polling"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019", manufacturer: "GE_Appliances", model: "ZLL Light", deviceJoinName: "GE Link Bulb"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019", manufacturer: "GE", model: "SoftWhite", deviceJoinName: "GE Link Soft White Bulb"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019", manufacturer: "GE", model: "Daylight", deviceJoinName: "GE Link Daylight Bulb"
}
// UI tile definitions

View File

@@ -1,4 +1,3 @@
#==============================================================================
# Copyright 2016 SmartThings
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -12,15 +11,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#==============================================================================
# Purpose: Mobile Presence i18n Translation File
#
# Filename: mobile-presence.src/i18n/messages.properties
#
# Change History:
# 1. 20160205 TW Initial release with informal Korean translation.
# 2. 20160224 TW Updated with formal Korean translation.
#==============================================================================
# Korean (ko)
# Device Preferences
'''Give your device a name'''.ko=기기 이름 설정

View File

@@ -1,5 +1,4 @@
/*
===============================================================================
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -13,14 +12,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
===============================================================================
* Purpose: Mobile Presence DTH File
*
* Filename: mobile-presence.src/mobile-presence.groovy
*
* Change History:
* 1. 20160205 TW - Update/Edit to support i18n translations
===============================================================================
*/
metadata {

View File

@@ -24,6 +24,7 @@ metadata {
command "enrollResponse"
fingerprint inClusters: "0000,0001,0003,0500,0020", manufacturer: "NYCE", model: "3010", deviceJoinName: "NYCE Door Hinge Sensor"
fingerprint inClusters: "0000,0001,0003,0406,0500,0020", manufacturer: "NYCE", model: "3011", deviceJoinName: "NYCE Door/Window Sensor"
fingerprint inClusters: "0000,0001,0003,0500,0020", manufacturer: "NYCE", model: "3011", deviceJoinName: "NYCE Door/Window Sensor"
fingerprint inClusters: "0000,0001,0003,0406,0500,0020", manufacturer: "NYCE", model: "3014", deviceJoinName: "NYCE Tilt Sensor"

View File

@@ -1,4 +1,3 @@
#==============================================================================
# Copyright 2016 SmartThings
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -12,14 +11,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#==============================================================================
# Purpose: SmartPower Outlet i18n Translation File
#
# Filename: SmartPower-Outlet.src/i18n/messages.properties
#
# Change History:
# 1. 20160116 TW Initial release with informal Korean translation.
#==============================================================================
# Korean (ko)
# Device Preferences
'''Give your device a name'''.ko=기기 이름 설정

View File

@@ -1,5 +1,4 @@
/*
===============================================================================
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -13,15 +12,8 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
===============================================================================
* Purpose: SmartPower Outlet DTH File
*
* Filename: SmartPower-Outlet.src/SmartPower-Outlet.groovy
*
* Change History:
* 1. 20160117 TW - Update/Edit to support i18n translations
===============================================================================
*/
metadata {
// Automatically generated. Make future change here.
definition (name: "SmartPower Outlet", namespace: "smartthings", author: "SmartThings") {
@@ -31,6 +23,7 @@ metadata {
capability "Configuration"
capability "Refresh"
capability "Sensor"
capability "Health Check"
// indicates that device keeps track of heartbeat (in state.heartbeat)
attribute "heartbeat", "string"
@@ -136,6 +129,7 @@ def refresh() {
}
def configure() {
sendEvent(name: "checkInterval", value: 1200, displayed: false)
zigbee.onOffConfig() + powerConfig() + refresh()
}

View File

@@ -1,4 +1,3 @@
#==============================================================================
# Copyright 2016 SmartThings
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -12,14 +11,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#==============================================================================
# Purpose: SmartSense Moisture Sensor i18n Translation File
#
# Filename: SmartSense-Moisture-Sensor.src/i18n/messages.properties
#
# Change History:
# 1. 20160116 TW Initial release with formal Korean translation.
#==============================================================================
# Korean (ko)
# Device Preferences
'''Dry'''.ko=건조

View File

@@ -1,5 +1,4 @@
/*
===============================================================================
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -13,15 +12,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
===============================================================================
* Purpose: SmartSense Moisture Sensor DTH File
*
* Filename: SmartSense-Moisture-Sensor.src/SmartSense-Moisture-Sensor.groovy
*
* Change History:
* 1. 20160116 TW - Update/Edit to support i18n translations
* 2. 20160125 TW = Incorporated new battery mapping from TM
===============================================================================
*/
metadata {
@@ -31,6 +21,7 @@ metadata {
capability "Refresh"
capability "Temperature Measurement"
capability "Water Sensor"
capability "Health Check"
command "enrollResponse"
@@ -320,6 +311,8 @@ def refresh() {
}
def configure() {
sendEvent(name: "checkInterval", value: 7200, displayed: false)
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
log.debug "Configuring Reporting, IAS CIE, and Bindings."
def configCmds = [

View File

@@ -1,4 +1,3 @@
#==============================================================================
# Copyright 2016 SmartThings
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -12,15 +11,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#==============================================================================
# Purpose: SmartSense Motion Sensor i18n Translation File
#
# Filename: SmartSense-Motion-Sensor.src/i18n/messages.properties
#
# Change History:
# 1. 20160116 TW Initial release with formal Korean translation.
# 2. 20160224 TW Updated formal Korean translations from Mike Stoller.
#==============================================================================
# Korean (ko)
# Device Preferences
'''battery'''.ko=배터리

View File

@@ -1,5 +1,4 @@
/*
===============================================================================
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -13,15 +12,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
===============================================================================
* Purpose: SmartSense Motion Sensor DTH File
*
* Filename: SmartSense-Motion-Sensor.src/SmartSense-Motion-Sensor.groovy
*
* Change History:
* 1. 20160116 TW - Update/Edit to support i18n translations
* 2. 20160125 TW = Incorporated new battery mapping from TM
===============================================================================
*/
metadata {
@@ -31,6 +21,7 @@ metadata {
capability "Battery"
capability "Temperature Measurement"
capability "Refresh"
capability "Health Check"
command "enrollResponse"
@@ -332,6 +323,8 @@ def refresh() {
}
def configure() {
sendEvent(name: "checkInterval", value: 7200, displayed: false)
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
log.debug "Configuring Reporting, IAS CIE, and Bindings."

View File

@@ -1,4 +1,3 @@
#==============================================================================
# Copyright 2016 SmartThings
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -12,14 +11,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#==============================================================================
# Purpose: SmartSense Multi Sensor i18n Translation File
#
# Filename: SmartSense-Multi-Sensor.src/i18n/messages.properties
#
# Change History:
# 1. 20160117 TW Initial release with informal Korean translation.
#==============================================================================
# Korean (ko)
# Device Preferences
'''Yes'''.ko=

View File

@@ -1,5 +1,4 @@
/*
===============================================================================
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -13,15 +12,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
===============================================================================
* Purpose: SmartSense Multi Sensor DTH File
*
* Filename: SmartSense-Multi-Sensor.src/SmartSense-Multi-Sensor.groovy
*
* Change History:
* 1. 20160117 TW - Update/Edit to support i18n translations
* 2. 20160125 TW = Incorporated new battery mapping from TM
===============================================================================
*/
metadata {
@@ -35,6 +25,7 @@ metadata {
capability "Acceleration Sensor"
capability "Refresh"
capability "Temperature Measurement"
capability "Health Check"
command "enrollResponse"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3320"
@@ -450,6 +441,8 @@ def refresh() {
}
def configure() {
sendEvent(name: "checkInterval", value: 7200, displayed: false)
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
log.debug "Configuring Reporting"

View File

@@ -23,8 +23,9 @@
capability "Acceleration Sensor"
capability "Refresh"
capability "Temperature Measurement"
command "enrollResponse"
capability "Health Check"
command "enrollResponse"
}
simulator {
@@ -299,6 +300,7 @@ def getTemperature(value) {
}
def configure() {
sendEvent(name: "checkInterval", value: 7200, displayed: false)
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
log.debug "Configuring Reporting, IAS CIE, and Bindings."

View File

@@ -20,6 +20,7 @@ metadata {
capability "Refresh"
capability "Temperature Measurement"
capability "Relative Humidity Measurement"
capability "Health Check"
fingerprint endpointId: "01", inClusters: "0001,0003,0020,0402,0B05,FC45", outClusters: "0019,0003"
}
@@ -251,6 +252,7 @@ def refresh()
}
def configure() {
sendEvent(name: "checkInterval", value: 7200, displayed: false)
log.debug "Configuring Reporting and Bindings."
def configCmds = [

View File

@@ -80,19 +80,31 @@ metadata {
state "default", label:''
}
main("standard1")
// multi-line text (explicit newlines)
standardTile("multiLine", "device.multiLine", width: 2, height: 2) {
state "default", label: '${currentValue}'
}
standardTile("multiLineWithIcon", "device.multiLine", width: 2, height: 2) {
state "default", label: '${currentValue}', icon: "st.switches.switch.off"
}
main("actionRings")
details([
"actionRings", "actionFlat", "noActionFlat",
"flatLabel", "flatIconLabel", "flatIcon",
"flatDefaultState", "flatImplicitDefaultState1", "flatImplicitDefaultState2",
"multiLine", "multiLineWithIcon"
])
}
}
def installed() {
sendEvent(name: "switch", value: "off")
sendEvent(name: "multiLine", value: "Line 1\nLine 2\nLine 3")
}
def parse(String description) {

View File

@@ -69,16 +69,25 @@ metadata {
]
}
valueTile("noValue", "device.nada", width: 2, height: 2) {
valueTile("noValue", "device.nada", width: 4, height: 2) {
state "default", label:'${currentValue}'
}
valueTile("multiLine", "device.multiLine", width: 3, height: 2) {
state "default", label: '${currentValue}'
}
valueTile("multiLineWithIcon", "device.multiLine", width: 3, height: 2) {
state "default", label: '${currentValue}', icon: "st.switches.switch.off"
}
main("text")
details([
"text", "longText", "integer",
"integerFloat", "pi", "floatAsText",
"bgColor", "bgColorRange", "bgColorRangeSingleItem",
"bgColorRangeConflict", "noValue"
"bgColorRangeConflict", "noValue",
"multiLine", "multiLineWithIcon"
])
}
}
@@ -90,6 +99,7 @@ def installed() {
sendEvent(name: "integerFloat", value: 47.0)
sendEvent(name: "pi", value: 3.14159)
sendEvent(name: "floatAsText", value: "3.14159")
sendEvent(name: "multiLine", value: "Line 1\nLine 2\nLine 3")
}
def parse(String description) {

View File

@@ -67,17 +67,50 @@ metadata {
attributeState "VALUE_DOWN", action: "levelDown"
}
}
multiAttributeTile(name:"lengthyTile", type:"generic", width:6, height:4) {
tileAttribute("device.lengthyText", key: "PRIMARY_CONTROL") {
attributeState "default", label:'The value of this tile is long and should wrap to two lines', backgroundColor:"#79b821"
}
tileAttribute("device.lengthyText", key: "SECONDARY_CONTROL") {
attributeState "default", label:'The value of this tile is long and should wrap to two lines', backgroundColor:"#79b821"
}
}
multiAttributeTile(name:"multilineTile", type:"generic", width:6, height:4) {
tileAttribute("device.multilineText", key: "PRIMARY_CONTROL") {
attributeState "default", label:'Line 1 YES\nLine 2 YES\nLine 3 NO', backgroundColor:"#79b821"
}
tileAttribute("device.multilineText", key: "SECONDARY_CONTROL") {
attributeState "default", label:'Line 1 YES\nLine 2 YES\nLine 3 NO', backgroundColor:"#79b821"
}
}
multiAttributeTile(name:"lengthyTileWithIcon", type:"generic", width:6, height:4) {
tileAttribute("device.lengthyText", key: "PRIMARY_CONTROL") {
attributeState "default", label:'The value of this tile is long and should wrap to two lines', backgroundColor:"#79b821", icon: "st.switches.switch.on"
}
tileAttribute("device.lengthyText", key: "SECONDARY_CONTROL") {
attributeState "default", label:'The value of this tile is long and should wrap to two lines', backgroundColor:"#79b821", icon: "st.switches.switch.on"
}
}
multiAttributeTile(name:"multilineTileWithIcon", type:"generic", width:6, height:4) {
tileAttribute("device.multilineText", key: "PRIMARY_CONTROL") {
attributeState "default", label:'Line 1 YES\nLine 2 YES\nLine 3 NO', backgroundColor:"#79b821", icon: "st.switches.switch.on"
}
tileAttribute("device.multilineText", key: "SECONDARY_CONTROL") {
attributeState "default", label:'Line 1 YES\nLine 2 YES\nLine 3 NO', backgroundColor:"#79b821", icon: "st.switches.switch.on"
}
}
main(["basicTile"])
details(["basicTile", "sliderTile", "valueTile"])
details(["basicTile", "sliderTile", "valueTile", "lengthyTile", "multilineTile", "lengthyTileWithIcon", "multilineTileWithIcon"])
}
}
def installed() {
sendEvent(name: "lengthyText", value: "The value of this tile is long and should wrap to two lines")
sendEvent(name: "multilineText", value: "Line 1 YES\nLine 2 YES\nLine 3 NO")
}
def parse() {
def parse(String description) {
// This is a simulated device. No incoming data to parse.
}

View File

@@ -33,7 +33,7 @@ metadata {
state "power", label: '${currentValue} W'
}
htmlTile(name: "powerContent", attribute: "powerContent", type: "HTML", whitelist: "www.wattvision.com" , url: '${currentValue}', width: 3, height: 2)
htmlTile(name: "powerContent", attribute: "powerContent", type: "HTML", whitelist: ["www.wattvision.com"] , url: '${currentValue}', width: 3, height: 2)
standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat") {
state "default", label: '', action: "refresh.refresh", icon: "st.secondary.refresh"

View File

@@ -11,6 +11,9 @@
* for the specific language governing permissions and limitations under the License.
*
*/
//@Deprecated - Moved to zll-rgbw-bulb
/* Philips Hue (via Zigbee)
Capabilities:
@@ -22,10 +25,10 @@ Capabilities:
Sensor
Switch
Switch Level
Custom Commands:
setAdjustedColor
*/
metadata {
@@ -41,7 +44,7 @@ metadata {
command "setAdjustedColor"
fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,0300,1000", outClusters: "0019"
//fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,0300,1000", outClusters: "0019"
}
// simulator metadata

View File

@@ -0,0 +1,102 @@
/**
* 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:
*
* 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: "ZLL Dimmer Bulb", namespace: "smartthings", author: "SmartThings") {
capability "Actuator"
capability "Configuration"
capability "Polling"
capability "Refresh"
capability "Switch"
capability "Switch Level"
//fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0000,0019"
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0019"
//fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0000,0019", manufacturer: "CREE", model: "Connected A-19 60W Equivalent", deviceJoinName: "Cree Connected Bulb"
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic A60 W clear", deviceJoinName: "OSRAM LIGHTIFY LED Smart Connected Light"
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic A60 W clear - LIGHTIFY", deviceJoinName: "OSRAM LIGHTIFY LED Smart Connected Light"
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0019", manufacturer: "Philips", model: "LWB006", deviceJoinName: "Philips Hue White"
}
// simulator metadata
simulator {
// status messages
status "on": "on/off: 1"
status "off": "on/off: 0"
// reply messages
reply "zcl on-off on": "on/off: 1"
reply "zcl on-off off": "on/off: 0"
}
// UI tile definitions
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel"
}
}
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", "refresh"])
}
}
// Parse incoming device messages to generate events
def parse(String description) {
log.debug "description is $description"
def resultMap = zigbee.getEvent(description)
if (resultMap) {
sendEvent(resultMap)
}
else {
log.debug "DID NOT PARSE MESSAGE for description : $description"
log.debug zigbee.parseDescriptionAsMap(description)
}
}
def off() {
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
}
def on() {
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
}
def setLevel(value) {
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
}
def refresh() {
zigbee.onOffRefresh() + zigbee.levelRefresh()
}
def poll() {
refresh()
}
def configure() {
log.debug "Configuring Reporting and Bindings."
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
}

View File

@@ -0,0 +1,150 @@
/**
* 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:
*
* 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: "ZLL RGBW Bulb", namespace: "smartthings", author: "SmartThings") {
capability "Actuator"
capability "Color Control"
capability "Color Temperature"
capability "Configuration"
capability "Polling"
capability "Refresh"
capability "Switch"
capability "Switch Level"
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300", outClusters: "0019"
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000", outClusters: "0019"
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000", outClusters: "0019", "manufacturer":"OSRAM", "model":"Classic A60 RGBW", deviceJoinName: "OSRAM LIGHTIFY LED Classic A60 RGBW"
}
// UI tile definitions
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel"
}
tileAttribute ("device.color", key: "COLOR_CONTROL") {
attributeState "color", action:"color control.setColor"
}
}
controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..6500)") {
state "colorTemperature", action:"color temperature.setColorTemperature"
}
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "colorTemperature", label: '${currentValue} K'
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
main(["switch"])
details(["switch", "colorTempSliderControl", "colorTemp", "refresh"])
}
}
//Globals
private getATTRIBUTE_HUE() { 0x0000 }
private getATTRIBUTE_SATURATION() { 0x0001 }
private getHUE_COMMAND() { 0x00 }
private getSATURATION_COMMAND() { 0x03 }
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"
def finalResult = zigbee.getEvent(description)
if (finalResult) {
log.debug finalResult
sendEvent(finalResult)
}
else {
def zigbeeMap = zigbee.parseDescriptionAsMap(description)
log.trace "zigbeeMap : $zigbeeMap"
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
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) / 255 * 100)
sendEvent(name: "saturation", value: saturationValue, displayed:false)
}
}
else {
log.info "DID NOT PARSE MESSAGE for description : $description"
}
}
}
def on() {
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
}
def off() {
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
}
def refresh() {
refreshAttributes() + configureAttributes()
}
def poll() {
refreshAttributes()
}
def configure() {
log.debug "Configuring Reporting and Bindings."
configureAttributes() + refreshAttributes()
}
def configureAttributes() {
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, 0x20, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, 0x20, 1, 3600, 0x01)
}
def refreshAttributes() {
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.readAttribute(0x0300, 0x00) + zigbee.readAttribute(0x0300, ATTRIBUTE_HUE) + zigbee.readAttribute(0x0300, ATTRIBUTE_SATURATION)
}
def setColorTemperature(value) {
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
}
def setLevel(value) {
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
}
def setColor(value){
log.trace "setColor($value)"
zigbee.on() + setHue(value.hue) + ["delay 300"] + setSaturation(value.saturation) + ["delay 2000"] + refreshAttributes()
}
def setHue(value) {
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) {
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") //payload-> sat value, transition time
}

View File

@@ -0,0 +1,124 @@
/**
* 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:
*
* 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: "ZLL White Color Temperature Bulb", namespace: "smartthings", author: "SmartThings") {
capability "Actuator"
capability "Color Temperature"
capability "Configuration"
capability "Polling"
capability "Refresh"
capability "Switch"
capability "Switch Level"
attribute "colorName", "string"
command "setGenericName"
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000, 0B04, FC0F", outClusters: "0019", "manufacturer":"OSRAM", "model":"Classic A60 TW", deviceJoinName: "OSRAM LIGHTIFY LED Classic A60 Tunable White"
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000, FC0F", outClusters: "0019", "manufacturer":"OSRAM", "model":"PAR16 50 TW", deviceJoinName: "OSRAM LIGHTIFY LED PAR16 50 Tunable White"
}
// UI tile definitions
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel"
}
tileAttribute ("colorName", key: "SECONDARY_CONTROL") {
attributeState "colorName", label:'${currentValue}'
}
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..6500)") {
state "colorTemperature", action:"color temperature.setColorTemperature"
}
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "colorTemperature", label: '${currentValue} K'
}
main(["switch"])
details(["switch", "colorTempSliderControl", "colorTemp", "refresh"])
}
}
// Parse incoming device messages to generate events
def parse(String description) {
log.debug "description is $description"
def event = zigbee.getEvent(description)
if (event) {
sendEvent(event)
}
else {
log.warn "DID NOT PARSE MESSAGE for description : $description"
log.debug zigbee.parseDescriptionAsMap(description)
}
}
def off() {
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
}
def on() {
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
}
def setLevel(value) {
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh()
}
def refresh() {
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
}
def poll() {
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
}
def configure() {
log.debug "Configuring Reporting and Bindings."
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
}
def setColorTemperature(value) {
setGenericName(value)
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
}
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
def setGenericName(value){
if (value != null) {
def genericName = ""
if (value < 3300) {
genericName = "Soft White"
} else if (value < 4150) {
genericName = "Moonlight"
} else if (value <= 5000) {
genericName = "Cool White"
} else {
genericName = "Daylight"
}
sendEvent(name: "colorName", value: genericName)
}
}

View File

@@ -25,7 +25,10 @@ metadata {
fingerprint deviceId: "0x2001", inClusters: "0x30,0x80,0x84,0x85,0x86,0x72"
fingerprint deviceId: "0x07", inClusters: "0x30"
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x98"
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 deviceId: "0x0701", inClusters: "0x5E,0x72,0x5A,0x80,0x73,0x86,0x84,0x85,0x59,0x71,0x70,0x7A,0x98" // Vision door/window
}
// simulator metadata
@@ -240,7 +243,7 @@ def batteryGetCommand() {
def retypeBasedOnMSR() {
switch (state.MSR) {
case "0086-0002-002D":
log.debug("Changing device type to Z-Wave Water Sensor")
log.debug "Changing device type to Z-Wave Water Sensor"
setDeviceType("Z-Wave Water Sensor")
break
case "011F-0001-0001": // Schlage motion
@@ -249,9 +252,16 @@ def retypeBasedOnMSR() {
case "0060-0001-0002": // Everspring SP814
case "0060-0001-0003": // Everspring HSP02
case "011A-0601-0901": // Enerwave ZWN-BPC
log.debug("Changing device type to Z-Wave Motion Sensor")
log.debug "Changing device type to Z-Wave Motion Sensor"
setDeviceType("Z-Wave Motion Sensor")
break
case "013C-0002-000D": // Philio multi +
log.debug "Changing device type to 3-in-1 Multisensor Plus (SG)"
setDeviceType("3-in-1 Multisensor Plus (SG)")
break
case "0109-2001-0106": // Vision door/window
log.debug "Changing device type to Door / Window Sensor Plus (SG)"
setDeviceType("Door / Window Sensor Plus (SG)")
break
}
}

View File

@@ -60,7 +60,7 @@ def bridgeDiscovery(params=[:])
app.updateSetting("selectedHue", "")
}
subscribe(location, null, locationHandler, [filterEvents:false])
ssdpSubscribe()
//bridge discovery request every 15 //25 seconds
if((bridgeRefreshCount % 5) == 0) {
@@ -152,6 +152,10 @@ private discoverBridges() {
sendHubCommand(new physicalgraph.device.HubAction("lan discovery urn:schemas-upnp-org:device:basic:1", physicalgraph.device.Protocol.LAN))
}
void ssdpSubscribe() {
subscribe(location, "ssdpTerm.urn:schemas-upnp-org:device:basic:1", ssdpBridgeHandler)
}
private sendDeveloperReq() {
def token = app.id
def host = getBridgeIP()
@@ -161,7 +165,7 @@ private sendDeveloperReq() {
headers: [
HOST: host
],
body: [devicetype: "$token-0"]], "${selectedHue}"))
body: [devicetype: "$token-0"]], "${selectedHue}", [callback: "usernameHandler"]))
}
private discoverHueBulbs() {
@@ -171,7 +175,7 @@ private discoverHueBulbs() {
path: "/api/${state.username}/lights",
headers: [
HOST: host
]], "${selectedHue}"))
]], "${selectedHue}", [callback: "lightsHandler"]))
}
private verifyHueBridge(String deviceNetworkId, String host) {
@@ -181,7 +185,7 @@ private verifyHueBridge(String deviceNetworkId, String host) {
path: "/description.xml",
headers: [
HOST: host
]], deviceNetworkId))
]], deviceNetworkId, [callback: "bridgeDescriptionHandler"]))
}
private verifyHueBridges() {
@@ -293,8 +297,9 @@ def bulbListHandler(hub, data = "") {
}
}
def bridge = null
if (selectedHue)
bridge = getChildDevice(selectedHue)
if (selectedHue) {
bridge = getChildDevice(selectedHue)
}
bridge.sendEvent(name: "bulbList", value: hub, data: bulbs, isStateChange: true, displayed: false)
msg = "${bulbs.size()} bulbs found. ${bulbs}"
return msg
@@ -327,8 +332,7 @@ private addChildBulb(dni, hueType, name, hub, update=false, device = null) {
if (deviceType) {
return addChildDevice("smartthings", deviceType, dni, hub, ["label": name])
}
else {
} else {
log.warn "Device type $hueType not supported"
return null
}
@@ -344,8 +348,10 @@ def addBulbs() {
newHueBulb = bulbs.find { (app.id + "/" + it.value.id) == dni }
if (newHueBulb != null) {
d = addChildBulb(dni, newHueBulb?.value?.type, newHueBulb?.value?.name, newHueBulb?.value?.hub)
log.debug "created ${d.displayName} with id $dni"
d.refresh()
if (d) {
log.debug "created ${d.displayName} with id $dni"
d.refresh()
}
} else {
log.debug "$dni in not longer paired to the Hue Bridge or ID changed"
}
@@ -353,7 +359,7 @@ def addBulbs() {
//backwards compatable
newHueBulb = bulbs.find { (app.id + "/" + it.id) == dni }
d = addChildBulb(dni, "Extended Color Light", newHueBulb?.value?.name, newHueBulb?.value?.hub)
d.refresh()
d?.refresh()
}
} else {
log.debug "found ${d.displayName} with id $dni already exists, type: '$d.typeName'"
@@ -382,8 +388,9 @@ def addBridge() {
def oldDNI = it.deviceNetworkId
log.debug "updating dni for device ${it} with $newDNI - previous DNI = ${it.deviceNetworkId}"
it.setDeviceNetworkId("${newDNI}")
if (oldDNI == selectedHue)
app.updateSetting("selectedHue", newDNI)
if (oldDNI == selectedHue) {
app.updateSetting("selectedHue", newDNI)
}
newbridge = false
}
}
@@ -412,6 +419,111 @@ def addBridge() {
}
}
def ssdpBridgeHandler(evt) {
def description = evt.description
log.trace "Location: $description"
def hub = evt?.hubId
def parsedEvent = parseLanMessage(description)
parsedEvent << ["hub":hub]
def bridges = getHueBridges()
log.trace bridges.toString()
if (!(bridges."${parsedEvent.ssdpUSN.toString()}")) {
//bridge does not exist
log.trace "Adding bridge ${parsedEvent.ssdpUSN}"
bridges << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
} else {
// update the values
def ip = convertHexToIP(parsedEvent.networkAddress)
def port = convertHexToInt(parsedEvent.deviceAddress)
def host = ip + ":" + port
log.debug "Device ($parsedEvent.mac) was already found in state with ip = $host."
def dstate = bridges."${parsedEvent.ssdpUSN.toString()}"
def dni = "${parsedEvent.mac}"
def d = getChildDevice(dni)
def networkAddress = null
if (!d) {
childDevices.each {
if (it.getDeviceDataByName("mac")) {
def newDNI = "${it.getDeviceDataByName("mac")}"
if (newDNI != it.deviceNetworkId) {
def oldDNI = it.deviceNetworkId
log.debug "updating dni for device ${it} with $newDNI - previous DNI = ${it.deviceNetworkId}"
it.setDeviceNetworkId("${newDNI}")
if (oldDNI == selectedHue) {
app.updateSetting("selectedHue", newDNI)
}
doDeviceSync()
}
}
}
} else {
if (d.getDeviceDataByName("networkAddress")) {
networkAddress = d.getDeviceDataByName("networkAddress")
} else {
networkAddress = d.latestState('networkAddress').stringValue
}
log.trace "Host: $host - $networkAddress"
if (host != networkAddress) {
log.debug "Device's port or ip changed for device $d..."
dstate.ip = ip
dstate.port = port
dstate.name = "Philips hue ($ip)"
d.sendEvent(name:"networkAddress", value: host)
d.updateDataValue("networkAddress", host)
}
}
}
}
void bridgeDescriptionHandler(physicalgraph.device.HubResponse hubResponse) {
log.trace "description.xml response (application/xml)"
def body = hubResponse.xml
if (body?.device?.modelName?.text().startsWith("Philips hue bridge")) {
def bridges = getHueBridges()
def bridge = bridges.find {it?.key?.contains(body?.device?.UDN?.text())}
if (bridge) {
bridge.value << [name:body?.device?.friendlyName?.text(), serialNumber:body?.device?.serialNumber?.text(), verified: true]
} else {
log.error "/description.xml returned a bridge that didn't exist"
}
}
}
void lightsHandler(physicalgraph.device.HubResponse hubResponse) {
if (isValidSource(hubResponse.mac)) {
def body = hubResponse.json
if (!body?.state?.on) { //check if first time poll made it here by mistake
def bulbs = getHueBulbs()
log.debug "Adding bulbs to state!"
body.each { k, v ->
bulbs[k] = [id: k, name: v.name, type: v.type, modelid: v.modelid, hub: hubResponse.hubId]
}
}
}
}
void usernameHandler(physicalgraph.device.HubResponse hubResponse) {
if (isValidSource(hubResponse.mac)) {
def body = hubResponse.json
if (body.success != null) {
if (body.success[0] != null) {
if (body.success[0].username)
state.username = body.success[0].username
}
} else if (body.error != null) {
//TODO: handle retries...
log.error "ERROR: application/json ${body.error}"
}
}
}
/**
* @deprecated This has been replaced by the combination of {@link #ssdpBridgeHandler()}, {@link #bridgeDescriptionHandler()},
* {@link #lightsHandler()}, and {@link #usernameHandler()}. After a pending event subscription migration, it can be removed.
*/
@Deprecated
def locationHandler(evt) {
def description = evt.description
log.trace "Location: $description"
@@ -447,17 +559,19 @@ def locationHandler(evt) {
def oldDNI = it.deviceNetworkId
log.debug "updating dni for device ${it} with $newDNI - previous DNI = ${it.deviceNetworkId}"
it.setDeviceNetworkId("${newDNI}")
if (oldDNI == selectedHue)
app.updateSetting("selectedHue", newDNI)
if (oldDNI == selectedHue) {
app.updateSetting("selectedHue", newDNI)
}
doDeviceSync()
}
}
}
} else {
if (d.getDeviceDataByName("networkAddress"))
networkAddress = d.getDeviceDataByName("networkAddress")
else
networkAddress = d.latestState('networkAddress').stringValue
if (d.getDeviceDataByName("networkAddress")) {
networkAddress = d.getDeviceDataByName("networkAddress")
} else {
networkAddress = d.latestState('networkAddress').stringValue
}
log.trace "Host: $host - $networkAddress"
if(host != networkAddress) {
log.debug "Device's port or ip changed for device $d..."
@@ -490,8 +604,9 @@ def locationHandler(evt) {
def body = new groovy.json.JsonSlurper().parseText(parsedEvent.body)
if (body.success != null) {
if (body.success[0] != null) {
if (body.success[0].username)
if (body.success[0].username) {
state.username = body.success[0].username
}
}
} else if (body.error != null) {
//TODO: handle retries...
@@ -516,11 +631,7 @@ def doDeviceSync(){
log.trace "Doing Hue Device Sync!"
convertBulbListToMap()
poll()
try {
subscribe(location, null, locationHandler, [filterEvents:false])
} catch (all) {
log.trace "Subscription already exist"
}
ssdpSubscribe()
discoverBridges()
}
@@ -714,7 +825,7 @@ def setColor(childDevice, huesettings) {
value.bri = Math.min(Math.round(huesettings.level * 255 / 100), 255)
}
value.alert = huesettings.alert ? huesettings.alert : "none"
value.transition = huesettings.transition ? huesettings.transition : 4
value.transitiontime = huesettings.transitiontime ? huesettings.transitiontime : 4
// Make sure to turn off light if requested
if (huesettings.switch == "off")
@@ -747,15 +858,11 @@ private getId(childDevice) {
private poll() {
def host = getBridgeIP()
def uri = "/api/${state.username}/lights/"
try {
sendHubCommand(new physicalgraph.device.HubAction("""GET ${uri} HTTP/1.1
log.debug "GET: $host$uri"
sendHubCommand(new physicalgraph.device.HubAction("""GET ${uri} HTTP/1.1
HOST: ${host}
""", physicalgraph.device.Protocol.LAN, selectedHue))
} catch (all) {
log.warn "Parsing Body failed - trying again..."
doDeviceSync()
}
}
private put(path, body) {

View File

@@ -131,19 +131,69 @@ def update() {
def type = params.deviceType
def data = request.JSON
def devices = settings[type]
def device = settings[type]?.find { it.id == params.id }
def command = data.command
log.debug "[PROD] update, params: ${params}, request: ${data}, devices: ${devices*.id}"
if (command) {
def device = devices?.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device."$command"()
}
if (!device) {
httpError(404, "Device not found")
}
if (validateCommand(device, type, command)) {
device."$command"()
} else {
httpError(403, "Access denied. This command is not supported by current capability.")
}
}
/**
* Validating the command passed by the user based on capability.
* @return boolean
*/
def validateCommand(device, deviceType, command) {
def capabilityCommands = getDeviceCapabilityCommands(device.capabilities)
def currentDeviceCapability = getCapabilityName(deviceType)
if (capabilityCommands[currentDeviceCapability]) {
return command in capabilityCommands[currentDeviceCapability] ? true : false
} else {
// Handling other device types here, which don't accept commands
httpError(400, "Bad request.")
}
}
/**
* Need to get the attribute name to do the lookup. Only
* doing it for the device types which accept commands
* @return attribute name of the device type
*/
def getCapabilityName(type) {
switch(type) {
case "switches":
return "Switch"
case "alarms":
return "Alarm"
case "locks":
return "Lock"
default:
return type
}
}
/**
* Constructing the map over here of
* supported commands by device capability
* @return a map of device capability -> supported commands
*/
def getDeviceCapabilityCommands(deviceCapabilities) {
def map = [:]
deviceCapabilities.collect {
map[it.name] = it.commands.collect{ it.name.toString() }
}
return map
}
def show() {
def type = params.deviceType
def devices = settings[type]

View File

@@ -236,23 +236,22 @@ def addSwitches() {
d = getChildDevices()?.find {
it.deviceNetworkId == selectedSwitch.value.mac || it.device.getDataValue("mac") == selectedSwitch.value.mac
}
}
if (!d) {
log.debug "Creating WeMo Switch with dni: ${selectedSwitch.value.mac}"
d = addChildDevice("smartthings", "Wemo Switch", selectedSwitch.value.mac, selectedSwitch?.value.hub, [
"label": selectedSwitch?.value?.name ?: "Wemo Switch",
"data": [
"mac": selectedSwitch.value.mac,
"ip": selectedSwitch.value.ip,
"port": selectedSwitch.value.port
]
])
def ipvalue = convertHexToIP(selectedSwitch.value.ip)
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
} else {
log.debug "found ${d.displayName} with id $dni already exists"
if (!d) {
log.debug "Creating WeMo Switch with dni: ${selectedSwitch.value.mac}"
d = addChildDevice("smartthings", "Wemo Switch", selectedSwitch.value.mac, selectedSwitch?.value.hub, [
"label": selectedSwitch?.value?.name ?: "Wemo Switch",
"data": [
"mac": selectedSwitch.value.mac,
"ip": selectedSwitch.value.ip,
"port": selectedSwitch.value.port
]
])
def ipvalue = convertHexToIP(selectedSwitch.value.ip)
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
} else {
log.debug "found ${d.displayName} with id $dni already exists"
}
}
}
}
@@ -267,23 +266,22 @@ def addMotions() {
d = getChildDevices()?.find {
it.deviceNetworkId == selectedMotion.value.mac || it.device.getDataValue("mac") == selectedMotion.value.mac
}
}
if (!d) {
log.debug "Creating WeMo Motion with dni: ${selectedMotion.value.mac}"
d = addChildDevice("smartthings", "Wemo Motion", selectedMotion.value.mac, selectedMotion?.value.hub, [
"label": selectedMotion?.value?.name ?: "Wemo Motion",
"data": [
"mac": selectedMotion.value.mac,
"ip": selectedMotion.value.ip,
"port": selectedMotion.value.port
]
])
def ipvalue = convertHexToIP(selectedMotion.value.ip)
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
} else {
log.debug "found ${d.displayName} with id $dni already exists"
if (!d) {
log.debug "Creating WeMo Motion with dni: ${selectedMotion.value.mac}"
d = addChildDevice("smartthings", "Wemo Motion", selectedMotion.value.mac, selectedMotion?.value.hub, [
"label": selectedMotion?.value?.name ?: "Wemo Motion",
"data": [
"mac": selectedMotion.value.mac,
"ip": selectedMotion.value.ip,
"port": selectedMotion.value.port
]
])
def ipvalue = convertHexToIP(selectedMotion.value.ip)
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
} else {
log.debug "found ${d.displayName} with id $dni already exists"
}
}
}
}
@@ -298,23 +296,22 @@ def addLightSwitches() {
d = getChildDevices()?.find {
it.deviceNetworkId == selectedLightSwitch.value.mac || it.device.getDataValue("mac") == selectedLightSwitch.value.mac
}
}
if (!d) {
log.debug "Creating WeMo Light Switch with dni: ${selectedLightSwitch.value.mac}"
d = addChildDevice("smartthings", "Wemo Light Switch", selectedLightSwitch.value.mac, selectedLightSwitch?.value.hub, [
"label": selectedLightSwitch?.value?.name ?: "Wemo Light Switch",
"data": [
"mac": selectedLightSwitch.value.mac,
"ip": selectedLightSwitch.value.ip,
"port": selectedLightSwitch.value.port
]
])
def ipvalue = convertHexToIP(selectedLightSwitch.value.ip)
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
log.debug "created ${d.displayName} with id $dni"
} else {
log.debug "found ${d.displayName} with id $dni already exists"
if (!d) {
log.debug "Creating WeMo Light Switch with dni: ${selectedLightSwitch.value.mac}"
d = addChildDevice("smartthings", "Wemo Light Switch", selectedLightSwitch.value.mac, selectedLightSwitch?.value.hub, [
"label": selectedLightSwitch?.value?.name ?: "Wemo Light Switch",
"data": [
"mac": selectedLightSwitch.value.mac,
"ip": selectedLightSwitch.value.ip,
"port": selectedLightSwitch.value.port
]
])
def ipvalue = convertHexToIP(selectedLightSwitch.value.ip)
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
log.debug "created ${d.displayName} with id $dni"
} else {
log.debug "found ${d.displayName} with id $dni already exists"
}
}
}
}

View File

@@ -273,7 +273,7 @@ def scheduleCheck(evt) {
else {
if(people){
//don't turn off lights if anyone is home
if(someoneIsHome()){
if(someoneIsHome){
log.debug("Stopping Check for Light")
unschedule()
}