Skip to content

Commit

Permalink
Merge pull request SmartThingsCommunity#18120 from SmartThingsCommuni…
Browse files Browse the repository at this point in the history
…ty/acceptance

Rolling up acceptance to production for deploy
  • Loading branch information
greens authored Jan 21, 2020
2 parents 709081e + 0643a30 commit 1e02b13
Show file tree
Hide file tree
Showing 21 changed files with 369 additions and 113 deletions.
4 changes: 2 additions & 2 deletions devicetypes/axis/axis-gear-st.src/axis-gear-st.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ metadata {
state "default", label: "Preset", action:"presetPosition", icon:"st.Home.home2"
}
preferences {
input "preset", "number", title: "Preset percentage (1-100) [Default - 50%]", defaultValue: 50, required: false, displayDuringSetup: true, range:"1..100"
input "preset", "number", title: "Preset position", description: "Set the window shade preset position", defaultValue: 50, required: false, displayDuringSetup: true, range:"1..100"
}

main(["main"])
Expand Down Expand Up @@ -416,4 +416,4 @@ private Map parseReportAttributeMessage(String description) {
log.debug "parseReportAttributeMessage() --- ignoring attribute"
}
return resultMap
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,6 @@ def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
logging("${device.displayName} woke up", "debug")
def cmds = []
if (state.wakeUpInterval?.state == "notSynced" && state.wakeUpInterval?.value != null) {
cmds << zwave.wakeUpV2.wakeUpIntervalSet(seconds: state.wakeUpInterval.value as Integer, nodeid: zwaveHubNodeId)
state.wakeUpInterval.state = "synced"
}
def event = createEvent(descriptionText: "${device.displayName} woke up", displayed: false)
cmds << encap(zwave.batteryV1.batteryGet())
cmds << "delay 500"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
/*
* Copyright 2020 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

import groovy.json.JsonOutput
import physicalgraph.zigbee.zcl.DataType

metadata {
definition (name: "EcoSmart 4-button Remote", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.remotecontroller", mcdSync: true, runLocally: false, executeCommandsLocally: false, mnmn: "SmartThings", vid: "generic-4-button") {
capability "Actuator"
capability "Battery"
capability "Button"
capability "Holdable Button"
capability "Configuration"
capability "Sensor"
capability "Health Check"

fingerprint inClusters: "0000, 0001, 0003, 1000, FD01", outClusters: "0003, 0004, 0006, 0008, 0019, 0300, 1000", manufacturer: "LDS", model: "ZBT-CCTSwitch-D0001", deviceJoinName: "EcoSmart 4-button remote"
}

tiles {
standardTile("button", "device.button", width: 2, height: 2) {
state "default", label: "", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffffff"
state "button 1 pushed", label: "pushed #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#00A0DC"
}

valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false) {
state "battery", label:'${currentValue}% battery', unit:""
}

main (["button"])
details(["button", "battery"])
}
}

private getCLUSTER_GROUPS() { 0x0004 }

private channelNumber(String dni) {
dni.split(":")[-1] as Integer
}

private getButtonName(buttonNum) {
return "${device.displayName} " + "Button ${buttonNum}"
}

private void createChildButtonDevices(numberOfButtons) {
state.oldLabel = device.label

log.debug "Creating $numberOfButtons children"

for (i in 1..numberOfButtons) {
log.debug "Creating child $i"
def child = addChildDevice("Child Button", "${device.deviceNetworkId}:${i}", device.hubId,
[completedSetup: true, label: getButtonName(i),
isComponent: true, componentName: "button$i", componentLabel: "Button ${i}"])

child.sendEvent(name: "supportedButtonValues", value: ["pushed"].encodeAsJSON(), displayed: false)
child.sendEvent(name: "numberOfButtons", value: 1, displayed: false)
child.sendEvent(name: "button", value: "pushed", data: [buttonNumber: 1], displayed: false)
}
}

def installed() {
def numberOfButtons = 4
state.ignoreNextButton3 = false

createChildButtonDevices(numberOfButtons)

sendEvent(name: "supportedButtonValues", value: ["pushed"].encodeAsJSON(), displayed: false)
sendEvent(name: "numberOfButtons", value: numberOfButtons, displayed: false)
numberOfButtons.times {
sendEvent(name: "button", value: "pushed", data: [buttonNumber: it+1], displayed: false)
}

// These devices don't report regularly so they should only go OFFLINE when Hub is OFFLINE
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "zigbee", scheme:"untracked"]), displayed: false)
}

def updated() {
if (childDevices && device.label != state.oldLabel) {
childDevices.each {
def newLabel = getButtonName(channelNumber(it.deviceNetworkId))
it.setLabel(newLabel)
}
state.oldLabel = device.label
}
}

def configure() {
log.debug "Configuring device ${device.getDataValue("model")}"

def cmds = zigbee.configureReporting(zigbee.POWER_CONFIGURATION_CLUSTER, 0x21, DataType.UINT8, 30, 21600, 0x01) +
zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x21) +
zigbee.addBinding(zigbee.ONOFF_CLUSTER) +
// This device doesn't report a binding to this group but will send all messages to this group ID
addHubToGroup(0x4003)


cmds
}

def parse(String description) {
log.debug "Parsing message from device: '$description'"
def event = zigbee.getEvent(description)
if (event) {
log.debug "Creating event: ${event}"
sendEvent(event)
} else {
if ((description?.startsWith("catchall:")) || (description?.startsWith("read attr -"))) {
def descMap = zigbee.parseDescriptionAsMap(description)
if (descMap.clusterInt == zigbee.POWER_CONFIGURATION_CLUSTER && descMap.attrInt == 0x0021) {
event = getBatteryEvent(zigbee.convertHexToInt(descMap.value))
} else if (descMap.clusterInt == zigbee.ONOFF_CLUSTER ||
descMap.clusterInt == zigbee.LEVEL_CONTROL_CLUSTER ||
descMap.clusterInt == zigbee.COLOR_CONTROL_CLUSTER) {
event = getButtonEvent(descMap)
}
}

def result = []
if (event) {
log.debug "Creating event: ${event}"
result = createEvent(event)
}

return result
}
}

private Map getBatteryEvent(value) {
def result = [:]
result.value = value / 2
result.name = 'battery'
result.descriptionText = "${device.displayName} battery was ${result.value}%"
return result
}

private sendButtonEvent(buttonNumber, buttonState) {
def child = childDevices?.find { channelNumber(it.deviceNetworkId) == buttonNumber }

if (child) {
def descriptionText = "$child.displayName was $buttonState" // TODO: Verify if this is needed, and if capability template already has it handled

child?.sendEvent([name: "button", value: buttonState, data: [buttonNumber: 1], descriptionText: descriptionText, isStateChange: true])
} else {
log.debug "Child device $buttonNumber not found!"
}
}

private Map getButtonEvent(Map descMap) {
def buttonState = ""
def buttonNumber = 0
Map result = [:]

// Button 1
if (descMap.clusterInt == zigbee.ONOFF_CLUSTER) {
buttonNumber = 1

// Button 2
} else if (descMap.clusterInt == zigbee.LEVEL_CONTROL_CLUSTER &&
(descMap.commandInt == 0x00 || descMap.commandInt == 0x01)) {
buttonNumber = 2

// Button 3
} else if (descMap.clusterInt == zigbee.COLOR_CONTROL_CLUSTER) {
if (descMap.commandInt == 0x0A || (descMap.commandInt == 0x4B && descMap.data[0] != "00")) {
if (state.ignoreNextButton3) {
// button 4 sends 2 cmds; one is a button 3 cmd. We want to ignore these specific cmds
state.ignoreNextButton3 = false
} else {
buttonNumber = 3
}
}

// Button 4
} else if (descMap.clusterInt == zigbee.LEVEL_CONTROL_CLUSTER &&
descMap.commandInt == 0x04) {
// remember to ignore the next button 3 message we get
state.ignoreNextButton3 = true
buttonNumber = 4
}


if (buttonNumber != 0) {
// Create and send component event
sendButtonEvent(buttonNumber, "pushed")
}
result
}

private List addHubToGroup(Integer groupAddr) {
["st cmd 0x0000 0x01 ${CLUSTER_GROUPS} 0x00 {${zigbee.swapEndianHex(zigbee.convertToHexString(groupAddr,4))} 00}",
"delay 200"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ metadata {
fingerprint profileId: "0010", inClusters: "0000 0003 0004 0005 0006 0008 0702 0B05", outClusters: "0019", manufacturer: "innr", model: "SP 120", deviceJoinName: "Innr Smart Plug"
fingerprint profileId: "0104", inClusters: "0000,0002,0003,0004,0005,0006,0009,0B04,0702", outClusters: "0019,000A,0003,0406", manufacturer: "Aurora", model: "SmartPlug51AU", deviceJoinName: "Aurora SmartPlug"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0702,0B04,0B05,FC03", outClusters: "0019", manufacturer: "CentraLite", model: "3210-L", deviceJoinName: "Iris Smart Plug"
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0004,0005,0006,0B04,0B05,0702", outClusters: "0003,000A,0B05,0019", manufacturer: " Sercomm Corp.", model: "SZ-ESW01-AU", deviceJoinName: "Sercomm Smart Power Plug"
}

// simulator metadata
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ metadata {
capability "Sensor"
capability "Battery"

attribute "status", "string"
attribute "door", "string"
}

simulator {
Expand All @@ -48,18 +46,12 @@ metadata {
}

tiles(scale: 2) {
multiAttributeTile(name:"status", type: "generic", width: 6, height: 4){
tileAttribute ("device.status", key: "PRIMARY_CONTROL") {
attributeState "closed", label:'${name}', icon:"st.doors.garage.garage-closed", backgroundColor:"#00A0DC", nextState:"opening"
attributeState "open", label:'${name}', icon:"st.doors.garage.garage-open", backgroundColor:"#e86d13", nextState:"closing"
attributeState "opening", label:'${name}', icon:"st.doors.garage.garage-opening", backgroundColor:"#e86d13"
attributeState "closing", label:'${name}', icon:"st.doors.garage.garage-closing", backgroundColor:"#00A0DC"
multiAttributeTile(name:"contact", type: "generic", width: 6, height: 4){
tileAttribute ("device.contact", key: "PRIMARY_CONTROL") {
attributeState "open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13"
attributeState "closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00a0dc"
}
}
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")
}
standardTile("acceleration", "device.acceleration", decoration: "flat", width: 2, height: 2) {
state("active", label:'${name}', icon:"st.motion.acceleration.active", backgroundColor:"#00A0DC")
state("inactive", label:'${name}', icon:"st.motion.acceleration.inactive", backgroundColor:"#ffffff")
Expand All @@ -74,8 +66,8 @@ metadata {
state "battery", label:'${currentValue}% battery', unit:""
}

main(["status", "contact", "acceleration"])
details(["status", "contact", "acceleration", "temperature", "3axis", "battery"])
main(["contact", "acceleration"])
details(["contact", "acceleration", "temperature", "3axis", "battery"])
}

preferences {
Expand Down Expand Up @@ -217,14 +209,10 @@ private List parseOrientationMessage(String description) {

if (absValueZ > 825) {
results << createEvent(name: "contact", value: "open", unit: "")
results << createEvent(name: "status", value: "open", unit: "")
results << createEvent(name: "door", value: "open", unit: "")
log.debug "STATUS: open"
}
else if (absValueZ < 100) {
results << createEvent(name: "contact", value: "closed", unit: "")
results << createEvent(name: "status", value: "closed", unit: "")
results << createEvent(name: "door", value: "closed", unit: "")
log.debug "STATUS: closed"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ metadata {
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3315-G", deviceJoinName: "Centralite Water Sensor"
fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500", outClusters: "0019", manufacturer: "SmartThings", model: "moisturev4", deviceJoinName: "Water Leak Sensor"
fingerprint inClusters: "0000,0001,0003,0020,0402,0500", outClusters: "0019", manufacturer: "Samjin", model: "water", deviceJoinName: "Water Leak Sensor"
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "Sercomm Corp.", model: "SZ-WTD03", deviceJoinName: "Sercomm Water Leak Detector"
}

simulator {
Expand Down
Loading

0 comments on commit 1e02b13

Please sign in to comment.