Device Handler
/*
* Custom Device type for ATSMART Z6 Triple Switch Controller http://www.atsmart.net/index.php?s=/Home/index/atsmart_switch
*
* Copyright 2017 Andy Chan
*
* 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: "ATSMART Z6 Triple Switch Controller", namespace: "simic", author: "simics@gmail.com") {
capability "Refresh"
capability "Polling"
capability "Sensor"
capability "Configuration"
capability "Switch"
capability "Actuator"
command "on2"
command "off2"
command "on3"
command "off3"
attribute "switch2","ENUM", ["on","off"]
attribute "switch3","ENUM", ["on","off"]
attribute "switchstate","ENUM",["on","off"]
//fingerprint profileId: "0104", inClusters: "0000", outClusters: "000D,0006"
//fingerprint inClusters: "0000 0001 0003 0004 0005 0006", endpointId: "01", deviceId: "0100", profileId: "0104"
}
// simulator metadata
simulator {
}
// UI tile definitions
tiles {
standardTile("switch1", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "off", label: '${name}', action: "Switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
state "on", label: '${name}', action: "Switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
}
standardTile("switch2", "device.switch2", width: 2, height: 2, canChangeIcon: true) {
state "off", label: '${name}', action: "on2", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
state "on", label: '${name}', action: "off2", icon: "st.switches.switch.on", backgroundColor: "#79b821"
}
standardTile("switch3", "device.switch3", width: 2, height: 2, canChangeIcon: true) {
state "off", label: '${name}', action: "on3", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
state "on", label: '${name}', action: "off3", icon: "st.switches.switch.on", backgroundColor: "#79b821"
}
standardTile("switchstate", "device.switchstate", width: 2, height: 2, canChangeIcon: true) {
state "off", label: '${name}' , icon: "st.switches.switch.off", backgroundColor: "#ffffff"
state "on", label: '${name}', icon: "st.switches.switch.on", backgroundColor: "#79b821"
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat") {
state "default", action:"refresh.refresh", icon:"st.secondary.refresh"
}
main (["switch1", "switch2", "switch3", "switchstate"])
details (["switch1", "switch2", "switch3", "switchstate", "refresh"])
}
}
// Parse incoming device messages to generate events
def parse(String description) {
log.debug "Parse description $description"
def name = null
def value = null
if (description?.startsWith("catchall: 0104 0006 01")) {
log.debug "On/Off command received from EP 1"
if (description?.endsWith(" 01 0140 00 6052 00 00 0000 01 01 0000001000")){
name = "switch"
value = "off"}
else if (description?.endsWith(" 01 0140 00 6052 00 00 0000 01 01 0000001001")){
name = "switch"
value = "on"}
}
else if (description?.startsWith("catchall: 0104 0006 02")) {
log.debug "On/Off command received from EP 2"
if (description?.endsWith(" 01 0140 00 6052 00 00 0000 01 01 0000001000")){
name = "switch2"
value = "off"}
else if (description?.endsWith(" 01 0140 00 6052 00 00 0000 01 01 0000001001")){
name = "switch2"
value = "on"}
}
else if (description?.startsWith("catchall: 0104 0006 03")) {
log.debug "On/Off command received from EP 3"
if (description?.endsWith(" 01 0140 00 6052 00 00 0000 01 01 0000001000")){
name = "switch3"
value = "off"}
else if (description?.endsWith(" 01 0140 00 6052 00 00 0000 01 01 0000001001")){
name = "switch3"
value = "on"}
}
else if (description?.startsWith("on/off")) {
log.debug "Prepare to kick refresh thru companion smartapp"
name = "switchstate"
value = "off"
}
def result = createEvent(name: name, value: value)
log.debug "Parse returned ${result?.descriptionText}"
return result
}
// Commands to device
def on() {
log.debug "Relay 1 on()"
sendEvent(name: "switch", value: "on")
"st cmd 0x${device.deviceNetworkId} 0x01 0x0006 0x1 {}"
}
def off() {
log.debug "Relay 1 off()"
sendEvent(name: "switch", value: "off")
"st cmd 0x${device.deviceNetworkId} 0x01 0x0006 0x0 {}"
}
def on2() {
log.debug "Relay 2 on()"
sendEvent(name: "switch2", value: "on")
"st cmd 0x${device.deviceNetworkId} 0x02 0x0006 0x1 {}"
}
def off2() {
log.debug "Relay 2 off()"
sendEvent(name: "switch2", value: "off")
"st cmd 0x${device.deviceNetworkId} 0x02 0x0006 0x0 {}"
}
def on3() {
log.debug "Relay 3 on()"
sendEvent(name: "switch3", value: "on")
"st cmd 0x${device.deviceNetworkId} 0x03 0x0006 0x1 {}"
}
def off3() {
log.debug "Relay 3 off()"
sendEvent(name: "switch3", value: "off")
"st cmd 0x${device.deviceNetworkId} 0x03 0x0006 0x0 {}"
}
def poll(){
log.debug "Poll is calling refresh"
refresh()
}
def refresh() {
log.debug "sending refresh command and reset switchstate"
sendEvent(name: "switchstate", value: "on")
def cmd = []
cmd << "st rattr 0x${device.deviceNetworkId} 0x01 0x0006 0x0000" // Read on / off value at End point 0x01
cmd << "delay 150"
cmd << "st rattr 0x${device.deviceNetworkId} 0x02 0x0006 0x0000" // Read on / off value at End point 0x02
cmd << "delay 250"
cmd << "st rattr 0x${device.deviceNetworkId} 0x03 0x0006 0x0000" // Read on / off value at End point 0x03
cmd << "delay 350"
cmd
}
def configure() {
log.debug "Binding SEP 0x01 DEP 0x01 Cluster 0x0006 On/Off cluster to hub"
def configCmds = [
"zdo bind 0x${device.deviceNetworkId} 0x01 0x01 0x0006 {${device.zigbeeId}} {}", "delay 500",
"zdo bind 0x${device.deviceNetworkId} 0x02 0x01 0x0006 {${device.zigbeeId}} {}", "delay 500",
"zdo bind 0x${device.deviceNetworkId} 0x03 0x01 0x0006 {${device.zigbeeId}} {}", "delay 1500",
]
log.info "Sending ZigBee Bind commands to 3 Button Switch"
return configCmds
}
SmartApp
/**
* ATSMART Switch Binder
* This app allows you to bind 2 Virtual On/Off Tiles to the 2 switchable outlets.
* I left out the first switch as it can be called from the actual DH
* I will also track the status of switchstate attribute and force a refresh switch state refresh when u physically
* press the buttons on the switch
* Author: Andy Chan
* Date: 22/02/2017
*/
// Automatically generated. Make future change here.
definition(
name: "ATSMART Switch Binder 1.0",
namespace: "",
author: "simics@gmail.com",
description: "This app allows you to bind 2 Virtual On/Off Tiles to the 2nd and 3rd switchable outlets on ATSMART.",
category: "Convenience",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience%402x.png")
preferences {
section("Which ATSMART Switch is used?"){
input "strip", "capability.switch"
}
section("Select a Virtual Switch to bind to Outlet 2"){
input "switch2", "capability.Switch"
}
section("Select a Virtual Switch to bind to Outlet 3"){
input "switch3", "capability.Switch"
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
// for force refresh of switch state when physical pressed
subscribe(strip, "switchstate.off", switchRefreshHandler)
//for update virtual switch when real DH endpoint state is changed
subscribe(strip, "switch2.on", MainSwitchOnTwoHandler)
subscribe(strip, "switch2.off", MainSwitchOffTwoHandler)
subscribe(strip, "switch3.on", MainSwitchOnThreeHandler)
subscribe(strip, "switch3.off", MainSwitchOffThreeHandler)
//for update real DH endpoint when virtual switch is changed
subscribe(switch2, "switch.on", switchOnTwoHandler)
subscribe(switch2, "switch.off", switchOffTwoHandler)
subscribe(switch3, "switch.off", switchOffThreeHandler)
subscribe(switch3, "switch.on", switchOnThreeHandler)
}
def updated(settings) {
log.debug "Updated with settings: ${settings}"
unsubscribe()
// for force refresh of switch state when physical pressed
subscribe(strip, "switchstate.off", switchRefreshHandler)
//for update virtual switch when real DH endpoint state is changed
subscribe(strip, "switch2.on", MainSwitchOnTwoHandler)
subscribe(strip, "switch2.off", MainSwitchOffTwoHandler)
subscribe(strip, "switch3.on", MainSwitchOnThreeHandler)
subscribe(strip, "switch3.off", MainSwitchOffThreeHandler)
//for update real DH endpoint when virtual switch is changed
subscribe(switch2, "switch.on", switchOnTwoHandler)
subscribe(switch2, "switch.off", switchOffTwoHandler)
subscribe(switch3, "switch.off", switchOffThreeHandler)
subscribe(switch3, "switch.on", switchOnThreeHandler)
}
def switchRefreshHandler(evt) {
log.debug "switch refresh"
strip.refresh()
}
def MainSwitchOnTwoHandler(evt) {
log.debug "switch on"
switch2.on()
}
def MainSwitchOffTwoHandler(evt) {
log.debug "switch off"
switch2.off()
}
def MainSwitchOnThreeHandler(evt) {
log.debug "switch on"
switch3.on()
}
def MainSwitchOffThreeHandler(evt) {
log.debug "switch off"
switch3.off()
}
def switchOnTwoHandler(evt) {
log.debug "switch on2"
strip.on2()
}
def switchOnThreeHandler(evt) {
log.debug "switch on3"
strip.on3()
}
def switchOffTwoHandler(evt) {
log.debug "switch off2"
strip.off2()
}
def switchOffThreeHandler(evt) {
log.debug "switch off3"
strip.off3()
}