Permalink
Find file
7f4c859 Jan 17, 2017
411 lines (357 sloc) 14.9 KB
/**
* HomeSeer HS-WS100+
*
* Copyright 2016, 2017 DarwinsDen.com
*
* For button mappings, device parameter information and images, questions or to provide feedback on this device handler,
* please visit:
*
* darwinsden.com/homeseer100plus/
*
* 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.
*
* Author: Darwin@DarwinsDen.com
* Date: 2016-04-08
*
* Changelog:
*
* 1.01 (01/16/2017) - Corrected advertised number of buttons (8)
* 1.00 (01/14/2017) - Added button 7 (single tap up) and button 8 (single tap down). Added firmware version display.
* 0.12 (06/03/2016) - Added press type indicator to display last tap/hold press status
* 0.11 (05/28/2016) - Set numberOfButtons attribute for ease of use with CoRE and other SmartApps. Corrected physical/digital states.
* 0.10 (04/08/2016) - Initial 0.1 Beta
*
*
* Button Mappings:
*
* ACTION BUTTON# BUTTON ACTION
* Double-Tap Up 1 pressed
* Double-Tap Down 2 pressed
* Triple-Tap Up 3 pressed
* Triple-Tap Down 4 pressed
* Hold Up 5 pressed
* Hold Down 6 pressed
* Single-Tap Up 7 pressed
* Single-Tap Down 8 pressed
*
*/
metadata {
definition (name: "WS100+ Switch", namespace: "darwinsden", author: "darwin@darwinsden.com") {
capability "Actuator"
capability "Indicator"
capability "Switch"
capability "Button"
capability "Polling"
capability "Refresh"
capability "Sensor"
capability "Configuration"
command "tapUp2"
command "tapDown2"
command "tapUp3"
command "tapDown3"
command "holdUp"
command "holdDown"
fingerprint deviceId: "0x1001", inClusters: "0x5E, 0x86, 0x72, 0x5A, 0x85, 0x59, 0x73, 0x25, 0x27, 0x70, 0x2C, 0x2B, 0x5B, 0x7A", outClusters: "0x5B"
}
// simulator metadata
simulator {
status "on": "command: 2003, payload: FF"
status "off": "command: 2003, payload: 00"
// reply messages
reply "2001FF,delay 100,2502": "command: 2503, payload: FF"
reply "200100,delay 100,2502": "command: 2503, payload: 00"
}
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.Home.home30", backgroundColor: "#79b821"
attributeState "off", label: '${name}', action: "switch.on", icon: "st.Home.home30", backgroundColor: "#ffffff"
}
tileAttribute("device.status", key: "SECONDARY_CONTROL") {
attributeState("default", label:'${currentValue}', unit:"")
}
}
standardTile("tapUp2", "device.button", width: 2, height: 2, decoration: "flat") {
state "default", label: "Tap ▲▲", backgroundColor: "#ffffff", action: "tapUp2", icon: "st.Home.home30"
}
standardTile("tapDown2", "device.button", width: 2, height: 2, decoration: "flat") {
state "default", label: "Tap ▼▼", backgroundColor: "#ffffff", action: "tapDown2", icon: "st.Home.home30"
}
standardTile("tapUp3", "device.button", width: 2, height: 2, decoration: "flat") {
state "default", label: "Tap ▲▲▲", backgroundColor: "#ffffff", action: "tapUp3", icon: "st.Home.home30"
}
standardTile("tapDown3", "device.button", width: 2, height: 2, decoration: "flat") {
state "default", label: "Tap ▼▼▼", backgroundColor: "#ffffff", action: "tapDown3", icon: "st.Home.home30"
}
standardTile("holdUp", "device.button", width: 2, height: 2, decoration: "flat") {
state "default", label: "Hold ▲", backgroundColor: "#ffffff", action: "holdUp", icon: "st.Home.home30"
}
standardTile("holdDown", "device.button", width: 2, height: 2, decoration: "flat") {
state "default", label: "Hold ▼", backgroundColor: "#ffffff", action: "holdDown", icon: "st.Home.home30"
}
standardTile("indicator", "device.indicatorStatus", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "when off", action:"indicator.indicatorWhenOn", icon:"st.indicators.lit-when-off"
state "when on", action:"indicator.indicatorNever", icon:"st.indicators.lit-when-on"
state "never", action:"indicator.indicatorWhenOff", icon:"st.indicators.never-lit"
}
standardTile("refresh", "device.switch", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
}
valueTile("firmwareVersion", "device.firmwareVersion", width:2, height: 2, decoration: "flat", inactiveLabel: false) {
state "default", label: '${currentValue}'
}
main "switch"
details(["switch","tapUp2","tapUp3","holdUp","tapDown2","tapDown3","holdDown","indicator","firmwareVersion","refresh"])
}
}
def parse(String description) {
def result = null
def cmd = zwave.parse(description, [0x20: 1, 0x70: 1])
if (cmd) {
result = zwaveEvent(cmd)
}
if (!result){
log.debug "Parse returned ${result} for command ${cmd}"
}
else {
log.debug "Parse returned ${result}"
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
createEvent([name: "switch", value: cmd.value ? "on" : "off", type: "physical"])
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
createEvent([name: "switch", value: cmd.value ? "on" : "off", type: "physical"])
}
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
createEvent([name: "switch", value: cmd.value ? "on" : "off", type: "digital"])
}
def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
def value = "when off"
if (cmd.configurationValue[0] == 1) {value = "when on"}
if (cmd.configurationValue[0] == 2) {value = "never"}
createEvent([name: "indicatorStatus", value: value, display: false])
}
def zwaveEvent(physicalgraph.zwave.commands.hailv1.Hail cmd) {
createEvent([name: "hail", value: "hail", descriptionText: "Switch button was pressed", displayed: false])
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
log.debug "manufacturerId: ${cmd.manufacturerId}"
log.debug "manufacturerName: ${cmd.manufacturerName}"
state.manufacturer=cmd.manufacturerName
log.debug "productId: ${cmd.productId}"
log.debug "productTypeId: ${cmd.productTypeId}"
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
updateDataValue("MSR", msr)
setFirmwareVersion()
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
}
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
log.debug ("received Version Report")
log.debug "applicationVersion: ${cmd.applicationVersion}"
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
state.firmwareVersion=cmd.applicationVersion+'.'+cmd.applicationSubVersion
log.debug "zWaveLibraryType: ${cmd.zWaveLibraryType}"
log.debug "zWaveProtocolVersion: ${cmd.zWaveProtocolVersion}"
log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
setFirmwareVersion()
createEvent([descriptionText: "Firmware V"+state.firmwareVersion, isStateChange: false])
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in
log.debug (cmd)
createEvent([:])
}
def on() {
delayBetween([
zwave.basicV1.basicSet(value: 0xFF).format(),
zwave.switchBinaryV1.switchBinaryGet().format()
])
}
def off() {
delayBetween([
zwave.basicV1.basicSet(value: 0x00).format(),
zwave.switchBinaryV1.switchBinaryGet().format()
])
}
def poll() {
delayBetween([
zwave.switchBinaryV1.switchBinaryGet().format(),
zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
])
}
def setFirmwareVersion() {
def versionInfo = ''
if (state.manufacturer)
{
versionInfo=state.manufacturer+' '
}
if (state.firmwareVersion)
{
versionInfo=versionInfo+"Firmware V"+state.firmwareVersion
}
else
{
versionInfo=versionInfo+"Firmware unknown"
}
sendEvent(name: "firmwareVersion", value: versionInfo, isStateChange: true)
}
def refresh() {
configure()
}
def indicatorWhenOn() {
sendEvent(name: "indicatorStatus", value: "when on", display: false)
zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format()
}
def indicatorWhenOff() {
sendEvent(name: "indicatorStatus", value: "when off", display: false)
zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format()
}
def indicatorNever() {
sendEvent(name: "indicatorStatus", value: "never", display: false)
zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 3, size: 1).format()
}
def invertSwitch(invert=true) {
if (invert) {
zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 4, size: 1).format()
}
else {
zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 4, size: 1).format()
}
}
def zwaveEvent(physicalgraph.zwave.commands.centralscenev1.CentralSceneNotification cmd) {
log.debug("sceneNumber: ${cmd.sceneNumber} keyAttributes: ${cmd.keyAttributes}")
def result = []
switch (cmd.sceneNumber) {
case 1:
// Up
switch (cmd.keyAttributes) {
case 0:
// Press Once
result=createEvent([name: "switch", value: "on", type: "physical"])
sendEvent(name: "status" , value: "Tap ▲")
sendEvent(name: "button" , value: "pushed", data: [buttonNumber: "7"], descriptionText: "$device.displayName Tap-Up-1 (button 7) pressed",
isStateChange: true, type: "$buttonType")
break
case 1:
result=createEvent([name: "switch", value: "on", type: "physical"])
break
case 2:
// Hold
result += createEvent(holdUpResponse("physical"))
result += response("delay 100")
result += createEvent([name: "switch", value: "on", type: "physical"])
break
case 3:
// 2 Times
result=createEvent(tapUp2Response("physical"))
break
case 4:
// 3 Three times
result=createEvent(tapUp3Response("physical"))
break
default:
log.debug ("unexpected up press keyAttribute: $cmd.keyAttributes")
}
break
case 2:
// Down
switch (cmd.keyAttributes) {
case 0:
// Press Once
result=createEvent([name: "switch", value: "off", type: "physical"])
sendEvent(name: "status" , value: "Tap ▼")
sendEvent(name: "button" , value: "pushed", data: [buttonNumber: "8"], descriptionText: "$device.displayName Tap-Down-1 (button 8) pressed",
isStateChange: true, type: "$buttonType")
break
case 1:
result=createEvent([name: "switch", value: "off", type: "physical"])
break
case 2:
// Hold
result += createEvent(holdDownResponse("physical"))
result += response("delay 100")
result += createEvent([name: "switch", value: "off", type: "physical"])
break
case 3:
// 2 Times
result=createEvent(tapDown2Response("physical"))
break
case 4:
// 3 Times
result=createEvent(tapDown3Response("physical"))
break
default:
log.debug ("unexpected down press keyAttribute: $cmd.keyAttributes")
}
break
default:
// unexpected case
log.debug ("unexpected scene: $cmd.sceneNumber")
}
return result
}
def tapUp2Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▲▲")
[name: "button", value: "pushed", data: [buttonNumber: "1"], descriptionText: "$device.displayName Tap-Up-2 (button 1) pressed",
isStateChange: true, type: "$buttonType"]
}
def tapDown2Response(String buttontype) {
sendEvent(name: "status" , value: "Tap ▼▼")
[name: "button", value: "pushed", data: [buttonNumber: "2"], descriptionText: "$device.displayName Tap-Down-2 (button 2) pressed",
isStateChange: true, type: "$buttonType"]
}
def tapUp3Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▲▲▲")
[name: "button", value: "pushed", data: [buttonNumber: "3"], descriptionText: "$device.displayName Tap-Up-3 (button 3) pressed",
isStateChange: true, type: "$buttonType"]
}
def tapDown3Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▼▼▼")
[name: "button", value: "pushed", data: [buttonNumber: "4"], descriptionText: "$device.displayName Tap-Down-3 (button 4) pressed",
isStateChange: true, type: "$buttonType"]
}
def holdUpResponse(String buttonType) {
sendEvent(name: "status" , value: "Hold ▲")
[name: "button", value: "pushed", data: [buttonNumber: "5"], descriptionText: "$device.displayName Hold-Up (button 5) pressed",
isStateChange: true, type: "$buttonType"]
}
def holdDownResponse(String buttonType) {
sendEvent(name: "status" , value: "Hold ▼")
[name: "button", value: "pushed", data: [buttonNumber: "6"], descriptionText: "$device.displayName Hold-Down (button 6) pressed",
isStateChange: true, type: "$buttonType"]
}
def tapUp2() {
sendEvent(tapUp2Response("digital"))
}
def tapDown2() {
sendEvent(tapDown2Response("digital"))
}
def tapUp3() {
sendEvent(tapUp3Response("digital"))
}
def tapDown3() {
sendEvent(tapDown3Response("digital"))
}
def holdUp() {
sendEvent(holdUpResponse("digital"))
}
def holdDown() {
sendEvent(holdDownResponse("digital"))
}
def configure() {
sendEvent(name: "numberOfButtons", value: 8, displayed: false)
def commands = []
commands << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
commands << zwave.versionV1.versionGet().format()
commands << zwave.switchBinaryV1.switchBinaryGet().format()
delayBetween(commands,500)
}