Skip to content

Commit

Permalink
Merge pull request #38722 from SmartThingsCommunity/master
Browse files Browse the repository at this point in the history
Rolling up master to staging
  • Loading branch information
greens authored Jul 28, 2020
2 parents e22b722 + ed676f0 commit 17d9342
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 61 deletions.
28 changes: 19 additions & 9 deletions devicetypes/qubino/qubino-dimmer.src/qubino-dimmer.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ def installed() {
state.currentPreferencesState."$it.key".value = getPreferenceValue(it)
state.currentPreferencesState."$it.key".status = "synced"
}
readConfigurationFromTheDevice()
// Preferences template end
}

Expand Down Expand Up @@ -167,13 +166,13 @@ def excludeParameterFromSync(preference){
return exclude
}

private readConfigurationFromTheDevice() {
private getReadConfigurationFromTheDeviceCommands() {
def commands = []
parameterMap.each {
state.currentPreferencesState."$it.key".status = "reverseSyncPending"
commands += zwave.configurationV2.configurationGet(parameterNumber: it.parameterNumber)
}
sendHubCommand(encapCommands(commands))
commands
}

private syncConfiguration() {
Expand Down Expand Up @@ -232,7 +231,15 @@ def configure() {
commands << zwave.associationV1.associationSet(groupingIdentifier:5, nodeId:[zwaveHubNodeId])
commands << zwave.associationV1.associationSet(groupingIdentifier:6, nodeId:[zwaveHubNodeId])
commands << zwave.multiChannelV3.multiChannelEndPointGet()
commands + getRefreshCommands()
commands += getRefreshCommands()

// 1% is default Minimum dimming value for dimmers,
// when device is set to 1% - it turns off and device does not send any level reports
// Minimum dimming value has to be set to 2%, so the device's internal range would be 2-100%
// Still, for users it will relatively be 1-100% on the UI and device will report it.
// Parameter no. 60 – Minimum dimming value
commands << zwave.configurationV2.configurationSet(scaledConfigurationValue: 2, parameterNumber: 60, size: 1)
commands += getReadConfigurationFromTheDeviceCommands()

encapCommands(commands)
}
Expand Down Expand Up @@ -334,7 +341,7 @@ def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd, ep = null) {

if(input1SwitchType == INPUT_TYPE_POTENTIOMETER) {
log.debug "BasicSet: ${cmd} / INPUT_TYPE_POTENTfIOMETER"
response(zwave.switchMultilevelV3.switchMultilevelGet())
sendHubCommand(encap(zwave.switchMultilevelV3.switchMultilevelGet()))
} else if (input1SwitchType == INPUT_TYPE_BI_STABLE_SWITCH) {
log.debug "BasicSet: ${cmd} / INPUT_TYPE_BI_STABLE_SWITCH"
dimmerEvents(cmd)
Expand Down Expand Up @@ -482,6 +489,11 @@ def setLevel(value, duration = null) {
commands << zwave.switchMultilevelV3.switchMultilevelSet(value: level, dimmingDuration: dimmingDuration)
commands << zwave.switchMultilevelV3.switchMultilevelGet()

if(supportsPowerMeter()){
commands << zwave.meterV2.meterGet(scale: 0)
commands << zwave.meterV2.meterGet(scale: 2)
}

encapCommands(commands, getStatusDelay)
}

Expand Down Expand Up @@ -570,11 +582,9 @@ private getParameterMap() {[
values: [
0: "Default value - Mono-stable switch type (push button) – button quick press turns between previous set dimmer value and zero)",
1: "Bi-stable switch type (on/off toggle switch)",
2: "Potentiometer (applies to Flush Dimmer 0-10V only, dimmer is using set value the last received from potentiometer or from z-wave controller)",
3: "0-10V Temperature sensor (regulated output, applies to Flush Dimmer 0-10V only)"
2: "Potentiometer (applies to Flush Dimmer 0-10V only, dimmer is using set value the last received from potentiometer or from z-wave controller)"
],
description: "Set input based on device type (switch, potentiometer, temperature sensor,..)." +
"After parameter change to value 3 first exclude module (without setting parameters to default value) then wait at least 30s and then re include the module! "
description: "Set input based on device type (mono-stable switch, bi-stable switch, potentiometer)."
],
[
name: "Input 2 switch type (applies to Qubino Flush Dimmer only)", key: "inputsSwitchTypes", type: "enum",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ metadata {
command "reset"

fingerprint mfr: "0159", prod: "0002", model: "0051", deviceJoinName: "Qubino Switch 1" //Qubino Flush 2 Relay
fingerprint mfr: "0159", prod: "0002", model: "0052", deviceJoinName: "Qubino Switch" //Qubino Flush 1 Relay
fingerprint mfr: "0159", prod: "0002", model: "0053", deviceJoinName: "Qubino Switch" //Qubino Flush 1D Relay
}

tiles(scale: 2) {
Expand Down Expand Up @@ -70,7 +72,12 @@ metadata {
}

def installed() {
state.numberOfSwitches = 2
if (zwaveInfo?.model.equals("0051")) {
state.numberOfSwitches = 2
} else {
state.numberOfSwitches = 1
}

if (!childDevices) {
addChildSwitches(state.numberOfSwitches)
}
Expand All @@ -85,6 +92,9 @@ def installed() {
state.currentPreferencesState."$it.key".status = "synced"
}
// Preferences template end
response([
refresh((1..state.numberOfSwitches).toList())
])
}

def updated() {
Expand All @@ -93,7 +103,7 @@ def updated() {
}
// Preferences template begin
parameterMap.each {
if (isPreferenceChanged(it)) {
if (isPreferenceChanged(it) && !excludeParameterFromSync(it)) {
log.debug "Preference ${it.key} has been updated from value: ${state.currentPreferencesState."$it.key".value} to ${settings."$it.key"}"
state.currentPreferencesState."$it.key".status = "syncPending"
} else if (!state.currentPreferencesState."$it.key".value) {
Expand All @@ -104,6 +114,20 @@ def updated() {
// Preferences template end
}

def excludeParameterFromSync(preference){
def exclude = false
if (preference.key == "outputQ2SwitchSelection") {
if (zwaveInfo?.model?.equals("0052") || zwaveInfo?.model?.equals("0053")) {
exclude = true
}
}

if (exclude) {
log.warn "Preference no ${preference.parameterNumber} - ${preference.key} is not supported by this device"
}
return exclude
}

private syncConfiguration() {
def commands = []
parameterMap.each {
Expand Down Expand Up @@ -446,6 +470,6 @@ private getParameterMap() {[
0: "When system is turned off the output is 0V (NC).",
1: "When system is turned off the output is 230V (NO).",
],
description: "Set value means the type of the device that is connected to the Q2 output. The device type can be normally open (NO) or normally close (NC). "
description: "(Only for Qubino Flush 2 Relay) Set value means the type of the device that is connected to the Q2 output. The device type can be normally open (NO) or normally close (NC). "
]
]}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ metadata {
capability "Configuration"

//zw:L type:1107 mfr:0159 prod:0003 model:0052 ver:1.01 zwv:4.05 lib:03 cc:5E,86,72,5A,73,20,27,25,26,32,60,85,8E,59,70 ccOut:20,26 epc:2
fingerprint mfr: "0159", prod: "0003", model: "0052", deviceJoinName: "Qubino Window Treatment"
fingerprint mfr: "0159", prod: "0003", model: "0052", deviceJoinName: "Qubino Window Treatment" // Qubino Flush Shutter (110-230 VAC)
//zw:L type:1107 mfr:0159 prod:0003 model:0053 ver:1.01 zwv:4.05 lib:03 cc:5E,86,72,5A,73,20,27,25,26,32,85,8E,59,70 ccOut:20,26
fingerprint mfr: "0159", prod: "0003", model: "0053", deviceJoinName: "Qubino Window Treatment" // Qubino Flush Shutter DC
}

tiles(scale: 2) {
Expand Down Expand Up @@ -227,23 +229,24 @@ def open() {
}

def pause() {
sendHubCommand(encap(zwave.switchMultilevelV3.switchMultilevelStopLevelChange()))
def currentShadeState = device.currentState("windowShade").value
if (currentShadeState == "opening" || currentShadeState == "closing") {
encap(zwave.switchMultilevelV3.switchMultilevelStopLevelChange())
} else {
encap(zwave.switchMultilevelV3.switchMultilevelGet())
}
}

def setLevelChild(level, childDni) {
setSlats(level)
}

def setLevel(level) {
state.blindsLastCommand = currentLevel > level ? "opening" : "closing"
setShadeLevel(level)
}

def setShadeLevel(level) {
log.debug "Setting shade level: ${level}"
def currentLevel = Integer.parseInt(device.currentState("shadeLevel").value)
state.blindsLastCommand = currentLevel > level ? "opening" : "closing"
state.shadeTarget = level
encap(zwave.switchMultilevelV3.switchMultilevelSet(value: Math.min(0x63, level)))
}

Expand All @@ -257,7 +260,10 @@ def setSlats(level) {
}

def refresh() {
encap(zwave.switchMultilevelV3.switchMultilevelGet())
[
encap(zwave.switchMultilevelV3.switchMultilevelGet()),
encap(zwave.meterV3.meterGet(scale: 0x00)),
]
}

def ping() {
Expand Down Expand Up @@ -313,6 +319,9 @@ def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelR
}

def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelSet cmd, ep = null) {
def currentLevel = Integer.parseInt(device.currentState("shadeLevel").value)
state.blindsLastCommand = currentLevel > cmd.value ? "opening" : "closing"
state.shadeTarget = cmd.value
sendHubCommand(encap(zwave.meterV3.meterGet(scale: 0x02)))
}

Expand Down Expand Up @@ -355,7 +364,7 @@ def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd, ep = null)
eventMap.value = Math.round(cmd.scaledMeterValue)
eventMap.unit = "W"
events += createEvent(eventMap)
if (cmd.scaledMeterValue) {
if (Math.round(cmd.scaledMeterValue)) {
events += createEvent([name: "windowShade", value: state.blindsLastCommand])
events += createEvent([name: "shadeLevel", value: state.shadeTarget, displayed: false])
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ metadata {
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "Contact Sensor-A", deviceJoinName: "SYLVANIA Open/Closed Sensor" //Sylvania SMART+ Contact and Temperature Smart Sensor
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "Visonic", model: "MCT-340 E", deviceJoinName: "Visonic Open/Closed Sensor" //Visonic Door/Window Sensor
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "Ecolink", model: "4655BC0-R", deviceJoinName: "Ecolink Open/Closed Sensor", mnmn: "SmartThings", vid: "ecolink-door-sensor" //Ecolink Door/Window Sensor
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "Ecolink", model: "DWZB1-ECO", deviceJoinName: "Ecolink Open/Closed Sensor", mnmn: "SmartThings", vid: "ecolink-door-sensor" //Ecolink Door/Window Sensor
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05,FC01,FC02", outClusters: "0003,0019", manufacturer: "iMagic by GreatStar", model: "1116-S", deviceJoinName: "Iris Open/Closed Sensor" //Iris Contact Sensor
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "Bosch", model: "RFMS-ZBMS", deviceJoinName: "Bosch Open/Closed Sensor" //Bosch multi-sensor
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "Megaman", model: "MS601/z1", deviceJoinName: "INGENIUM Open/Closed Sensor" //INGENIUM ZB Magnetic ON/OFF Sensor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ private getHUE_COMMAND() { 0x00 }
private getSATURATION_COMMAND() { 0x03 }
private getMOVE_TO_HUE_AND_SATURATION_COMMAND() { 0x06 }
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }

// Parse incoming device messages to generate events
def parse(String description) {
Expand Down Expand Up @@ -203,12 +202,9 @@ def ping() {

def refresh() {
zigbee.onOffRefresh() +
zigbee.levelRefresh() +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) +
zigbee.onOffConfig(0, 300) +
zigbee.levelConfig()
zigbee.levelRefresh() +
zigbee.colorTemperatureRefresh() +
zigbee.hueSaturationRefresh()
}

def configure() {
Expand All @@ -217,17 +213,24 @@ def configure() {
// enrolls with default periodic reporting until newer 5 min interval is confirmed
sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])

// OnOff minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no activity
refresh()

def cmds = []
if(device.currentState("colorTemperature")?.value == null) {
cmds += zigbee.setColorTemperature(5000)
}

cmds += refresh() +
// OnOff, level minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no activity
zigbee.onOffConfig(0, 300) +
zigbee.levelConfig(0, 300)
cmds
}

def setColorTemperature(value) {
value = value as Integer
def tempInMired = Math.round(1000000 / value)
def finalHex = zigbee.swapEndianHex(zigbee.convertToHexString(tempInMired, 4))

zigbee.command(COLOR_CONTROL_CLUSTER, 0x0A, "$finalHex 0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE)
zigbee.setColorTemperature(value) +
zigbee.colorTemperatureRefresh()
}

//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
Expand Down Expand Up @@ -262,20 +265,19 @@ private getScaledSaturation(value) {
def setColor(value){
log.trace "setColor($value)"
zigbee.on() +
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
zigbee.hueSaturationRefresh()
}

def setHue(value) {
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, getScaledHue(value), "00", "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
}

def setSaturation(value) {
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, getScaledSaturation(value), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
}

def installed() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ metadata {
// Third Reality
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300", outClusters: "0019", manufacturer: "Third Reality, Inc", model: "3RSL011Z", deviceJoinName: "RealityLight Light" //RealityLight
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300", outClusters: "0019", manufacturer: "Third Reality, Inc", model: "3RSL012Z", deviceJoinName: "RealityLight Light" //RealityLight

// Ajax Online
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000", outClusters: "0019", manufacturer: "Ajax Online", model: "CCT", deviceJoinName: "Ajax Light", mnmn: "SmartThings", vid: "generic-color-temperature-bulb-2200K-6500K" // Ajax Online Filament Bulb
}

// UI tile definitions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0102", outClusters: "000A", manufacturer: "Feibit Co.Ltd", model: "FTB56-ZT218AK1.8", deviceJoinName: "Wistar Window Treatment" //Wistar Curtain Motor(CMJ)
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0102", outClusters: "0003", manufacturer: "REXENSE", model: "KG0001", deviceJoinName: "Window Treatment" //Smart Curtain Motor(BCM300D)
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0102", outClusters: "0003", manufacturer: "REXENSE", model: "DY0010", deviceJoinName: "Window Treatment" //Smart Curtain Motor(DT82TV)
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0102", outClusters: "0003", manufacturer: "SOMFY", model: "Glydea Somfy", deviceJoinName: "Somfy Window Treatment" //Somfy Glydea Ultra
}

preferences {
Expand Down Expand Up @@ -193,7 +194,7 @@ def pause() {
}

def presetPosition() {
setLevel(preset ?: 50)
setLevel(preset ?: 50)
}

/**
Expand Down Expand Up @@ -271,7 +272,7 @@ private List readDeviceBindingTable() {
}

def shouldInvertLiftPercentage() {
return isIkeaKadrilj() || isIkeaFyrtur()
return isIkeaKadrilj() || isIkeaFyrtur() || isSomfyGlydea()
}

def reportsBatteryPercentage() {
Expand All @@ -285,3 +286,7 @@ def isIkeaKadrilj() {
def isIkeaFyrtur() {
device.getDataValue("model") == "FYRTUR block-out roller blind"
}

def isSomfyGlydea() {
device.getDataValue("model") == "Glydea Somfy"
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ metadata {

fingerprint mfr:"0086", prod:"0003", model:"008D", deviceJoinName: "Aeotec Window Treatment" //Aeotec Nano Shutter
fingerprint mfr:"0086", prod:"0103", model:"008D", deviceJoinName: "Aeotec Window Treatment" //Aeotec Nano Shutter
fingerprint mfr:"0371", prod:"0003", model:"008D", deviceJoinName: "Aeotec Window Treatment" //Aeotec Nano Shutter
fingerprint mfr:"0371", prod:"0103", model:"008D", deviceJoinName: "Aeotec Window Treatment" //Aeotec Nano Shutter
}

tiles(scale: 2) {
Expand Down Expand Up @@ -137,7 +139,7 @@ def ping() {
def installed() {
log.debug "Installed ${device.displayName}"
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
sendEvent(name: "availableCurtainPowerButtons", value: JsonOutput.toJson(["open", "close", "pause"]))
sendEvent(name: "availableCurtainPowerButtons", value: JsonOutput.toJson(["open", "close", "pause"]), displayed: false)
state.shadeState = "paused"
state.reverseDirection = reverseDirection ? reverseDirection : false
}
Expand All @@ -149,7 +151,10 @@ def updated() {

def configure() {
log.debug "Configure..."
response(secure(zwave.configurationV1.configurationSet(parameterNumber: 80, size: 1, scaledConfigurationValue: 1)))
response([
secure(zwave.configurationV1.configurationSet(parameterNumber: 80, size: 1, scaledConfigurationValue: 1)),
secure(zwave.configurationV1.configurationSet(parameterNumber: 85, size: 1, scaledConfigurationValue: 1))
])
}

private secure(cmd) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ metadata {
capability "Configuration"

//zw:S type:0701 mfr:021F prod:0003 model:0083 ver:3.92 zwv:4.05 lib:06 cc:5E,86,72,5A,73,80,31,71,30,70,85,59,84 role:06 ff:8C07 ui:8C07
fingerprint mfr: "021F", prod: "0003", model: "0083", deviceJoinName: "Dome Motion Sensor" //Dome Motion/Light Sensor
fingerprint mfr: "021F", prod: "0003", model: "0083", deviceJoinName: "Dome Motion/Light Sensor", mnmn: "SmartThings", vid: "SmartThings-smartthings-Dome_Motion_Light_Sensor_DMMS1"
//zw:S type:0701 mfr:0258 prod:0003 model:008D ver:3.80 zwv:4.38 lib:06 cc:5E,86,72,5A,73,80,31,71,30,70,85,59,84 role:06 ff:8C07 ui:8C07
fingerprint mfr: "0258", prod: "0003", model: "008D", deviceJoinName: "NEO Coolcam Motion Sensor" //NEO Coolcam Motion/Light Sensor
fingerprint mfr: "0258", prod: "0003", model: "008D", deviceJoinName: "NEO Coolcam Motion/Light Sensor", mnmn: "SmartThings", vid: "SmartThings-smartthings-NEO_Coolcam_Motion_Light_Sensor"
//zw:S type:0701 mfr:0258 prod:0003 model:108D ver:3.80 zwv:4.38 lib:06 cc:5E,86,72,5A,73,80,31,71,30,70,85,59,84 role:06 ff:8C07 ui:8C07 EU version
fingerprint mfr: "0258", prod: "0003", model: "108D", deviceJoinName: "NEO Coolcam Motion Sensor" //NEO Coolcam Motion/Light Sensor
fingerprint mfr: "0258", prod: "0003", model: "108D", deviceJoinName: "NEO Coolcam Motion/Light Sensor", mnmn: "SmartThings", vid: "SmartThings-smartthings-NEO_Coolcam_Motion_Light_Sensor"
fingerprint mfr: "017F", prod: "0101", model: "0001", deviceJoinName: "Wink Motion Sensor"
}

Expand Down
Loading

0 comments on commit 17d9342

Please sign in to comment.