From 7ad6d8f87149a7d5da745428b91393fcd0aea496 Mon Sep 17 00:00:00 2001 From: patyiandras <38727584+patyiandras@users.noreply.github.com> Date: Thu, 26 Apr 2018 11:12:55 +0200 Subject: [PATCH 1/2] Comment non-needed venetian blind functions and fixed isStateChanged --- .../QubinoFlushShutterDeviceHandler.groovy | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/DeviceHandlers/Qubino/FlushShutter/QubinoFlushShutterDeviceHandler.groovy b/DeviceHandlers/Qubino/FlushShutter/QubinoFlushShutterDeviceHandler.groovy index 970f3a5..771308b 100644 --- a/DeviceHandlers/Qubino/FlushShutter/QubinoFlushShutterDeviceHandler.groovy +++ b/DeviceHandlers/Qubino/FlushShutter/QubinoFlushShutterDeviceHandler.groovy @@ -59,9 +59,9 @@ metadata { command "resetPower" //command to issue Meter Reset commands to reset accumulated pwoer measurements command "calibrate" //command to calibrate the shutter module command "stop" //command to stop the vertical blind movement - command "setSlatLevel" //command to issue slat tilting controls - command "openSlats" //command to set maximum level for slats - command "closeSlats" //command to set minimum level for slats + //command "setSlatLevel" //command to issue slat tilting controls + //command "openSlats" //command to set maximum level for slats + //command "closeSlats" //command to set minimum level for slats fingerprint mfr:"0159", prod:"0003", model:"0052" //Manufacturer Information value for Qubino Flush Shutter } @@ -74,9 +74,9 @@ metadata { tiles(scale: 2) { multiAttributeTile(name:"shade", type: "generic", width: 6, height: 4, canChangeIcon: true){ tileAttribute ("device.windowShade", key: "PRIMARY_CONTROL") { - attributeState "open", label:'${name}', action:"close", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"closing" + attributeState "opened", label:'${name}', action:"close", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"closing" attributeState "closed", label:'${name}', action:"open", icon:"st.Home.home9", backgroundColor:"#ffffff", nextState:"opening" - attributeState "opening", label:'${name}', action:"close", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"open" + attributeState "opening", label:'${name}', action:"close", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"opened" attributeState "closing", label:'${name}', action:"open", icon:"st.Home.home9", backgroundColor:"#ffffff", nextState:"closed" } tileAttribute ("device.level", key: "SLIDER_CONTROL") { @@ -89,6 +89,7 @@ metadata { standardTile("stop", "device.stop", decoration: "flat", width: 6, height: 2) { state("stop", label:'', action:'stop', icon: "st.sonos.stop-btn") } + /* standardTile("venetianLabel", "device.venetianLabel", decoration: "flat", width: 6, height: 2) { state("venetianLabel", label:'SLAT TILT CONTROLS:') } @@ -103,6 +104,7 @@ metadata { attributeState "venetianLevel", action:"setSlatLevel" } } + */ standardTile("power", "device.power", decoration: "flat", width: 3, height: 3) { state("power", label:'${currentValue} W', icon: 'st.Appliances.appliances17') } @@ -148,7 +150,7 @@ metadata { } main("shade") - details(["shade", "stop", "venetianLabel", "venetianTile", "power", "kwhConsumption", "resetPower", "refreshPowerConsumption", "setConfiguration", "setAssociation", "calibrate"]) + details(["shade", "stop"/*, "venetianLabel", "venetianTile"*/, "power", "kwhConsumption", "resetPower", "refreshPowerConsumption", "setConfiguration", "setAssociation", "calibrate"]) } preferences { /** @@ -555,7 +557,8 @@ def refreshPowerConsumption() { log.debug "Qubino Flush Shutter: refreshPowerConsumption()" delayBetween([ zwave.meterV2.meterGet(scale: 0).format(), - zwave.meterV2.meterGet(scale: 2).format() + zwave.meterV2.meterGet(scale: 2).format(), + zwave.switchMultilevelV3.switchMultilevelGet().format() ], 1000) } /** @@ -845,10 +848,12 @@ def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd) { def result = [] switch(cmd.scale){ case 0: - result << createEvent(name:"kwhConsumption", value: cmd.scaledMeterValue, unit:"kWh", descriptionText:"${device.displayName} consumed ${cmd.scaledMeterValue} kWh", isStateChange: true) + def currentPower = device.currentState("kwhConsumption") + result << createEvent(name:"kwhConsumption", value: cmd.scaledMeterValue, unit:"kWh", descriptionText:"${device.displayName} consumed ${cmd.scaledMeterValue} kWh", isStateChange: (cmd.scaledMeterValue.toDouble() != currentPower?.value.toDouble())) break; case 2: - result << createEvent(name:"power", value: cmd.scaledMeterValue, unit:"W", descriptionText:"${device.displayName} consumes ${cmd.scaledMeterValue} W", isStateChange: true) + def currentPower = device.currentState("power") + result << createEvent(name:"power", value: cmd.scaledMeterValue, unit:"W", descriptionText:"${device.displayName} consumes ${cmd.scaledMeterValue} W", isStateChange: (cmd.scaledMeterValue.toDouble() != currentPower?.value.toDouble())) break; } return result @@ -871,13 +876,16 @@ def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport * @return Main roller level state events. */ def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd){ - log.debug "Qubino Flush Shutter: firing basic report event" + def currentState = device.currentState("windowShade") + def currentLevel = device.currentState("level") + def desiredState = cmd.value ? "open" : "closed" + log.debug "Qubino Flush Shutter: firing basic report event (currentState: ${currentState?.value}, currentLevel: ${currentLevel?.value}, desiredState: $desiredState, desiredLevel: ${cmd.value})" def result = [] - result << createEvent(name:"windowShade", value: cmd.value ? "open" : "closed", isStateChange: true) + result << createEvent(name:"windowShade", value: desiredState, isStateChange: (currentState?.value!=desiredState)) if(cmd.value > 99){ result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} is uncalibrated! Please press calibrate!", isStateChange: true) }else{ - result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} moved to ${cmd.value==99 ? 100 : cmd.value}%", isStateChange: true) + result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} moved to ${cmd.value==99 ? 100 : cmd.value}%", isStateChange: (currentLevel?.value.toInteger()!=cmd.value.toInteger())) } return result } From 43822e7201b3c13e5691e2a01ec4ae6fa1b0624b Mon Sep 17 00:00:00 2001 From: patyiandras <38727584+patyiandras@users.noreply.github.com> Date: Tue, 30 Oct 2018 12:59:18 +0100 Subject: [PATCH 2/2] Update QubinoFlushShutterDeviceHandler.groovy --- .../QubinoFlushShutterDeviceHandler.groovy | 192 +++++++++++++++--- 1 file changed, 161 insertions(+), 31 deletions(-) diff --git a/DeviceHandlers/Qubino/FlushShutter/QubinoFlushShutterDeviceHandler.groovy b/DeviceHandlers/Qubino/FlushShutter/QubinoFlushShutterDeviceHandler.groovy index 771308b..cfea6ee 100644 --- a/DeviceHandlers/Qubino/FlushShutter/QubinoFlushShutterDeviceHandler.groovy +++ b/DeviceHandlers/Qubino/FlushShutter/QubinoFlushShutterDeviceHandler.groovy @@ -37,11 +37,14 @@ * 0.99: Final release code cleanup and commenting * 1.00: Added comments to code for readability * 1.10: Added Stop button to stop vertical axis motion + * 1.11: Added switch capability for access the device via Google Home + * 1.20: Layout change and Dedicated open/close and preset1,2,3 buttons */ metadata { definition (name: "Qubino Flush Shutter", namespace: "Goap", author: "Kristjan Jamšek") { capability "Actuator" capability "Window Shade" + capability "Switch"//Needed for show in google home capability "Switch Level" capability "Power Meter" @@ -51,7 +54,9 @@ metadata { attribute "kwhConsumption", "number" //attribute used to store and display power consumption in KWH attribute "venetianLevel", "number" //attribute used to control and store venetian blinds level attribute "venetianState", "string" //attribute for the binary control element of the venetian blinds control - + attribute "preset1", "number" + attribute "preset2", "number" + attribute "preset3", "number" command "setConfiguration" //command to issue Configuration Set commands to the module according to user preferences command "setAssociation" //command to issue Association Set commands to the modules according to user preferences @@ -59,6 +64,10 @@ metadata { command "resetPower" //command to issue Meter Reset commands to reset accumulated pwoer measurements command "calibrate" //command to calibrate the shutter module command "stop" //command to stop the vertical blind movement + command "preset1" + command "preset2" + command "preset3" + //command "setSlatLevel" //command to issue slat tilting controls //command "openSlats" //command to set maximum level for slats //command "closeSlats" //command to set minimum level for slats @@ -74,9 +83,10 @@ metadata { tiles(scale: 2) { multiAttributeTile(name:"shade", type: "generic", width: 6, height: 4, canChangeIcon: true){ tileAttribute ("device.windowShade", key: "PRIMARY_CONTROL") { - attributeState "opened", label:'${name}', action:"close", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"closing" + attributeState "open", label:'${name}', action:"close", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"closing" + attributeState "partially open", label:'${name}', action:"open", icon:"st.Home.home9", backgroundColor:"#b77600", nextState:"opening" attributeState "closed", label:'${name}', action:"open", icon:"st.Home.home9", backgroundColor:"#ffffff", nextState:"opening" - attributeState "opening", label:'${name}', action:"close", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"opened" + attributeState "opening", label:'${name}', action:"close", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"open" attributeState "closing", label:'${name}', action:"open", icon:"st.Home.home9", backgroundColor:"#ffffff", nextState:"closed" } tileAttribute ("device.level", key: "SLIDER_CONTROL") { @@ -86,9 +96,6 @@ metadata { attributeState "power", label:'Power level: ${currentValue} W', icon: "st.Appliances.appliances17" } } - standardTile("stop", "device.stop", decoration: "flat", width: 6, height: 2) { - state("stop", label:'', action:'stop', icon: "st.sonos.stop-btn") - } /* standardTile("venetianLabel", "device.venetianLabel", decoration: "flat", width: 6, height: 2) { state("venetianLabel", label:'SLAT TILT CONTROLS:') @@ -105,16 +112,46 @@ metadata { } } */ - standardTile("power", "device.power", decoration: "flat", width: 3, height: 3) { + standardTile("open", "device.open", decoration: "flat", width: 2, height: 2) { + state("open", label:'OPEN', action:'open', icon: "st.doors.garage.garage-opening") + } + standardTile("stop", "device.stop", decoration: "flat", width: 2, height: 2) { + state("stop", label:'STOP', action:'stop', icon: "st.Transportation.transportation13") + } + standardTile("close", "device.close", decoration: "flat", width: 2, height: 2) { + state("close", label:'CLOSE', action:'close', icon: "st.doors.garage.garage-closing") + } + + standardTile("preset1", "device.preset1", decoration: "flat", width: 2, height: 2) { + state("preset1", label:'${currentValue}%', action:'preset1', backgroundColors: [ + [value: 20, color: "#333333"], + [value: 99, color: "#cccccc"] + ]) + } + standardTile("preset2", "device.preset2", decoration: "flat", width: 2, height: 2) { + state("preset2", label:'${currentValue}%', action:'preset2', backgroundColors: [ + [value: 20, color: "#333333"], + [value: 99, color: "#cccccc"] + ]) + } + standardTile("preset3", "device.preset3", decoration: "flat", width: 2, height: 2) { + state("preset3", label:'${currentValue}%', action:'preset3', , backgroundColors: [ + [value: 20, color: "#333333"], + [value: 99, color: "#cccccc"] + ]) + } + + standardTile("power", "device.power", decoration: "flat", width: 3, height: 2) { state("power", label:'${currentValue} W', icon: 'st.Appliances.appliances17') } - standardTile("kwhConsumption", "device.kwhConsumption", decoration: "flat", width: 3, height: 3) { + standardTile("kwhConsumption", "device.kwhConsumption", decoration: "flat", width: 3, height: 2) { state("kwhConsumption", label:'${currentValue} kWh', icon: 'st.Appliances.appliances17') } - standardTile("resetPower", "device.resetPower", decoration: "flat", width: 3, height: 3) { + + standardTile("resetPower", "device.resetPower", decoration: "flat", width: 3, height: 1) { state("resetPower", label:'Reset Power', action:'resetPower') } - standardTile("refreshPowerConsumption", "device.refreshPowerConsumption", decoration: "flat", width: 3, height: 3) { + standardTile("refreshPowerConsumption", "device.refreshPowerConsumption", decoration: "flat", width: 3, height: 1) { state("refreshPowerConsumption", label:'Refresh power', action:'refreshPowerConsumption') } /* //THIS VERSION DOESN?T SUPPORT TEMPERATURE SENSORS YET @@ -139,20 +176,32 @@ metadata { ]) } */ - standardTile("setConfiguration", "device.setConfiguration", decoration: "flat", width: 3, height: 3) { + standardTile("setConfiguration", "device.setConfiguration", decoration: "flat", width: 3, height: 1) { state("setConfiguration", label:'Set Configuration', action:'setConfiguration') } - standardTile("setAssociation", "device.setAssociation", decoration: "flat", width: 3, height: 3) { + standardTile("setAssociation", "device.setAssociation", decoration: "flat", width: 3, height: 1) { state("setAssociation", label:'Set Associations', action:'setAssociation') } - standardTile("calibrate", "device.calibrate", decoration: "flat", width: 6, height: 2) { + standardTile("calibrate", "device.calibrate", decoration: "flat", width: 6, height: 1) { state("calibrate", label:'Calibrate', action:'calibrate') } main("shade") - details(["shade", "stop"/*, "venetianLabel", "venetianTile"*/, "power", "kwhConsumption", "resetPower", "refreshPowerConsumption", "setConfiguration", "setAssociation", "calibrate"]) + details(["shade", "open", "stop", "close"/*, "venetianLabel", "venetianTile"*/, "preset1", "preset2", "preset3", "power", "kwhConsumption", "resetPower", "refreshPowerConsumption", "setConfiguration", "setAssociation", "calibrate"]) } preferences { + input ( + type: "paragraph", + element: "paragraph", + title: "GENERAL SETTINGS:", + description: "General settings." + ) + input name: "preset1level", type: "number", required: false, + title: "Preset#1 level:", range: "0..99", defaultValue: 25 + input name: "preset2level", type: "number", required: false, + title: "Preset#2 level:", range: "0..99", defaultValue: 50 + input name: "preset3level", type: "number", required: false, + title: "Preset#3 level:", range: "0..99", defaultValue: 75 /** * -------- CONFIGURATION PARAMETER SECTION -------- */ @@ -405,6 +454,57 @@ def configure() { assocCmds << zwave.multiChannelV3.multiChannelEndPointGet().format() return delayBetween(assocCmds, 500) } + +def installed() { + log.debug "Qubino Flush Shutter: installed()" + updated() +} + +def updated() { + log.debug "Qubino Flush Shutter: updated()" + def level1=preset1level + if(!level1) { level1=25 } + sendEvent(name: "preset1", value: level1, displayed: false) + def level2=preset2level + if(!level2) { level2=50 } + sendEvent(name: "preset2", value: level2, displayed: false) + def level3=preset3level + if(!level3) { level3=75 } + sendEvent(name: "preset3", value: level3, displayed: false) +} + +def preset1() { + def level=preset1level + if (!level) { level=25 } + log.debug "Qubino Flush Shutter: preset1(${level})" + setLevel(level) +} + +def preset2() { + def level=preset2level + if (!level) { level=50 } + log.debug "Qubino Flush Shutter: preset2(${level})" + setLevel(level) +} + +def preset3() { + def level=preset3level + if (!level) { level=75 } + log.debug "Qubino Flush Shutter: preset3(${level})" + setLevel(level) +} + + +def on() { + log.debug "Qubino Flush Shutter: on()" + open() +} + +def off() { + log.debug "Qubino Flush Shutter: off()" + close() +} + /** * Stop command handler. Issues StopLevelChange when operating as singlechannel device handler. * @@ -779,11 +879,22 @@ def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelR def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelReport cmd){ log.debug "Qubino Flush Shutter: firing switch multilevel event" def result = [] - result << createEvent(name:"windowShade", value: cmd.value ? "open" : "closed", isStateChange: true) + def currentState = device.currentState("windowShade") + def currentSwitch = device.currentState("switch") + def currentLevel = device.currentState("level") + def desiredState = "closed" + if (cmd.value<99 && cmd.value>0) { + desiredState = "partially open" + } else if (cmd.value >= 99) { + desiredState = "open" + } + def desiredSwitch = cmd.value ? "on" : "off" + result << createEvent(name:"switch", value: desiredSwitch, isStateChange: (currentSwitch?.value!=desiredSwitch)) + result << createEvent(name:"windowShade", value: desiredState, isStateChange: (currentState?.value!=desiredState)) if(cmd.value > 99){ result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} is uncalibrated! Please press calibrate!", isStateChange: true) }else{ - result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} moved to ${cmd.value==99 ? 100 : cmd.value}%", isStateChange: true) + result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} moved to ${cmd.value==99 ? 100 : cmd.value}%", isStateChange: (currentLevel?.value.toInteger()!=cmd.value.toInteger())) } return result } @@ -798,12 +909,23 @@ def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelR def result = [] switch(command.sourceEndPoint){ case 1: - result << createEvent(name:"windowShade", value: cmd.value ? "open" : "closed", isStateChange: true) - if(cmd.value > 99){ - result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} is uncalibrated! Please press calibrate!") - }else{ - result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} moved to ${cmd.value==99 ? 100 : cmd.value}%", isStateChange: true) - } + def currentState = device.currentState("windowShade") + def currentSwitch = device.currentState("switch") + def currentLevel = device.currentState("level") + def desiredState = "closed" + if (cmd.value<99 && cmd.value>0) { + desiredState = "partially open" + } else if (cmd.value >= 99) { + desiredState = "open" + } + def desiredSwitch = cmd.value ? "on" : "off" + result << createEvent(name:"switch", value: desiredSwitch, isStateChange: (currentSwitch?.value!=desiredSwitch)) + result << createEvent(name:"windowShade", value: desiredState, isStateChange: (currentState?.value!=desiredState)) + if(cmd.value > 99){ + result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} is uncalibrated! Please press calibrate!", isStateChange: true) + }else{ + result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} moved to ${cmd.value==99 ? 100 : cmd.value}%", isStateChange: (currentLevel?.value.toInteger()!=cmd.value.toInteger())) + } break; case 2: log.debug "Received command from EP2" @@ -849,11 +971,11 @@ def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd) { switch(cmd.scale){ case 0: def currentPower = device.currentState("kwhConsumption") - result << createEvent(name:"kwhConsumption", value: cmd.scaledMeterValue, unit:"kWh", descriptionText:"${device.displayName} consumed ${cmd.scaledMeterValue} kWh", isStateChange: (cmd.scaledMeterValue.toDouble() != currentPower?.value.toDouble())) + result << createEvent(name:"kwhConsumption", value: cmd.scaledMeterValue, unit:"kWh", descriptionText:"${device.displayName} consumed ${cmd.scaledMeterValue} kWh", isStateChange: (cmd.scaledMeterValue?.toDouble() != currentPower?.value?.toDouble())) break; case 2: def currentPower = device.currentState("power") - result << createEvent(name:"power", value: cmd.scaledMeterValue, unit:"W", descriptionText:"${device.displayName} consumes ${cmd.scaledMeterValue} W", isStateChange: (cmd.scaledMeterValue.toDouble() != currentPower?.value.toDouble())) + result << createEvent(name:"power", value: cmd.scaledMeterValue, unit:"W", descriptionText:"${device.displayName} consumes ${cmd.scaledMeterValue} W", isStateChange: (cmd.scaledMeterValue?.toDouble() != currentPower?.value?.toDouble())) break; } return result @@ -877,16 +999,24 @@ def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport */ def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd){ def currentState = device.currentState("windowShade") + def currentSwitch = device.currentState("switch") def currentLevel = device.currentState("level") - def desiredState = cmd.value ? "open" : "closed" + def desiredState = "closed" + if (cmd.value<99 && cmd.value>0) { + desiredState = "partially open" + } else if (cmd.value >= 99) { + desiredState = "open" + } + def desiredSwitch = cmd.value ? "on" : "off" log.debug "Qubino Flush Shutter: firing basic report event (currentState: ${currentState?.value}, currentLevel: ${currentLevel?.value}, desiredState: $desiredState, desiredLevel: ${cmd.value})" def result = [] - result << createEvent(name:"windowShade", value: desiredState, isStateChange: (currentState?.value!=desiredState)) - if(cmd.value > 99){ - result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} is uncalibrated! Please press calibrate!", isStateChange: true) - }else{ - result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} moved to ${cmd.value==99 ? 100 : cmd.value}%", isStateChange: (currentLevel?.value.toInteger()!=cmd.value.toInteger())) - } + result << createEvent(name:"switch", value: desiredSwitch, isStateChange: (currentSwitch?.value!=desiredSwitch)) + result << createEvent(name:"windowShade", value: desiredState, isStateChange: (currentState?.value!=desiredState)) + if(cmd.value > 99){ + result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} is uncalibrated! Please press calibrate!", isStateChange: true) + }else{ + result << createEvent(name:"level", value: cmd.value, unit:"%", descriptionText:"${device.displayName} moved to ${cmd.value==99 ? 100 : cmd.value}%", isStateChange: (currentLevel?.value.toInteger()!=cmd.value.toInteger())) + } return result } /**