From ff5cf1e944d610d32fc23e5489c91fcc87289700 Mon Sep 17 00:00:00 2001 From: Konrad K <33450498+KKlimczukS@users.noreply.github.com> Date: Mon, 8 Mar 2021 21:32:46 +0100 Subject: [PATCH 1/2] ICP-13724, ICP-14062 - Somfy remotes / Fix for configuration, handling button events from all endpoints (#59763) * ICP-13724, ICP-14062 - fix for configuration (Somfy Situo 1 and Situo 4), handling button events from all endpoints (Situo 4), code refactoring. * ICP-14062 - updates vid for Somfy Situo 4 * ICP-14062 - updates vid for Somfy Situo 4 --- .../ikea-button.src/ikea-button.groovy | 77 +++++++++++++++---- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/devicetypes/smartthings/ikea-button.src/ikea-button.groovy b/devicetypes/smartthings/ikea-button.src/ikea-button.groovy index df6ef22e976..0463afe45b8 100644 --- a/devicetypes/smartthings/ikea-button.src/ikea-button.groovy +++ b/devicetypes/smartthings/ikea-button.src/ikea-button.groovy @@ -31,7 +31,7 @@ metadata { fingerprint inClusters: "0000, 0001, 0003, 0009, 0102, 1000, FC7C", outClusters: "0003, 0004, 0006, 0008, 0019, 0102, 1000", manufacturer:"IKEA of Sweden", model: "TRADFRI on/off switch", deviceJoinName: "IKEA Remote Control", mnmn: "SmartThings", vid: "SmartThings-smartthings-IKEA_TRADFRI_On/Off_Switch" //IKEA TRÅDFRI On/Off switch fingerprint manufacturer: "IKEA of Sweden", model: "TRADFRI open/close remote", deviceJoinName: "IKEA Remote Control", mnmn: "SmartThings", vid: "SmartThings-smartthings-IKEA_TRADFRI_open/close_remote" // raw description 01 0104 0203 01 07 0000 0001 0003 0009 0020 1000 FC7C 07 0003 0004 0006 0008 0019 0102 1000 //IKEA TRÅDFRI Open/Close Remote fingerprint manufacturer: "KE", model: "TRADFRI open/close remote", deviceJoinName: "IKEA Remote Control", mnmn: "SmartThings", vid: "SmartThings-smartthings-IKEA_TRADFRI_open/close_remote" // raw description 01 0104 0203 01 07 0000 0001 0003 0009 0020 1000 FC7C 07 0003 0004 0006 0008 0019 0102 1000 //IKEA TRÅDFRI Open/Close Remote - fingerprint manufacturer: "SOMFY", model: "Situo 4 Zigbee", deviceJoinName: "SOMFY Remote Control", mnmn: "SmartThings", vid: "SmartThings-smartthings-Somfy_open/close_remote" // raw description 01 0104 0203 00 02 0000 0003 04 0003 0005 0006 0102 + fingerprint manufacturer: "SOMFY", model: "Situo 4 Zigbee", deviceJoinName: "SOMFY Remote Control", mnmn: "SmartThings", vid: "SmartThings-smartthings-Somfy_Situo4_open/close_remote" // raw description 01 0104 0203 00 02 0000 0003 04 0003 0005 0006 0102 fingerprint manufacturer: "SOMFY", model: "Situo 1 Zigbee", deviceJoinName: "SOMFY Remote Control", mnmn: "SmartThings", vid: "SmartThings-smartthings-Somfy_open/close_remote" // raw description 01 0104 0203 00 02 0000 0003 04 0003 0005 0006 0102 } @@ -72,10 +72,29 @@ private getOPENCLOSE_BUTTONS() { DOWN:2] } -private getOPENCLOSESTOP_BUTTONS() { - [UP:1, - STOP:2, - DOWN:3 +private getOPENCLOSESTOP_BUTTONS_ENDPOINTS() { + [ + 1: [UP:1, + STOP:2, + DOWN:3], + 2: [UP:4, + STOP:5, + DOWN:6], + 3: [UP:7, + STOP:8, + DOWN:9], + 4: [UP:10, + STOP:11, + DOWN:12] + ] +} + +private getBUTTON_NUMBER_ENDPOINT() { + [ + 1: 1, 2: 1, 3: 1, + 4: 2, 5: 2, 6: 2, + 7: 3, 8: 3, 9: 3, + 10:4, 11: 4, 12: 4 ] } @@ -123,8 +142,14 @@ private getButtonLabel(buttonNum) { label = ikeaOnOffSwitchNames[buttonNum - 1] } else if (isIkeaOpenCloseRemote()) { label = openCloseRemoteNames[buttonNum - 1] - } else if (isSomfySituo()) { - label = openCloseStopRemoteNames[buttonNum - 1] + } else if (isSomfy()) { + // UP, STOP, DOWN events in "Somfy Situo 4" come from 4 endpoints, so there are 12 child buttons + // endpoint 1: buttons 1-3, enpoint 2: buttons 4-6, endpoint 3: buttons 7-9, endpoint 4: buttons 10-12 + // Situo 1 reports from endpoint 1 only + def endpoint = BUTTON_NUMBER_ENDPOINT[buttonNum] + def buttonNameIdx = (buttonNum - 1)%3 + def buttonName = openCloseStopRemoteNames[buttonNameIdx] + label = "endpoint $endpoint $buttonName" } return label @@ -141,7 +166,7 @@ private void createChildButtonDevices(numberOfButtons) { for (i in 1..numberOfButtons) { log.debug "Creating child $i" - def supportedButtons = ((isIkeaRemoteControl() && i == REMOTE_BUTTONS.MIDDLE) || isIkeaOpenCloseRemote() || isSomfySituo()) ? ["pushed"] : ["pushed", "held"] + def supportedButtons = ((isIkeaRemoteControl() && i == REMOTE_BUTTONS.MIDDLE) || isIkeaOpenCloseRemote() || isSomfy()) ? ["pushed"] : ["pushed", "held"] def child = addChildDevice("Child Button", "${device.deviceNetworkId}:${i}", device.hubId, [completedSetup: true, label: getButtonName(i), isComponent: true, componentName: "button$i", componentLabel: getButtonLabel(i)]) @@ -159,15 +184,17 @@ def installed() { numberOfButtons = 5 } else if (isIkeaOnOffSwitch() || isIkeaOpenCloseRemote()) { numberOfButtons = 2 - } else if (isSomfySituo()) { + } else if (isSomfySituo1()) { numberOfButtons = 3 + } else if (isSomfySituo4()) { + numberOfButtons = 12 } if (numberOfButtons > 1) { createChildButtonDevices(numberOfButtons) } - def supportedButtons = isIkeaOpenCloseRemote() || isSomfySituo() ? ["pushed"] : ["pushed", "held"] + def supportedButtons = isIkeaOpenCloseRemote() || isSomfy() ? ["pushed"] : ["pushed", "held"] sendEvent(name: "supportedButtonValues", value: supportedButtons.encodeAsJSON(), displayed: false) sendEvent(name: "numberOfButtons", value: numberOfButtons, displayed: false) numberOfButtons.times { @@ -193,10 +220,17 @@ def configure() { def cmds = [] - if (isSomfySituo()) { + if (isSomfy()) { cmds += zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x21, ["destEndpoint":0xE8]) + zigbee.configureReporting(zigbee.POWER_CONFIGURATION_CLUSTER, 0x21, DataType.UINT8, 30, 21600, 0x01, ["destEndpoint":0xE8]) + - zigbee.addBinding(CLUSTER_WINDOW_COVERING) + zigbee.removeBinding(zigbee.ONOFF_CLUSTER, device.zigbeeId, 0x01, device.hub.zigbeeEui, 0x01) + + zigbee.addBinding(CLUSTER_WINDOW_COVERING, ["destEndpoint":0x01]) + + if (isSomfySituo4()) { + cmds += zigbee.addBinding(CLUSTER_WINDOW_COVERING, ["destEndpoint":0x02]) + + zigbee.addBinding(CLUSTER_WINDOW_COVERING, ["destEndpoint":0x03]) + + zigbee.addBinding(CLUSTER_WINDOW_COVERING, ["destEndpoint":0x04]) + } } else { cmds += zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x21) + zigbee.configureReporting(zigbee.POWER_CONFIGURATION_CLUSTER, 0x21, DataType.UINT8, 30, 21600, 0x01) + @@ -326,17 +360,18 @@ private Map getButtonEvent(Map descMap) { buttonNumber = OPENCLOSE_BUTTONS.DOWN } } - } else if (isSomfySituo() && descMap.data?.size() == 0){ + } else if (isSomfy() && descMap.data?.size() == 0){ // Somfy Situo Remotes query their shades directly after "My"(stop) button is pressed (that's intended behavior) // descMap contains 'data':['00', '00'] in such cases, so we have to ignore those redundant misinterpreted UP events if (descMap.clusterInt == CLUSTER_WINDOW_COVERING) { buttonState = "pushed" + def endpoint = Integer.parseInt(descMap.sourceEndpoint) if (descMap.commandInt == 0x00) { - buttonNumber = OPENCLOSESTOP_BUTTONS.UP + buttonNumber = OPENCLOSESTOP_BUTTONS_ENDPOINTS[endpoint].UP } else if (descMap.commandInt == 0x01) { - buttonNumber = OPENCLOSESTOP_BUTTONS.DOWN + buttonNumber = OPENCLOSESTOP_BUTTONS_ENDPOINTS[endpoint].DOWN } else if (descMap.commandInt == 0x02) { - buttonNumber = OPENCLOSESTOP_BUTTONS.STOP + buttonNumber = OPENCLOSESTOP_BUTTONS_ENDPOINTS[endpoint].STOP } } } @@ -368,10 +403,18 @@ private boolean isIkea() { isIkeaRemoteControl() || isIkeaOnOffSwitch() || isIkeaOpenCloseRemote() } -private boolean isSomfySituo() { +private boolean isSomfy() { device.getDataValue("manufacturer") == "SOMFY" } +private boolean isSomfySituo1() { + isSomfy() && device.getDataValue("model") == "Situo 1 Zigbee" +} + +private boolean isSomfySituo4() { + isSomfy() && device.getDataValue("model") == "Situo 4 Zigbee" +} + private Integer getGroupAddrFromBindingTable(description) { log.info "Parsing binding table - '$description'" def btr = zigbee.parseBindingTableResponse(description) From ecb221ae0beacb66435b45b5b842cc52d152efd6 Mon Sep 17 00:00:00 2001 From: frient-design <73893001+frient-design@users.noreply.github.com> Date: Tue, 9 Mar 2021 08:39:45 +0100 Subject: [PATCH 2/2] DevWs for frient containing containing Zigbee Metering Plug (#60110) * DevWs for frient containing containing Zigbee Metering Plug * Update zigbee-metering-plug.groovy Fix line ending encoding Co-authored-by: Mohammed Kemal Co-authored-by: rboy1 <3846367+rboy1@users.noreply.github.com> --- .../zigbee-metering-plug.src/zigbee-metering-plug.groovy | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/devicetypes/smartthings/zigbee-metering-plug.src/zigbee-metering-plug.groovy b/devicetypes/smartthings/zigbee-metering-plug.src/zigbee-metering-plug.groovy index e42d58ea6e3..64b6b97e3c8 100644 --- a/devicetypes/smartthings/zigbee-metering-plug.src/zigbee-metering-plug.groovy +++ b/devicetypes/smartthings/zigbee-metering-plug.src/zigbee-metering-plug.groovy @@ -167,7 +167,7 @@ private int getPowerDiv() { } private int getEnergyDiv() { - (isSengledOutlet() || isJascoProductsOutlet()) ? 10000 : 100 + (isSengledOutlet() || isJascoProductsOutlet()) ? 10000 : isFrientOutlet() ? 1000 : 100 } private boolean isSengledOutlet() { @@ -177,3 +177,7 @@ private boolean isSengledOutlet() { private boolean isJascoProductsOutlet() { device.getDataValue("manufacturer") == "Jasco Products" } + +private boolean isFrientOutlet() { + device.getDataValue("manufacturer") == "frient A/S" +}