New zigbee device handler for EMI Han Meter

Hi
I am trying to create a device handler for EMI Norwegian HAN - EMIZB-132 (zigbee) . The device connects to smartthings, but I am not able to get any data from it.

I use this documentation.

When I try to use:
configureReporting(0x0702, 0x00, 0x25, 0, 600, null) //CurrentSummationDelivered
I only get error message: groovy.lang.MissingMethodException: No signature of method: script_dth_e5595f51c701449303af18db76fa0513576434d5905adf2fc25939b9bfb1968d.configureReporting() is applicable for argument types: (java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, null) values: [1794, 0, 37, 0, 600, null] @line 65 (configure)

So I assume this is not supported by the device.

When I try this code:
log.debug zigbee.readAttribute(0x0702, 0x00) // CurrentSummationDelivered
I get this in my log: [st rattr 0x1E9C 0x01 0x0702 0x0000, delay 2000]

My parse(String description) is quite easy, but I never get anything in the log at all:

def parse(String description) {
log.debug “parse description: $description”
def event = zigbee.getEvent(description)
if (event) {
log.debug “Sending Event”
sendEvent(event)
}
else {
log.warn “DID NOT PARSE MESSAGE for description : $description”
log.debug zigbee.parseDescriptionAsMap(description)
}
}

Any suggestion how to get any further?

Try using “zigbee.configureReporting”. Here’s a working example that I use for my thermostats that you can reference that should be able to help you out alittle:

https://raw.githubusercontent.com/jsconstantelos/SmartThings/master/devicetypes/jsconstantelos/my-centralite-thermostat.src/my-centralite-thermostat.groovy

1 Like

“No signature of method” often means you pasted in a DTH as a smartapp on the groovy platform. So just check that first to get it out of the way. :sunglasses:

FAQ: An Overview of Using Custom Code in SmartThings (SmartThings Classic)

Thanks.
I assumed the zigbee.configureReporting() should “activate” sending data for every change in the device.

My code inside def configure():
zigbee.configureReporting(0x0702, 0x00, 0x25, 0, 600, null)

This only give response in parse() when I change Device Handler (Just changing from/to Things to make some change). Nothing else is happening…
From my log:

Thanks! Checked and verified.
I had a typo in my zigbee.configureReporting(). So error message is now gone.

2 Likes

Just an update: I can now ready values. There where two issues that fixed it this time. I had to add [destEndpoint: 0x02] to configureReporting(). And I must be patient. It took about 2-5 minutes from my code changes to devices responded.

My code is now like this:

def refresh() {
log.debug “Refreshing values”

zigbee.configureReporting(0x0702, 0x0000, 0x25, 600, 3600, 0x01,[destEndpoint: 0x02]) // CurrentSummationDelivered
zigbee.configureReporting(0x0B04, 0x0304, 0x21, 60, 600, 0x01,[destEndpoint: 0x02]) // TotalActivePower
zigbee.configureReporting(0x0B04, 0x0505, 0x21, 60, 600, 0x01,[destEndpoint: 0x02]) // RMSVoltagePhA
zigbee.configureReporting(0x0B04, 0x0508, 0x21, 60, 600, 0x01,[destEndpoint: 0x02]) // RMSCurrentPhA

}

def configure(){
log.debug “Config Called start”

zigbee.configureReporting(0x0702, 0x0000, 0x25, 600, 3600, 0x01,[destEndpoint: 0x02]) // CurrentSummationDelivered
zigbee.configureReporting(0x0B04, 0x0304, 0x21, 60, 600, 0x01,[destEndpoint: 0x02]) // TotalActivePower
zigbee.configureReporting(0x0B04, 0x0505, 0x21, 60, 600, 0x01,[destEndpoint: 0x02]) // RMSVoltagePhA
zigbee.configureReporting(0x0B04, 0x0508, 0x21, 60, 600, 0x01,[destEndpoint: 0x02]) // RMSCurrentPhA

}

My next challange: I get data from device very often, about 6-8 times a minute. This is not necessary at this point, so I have minimum reporting time to 60 sec and maximum to 3600 or 600 (sse code above).

Any ideas why the device is sending more often then I have requested?

I have also set ut 4 different attributes to ready, but I only get update from two of them. Any suggestions why not all 4 attributes are updated? Where should I start debugging?

New update: I have rewritten all code based on Zigbee Power meter. It is working much better now.

/**
 *  Copyright 2019 SmartThings
 *
 *  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.
 *
 */
metadata {
    definition (name: "Zigbee Energy Meter Test", namespace: "Testing", author: "Testing", mnmn: "Testing", vid: "Testing") {
        capability "Energy Meter"
        capability "Power Meter"
        capability "Refresh"
        capability "Health Check"
        capability "Sensor"
        capability "Configuration"

        fingerprint profileId: "0104", deviceId:"0053", inClusters: "0000, 0003, 0004, 0B04, 0702", outClusters: "0019", manufacturer: "Develco Products A/S", model: "“EMIZB-132", deviceJoinName: ""
        
    }

    // tile definitions
    tiles(scale: 2) {
        multiAttributeTile(name:"power", type: "generic", width: 6, height: 4){
            tileAttribute("device.power", key: "PRIMARY_CONTROL") {
                attributeState("default", label:'${currentValue} W')
            }
            tileAttribute("device.energy", key: "SECONDARY_CONTROL") {
                attributeState("default", label:'${currentValue} kWh')
            }
        }
        standardTile("RMSVoltagePhA", "device.RMSVoltagePhA", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
            state "default", label:'Voltage A: ${currentValue} V'
        }
        standardTile("RMSCurrentPhA", "device.RMSCurrentPhA", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
            state "default", label:'Current A: ${currentValue} A'
        }
        standardTile("RMSVoltagePhB", "device.RMSVoltagePhB", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
            state "default", label:'Voltage B: ${currentValue} V'
        }
        standardTile("RMSCurrentPhB", "device.RMSCurrentPhB", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
            state "default", label:'Current B: ${currentValue} A'
        }
        standardTile("RMSVoltagePhC", "device.RMSVoltagePhC", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
            state "default", label:'Voltage C: ${currentValue} V'
        }
        standardTile("RMSCurrentPhC", "device.RMSCurrentPhC", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
            state "default", label:'Current C: ${currentValue} A'
        }
        /*standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
            state "default", label:'reset kWh', action:"reset"
        }*/
        standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
            state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
        }

        main (["power", "energy"])
        details(["power", "energy","RMSVoltagePhA","RMSCurrentPhA","RMSVoltagePhB", "RMSCurrentPhB","RMSVoltagePhC", "RMSCurrentPhC", "refresh"])
    }
}

def parse(String description) {
   // log.debug "description is $description"
	    
    def descMap = zigbee.parseDescriptionAsMap(description)
    
    if(descMap) {
        List result = []
                
        List attrData = [[cluster: descMap.cluster ,attrId: descMap.attrId, value: descMap.value]]
        descMap.additionalAttrs.each {
            attrData << [cluster: descMap.cluster, attrId: it.attrId, value: it.value]
        }
        attrData.each {
                def map = [:]
                
               // log.debug "ClusterId: ${it.cluster} AttributeId: ${it.attrId} Value: ${it.value}"
                 
                if (it.cluster == "0B04" && it.attrId == "0304") {
                        log.debug "Power Value: ${zigbee.convertHexToInt(it.value)/1000}"
                        map.name = "power"
                        map.value = zigbee.convertHexToInt(it.value)/1000
                        map.unit = "W"
                }
                if (it.cluster == "0702" && it.attrId == "0000") {
                         log.debug "Energy Value: ${zigbee.convertHexToInt(it.value)}"
                         map.name = "energy"
                         map.value = zigbee.convertHexToInt(it.value)/1000
                         map.unit = "kWh"
                }
                if (it.cluster == "0B04" && it.attrId == "0505") {
                         log.debug "RMSVoltagePhA Value: ${zigbee.convertHexToInt(it.value)}"
                         map.name = "RMSVoltagePhA"
                         map.value = zigbee.convertHexToInt(it.value)
                         map.unit = "V"
                }
                if (it.cluster == "0B04" && it.attrId == "0508") {
                         log.debug "RMSCurrentPhA Value: ${zigbee.convertHexToInt(it.value)}"
                         map.name = "RMSCurrentPhA"
                         map.value = zigbee.convertHexToInt(it.value)
                         map.unit = "A"
                }
                if (it.cluster == "0B04" && it.attrId == "0905") {
                         log.debug "RMSVoltagePhB Value: ${zigbee.convertHexToInt(it.value)}"
                         map.name = "RMSVoltagePhB"
                         map.value = zigbee.convertHexToInt(it.value)
                         map.unit = "V"
                }
                if (it.cluster == "0B04" && it.attrId == "0908") {
                         log.debug "RMSCurrentPhB Value: ${zigbee.convertHexToInt(it.value)}"
                         map.name = "RMSCurrentPhB"
                         map.value = zigbee.convertHexToInt(it.value)
                         map.unit = "A"   
                }
                if (it.cluster == "0B04" && it.attrId == "0a05") {
                         log.debug "RMSVoltagePhC Value: ${zigbee.convertHexToInt(it.value)}"
                         map.name = "RMSVoltagePhC"
                         map.value = zigbee.convertHexToInt(it.value)
                         map.unit = "V"  
                }
                if (it.cluster == "0B04" && it.attrId == "0a08") {
                         log.debug "RMSCurrentPhC Value: ${zigbee.convertHexToInt(it.value)}"
                         map.name = "RMSCurrentPhC"
                         map.value = zigbee.convertHexToInt(it.value)
                         map.unit = "A"   
                }
                
                if (map) {
                        result << createEvent(map)
                }
                //log.debug "Parse returned $map"
                
        }
        return result      
    }
}


/**
 * PING is used by Device-Watch in attempt to reach the Device
 * */
def ping() {
    return refresh()
}

def refresh() {
    log.debug "refresh "
    zigbee.electricMeasurementPowerRefresh() +
           zigbee.simpleMeteringPowerRefresh()
}

def configure() {
    // this device will send instantaneous demand and current summation delivered every 1 minute
    sendEvent(name: "checkInterval", value: 2 * 60 + 10 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])

    log.debug "Configuring Reporting"
    return refresh() +
           zigbee.simpleMeteringPowerConfig() +
           zigbee.electricMeasurementPowerConfig()
}
1 Like

Hi Tore,

I have an almost identical device, a Develco MEIZH-061. I have gone through the documentation for it and changed only a few things. However I am not able to get it to show anything important.

The two tecnical docs here for comparing:

With this code I manage to add the device but only with the classic mobile app, not the new one.

When connected however the “thing” is showing “please wait” in the classic app, and connected but no activity in the new app.

I hope you can point me in the right direction on this one.

Here is my full code, which is the same as your code, with a few minor changes:

**

  • Copyright 2019 SmartThings
  • 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.

*/
metadata {
definition (name: “Develco MEIZH-061 Device Handler”, namespace: “02dag”, author: “Testing”, mnmn: “Testing”, vid: “Testing”) {
capability “Energy Meter”
capability “Power Meter”
capability “Refresh”
capability “Health Check”
capability “Sensor”
capability “Configuration”

    fingerprint profileId: "0104", deviceId:"0053", inClusters: "0000, 0003, 0004, FC00, 0702", outClusters: "0019", manufacturer: "Develco Products A/S", model: "“MEIZH-061", deviceJoinName: ""
    
}

// tile definitions
tiles(scale: 2) {
    multiAttributeTile(name:"power", type: "generic", width: 6, height: 4){
        tileAttribute("device.power", key: "PRIMARY_CONTROL") {
            attributeState("default", label:'${currentValue} W')
        }
        tileAttribute("device.energy", key: "SECONDARY_CONTROL") {
            attributeState("default", label:'${currentValue} kWh')
        }
    }
    standardTile("RMSVoltagePhA", "device.RMSVoltagePhA", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
        state "default", label:'Voltage A: ${currentValue} V'
    }
    standardTile("RMSCurrentPhA", "device.RMSCurrentPhA", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
        state "default", label:'Current A: ${currentValue} A'
    }
    standardTile("RMSVoltagePhB", "device.RMSVoltagePhB", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
        state "default", label:'Voltage B: ${currentValue} V'
    }
    standardTile("RMSCurrentPhB", "device.RMSCurrentPhB", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
        state "default", label:'Current B: ${currentValue} A'
    }
    standardTile("RMSVoltagePhC", "device.RMSVoltagePhC", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
        state "default", label:'Voltage C: ${currentValue} V'
    }
    standardTile("RMSCurrentPhC", "device.RMSCurrentPhC", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
        state "default", label:'Current C: ${currentValue} A'
    }
    /*standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
        state "default", label:'reset kWh', action:"reset"
    }*/
    standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
        state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
    }

    main (["power", "energy"])
    details(["power", "energy","RMSVoltagePhA","RMSCurrentPhA","RMSVoltagePhB", "RMSCurrentPhB","RMSVoltagePhC", "RMSCurrentPhC", "refresh"])
}

}

def parse(String description) {
// log.debug “description is $description”

def descMap = zigbee.parseDescriptionAsMap(description)

if(descMap) {
    List result = []
            
    List attrData = [[cluster: descMap.cluster ,attrId: descMap.attrId, value: descMap.value]]
    descMap.additionalAttrs.each {
        attrData << [cluster: descMap.cluster, attrId: it.attrId, value: it.value]
    }
    attrData.each {
            def map = [:]
            
           // log.debug "ClusterId: ${it.cluster} AttributeId: ${it.attrId} Value: ${it.value}"
             
            if (it.cluster == "FC00" && it.attrId == "03FF") {
                    log.debug "Power Value: ${zigbee.convertHexToInt(it.value)/1000}"
                    map.name = "power"
                    map.value = zigbee.convertHexToInt(it.value)/1000
                    map.unit = "W"
            }
            if (it.cluster == "0702" && it.attrId == "0000") {
                     log.debug "Energy Value: ${zigbee.convertHexToInt(it.value)}"
                     map.name = "energy"
                     map.value = zigbee.convertHexToInt(it.value)/1000
                     map.unit = "kWh"
            }
            if (it.cluster == "FC00" && it.attrId == "041E") {
                     log.debug "RMSVoltagePhA Value: ${zigbee.convertHexToInt(it.value)}"
                     map.name = "RMSVoltagePhA"
                     map.value = zigbee.convertHexToInt(it.value)
                     map.unit = "V"
            }
            if (it.cluster == "FC00" && it.attrId == "0434") {
                     log.debug "RMSCurrentPhA Value: ${zigbee.convertHexToInt(it.value)}"
                     map.name = "RMSCurrentPhA"
                     map.value = zigbee.convertHexToInt(it.value)
                     map.unit = "A"
            }
            if (it.cluster == "FC00" && it.attrId == "041F") {
                     log.debug "RMSVoltagePhB Value: ${zigbee.convertHexToInt(it.value)}"
                     map.name = "RMSVoltagePhB"
                     map.value = zigbee.convertHexToInt(it.value)
                     map.unit = "V"
            }
            if (it.cluster == "FC00" && it.attrId == "0435") {
                     log.debug "RMSCurrentPhB Value: ${zigbee.convertHexToInt(it.value)}"
                     map.name = "RMSCurrentPhB"
                     map.value = zigbee.convertHexToInt(it.value)
                     map.unit = "A"   
            }
            if (it.cluster == "FC00" && it.attrId == "0420") {
                     log.debug "RMSVoltagePhC Value: ${zigbee.convertHexToInt(it.value)}"
                     map.name = "RMSVoltagePhC"
                     map.value = zigbee.convertHexToInt(it.value)
                     map.unit = "V"  
            }
            if (it.cluster == "FC00" && it.attrId == "0436") {
                     log.debug "RMSCurrentPhC Value: ${zigbee.convertHexToInt(it.value)}"
                     map.name = "RMSCurrentPhC"
                     map.value = zigbee.convertHexToInt(it.value)
                     map.unit = "A"   
            }
            
            if (map) {
                    result << createEvent(map)
            }
            //log.debug "Parse returned $map"
            
    }
    return result      
}

}

/**

  • PING is used by Device-Watch in attempt to reach the Device
  • */
    def ping() {
    return refresh()
    }

def refresh() {
log.debug "refresh "
zigbee.electricMeasurementPowerRefresh() +
zigbee.simpleMeteringPowerRefresh()
}

def configure() {
// this device will send instantaneous demand and current summation delivered every 1 minute
sendEvent(name: “checkInterval”, value: 2 * 60 + 10 * 60, displayed: false, data: [protocol: “zigbee”, hubHardwareId: device.hub.hardwareID])

log.debug "Configuring Reporting"
return refresh() +
       zigbee.simpleMeteringPowerConfig() +
       zigbee.electricMeasurementPowerConfig()

}

I also have to mention that I get nothing in the logs. I also see now that you eare referencing device.rmscurrentpha which is not what it is called in the new device. Could it be that simple?

It should not be “Thing” in your classic app. So you have to change the device handler for your device to the one you have created. This is done under My Devices in Smartthings IDE.

ok, that was stupid of me, but I learn something everyday. I thought the connection between the device handler and the device was automatic, when you had a device handler with the correct device information.

Ok, so what happened now is that there was a small change in the behavior. I got two new tiles, but still no data.

My guess is that this is due to either incorrect naming or some incorrect attribute. I have changed the cluster id to fc00 instead of 0b04 and the attribute ids since this seemed logical according to the two technical documents. This may of course be incorrect. I am feeling that I am so close now.

Do you get anything in Live Logging at all from device? I had to do a factory resetting to make it work first time. But not sure if it was an acctual problem or a user problem…

I had to factory reset it to make it connect to smartthings at all. First of all it connects as a “thing” My guess is that if I factory reset it now it will not reconnect to the same device, but a new “thing”. But I can try.
Nothing in the logs, but I see that you have remmed out some loging/debugging options. How do they work?

But you should have got some information from “log.debug”-statements for each paramter. But if there are not match you will not get anything.
Try to un-comment this line by removing // .

// log.debug “description is $description”

Remenber to save and publish-self

ok, here are my findings:

Did a factory reset of the device, and it stopped working. Deleted the device and tried to readd it.

Impossibe to do from the new smartthings ios app. Tried again from the old app and it actually found the device with the name I gave it,so not a “thing” anymore.

I had already published the debugging, and by looking at the live logging, something turned up:

debug Parse returned [:]
debug ClusterId: 0702 AttributeId: 0400 Value: 000388
debug description is read attr - raw: 4BF80207020C00042A880300, dni: 4BF8, endpoint: 02, cluster: 0702, size: 12, attrId: 0400, result: success, encoding: 2a, value: 000388
debug Parse returned [:]
debug ClusterId: 0702 AttributeId: 0400 Value: 0003ac
debug description is read attr - raw: 4BF80207020C00042AAC0300, dni: 4BF8, endpoint: 02, cluster: 0702, size: 12, attrId: 0400, result: success, encoding: 2a, value: 0003ac

And here is some other if I do some fast refreshes in the classic app. With the refresh button which works. I can also mention that all the tiles are present in the classic app, but not in the new app.

debug Parse returned [:]
debug ClusterId: 0702 AttributeId: 0400 Value: 0033b9
debug description is read attr - raw: 4BF80207020E0004002AB93300, dni: 4BF8, endpoint: 02, cluster: 0702, size: 14, attrId: 0400, result: success, encoding: 2a, value: 0033b9
debug Parse returned [:]
debug ClusterId: null AttributeId: 050B Value: null
debug description is catchall: 0104 0B04 02 01 0000 00 4BF8 00 00 0000 01 01 0B0586
debug Parse returned [:]
debug ClusterId: null AttributeId: 050B Value: null
debug description is catchall: 0104 0B04 02 01 0000 00 4BF8 00 00 0000 01 01 0B0586
debug refresh
debug refresh
info SHM getInitialData 0.04 (00) incidents:00, locationId:c0c68ec0-c950-462b-bfc9-a4092abe581b
debug summaryData: [[icon:indicator-dot-green, iconColor:#79b821, value:Everything OK, heroInfo:[heroStatus:ok, heroMessage:Everything OK]]] - [[heroInfo:[heroMessage:Everything OK, heroStatus:ok], icon:indicator-dot-green, iconColor:#79b821, value:Everything OK]]
trace getPhrases(), state.welcomeIssue = null
trace getPhrases(), state.welcomeIssue = null
debug Parse returned [:]
debug ClusterId: 0702 AttributeId: 0400 Value: 00345d

Thats good! Now you can read data (at least Cluster 0702; attribute 0400)
Please uncomment this line to debug even more:

Then you can match ClusterId and AttributeId in the IF statemants with your findings.

I already did, and the result in the log is already there.

Is the device handler reading through all attributes in all clusters or do you target only the specific attributes that you are after?

I my code I have targeted specific attributes. But you should be able to ready more attributes than only 0400 from cluster 0702 8as it seems from log.
But I am not sure why you do not receive anything else…

Hi @tore.dahl,

How has this device been working for you? I’m looking at their External Meter Interface (https://www.develcoproducts.com/products/meter-interfaces/external-meter-interface/) because it may actually work with the smart meter installed by our power company via the optical port on the front.

How often does your device report energy and power values?