Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update hue-dimmer-switch-zha.groovy #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Update hue-dimmer-switch-zha.groovy
Formatted white space for easier reading and debug.

Changed default button return from 'pushed' to 'in' as code was returning 'pushed' before every 'held' event. Now button returns 'in' until it is released and a 'pushed' or 'held' event is returned.
StevenJonSmith authored May 23, 2018
commit 8c423e710c668bb8c17ba28f30daff0d38618e80
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
/**
* Hue Dimmer Switch
*
* Copyright 2016 Stephen McLaughlin
*
* 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.
*
*/
* Hue Dimmer Switch
*
* Copyright 2016 Stephen McLaughlin
*
* 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: "Hue Dimmer Switch (ZHA)", namespace: "digitalgecko", author: "Stephen McLaughlin") {
capability "Configuration"
capability "Battery"
capability "Refresh"
capability "Button"
capability "Button"
capability "Sensor"
fingerprint profileId: "0104", endpointId: "02", application:"02", outClusters: "0019", inClusters: "0000,0001,0003,000F,FC00", manufacturer: "Philips", model: "RWL020", deviceJoinName: "Hue Dimmer Switch (ZHA)"

fingerprint profileId: "0104", endpointId: "02", application:"02", outClusters: "0019", inClusters: "0000,0001,0003,000F,FC00", manufacturer: "Philips", model: "RWL020", deviceJoinName: "Hue Dimmer Switch (ZHA)"

attribute "lastAction", "string"
}
@@ -31,70 +30,66 @@ metadata {
// TODO: define status and reply messages here
}

tiles(scale: 2) {
tiles(scale: 2) {
// TODO: define your main and details tiles here
multiAttributeTile(name:"lastAction", type: "generic", width: 6, height: 4){
tileAttribute ("device.battery", key: "SECONDARY_CONTROL") {
multiAttributeTile(name:"lastAction", type: "generic", width: 6, height: 4){
tileAttribute ("device.battery", key: "SECONDARY_CONTROL") {
attributeState "battery", label:'${currentValue}% battery',icon:"st.Outdoor.outdoor3", unit:"", backgroundColors:[
[value: 30, color: "#ff0000"],
[value: 40, color: "#760000"],
[value: 40, color: "#760000"],
[value: 60, color: "#ff9900"],
[value: 80, color: "#007600"]
]
}
tileAttribute ("device.lastAction", key: "PRIMARY_CONTROL") {
tileAttribute ("device.lastAction", key: "PRIMARY_CONTROL") {
attributeState "active", label:'${currentValue}', icon:"st.Home.home30"
}

}
// valueTile("lastAction", "device.lastAction", width: 6, height: 2) {
// state("lastAction", label:'${currentValue}')
// }

// valueTile("lastAction", "device.lastAction", width: 6, height: 2) {
// state("lastAction", label:'${currentValue}')
// }

valueTile("battery2", "device.battery", decoration: "flat", inactiveLabel: false, width: 5, height: 1) {
valueTile("battery2", "device.battery", decoration: "flat", inactiveLabel: false, width: 5, height: 1) {
state("battery", label:'${currentValue}% battery', unit:"")
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 1, height: 1) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
// standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
// state "default", label:"bind", action:"configure"
// }

standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 1, height: 1) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}

// standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
// state "default", label:"bind", action:"configure"
// }
}

main "lastAction"
details(["lastAction","battery2","refresh","configure"])

main "lastAction"
details(["lastAction","battery2","refresh","configure"])
}

// parse events into attributes
def parse(String description) {
def msg = zigbee.parse(description)
//log.warn msg
/// Actual code down here
Map map = [:]
if (description?.startsWith('catchall:')) {
def msg = zigbee.parse(description)

//log.warn msg
/// Actual code down here
Map map = [:]
if (description?.startsWith('catchall:')) {
map = parseCatchAllMessage(description)
}



def result = map ? createEvent(map) : null

if (description?.startsWith('enroll request')) {

def result = map ? createEvent(map) : null

if (description?.startsWith('enroll request')) {
List cmds = enrollResponse()
result = cmds?.collect { new physicalgraph.device.HubAction(it) }
}
else if (description?.startsWith('read attr -')) {
result = parseReportAttributeMessage(description).each { createEvent(it) }
}

return result

return result
// TODO: handle 'numberOfButtons' attribute

}
/*
parseReportAttributeMessage
@@ -107,9 +102,9 @@ private List parseReportAttributeMessage(String description) {

List result = []

// Battery
// Battery
if (descMap.cluster == "0001" && descMap.attrId == "0020") {
// log.warn descMap
// log.warn descMap
result << getBatteryResult(Integer.parseInt(descMap.value, 16))
}

@@ -136,9 +131,8 @@ private Map getBatteryResult(rawValue) {
value: '--',
translatable: true
]

def volts = rawValue / 10

if (rawValue == 0 || rawValue == 255) {}
else {
if (volts > 3.5) {
@@ -148,7 +142,7 @@ private Map getBatteryResult(rawValue) {
if (device.getDataValue("manufacturer") == "SmartThings") {
volts = rawValue // For the batteryMap to work the key needs to be an int
def batteryMap = [28:100, 27:100, 26:100, 25:90, 24:90, 23:70,
22:70, 21:50, 20:50, 19:30, 18:30, 17:15, 16:1, 15:0]
22:70, 21:50, 20:50, 19:30, 18:30, 17:15, 16:1, 15:0]
def minVolts = 15
def maxVolts = 28

@@ -168,43 +162,42 @@ private Map getBatteryResult(rawValue) {
def pct = (volts - minVolts) / (maxVolts - minVolts)
def roundedPct = Math.round(pct * 100)
if (roundedPct <= 0)
roundedPct = 1
roundedPct = 1
result.value = Math.min(100, roundedPct)
result.descriptionText = "{{ device.displayName }} battery was {{ value }}%"
}
}
}

return result
}

private Map getButtonResult(rawValue) {

def result = [
name: 'button',
value: '--',
value: 'in',
translatable: true
]
def button = rawValue[0]
def buttonState = rawValue[4]
def buttonHoldTime = rawValue[6]
def hueStatus = (button as String) + "00" + (buttonState as String) // This is the state in the HUE api
log.error "Button: " + button + " Hue Code: " + hueStatus + " Hold Time: " + buttonHoldTime
result.data = ['buttonNumber': button]
result.value = 'pushed'
if ( buttonState == 2 ) {
result = createEvent(name: "button", value: "pushed", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was pushed", isStateChange: true)
sendEvent(name: "lastAction", value: button + " pushed")

}
if ( buttonState == 3 ) {
result = createEvent(name: "button", value: "held", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was held", isStateChange: true)
sendEvent(name: "lastAction", value: button + " held")
}
return result
def button = rawValue[0]
def buttonState = rawValue[4]
def buttonHoldTime = rawValue[6]
def hueStatus = (button as String) + "00" + (buttonState as String) // This is the state in the HUE api
log.error "Button: " + button + " Hue Code: " + hueStatus + " Hold Time: " + buttonHoldTime
result.data = ['buttonNumber': button]

if ( buttonState == 2 ) {
result = createEvent(name: "button", value: "pushed", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was pushed", isStateChange: true)
sendEvent(name: "lastAction", value: button + " pushed")
}

if ( buttonState == 3 ) {
result = createEvent(name: "button", value: "held", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was held", isStateChange: true)
sendEvent(name: "lastAction", value: button + " held")
}
return result
}

/*
@@ -220,84 +213,76 @@ private Map parseCatchAllMessage(String description) {
if (cluster.command != 0x07) {
resultMap = getBatteryResult(cluster.data.last())
}
break

break
case 0xFC00:
if ( cluster.command == 0x00 ) {
if ( cluster.command == 0x00 ) {
resultMap = getButtonResult( cluster.data );
}
break

}
}
break
}
}

return resultMap
}


def refresh() {
//log.debug "Refresh"

def refreshCmds = []

refreshCmds += "st rattr 0x${device.deviceNetworkId} 0x02 0x0001 0x0020"; // WORKS! - Fetches battery from 0x02


// configCmds += zigbee.configureReporting(0x406,0x0000, 0x18, 30, 600, null) // motion // confirmed
// log.debug "Refresh"

//refreshCmds += zigbee.configureReporting(0x000F, 0x0055, 0x10, 30, 30, null);
// refreshCmds += "zdo bind 0xDAD6 0x01 0x02 0x000F {00178801103317AA} {}"
// refreshCmds += "delay 2000"
// refreshCmds += "st cr 0xDAD6 0x02 0x000F 0x0055 0x10 0x001E 0x001E {}"
// refreshCmds += "delay 2000"

//refreshCmds += zigbee.configureReporting(0x000F, 0x006F, 0x18, 0x30, 0x30);
// refreshCmds += "zdo bind 0x${device.deviceNetworkId} 0x02 0x02 0xFC00 {${device.zigbeeId}} {}"
// refreshCmds += "delay 2000"
// refreshCmds += "st cr 0x${device.deviceNetworkId} 0x02 0xFC00 0x0000 0x18 0x001E 0x001E {}"
// refreshCmds += "delay 2000"
//log.debug refreshCmds

return refreshCmds
def refreshCmds = []
refreshCmds += "st rattr 0x${device.deviceNetworkId} 0x02 0x0001 0x0020"; // WORKS! - Fetches battery from 0x02

// configCmds += zigbee.configureReporting(0x406,0x0000, 0x18, 30, 600, null) // motion // confirmed

// refreshCmds += zigbee.configureReporting(0x000F, 0x0055, 0x10, 30, 30, null);
// refreshCmds += "zdo bind 0xDAD6 0x01 0x02 0x000F {00178801103317AA} {}"
// refreshCmds += "delay 2000"
// refreshCmds += "st cr 0xDAD6 0x02 0x000F 0x0055 0x10 0x001E 0x001E {}"
// refreshCmds += "delay 2000"

// refreshCmds += zigbee.configureReporting(0x000F, 0x006F, 0x18, 0x30, 0x30);
// refreshCmds += "zdo bind 0x${device.deviceNetworkId} 0x02 0x02 0xFC00 {${device.zigbeeId}} {}"
// refreshCmds += "delay 2000"
// refreshCmds += "st cr 0x${device.deviceNetworkId} 0x02 0xFC00 0x0000 0x18 0x001E 0x001E {}"
// refreshCmds += "delay 2000"
// log.debug refreshCmds

return refreshCmds
}

def configure() {
// String zigbeeId = swapEndianHex(device.hub.zigbeeId)
//log.debug "Configiring Reporting and Bindings."
def configCmds = []

// Configure Button Count
sendEvent(name: "numberOfButtons", value: 4, displayed: false)
// String zigbeeId = swapEndianHex(device.hub.zigbeeId)
// log.debug "Configiring Reporting and Bindings."
def configCmds = []

// Monitor Buttons
//TODO: This could be zigbee.configureReporting(0xFC00, 0x0000, 0x18, 0x001e, 0x001e); but no idea how to point it at a different endpoint
// Configure Button Count
sendEvent(name: "numberOfButtons", value: 4, displayed: false)

// Monitor Buttons
// TODO: This could be zigbee.configureReporting(0xFC00, 0x0000, 0x18, 0x001e, 0x001e); but no idea how to point it at a different endpoint
configCmds += "zdo bind 0x${device.deviceNetworkId} 0x02 0x02 0xFC00 {${device.zigbeeId}} {}"
configCmds += "delay 2000"
configCmds += "st cr 0x${device.deviceNetworkId} 0x02 0xFC00 0x0000 0x18 0x001E 0x001E {}"
configCmds += "delay 2000"
configCmds += "delay 2000"
configCmds += "st cr 0x${device.deviceNetworkId} 0x02 0xFC00 0x0000 0x18 0x001E 0x001E {}"
configCmds += "delay 2000"

// Monitor Battery
//TODO: This could be zigbee.batteryConfig(); but no idea how to point it at a different endpoint
// Monitor Battery
// TODO: This could be zigbee.batteryConfig(); but no idea how to point it at a different endpoint
configCmds += "zdo bind 0x${device.deviceNetworkId} 0x02 0x02 0x0001 {${device.zigbeeId}} {}"
configCmds += "delay 2000"
configCmds += "st cr 0x${device.deviceNetworkId} 0x02 0x0001 0x0020 0x20 0x001E 0x0258 {}"
// configCmds += "st cr 0x${device.deviceNetworkId} 0x02 0x0001 0x0020 0x20 0x001E 0x001e {}"

configCmds += "delay 2000"

return configCmds + refresh()
configCmds += "delay 2000"
configCmds += "st cr 0x${device.deviceNetworkId} 0x02 0x0001 0x0020 0x20 0x001E 0x0258 {}"
// configCmds += "st cr 0x${device.deviceNetworkId} 0x02 0x0001 0x0020 0x20 0x001E 0x001e {}"

configCmds += "delay 2000"

return configCmds + refresh()
}

def configureHealthCheck() {
Integer hcIntervalMinutes = 12
refresh()
sendEvent(name: "checkInterval", value: hcIntervalMinutes * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
Integer hcIntervalMinutes = 12
refresh()
sendEvent(name: "checkInterval", value: hcIntervalMinutes * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
}

def updated() {
// log.debug "in updated()"
configureHealthCheck()
}
// log.debug "in updated()"

configureHealthCheck()
}