Nue Zigbee Double Powerpoint DH help needed

Hi Everyone,

Hoping to get some help. I recently bought a Nue Zigbee Double Powerpoint and it come with a really poorly designed device handler and I doubt that I will get them to fix it for me.

The device handler which I have added below will allow me to control the powerpoints from smartthings however it wont update when the physical device is turned on or off.

The other problem that I am having is that I cannot use this in automation as it does not list two devices to turn on or off, when I put the device into an automation and try to turn it on or off when something happens it simply does nothing.

As a work around I tried to use webCoRE to do the automation however it doesn’t work because (and I am assuming here) the device handler does not report in the recently tab anything so webCoRE doesn’t recognise anything as happening.

I hope that someone can look at this DH and help me, otherwise I think I have just wasted my money. Appreciate any help.

/**

  • Copyright 2017 SmartThings original - shamlessly borrowed by the netsheriff and modded.
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.
  •          Nue ZigBee Double Points
    
  •        Author: Kevin 3A Smart Home
    
  •        Date: 04/05/2018
    

*/
metadata {
// Automatically generated. Make future change here.
// flipped the on/off detection
definition (name: “Nue ZigBee Double Powerpoints”, namespace: “”, author: “kevinx”) {
capability “Switch”
capability “Configuration”
capability “Refresh”
capability “Actuator”
capability “Sensor”
command “OneOn”
command “OneOff”
command “TwoOn”
command “TwoOff”
attribute “switch1”,“ENUM”,[“on”,“off”]
attribute “switch2”,“ENUM”,[“on”,“off”]

fingerprint profileId: “0104”, inClusters: “0000, 0003, 0005, 0004, 0006, 0702”, outClusters: “1000, 0008, 0019”
fingerprint inClusters: “0000, 0003, 0005, 0004, 0006”, endpointId: “0B”, deviceId: “0000”, profileId: “0104”

fingerprint profileId: “0104”, inClusters: “0000 0004 0005 0006 0003 0B05 0702”, outClusters: “0003 000A 0019”, manufacturer: “Feibit Inc co.”, model: “FB56+ZSW1IKJ1.7”
fingerprint profileId: “0104”, inClusters: “0000,0003,0004,0005,0006,0B05,0702”, outClusters: “000A,0019”, manufacturer: “Feibit Inc co.”, model: “FB56+ZSW1IKJ1.7”

}

// simulator metadata

simulator {
// status messages
status “on”: “on/off: 1”
status “off”: “on/off: 0”

            // reply messages
            reply "zcl on-off on": "on/off: 1"
            reply "zcl on-off off": "on/off: 0"

}

// UI tile definitions
tiles {
multiAttributeTile(name:“switch1”, type: “lighting”, width: 1, height: 1, canChangeIcon: true) {
tileAttribute (“device.switch”, key: “PRIMARY_CONTROL”) {
attributeState “on”, label:‘SW1 On’, action:“OneOff”, icon:“st.switches.light.on”, backgroundColor:"#00a0dc", nextState:“turningOff”
attributeState “off”, label:‘SW1 Off’, action:“OneOn”, icon:“st.switches.light.off”, backgroundColor:"#ffffff", nextState:“turningOn”
attributeState “turningOn”, label:‘SW1 On’, action:“OneOff”, icon:“st.switches.light.on”, backgroundColor:"#00A0DC", nextState:“turningOff”
attributeState “turningOff”, label:‘SW1 Off’, action:“OneOn”, icon:“st.switches.light.off”, backgroundColor:"#ffffff", nextState:“turningOn”
}
}
multiAttributeTile(name:“switch2”, type: “lighting”, width: 1, height: 1, canChangeIcon: true) {
tileAttribute (“device.switch”, key: “PRIMARY_CONTROL”) {
attributeState “on”, label:‘SW2 On’, action:“TwoOff”, icon:“st.switches.light.on”, backgroundColor:"#00a0dc", nextState:“turningOff”
attributeState “off”, label:‘SW2 Off’, action:“TwoOn”, icon:“st.switches.light.off”, backgroundColor:"#ffffff", nextState:“turningOn”
attributeState “turningOn”, label:‘SW2 On’, action:“TwoOff”, icon:“st.switches.light.on”, backgroundColor:"#00A0DC", nextState:“turningOff”
attributeState “turningOff”, label:‘SW2 Off’, action:“TwoOn”, icon:“st.switches.light.off”, backgroundColor:"#ffffff", nextState:“turningOn”
}
}

standardTile(“refresh”, “device.refresh”, inactiveLabel: false, decoration: “flat”, width: 1, height: 1) {
state “default”, label:"", action:“refresh.refresh”, icon:“st.secondary.refresh”
}
main ([“switch1”, “switch2”])
details([“switch1”, “switch2”,“refresh”])
}
}
// Parse incoming device messages to generate events
def parse(String description) {
log.debug “description is $description”
log.debug parseDescriptionAsMap(description)

def finalResult = isKnownDescription(description)

if (finalResult != “false”) {
log.info finalResult
if (finalResult.type == “update”) {
log.info “device updates: {finalResult.value}”
log.debug “device updates: {finalResult.value}”
}
else {
sendEvent(name: finalResult.type, value: finalResult.value)
}
}
else {
log.warn “DID NOT PARSE MESSAGE for description : description" log.debug parseDescriptionAsMap(description) } } // Commands to device def zigbeeCommand(endp, cluster, attribute){ "st cmd 0x{device.deviceNetworkId} {endp} {cluster} ${attribute} {}”
}

def OneOn() {
zigbeeCommand(“0x0C”,“6”, “1”)
}
def OneOff() {
zigbeeCommand(“0x0C”,“6”, “0”)
}
def TwoOn() {
zigbeeCommand(“0x0B”,“6”, “1”)
}
def TwoOff() {
zigbeeCommand(“0x0B”,“6”, “0”)
}

def ping() {
return refresh()
}

def refresh() {
[
“st rattr 0x${device.deviceNetworkId} ${endpointId} 6 1”
]
}
def configure() {
onOffConfig() + refresh()
}
private getEndpointId() {
new BigInteger(device.endpointId, 16).toString()
}
private hex(value, width=2) {
def s = new BigInteger(Math.round(value).toString()).toString(16)
while (s.size() < width) {
s = “0” + s
}
s
}
private String swapEndianHex(String hex) {
reverseArray(hex.decodeHex()).encodeHex()
}
private Integer convertHexToInt(hex) {
Integer.parseInt(hex,16)
}
//Need to reverse array of size 2
private byte reverseArray(byte array) {
byte tmp;
tmp = array[1];
array[1] = array[0];
array[0] = tmp;
return array
}
def parseDescriptionAsMap(description) {
if (description?.startsWith(“read attr -”)) {
(description - “read attr - “).split(”,”).inject([:]) { map, param ->
def nameAndValue = param.split(":")
map += [(nameAndValue[0].trim()): nameAndValue[1].trim()]
}
}
else if (description?.startsWith("catchall: ")) {
def seg = (description - "catchall: “).split(” ")
def zigbeeMap = [:]
zigbeeMap += [raw: (description - “catchall: “)]
zigbeeMap += [profileId: seg[0]]
zigbeeMap += [clusterId: seg[1]]
zigbeeMap += [sourceEndpoint: seg[2]]
zigbeeMap += [destinationEndpoint: seg[3]]
zigbeeMap += [options: seg[4]]
zigbeeMap += [messageType: seg[5]]
zigbeeMap += [dni: seg[6]]
zigbeeMap += [isClusterSpecific: Short.valueOf(seg[7], 16) != 0]
zigbeeMap += [isManufacturerSpecific: Short.valueOf(seg[8], 16) != 0]
zigbeeMap += [manufacturerId: seg[9]]
zigbeeMap += [command: seg[10]]
zigbeeMap += [direction: seg[11]]
zigbeeMap += [data: seg.size() > 12 ? seg[12].split(””).findAll { it }.collate(2).collect {
it.join(’’)
} : ]
zigbeeMap
}
}
def isKnownDescription(description) {
if ((description?.startsWith(“catchall:”)) || (description?.startsWith(“read attr -”))) {
def descMap = parseDescriptionAsMap(description)
if (descMap.cluster == “0006” || descMap.clusterId == “0006”) {
isDescriptionOnOff(descMap)
}
else if (descMap.cluster == “0702” || descMap.clusterId == “0702”){
isDescriptionPower(descMap)
}
else {
return “false”
}
}
else if(description?.startsWith(“on/off:”)) {
def switchValue = description?.endsWith(“1”) ? “on” : “off”
if (descMap.sourceEndpoint == “11”) {
return [type: “switch1”, value : switchValue]
}
else if (descMap.sourceEndpoint == “10”) {
return [type: “switch2”, value : switchValue]
}

}
else {
return “false”
}
}
def isDescriptionOnOff(descMap) {
def switchValue = “undefined”
if (descMap.cluster == “0006”) { //cluster info from read attr
value = descMap.value
if (value == “01”){
switchValue = “on”
}
else if (value == “00”){
switchValue = “off”
}
}
else if (descMap.clusterId == “0006”) {
//cluster info from catch all
//command 0B is Default response and the last two bytes are [on/off][success]. on/off=00, success=00
//command 01 is Read attr response. the last two bytes are [datatype][value]. boolean datatype=10; on/off value = 01/00
if ((descMap.command==“0B” && descMap.raw.endsWith(“0100”)) || (descMap.command==“01” && descMap.raw.endsWith(“1001”))){
if (descMap.sourceEndpoint == “11”) {
return [type: “switch1”, value : “on”]
}
else if (descMap.sourceEndpoint == “10”) {
return [type: “switch2”, value : “on”]
}

            }
            else if ((descMap.command=="0B" && descMap.raw.endsWith("0000")) || (descMap.command=="01" && descMap.raw.endsWith("1000"))){
                           
           
                            if (descMap.sourceEndpoint == "11") {   
                                            return   [type: "switch1", value : "off"]
            }
            else if (descMap.sourceEndpoint == "10") {   
                           return   [type: "switch2", value : "off"]
            }
}

else if (descMap.command=="01" && descMap.raw.endsWith("2000")){
           
                            if (descMap.sourceEndpoint == "11") {   
                                            return   [type: "switch1", value : "off"]
            }
            else if (descMap.sourceEndpoint == "10") {   
                           return   [type: "switch2", value : "off"]
            }

}
else if (descMap.command=="01" && descMap.raw.endsWith("2001")){
           
                            if (descMap.sourceEndpoint == "11") {   
                                            return   [type: "switch1", value : "on"]
            }
            else if (descMap.sourceEndpoint == "10") {   
                           return   [type: "switch2", value : "on"]
            }

            }


            else if(descMap.command=="07"){
                            return   [type: "update", value : "switch (0006) capability configured successfully"]
            }

}

if (switchValue != “undefined”){
return [type: “switch”, value : switchValue]
}
else {
return “false”
}
}
def isDescriptionPower(descMap) {
def powerValue = “undefined”
if (descMap.cluster == “0702”) {
if (descMap.attrId == “0400”) {
powerValue = convertHexToInt(descMap.value)
}
}
else if (descMap.clusterId == “0702”) {
if(descMap.command==“07”){
return [type: “update”, value : “power (0702) capability configured successfully”]
}
}
if (powerValue != “undefined”){
return [type: “power”, value : powerValue]
}
else {
return “false”
}
}
def onOffConfig() {
[
“zdo bind 0x${device.deviceNetworkId} 1 {endpointId} 6 {{device.zigbeeId}} {}”, “delay 200”,
“zcl global send-me-a-report 6 0 0x10 0 600 {01}”,
“send 0x${device.deviceNetworkId} 1 ${endpointId}”, “delay 500”
]
}
String convertToHexString(value, width=2) {
def s = new BigInteger(Math.round(value).toString()).toString(16)
while (s.size() < width) {
s = “0” + s
}
s
}

here are the logs

eeffa3e6-b47c-4695-8b39-242d125e69ae 16:21:21: debug [raw:0104 0006 0B 01 0000 00 932A 00 00 0000 0B 01 0100, profileId:0104, clusterId:0006, sourceEndpoint:0B, destinationEndpoint:01, options:0000, messageType:00, dni:932A, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:0B, direction:01, data:[01, 00]]

eeffa3e6-b47c-4695-8b39-242d125e69ae 16:21:21: warn DID NOT PARSE MESSAGE for description : catchall: 0104 0006 0B 01 0000 00 932A 00 00 0000 0B 01 0100

eeffa3e6-b47c-4695-8b39-242d125e69ae 16:21:21: debug [raw:0104 0006 0B 01 0000 00 932A 00 00 0000 0B 01 0100, profileId:0104, clusterId:0006, sourceEndpoint:0B, destinationEndpoint:01, options:0000, messageType:00, dni:932A, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:0B, direction:01, data:[01, 00]]

eeffa3e6-b47c-4695-8b39-242d125e69ae 16:21:20: debug description is catchall: 0104 0006 0B 01 0000 00 932A 00 00 0000 0B 01 0100