/**
* **************** Tuya Scene Knob Blind Controller ****************
*
* Usage:
* This app links a Tuya Scene Knob to a blind device
* The Scene Knob should be using @kkossev's Tuya Zigbee Scene Switch TS004F driver, in Scene Mode. Position Change Steps setting determines how much granularity
* the knob has for changing the blind position.
*
**/
definition (
name: "Tuya Scene Knob Blind Controller",
namespace: "Hubitat",
author: "cburgess",
description: "Controller for a Tuya Scene Knob to control a Window Shade Device",
category: "My Apps",
iconUrl: "",
iconX2Url: ""
)
preferences {
page name: "mainPage", title: "", install: true, uninstall: true
}
def mainPage() {
dynamicPage(name: "mainPage") {
section("App Name") {
label title: "Optionally assign a custom name for this app", required: false
}
section("Tuya Scene Knob") {
input (
name: "sceneKnob",
type: "capability.actuator",
title: "Select Tuya Scene Knob Device",
required: true,
multiple: false
)
}
section("Window Shade Device") {
input (
name: "blind",
type: "capability.windowShade",
title: "Select Window Shade Device",
required: true,
multiple: false
)
}
section("") {
input (
name: "positionChangeDuration",
type: "number",
title: "Milliseconds for position change per knob click",
required: true,
defaultValue: 400
)
}
section("") {
input (
name: "closedPosition",
type: "number",
title: "Postion when shade is closed",
required: true,
defaultValue: 20
)
}
section("") {
input (
name: "partialPosition",
type: "number",
title: "Postion when shade is half open",
required: true,
defaultValue: 60
)
}
section("") {
input (
name: "debugMode",
type: "bool",
title: "Enable logging",
required: true,
defaultValue: false
)
}
}
}
def installed() {
updated()
}
def updated() {
if (debugMode) runIn(1800,logsOff)
initialize()
}
def initialize() {
subscribe(sceneKnob, "pushed", knobPushedHandler)
subscribe(sceneKnob, "doubleTapped", knobDoubleTappedHandler)
subscribe(sceneKnob, "held", knobHeldHandler)
}
// on/off and increment level with push
def knobPushedHandler(evt) {
logDebug("knobPushedHandler(${evt.value}) called")
def pressed = (evt.value).toInteger()
if (pressed == 1) {
if (blind.currentValue("windowShade") == "closed") blind.open()
else if (blind.currentValue("windowShade") == "open") blind.close()
else if (blind.currentValue("windowShade") == "partially open" ) {
if (blind.currentValue("position").toInteger() < 60) {blind.open()} else {blind.close()}
}
}
if (pressed == 3) { // step open
blind.startPositionChange("open")
runInMillis(settings?.positionChangeDuration.toInteger(), stopPositionChange)
}
if (pressed == 2) { // step closed
blind.startPositionChange("close")
runInMillis(settings?.positionChangeDuration.toInteger(), stopPositionChange)
}
}
def stopPositionChange() {
blind.stopPositionChange()
}
// stop position change with double tap
def knobDoubleTappedHandler(evt) {
logDebug("knobDoubleTappedHandler(${evt.value}) called")
blind.stopPositionChange()
}
// Half Open when held
def knobHeldHandler(evt) {
logDebug("knobHeldHandler(${evt.value}) called")
blind.setPosition(settings?.partialPosition.toInteger())
}
def logDebug(txt){
try {
if (settings.debugMode) { log.debug("${app.label} - ${txt}") }
} catch(ex) {
log.error("bad debug message")
}
}
def logsOff(){
log.warn "debug logging disabled..."
device.updateSetting("debugMode",[value:"false",type:"bool"])
}