Permalink
Cannot retrieve contributors at this time
/** | |
* 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.04 (08/13/2020) - Merge pull request from mikerossman for updates to better support new SmartThings app | |
* 1.03 (11/14/2017) - Turn off firmware event log, correct physical button setting for some presses, remove 100ms delay in instant status | |
* 1.02 (06/25/2017) - Pulled in @stephack's changes to include button 7/8 events when triggered remotely | |
* 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 mfr: "000C", prod: "4447", model: "3033" | |
// 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 Up x2", backgroundColor: "#ffffff", action: "tapUp2", icon: "st.Home.home30" | |
} | |
standardTile("tapDown2", "device.button", width: 2, height: 2, decoration: "flat") { | |
state "default", label: "Tap Down x2", backgroundColor: "#ffffff", action: "tapDown2", icon: "st.Home.home30" | |
} | |
standardTile("tapUp3", "device.button", width: 2, height: 2, decoration: "flat") { | |
state "default", label: "Tap Up x3", backgroundColor: "#ffffff", action: "tapUp3", icon: "st.Home.home30" | |
} | |
standardTile("tapDown3", "device.button", width: 2, height: 2, decoration: "flat") { | |
state "default", label: "Tap Down x3", backgroundColor: "#ffffff", action: "tapDown3", icon: "st.Home.home30" | |
} | |
standardTile("holdUp", "device.button", width: 2, height: 2, decoration: "flat") { | |
state "default", label: "Hold Up", backgroundColor: "#ffffff", action: "holdUp", icon: "st.Home.home30" | |
} | |
standardTile("holdDown", "device.button", width: 2, height: 2, decoration: "flat") { | |
state "default", label: "Hold Down", 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() { | |
sendEvent(tapUp1Response("digital")) | |
delayBetween([ | |
zwave.basicV1.basicSet(value: 0xFF).format(), | |
zwave.switchBinaryV1.switchBinaryGet().format() | |
]) | |
} | |
def off() { | |
sendEvent(tapDown1Response("digital")) | |
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, displayed: false) | |
} | |
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(tapUp1Response("physical")) | |
result += createEvent([name: "switch", value: "on", type: "physical"]) | |
break | |
case 1: | |
result=createEvent([name: "switch", value: "on", type: "physical"]) | |
break | |
case 2: | |
// Hold | |
result += createEvent(holdUpResponse("physical")) | |
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(tapDown1Response("physical")) | |
result += createEvent([name: "switch", value: "off", type: "physical"]) | |
break | |
case 1: | |
result=createEvent([name: "switch", value: "off", type: "physical"]) | |
break | |
case 2: | |
// Hold | |
result += createEvent(holdDownResponse("physical")) | |
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 tapUp1Response(String buttonType) { | |
sendEvent(name: "status" , value: "Tap Up") | |
[name: "button", value: "pushed", data: [buttonNumber: "7"], descriptionText: "$device.displayName Tap-Up-1 (button 7) pressed", | |
isStateChange: true, type: "$buttonType"] | |
} | |
def tapDown1Response(String buttonType) { | |
sendEvent(name: "status" , value: "Tap Down") | |
[name: "button", value: "pushed", data: [buttonNumber: "8"], descriptionText: "$device.displayName Tap-Down-1 (button 8) pressed", | |
isStateChange: true, type: "$buttonType"] | |
} | |
def tapUp2Response(String buttonType) { | |
sendEvent(name: "status" , value: "Tap Up x2") | |
[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 Down x2") | |
[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 Up x3") | |
[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 Down x3") | |
[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 Up") | |
[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 Down") | |
[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")) | |
} | |
private getSupportedButtonValues() { | |
def values = ["pushed", "held"] | |
log.debug ("getSupportedButtonValues() called") | |
return values | |
} | |
def configure() { | |
sendEvent(name: "numberOfButtons", value: 8, displayed: false) | |
sendEvent(name: "supportedButtonValues", value: supportedButtonValues.encodeAsJSON(), displayed: false) | |
def commands = [] | |
commands << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format() | |
commands << zwave.versionV1.versionGet().format() | |
commands << zwave.switchBinaryV1.switchBinaryGet().format() | |
delayBetween(commands,500) | |
} |