/** * **************** Dual Window Curtains Parent App **************** * * Usage: * Controller for one virtual window shade device to control two curtains on one window **/ definition ( name: "Dual Window Curtains Parent App", namespace: "Hubitat", author: "Burgess", description: "Controller for one virtual window shade device to control two curtains on one window", 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("Left Curtain Device") { input ( name: "leftShade", type: "capability.windowShade", title: "Select Left Windowshade Device", required: true, multiple: false, submitOnChange: true ) } section("Right Curtain Device") { input ( name: "rightShade", type: "capability.windowShade", title: "Select Right Windowshade Device", required: true, multiple: false, submitOnChange: true ) } section("") { input ( name: "debugMode", type: "bool", title: "Enable logging", required: true, defaultValue: false ) } } } def installed() { updated() } def updated() { unsubscribe() if (!curtainDevice) {setCurtainDevice()} initialize() } def initialize() { subscribe(leftShade, leftShadeHandler) subscribe(rightShade, rightShadeHandler) } def leftShadeHandler(evt) { logDebug("leftShadeHandler called with ${evt.name} and ${evt.value}") if (evt.name == "position" || evt.name == "level" || evt.name == "battery") { updateDriver(evt.name, evt.value) if (evt.name == "position") updateDriver("positionLeft", evt.value) if (evt.name == "battery") {updateBattery("left", evt.value.toInteger())} } else { // if(rightShade.currentValue(evt.name) == evt.value) { pauseExecution(50) updateDriver(evt.name, evt.value) // update device when attribute value of both shades mataches } } def rightShadeHandler(evt) { logDebug("rightShadeHandler called with ${evt.name} and ${evt.value}") if (evt.name == "position" || evt.name == "level") { updateDriver(evt.name, evt.value) if (evt.name == "position") updateDriver("positionRight", evt.value) if (evt.name == "battery") {updateBattery("right", evt.value.toInteger())} } else {//if (leftShade.currentValue(evt.name) == evt.value) { pauseExecution(50) updateDriver(evt.name, evt.value) } } def updateBattery(side,value) { def left def right if (side == "left") { left = value right = rightShade.currentValue("battery").toInteger() updateDriver("batteryLeft", left) } if (side == "right") { right = value left = leftShade.currentValue("battery").toInteger() updateDriver("batteryRight", right) } def battery = Math.round((left.toFloat() + right.toFloat()) / 2.0) updateDriver("battery", battery) } def updateDriver(name, value) { logDebug("updateDriver called with ${name} and ${value}") if (curtainDevice.currentValue(name) != value) { curtainDevice.eventSend(name, value) } } def setCurtainDevice() { logDebug("settingCurtainDevice") if (!curtainDevice) { def ID = createCurtainDevice() app.updateSetting("curtainDevice",[value:getChildDevice(ID),type:"capability.actuator"]) } } def createCurtainDevice() { logDebug("createCurtainDevice() called") def deviceNetworkId = "CD_${app.id}_${new Date().time}" try { def curtainDevice = addChildDevice("Hubitat", "Dual Window Curtains Device", deviceNetworkId, null, [name: "Dual Window Curtain Device",label: "Curtains", isComponent: false]) logDebug("Created curtain device in 'Hubitat' using driver 'Dual Window Curtains Device' (DNI: ${deviceNetworkId})") state.curtainDevice = deviceNetworkId return deviceNetworkId } catch (Exception e) { log.error "Failed to create Curtain Device: ${e}" } } def off() { rightShade.off() leftShade.off() } def on() { rightShade.on() leftShade.on() } def open() { rightShade.open() leftShade.open() } def close() { rightShade.close() leftShade.close() } def stepOpen(steps) { rightShade.stepOpen(steps) leftShade.stepOpen(steps) } def stepClose(steps) { rightShade.stepClose(steps) leftShade.stepClose(steps) } def setPosition(position) { logDebug("setPositon(${position}) was called)") rightShade.setPosition(position) leftShade.setPosition(position) } def startPositionChange(direction) { rightShade.startPositionChange(direction) leftShade.startPositionChange(direction) } def stopPositionChange() { rightShade.stopPositionChange() leftShade.stopPositionChange() } def setLevel(value, rate = null) { rightShade.setLevel(value) leftShade.setLevel(value) } def setSpeed(speed) { rightShade.setSpeed(speed) leftShade.setSpeed(speed) } def logDebug(txt){ try { if (settings.debugMode) { log.debug("${app.label} - ${txt}") } } catch(ex) { log.error("bad debug message") } }