Compare commits

...

18 Commits

Author SHA1 Message Date
bflorian
63d8e6444b Merge pull request #1881 from bflorian/SAPLAT-41-composite-refrigerator-example
SAPLAT-41 added simulated refrigerator composite device type example
2017-04-05 11:55:20 -07:00
Bob Florian
24f63a514a SAPLAT-41 added simulated refrigerator composite device type example 2017-04-05 11:40:46 -07:00
Vinay Rao
2bc44e0205 Merge pull request #1877 from SmartThingsCommunity/staging
Rolling down staging to master
2017-04-04 14:41:02 -07:00
Vinay Rao
24d079db7c Merge pull request #1876 from SmartThingsCommunity/revert-1870-revert-phase2
Revert "[CHF-571] [CHF-568] Revert untested Health Check on Keen Home EcoNet"
2017-04-04 14:39:37 -07:00
Vinay Rao
283ed425d8 Merge pull request #1875 from SmartThingsCommunity/revert-1872-revert-harmony
CHF-574 Revert "Revert "Added health-check for Logitech Harmony Hub""
2017-04-04 14:39:10 -07:00
Vinay Rao
1545707ae3 Revert "[CHF-571] [CHF-568] Revert untested Health Check on Keen Home EcoNet" 2017-04-04 14:38:54 -07:00
Vinay Rao
2fd8cf1416 Revert "Revert "Added health-check for Logitech Harmony Hub"" 2017-04-04 14:38:11 -07:00
Vinay Rao
fe4a5239c7 Merge pull request #1869 from SmartThingsCommunity/staging
Rolling down staging to master
2017-04-03 15:59:49 -07:00
Vinay Rao
ec781b18be Merge pull request #1865 from CosmicPuppy/ActionTiles-Wattvision-CapabilitySensor-Patch
To Wattvision power metering Sensor DTH, added Capability "Sensor"
2017-04-03 03:08:10 -07:00
CosmicPuppy
43bedd41a8 To Wattvision power metering Sensor DTH, added Capability "Sensor" per http://docs.smartthings.com/en/latest/device-type-developers-guide/overview.html?highlight=sensor%20actuator#actuator-and-sensor. 2017-04-03 00:21:11 -07:00
Jack Chi
f75e8a6b2d Merge pull request #1853 from parijatdas/zigbee_lock
[CHF-557] Health Check ZigBee Lock
2017-04-02 09:50:44 -07:00
Parijat Das
515fab9fa4 Added health-check for Zigbee Lock 2017-03-30 17:22:43 -07:00
Vinay Rao
100e696d02 Merge pull request #1857 from varzac/fix-humidity-configuration
Support config on both temp-humidty firmwares
2017-03-30 16:58:12 -07:00
Vinay Rao
3e988ce657 Merge pull request #1860 from SmartThingsCommunity/staging
Rolling down staging to master
2017-03-30 15:50:32 -07:00
Zach Varberg
00224c2d0b Support config on both temp-humidty firmwares
This solves an issue with invalid configuration of the reporting for
humidity on the smartsense-temp-humidity-sensor.  This issue was masked
by the fact that the device has a default configuration for reporting
humidity, but the configuration has never been valid as it used an
incorrect dataType for the configuration.

This resolves: https://smartthings.atlassian.net/browse/DPROT-263
This resolves: https://smartthings.atlassian.net/browse/EBF-1205
This resolves: https://smartthings.atlassian.net/browse/DVCSMP-2420
2017-03-30 15:44:40 -05:00
Jack Chi
f05daf2f34 Merge pull request #1538 from pchomal/zwave_metering_dimmer
[CHF-482] Health Check implementation for Z-Wave Metering Dimmer
2017-03-29 14:42:39 -07:00
Piyush Chomal
6fae023f7a Merge branch 'master' into zwave_metering_dimmer 2017-03-22 22:57:47 +05:30
piyush.c
ef8611d2ea [CHF-482]
Health Check implementation for Z-Wave Metering Dimmer
2016-12-22 13:14:35 +05:30
13 changed files with 346 additions and 10 deletions

View File

@@ -11,7 +11,7 @@ metadata {
capability "Sensor"
capability "Temperature Measurement"
capability "Battery"
// capability "Health Check"
capability "Health Check"
command "getLevel"
command "getOnOff"
@@ -476,7 +476,7 @@ def configure() {
// Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time)
// enrolls with default periodic reporting until newer 5 min interval is confirmed
// sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
// get ZigBee ID by hidden tile because that's the only way we can do it
setZigBeeIdTile()

View File

@@ -26,13 +26,13 @@ metadata {
capability "Sensor"
capability "Polling"
capability "Configuration"
// capability "Health Check"
capability "Health Check"
command "open"
command "close"
fingerprint deviceId: "0x1100", inClusters: "0x26,0x72,0x86,0x77,0x80,0x20"
// fingerprint mfr:"0157", prod:"0100", model:"0100", deviceJoinName: "EcoNet Controls Z-Wave Vent"
fingerprint mfr:"0157", prod:"0100", model:"0100", deviceJoinName: "EcoNet Controls Z-Wave Vent"
}
simulator {
@@ -88,7 +88,7 @@ def parse(String description) {
//send the command to stop polling
def updated() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
// sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
response("poll stop")
}

View File

@@ -7,6 +7,7 @@ metadata {
definition (name: "Logitech Harmony Hub C2C", namespace: "smartthings", author: "SmartThings") {
capability "Media Controller"
capability "Refresh"
capability "Health Check"
command "activityoff"
command "alloff"
@@ -38,6 +39,16 @@ metadata {
}
}
def installed() {
log.debug "installed()"
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "cloud", scheme:"untracked"]), displayed: false)
}
def updated() {
log.debug "updated()"
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "cloud", scheme:"untracked"]), displayed: false)
}
def startActivity(String activityId) {
log.debug "Executing 'Start Activity'"
log.trace parent.activity("$device.deviceNetworkId-$activityId","start")
@@ -58,6 +69,10 @@ def poll() {
log.trace parent.poll()
}
def ping() {
refresh()
}
def refresh() {
log.debug "Executing 'Refresh'"
log.trace parent.poll()

View File

@@ -135,10 +135,7 @@ def refresh() {
return zigbee.readAttribute(0xFC45, 0x0000, ["mfgCode": 0x104E]) + // New firmware
zigbee.readAttribute(0xFC45, 0x0000, ["mfgCode": 0xC2DF]) + // Original firmware
zigbee.readAttribute(zigbee.TEMPERATURE_MEASUREMENT_CLUSTER, 0x0000) +
zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020) +
zigbee.configureReporting(0xFC45, 0x0000, DataType.INT16, 30, 3600, 100) +
zigbee.batteryConfig() +
zigbee.temperatureConfig(30, 300)
zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020)
}
def configure() {
@@ -150,5 +147,10 @@ def configure() {
// temperature minReportTime 30 seconds, maxReportTime 5 min. Reporting interval if no activity
// battery minReport 30 seconds, maxReportTime 6 hrs by default
return refresh()
return refresh() +
zigbee.configureReporting(0xFC45, 0x0000, DataType.UINT16, 30, 3600, 100, ["mfgCode": 0x104E]) + // New firmware
zigbee.configureReporting(0xFC45, 0x0000, DataType.UINT16, 30, 3600, 100, ["mfgCode": 0xC2DF]) + // Original firmware
zigbee.batteryConfig() +
zigbee.temperatureConfig(30, 300)
}

View File

@@ -0,0 +1,57 @@
/**
* Copyright 2017 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
*/
metadata {
definition (name: "Simulated Refrigerator Door", namespace: "smartthings/testing", author: "SmartThings") {
capability "Contact Sensor"
capability "Sensor"
command "open"
command "close"
}
tiles {
standardTile("contact", "device.contact", width: 2, height: 2) {
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821", action: "open")
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e", action: "close")
}
standardTile("freezerDoor", "device.contact", width: 2, height: 2, decoration: "flat") {
state("closed", label:'Freezer', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
state("open", label:'Freezer', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
}
standardTile("mainDoor", "device.contact", width: 2, height: 2, decoration: "flat") {
state("closed", label:'Fridge', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
state("open", label:'Fridge', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
}
standardTile("control", "device.contact", width: 1, height: 1, decoration: "flat") {
state("closed", label:'${name}', icon:"st.contact.contact.closed", action: "open")
state("open", label:'${name}', icon:"st.contact.contact.open", action: "close")
}
main "contact"
details "contact"
}
}
def installed() {
sendEvent(name: "contact", value: "closed")
}
def open() {
sendEvent(name: "contact", value: "open")
parent.doorOpen(device.deviceNetworkId)
}
def close() {
sendEvent(name: "contact", value: "closed")
parent.doorClosed(device.deviceNetworkId)
}

View File

@@ -0,0 +1,94 @@
/**
* Simulated Refrigerator Temperature Control
*
* Copyright 2017 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
*/
metadata {
definition (name: "Simulated Refrigerator Temperature Control", namespace: "smartthings/testing", author: "SmartThings") {
capability "Temperature Measurement"
capability "Thermostat Cooling Setpoint"
command "tempUp"
command "tempDown"
command "setpointUp"
command "setpointDown"
}
tiles {
valueTile("refrigerator", "device.temperature", width: 2, height: 2, canChangeBackground: true) {
state("temperature", label:'${currentValue}°', unit:"F",
backgroundColors:[
[value: 0, color: "#153591"],
[value: 40, color: "#1e9cbb"],
[value: 45, color: "#f1d801"]
]
)
}
valueTile("freezer", "device.temperature", width: 2, height: 2, canChangeBackground: true) {
state("temperature", label:'${currentValue}°', unit:"F",
backgroundColors:[
[value: 0, color: "#153591"],
[value: 5, color: "#1e9cbb"],
[value: 15, color: "#f1d801"]
]
)
}
valueTile("freezerSetpoint", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
state "setpoint", label:'Freezer Set: ${currentValue}°', unit:"F"
}
valueTile("refrigeratorSetpoint", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
state "heat", label:'Fridge Set: ${currentValue}°', unit:"F"
}
standardTile("tempUp", "device.temperature", inactiveLabel: false, decoration: "flat") {
state "default", action:"tempUp", icon:"st.thermostat.thermostat-up"
}
standardTile("tempDown", "device.temperature", inactiveLabel: false, decoration: "flat") {
state "default", action:"tempDown", icon:"st.thermostat.thermostat-down"
}
standardTile("setpointUp", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
state "default", action:"setpointUp", icon:"st.thermostat.thermostat-up"
}
standardTile("setpointDown", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
state "default", action:"setpointDown", icon:"st.thermostat.thermostat-down"
}
}
}
def installed() {
sendEvent(name: "temperature", value: device.componentName == "freezer" ? 2 : 40)
sendEvent(name: "coolingSetpoint", value: device.componentName == "freezer" ? 2 : 40)
}
def updated() {
installed()
}
void tempUp() {
def value = device.currentValue("temperature") as Integer
sendEvent(name: "temperature", value: value + 1)
}
void tempDown() {
def value = device.currentValue("temperature") as Integer
sendEvent(name: "temperature", value: value - 1)
}
void setpointUp() {
def value = device.currentValue("coolingSetpoint") as Integer
sendEvent(name: "coolingSetpoint", value: value + 1)
}
void setpointDown() {
def value = device.currentValue("coolingSetpoint") as Integer
sendEvent(name: "coolingSetpoint", value: value - 1)
}

View File

@@ -0,0 +1,91 @@
/**
* Simulated Refrigerator
*
* Example composite device handler that simulates a refrigerator with a freezer compartment and a main compartment.
* Each of these compartments has its own door, temperature, and temperature setpoint. Each compartment modeled
* as a child device of the main refrigerator device so that temperature-based SmartApps can be used with each
* compartment
*
* Copyright 2017 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
*/
metadata {
definition (name: "Simulated Refrigerator", namespace: "smartthings/testing", author: "SmartThings") {
capability "Contact Sensor"
}
tiles(scale: 2) {
standardTile("contact", "device.contact", width: 4, height: 4) {
state("closed", label:'${name}', icon:"st.fridge.fridge-closed", backgroundColor:"#79b821")
state("open", label:'${name}', icon:"st.fridge.fridge-open", backgroundColor:"#ffa81e")
}
childDeviceTile("freezerDoor", "freezerDoor", height: 2, width: 2, childTileName: "freezerDoor")
childDeviceTile("mainDoor", "mainDoor", height: 2, width: 2, childTileName: "mainDoor")
childDeviceTile("freezer", "freezer", height: 2, width: 2, childTileName: "freezer")
childDeviceTile("refrigerator", "refrigerator", height: 2, width: 2, childTileName: "refrigerator")
childDeviceTile("freezerSetpoint", "freezer", height: 1, width: 2, childTileName: "freezerSetpoint")
childDeviceTile("refrigeratorSetpoint", "refrigerator", height: 1, width: 2, childTileName: "refrigeratorSetpoint")
// for simulator
childDeviceTile("freezerUp", "freezer", height: 1, width: 1, childTileName: "tempUp")
childDeviceTile("freezerDown", "freezer", height: 1, width: 1, childTileName: "tempDown")
childDeviceTile("refrigeratorUp", "refrigerator", height: 1, width: 1, childTileName: "tempUp")
childDeviceTile("refrigeratorDown", "refrigerator", height: 1, width: 1, childTileName: "tempDown")
childDeviceTile("freezerDoorControl", "freezerDoor", height: 1, width: 1, childTileName: "control")
childDeviceTile("mainDoorControl", "mainDoor", height: 1, width: 1, childTileName: "control")
childDeviceTile("freezerSetpointUp", "freezer", height: 1, width: 1, childTileName: "setpointUp")
childDeviceTile("freezerSetpointDown", "freezer", height: 1, width: 1, childTileName: "setpointDown")
childDeviceTile("refrigeratorSetpointUp", "refrigerator", height: 1, width: 1, childTileName: "setpointUp")
childDeviceTile("refrigeratorSetpointDown", "refrigerator", height: 1, width: 1, childTileName: "setpointDown")
}
}
def installed() {
state.counter = state.counter ? state.counter + 1 : 1
if (state.counter == 1) {
addChildDevice(
"Simulated Refrigerator Door",
"${device.deviceNetworkId}.1",
null,
[completedSetup: true, label: "${device.label} (Freezer Door)", componentName: "freezerDoor", componentLabel: "Freezer Door"])
addChildDevice(
"Simulated Refrigerator Door",
"${device.deviceNetworkId}.2",
null,
[completedSetup: true, label: "${device.label} (Main Door)", componentName: "mainDoor", componentLabel: "Main Door"])
addChildDevice(
"Simulated Refrigerator Temperature Control",
"${device.deviceNetworkId}.3",
null,
[completedSetup: true, label: "${device.label} (Freezer)", componentName: "freezer", componentLabel: "Freezer"])
addChildDevice(
"Simulated Refrigerator Temperature Control",
"${device.deviceNetworkId}.3",
null,
[completedSetup: true, label: "${device.label} (Fridge)", componentName: "refrigerator", componentLabel: "Fridge"])
}
}
def doorOpen(dni) {
// If any door opens, then the refrigerator is considered to be open
sendEvent(name: "contact", value: "open")
}
def doorClosed(dni) {
// Both doors must be closed for the refrigerator to be considered closed
if (!childDevices.find{it.deviceNetworkId != dni && it.currentValue("contact") == "open"}) {
sendEvent(name: "contact", value: "closed")
}
}

View File

@@ -20,6 +20,7 @@ metadata {
definition(name: "Wattvision", namespace: "smartthings", author: "Steve Vlaminck") {
capability "Power Meter"
capability "Refresh"
capability "Sensor"
attribute "powerContent", "string"
}

View File

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

View File

@@ -0,0 +1,46 @@
# Zigbee Lock
Cloud Execution
Works with:
* [Yale Push Button Deadbolt (YRD210-HA)](https://www.smartthings.com/works-with-smartthings/door-locks/yale-push-button-deadbolt-yrd210)
* [Yale Touchscreen Lever (YRL220-ZB)](https://www.smartthings.com/works-with-smartthings/door-locks/yale-touchscreen-lever-yrl220)
* [Yale Touchscreen Deadbolt (YRD220-HA))](https://www.smartthings.com/works-with-smartthings/door-locks/yale-touchscreen-deadbolt-yrd220)
* [Yale Key Free Touchscreen Deadbolt (YRD240-HA)](https://www.smartthings.com/works-with-smartthings/door-locks/yale-key-free-touchscreen-deadbolt-yrd240)
* [Yale Push Button Lever Lock (YRL210-HA)](https://www.smartthings.com/works-with-smartthings/door-locks/yale-push-button-lever-lock-yrl210)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Battery](#battery-specification)
* [Troubleshooting](#troubleshooting)
## Capabilities
* **Actuator** - represents that a Device has commands
* **Lock** - allows for the control of a lock device
* **Refresh** - _refresh()_ command for status updates
* **Sensor** - detects sensor events
* **Battery** - defines device uses a battery
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
* **Health Check** - indicates ability to get device health notifications
## Device Health
Yale Push Button Deadbolt (YRD210-HA) is a Zigbee device and checks in every 1 hour.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*60 + 2)mins = 122 mins.
* __122min__ checkInterval
## Battery Specification
Four AA 1.5V batteries are required.
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the sensor from SmartThings can be found in the following link:
* [Yale Locks Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/205138400)

View File

@@ -24,6 +24,7 @@ import physicalgraph.zigbee.zcl.DataType
capability "Sensor"
capability "Battery"
capability "Configuration"
capability "Health Check"
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0004,0005,0009,0020,0101,0402,0B05,FDBD", outClusters: "000A,0019", manufacturer: "Kwikset", model: "SMARTCODE_DEADBOLT_5", deviceJoinName: "Kwikset 5-Button Deadbolt"
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0004,0005,0009,0020,0101,0402,0B05,FDBD", outClusters: "000A,0019", manufacturer: "Kwikset", model: "SMARTCODE_LEVER_5", deviceJoinName: "Kwikset 5-Button Lever"
@@ -83,6 +84,9 @@ def uninstalled() {
}
def configure() {
// Device-Watch allows 2 check-in misses from device + ping (plus 2 min lag time)
sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
def cmds =
zigbee.configureReporting(CLUSTER_DOORLOCK, DOORLOCK_ATTR_LOCKSTATE,
DataType.ENUM8, 0, 3600, null) +
@@ -92,6 +96,13 @@ def configure() {
return refresh() + cmds // send refresh cmds as part of config
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
zigbee.readAttribute(CLUSTER_DOORLOCK, DOORLOCK_ATTR_LOCKSTATE)
}
def refresh() {
def cmds =
zigbee.readAttribute(CLUSTER_DOORLOCK, DOORLOCK_ATTR_LOCKSTATE) +

View File

@@ -25,11 +25,13 @@ metadata {
capability "Switch Level"
capability "Sensor"
capability "Actuator"
capability "Health Check"
capability "Light"
command "reset"
fingerprint inClusters: "0x26,0x32"
fingerprint mfr:"0086", prod:"0003", model:"001B", deviceJoinName: "Aeon Labs Micro Smart Dimmer 2E"
}
simulator {
@@ -99,6 +101,9 @@ def parse(String description) {
}
def updated() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
response(refresh())
}
@@ -163,6 +168,14 @@ def poll() {
], 1000)
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
log.debug "ping() called"
refresh()
}
def refresh() {
delayBetween([
zwave.switchMultilevelV1.switchMultilevelGet().format(),

View File

@@ -511,6 +511,10 @@ def pollResponse(response, data) {
if (ResponseValues) {
def map = [:]
ResponseValues.hubs.each {
// Device-Watch relies on the Logitech Harmony Cloud to get the Device state.
def isAlive = it.value.status
def d = getChildDevice("harmony-${it.key}")
d?.sendEvent(name: "DeviceWatch-DeviceStatus", value: isAlive!=504? "online":"offline", displayed: false, isStateChange: true)
if (it.value.message == "OK") {
map["${it.key}"] = "${it.value.response.data.currentAvActivity},${it.value.response.data.activityStatus}"
def hub = getChildDevice("harmony-${it.key}")