Zigbee Energy Meter

So a few years ago Xcel Energy gave me a EnergyHub home monitor. I have since retired it and I no longer use most of the stuff that it came with.
It included the following zigbee devices

  1. Honeywell Thermostat (I replaced it when I got Wink with a Honeywell Wifi)
  2. 2 Zigbee plug modules (these proved to be most unreliable with them turning on and off when you tried to turn them on)
  3. Energy meter.

Now I’m most interested in the energy meter. This device is similar in nature to the Aeon labs clamps. It sits outside of my breaker box mounted on the wall. It has a green button on the front to reset it and then has wires that go up and into the panel with 2 clamps that go around my mains.

So here is where I’m at so far with this. I’ve managed to get the fingerprint ID from it:
09 0104 0100 00 06 0000 0003 0004 0005 0006 0702 01 000A

I have this much written in the code for it:

/**

 */
 
  def getClusters() { 
"zdo active 0x${device.deviceNetworkId}" 
log.debug "Get Clusters Called";
}

metadata {
	definition (name: "Energy Hub Energy Meter", namespace: "thefuzz4", author: "Jason Hamilton") {
		capability "Energy Meter"
		capability "Power Meter"
		capability "Configuration"
		capability "Sensor"

		command "reset"

		fingerprint profileId: "0104", deviceId: "0100", inClusters: "0000,0003,0004,0005,0006,0702", outClusters: "000A"	}
	}

	

So the device does now indeed identify itself with the app and I’m trying to get it to output the getclusters like I did with the water sensor but so far no love.

While I continue to work on this, has anyone else had any luck with a Zigbee energy usage monitor?

I’ve been trying to find online just who made this box and since I’m not at home at the moment I can’t crack it open to see if the manufacture is listed anywhere in there.

Thank you all for your help with this in advance.

this tread will get you a little bit further,

zigbee - quirky-overflow

I see where I screwed up with this. Unlike in the Quirky Overflow I put the get clusters at the top. Just moved it down and published it. Lets see what it spits out in the logs now. Thank you @sidjohn1

Great project. Can you show the rest of your code? Your going to need to query cluster 0x0702 (meter cluster) attributes to get the power reading. Have you got that far yet?

Hey John,

That actually is all of my code. Right now I’m just trying to get it to spill its guts but nothing shows up in the log when I pair it up.

I’ll have to investigate how to query that cluster. Thank you for the help.

So far this is what I have

/**

 */
 
metadata {
	definition (name: "Energy Hub Energy Meter", namespace: "thefuzz4", author: "Jason Hamilton") {
		capability "Energy Meter"
		capability "Power Meter"
		capability "Configuration"
		capability "Sensor"

		command "reset"

		fingerprint profileId: "0104", deviceId: "0100", inClusters: "0000,0003,0004,0005,0006,0702", outClusters: "000A"	}
	}

/**def getClusters() { 
     "zdo active 0x${device.deviceNetworkId}" 
       log.debug "Get Clusters Called";	
       }
*/


	// tile definitions
	tiles {
		valueTile("power", "device.power", decoration: "flat") {
			state "default", label:'${currentValue} W'
		}
		valueTile("energy", "device.energy", decoration: "flat") {
			state "default", label:'${currentValue} kWh'
		}
		standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat") {
			state "default", label:'reset kWh', action:"reset"
		}
		standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}
		standardTile("configure", "device.power", inactiveLabel: false, decoration: "flat") {
			state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
		}

		main (["power","energy"])
		details(["power","energy", "reset","refresh", "configure"])
	}
    
    def refresh()
{
	log.debug "Refreshing Power"
	[
        "st rattr 0x${device.deviceNetworkId} ${endpointId} 2 0 {}"

]
}

def parse(String description) {
	log.debug "description: $description"

	Map map = [:]
	if (description?.startsWith('catchall:')) {
		map = parseCatchAllMessage(description)
	}
	else if (description?.startsWith('read attr -')) {
		map = parseReportAttributeMessage(description)
	}
    else if (description?.startsWith('zone status')) {
	    map = parseIasMessage(description)
    }

	log.debug "Parse returned $map"
	def result = map ? createEvent(map) : null

    if (description?.startsWith('enroll request')) {
    	List cmds = enrollResponse()
        log.debug "enroll response: ${cmds}"
        result = cmds?.collect { new physicalgraph.device.HubAction(it) }
    }
    return result
}
def enrollResponse() {
	log.debug "Sending enroll response"
    [	

	"raw 0x500 {01 23 00 00 00}", "delay 200",
    "send 0x${device.deviceNetworkId} 1 1"

    ]
}

I’m trying to figure out how to query the 0702 cluster by reading through the ST zigbee primer.

I’m still learning how to program so a lot of this is quite foreign to me. If possible could someone provide me some tips here on how to query that cluster? Thanks.

Try this out. It’s based on the GE Zigbee Dimmer device type that’s shared in the IDE. That device supports the same endpoints (and then some). Stripped out the on/off and dimmer stuff and am left with what’s below

/*

*/

metadata {
	// Automatically generated. Make future change here.
	definition (name: "Energy Hub Energy Meter", namespace: "thefuzz4", author: "Jason Hamilton") {
		capability "Power Meter"
		capability "Configuration"
		capability "Sensor"
		capability "Refresh"
	fingerprint profileId: "0104", deviceId: "0100", inClusters: "0000,0003,0004,0005,0006,0702", outClusters: "000A"
	}

	// simulator metadata
	simulator {

	}

	// UI tile definitions
	tiles {
		standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
			state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
		}
        valueTile("power", "device.power", inactiveLabel: false, decoration: "flat") {
			state "power", label:'${currentValue} Watts'
		}
		main "power"
		details([ "power", "refresh"])
	}
}

// Parse incoming device messages to generate events
def parse(String description) {
	log.info description
	if (description?.startsWith("catchall:")) {
		def msg = zigbee.parse(description)
		log.trace "data: $msg.data"

	} else if (description?.startsWith("read attr -")) {
		def descMap = parseDescriptionAsMap(description)
		log.debug "Read attr: $description"
    } else if (descMap.cluster == "0006" && descMap.attrId == "0000") {
			name = "switch"
			value = descMap.value.endsWith("01") ? "on" : "off"
            def result = createEvent(name: name, value: value)
            log.debug "Parse returned ${result?.descriptionText}"
            return result
    } else if(descMap.cluster =="0702" && descMap.attrId == "0400") {
        def value = convertHexToInt(descMap.value)/10 
        //Dividing by 10 as the Divisor is 10000 and unit is kW for the device. AttrId: 0302 and 0300. Simplifying to 10
        log.debug value
        def name = "power"
        def result = createEvent(name: name, value: value)
        log.debug "Parse returned ${result?.descriptionText}"
        return resulthttps://graph.api.smartthings.com/ide/device/editor/f64c2963-da1e-4ce3-8263-c9922e506c9c#
	
    } else {
		def name = description?.startsWith("on/off: ") ? "switch" : null
		def value = name == "switch" ? (description?.endsWith(" 1") ? "on" : "off") : null
		def result = createEvent(name: name, value: value)
		log.debug "Parse returned ${result?.descriptionText}"
		return result
	}
}


def refresh() {
	[
		"st rattr 0x${device.deviceNetworkId} ${endpointId} 6 0", "delay 200",
		"st rattr 0x${device.deviceNetworkId} ${endpointId} 0x0702 0x0400"
	]

}

def configure() {

	def configCmds = [
    
		"zdo bind 0x${device.deviceNetworkId} ${endpointId} 1 6 {${device.zigbeeId}} {}", "delay 200",
        "st rattr 0x${device.deviceNetworkId} ${endpointId} 0x0702 0x0400"


	]

	configCmds + refresh()
}

def meter() {
    [
        "delay 3000", "st rattr 0x${device.deviceNetworkId} ${endpointId} 0x0702 0x0400"
    ]
}

def parseDescriptionAsMap(description) {
	(description - "read attr - ").split(",").inject([:]) { map, param ->
		def nameAndValue = param.split(":")
		map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
	}
}

private hex(value, width=2) {
	def s = new BigInteger(Math.round(value).toString()).toString(16)
	while (s.size() < width) {
		s = "0" + s
	}
	s
}

private Integer convertHexToInt(hex) {
    Integer.parseInt(hex,16)
}

private getEndpointId() {
	new BigInteger(device.endpointId, 16).toString()
}

Hey Kevin,

Trying it out now. Throwing a syntax error around line 56. Trying to figure out what its complaining about

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
script14358724058421506058167.groovy: 56: expecting '}', found ':' @ line 56, column 27.
return resulthttps://graph.api.smartthings.com/ide/device/editor/f64c2963-da1e-4ce3-8263-c9922e506c9c#
^

1 error

Found it there is a resulthttps in there so I just cleaned that up.

Getting farther with this now. Its actually spitting some stuff out into the logs

64c66fce-9138-49b7-b3c6-a8f2030fc98f 3:31:08 PM: debug Read attr: read attr - raw: 66A209070206000486, dni: 66A2, endpoint: 09, cluster: 0702, size: 06, attrId: 0400, result: unsupported attr
64c66fce-9138-49b7-b3c6-a8f2030fc98f 3:31:08 PM: info read attr - raw: 66A209070206000486, dni: 66A2, endpoint: 09, cluster: 0702, size: 06, attrId: 0400, result: unsupported attr
64c66fce-9138-49b7-b3c6-a8f2030fc98f 3:31:08 PM: trace data: [0, 0, 0, 16, 1]
64c66fce-9138-49b7-b3c6-a8f2030fc98f 3:31:08 PM: info catchall: 0104 0006 09 01 0100 00 66A2 00 00 0000 01 01 0000001001
64c66fce-9138-49b7-b3c6-a8f2030fc98f 3:31:07 PM: debug Read attr: read attr - raw: 66A209070206000486, dni: 66A2, endpoint: 09, cluster: 0702, size: 06, attrId: 0400, result: unsupported attr
64c66fce-9138-49b7-b3c6-a8f2030fc98f 3:31:07 PM: info read attr - raw: 66A209070206000486, dni: 66A2, endpoint: 09, cluster: 0702, size: 06, attrId: 0400, result: unsupported attr
64c66fce-9138-49b7-b3c6-a8f2030fc98f 3:31:07 PM: trace data: [0, 0, 0, 16, 1]
64c66fce-9138-49b7-b3c6-a8f2030fc98f 3:31:07 PM: info catchall: 0104 0006 09 01 0100 00 66A2 00 00 0000 01 01 0000001001

At least now I can see its truly talking with the hub now to figure out what it doesn’t like about it.

So I’m wondering if this thread

That talks about the older Zigbee firmware might be the issue. I’ve had this device for about 3 years I think so I wonder if I’ll need some ugly code like that thread mentions in order to get this to report?

Does anyone have any thoughts on this? It would be cool if I could put this device back into action. Thank you all so much for your help it is really appreciate. Here is the output from today’s logs

64c66fce-9138-49b7-b3c6-a8f2030fc98f 10:46:07 AM: debug Read attr: read attr - raw: 66A209070206000486, dni: 66A2, endpoint: 09, cluster: 0702, size: 06, attrId: 0400, result: unsupported attr
64c66fce-9138-49b7-b3c6-a8f2030fc98f 10:46:07 AM: info read attr - raw: 66A209070206000486, dni: 66A2, endpoint: 09, cluster: 0702, size: 06, attrId: 0400, result: unsupported attr
64c66fce-9138-49b7-b3c6-a8f2030fc98f 10:46:07 AM: trace data: [0, 0, 0, 16, 1]
64c66fce-9138-49b7-b3c6-a8f2030fc98f 10:46:07 AM: info catchall: 0104 0006 09 01 0100 00 66A2 00 00 0000 01 01 0000001001
64c66fce-9138-49b7-b3c6-a8f2030fc98f 10:46:03 AM: debug Read attr: read attr - raw: 66A209070206000486, dni: 66A2, endpoint: 09, cluster: 0702, size: 06, attrId: 0400, result: unsupported attr
64c66fce-9138-49b7-b3c6-a8f2030fc98f 10:46:03 AM: info read attr - raw: 66A209070206000486, dni: 66A2, endpoint: 09, cluster: 0702, size: 06, attrId: 0400, result: unsupported attr
64c66fce-9138-49b7-b3c6-a8f2030fc98f 10:46:03 AM: trace data: [0, 0, 0, 16, 1]
64c66fce-9138-49b7-b3c6-a8f2030fc98f 10:46:03 AM: info catchall: 0104 0006 09 01 0100 00 66A2 00 00 0000 01 01 0000001001

I think there’s an issue with the code I put together.

Try changing this

def configCmds = [

	"zdo bind 0x${device.deviceNetworkId} ${endpointId} 1 6 {${device.zigbeeId}} {}", "delay 200",
    "st rattr 0x${device.deviceNetworkId} ${endpointId} 0x0702 0x0400"


]

to this

def configCmds = [

	"zdo bind 0x${device.deviceNetworkId} ${endpointId} 1 6 {${device.zigbeeId}} {}", "delay 200",
    "st rattr 0x${device.deviceNetworkId} ${endpointId} 0x0702"


]

The 0x0400 shouldn’t be there

Thank you @kevintierney just published it will let you know the results :smile:

Ok so now with that changed and I also had to remove it from the refresh part as well. Here is what the logs now show

64c66fce-9138-49b7-b3c6-a8f2030fc98f 3:08:46 PM: trace data: [0, 0, 0, 16, 1]
64c66fce-9138-49b7-b3c6-a8f2030fc98f 3:08:46 PM: info catchall: 0104 0006 09 01 0100 00 66A2 00 00 0000 01 01 0000001001

So while it looks like we’re now talking to the device with no errors it isn’t reporting back its status correctly yet. I wonder what I’m gong to need to query on in order to get the current energy usage. I also know that once it hits it correctly the light on it should change color, right now its red but once we’re querying it properly it should go go to green I think.

Ok I also found this going into the device from 5 days ago

Name	Value
data	
{
    "id": "64c66fce-9138-49b7-b3c6-a8f2030fc98f",
    "name": "Energy Hub Energy Meter",
    "index": 2,
    "dni": "66A2"
}
date	2015-07-09 5:47:21.206 PM MDT (2015-07-09T23:47:21.206Z)
description	Energy Hub Energy Meter is a neighbor of Home Hub
deviceId	64c66fce-9138-49b7-b3c6-a8f2030fc98f
deviceTypeId	85c7df91-7cdd-4c5b-a7bb-00d5b49aabf0
displayed	false
eventSource	DEVICE
eventType	GRAPH
hubId	6cfa58ca-2367-445a-b8b0-9af2cc700389
id	d7321563-2694-11e5-93c2-22000b0c8328
isStateChange	false
isVirtualHub	false
linkText	
locationId	846d6e0a-dcc0-44e8-a09b-bac269bfa6c1
name	graph
rawDescription	raw:0266A20026C00000005705FE010304, index:02, dni:66A2, d:0026C00000005705, lqiAvg:FE, incomingPacketCost:01, outgoingPacketCost:03, agingPeriods:04
unixTime	1436485641206
value	nabes
viewed	false

So I emailed the energyhub people to see if they could give me a manual for this thing. However they could not but they did remind me that there is a code on the side of the box. Its a setup code for the thing. In my case the code is EF0. I remember when the guy came out he had to get this code off of all of the zigbee devices that they gave me (Honeywell Thermostat, 2 wall modules and this thing)

Do you think that this setupcode needs to be passed to the device to get it to spill its guts? I think that might also cause that LED outside to change to green as well.

Do you think that this might be in the realms of the HA devices where they only like to play nice with their own kind?

Jason

Hello Jason,

I posted some code that might be of use to solve the issue 0x702 issue you are having.
Im my code check the refresh and configure sections. Note that the configure button must be pressed on the simulator in order for the configure method to load and subscribe to the notifications.

Here is the link to the code.

Thanks,
Benjamin

2 Likes

Hey Benjamin @bortuzar I apologize for the delay here in my response I didn’t get the notification. I’m going to go give your code a whirl and see how it goes. Thank you very much for your help.

Ok so as I’ve stated before I’m no coder by any means but I can sometimes fiddle around enough to figure something out. Right now I’m getting an error on line 120 with this in regards to a null+null but I can’t find anything that looks funny here

/*

*/

metadata {
	// Automatically generated. Make future change here.
	definition (name: "Energy Hub Energy Meter", namespace: "thefuzz4", author: "Jason Hamilton") {
		capability "Power Meter"
		capability "Configuration"
		capability "Sensor"
		capability "Refresh"
	fingerprint profileId: "0104", deviceId: "0100", inClusters: "0000,0003,0004,0005,0006,0702", outClusters: "000A"
	}

	// simulator metadata
	simulator {

	}

	// UI tile definitions
	tiles {
		standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
			state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
		}
        valueTile("power", "device.power", inactiveLabel: false, decoration: "flat") {
			state "power", label:'${currentValue} Watts'
		}
		main "power"
		details([ "power", "refresh"])
        standardTile("configure", "device.power", inactiveLabel: false, decoration: "flat") {
		state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
		}
	}
}

// Parse incoming device messages to generate events
def parse(String description) {
	log.info description
	if (description?.startsWith("catchall:")) {
		def msg = zigbee.parse(description)
		log.trace "data: $msg.data"

	} else if (description?.startsWith("read attr -")) {
		def descMap = parseDescriptionAsMap(description)
		log.debug "Read attr: $description"
    } else if (descMap.cluster == "0006" && descMap.attrId == "0000") {
			name = "switch"
			value = descMap.value.endsWith("01") ? "on" : "off"
            def result = createEvent(name: name, value: value)
            log.debug "Parse returned ${result?.descriptionText}"
            return result
    } else if(descMap.cluster =="0702" && descMap.attrId == "0400") {
        def value = convertHexToInt(descMap.value)/10 
        //Dividing by 10 as the Divisor is 10000 and unit is kW for the device. AttrId: 0302 and 0300. Simplifying to 10
        log.debug value
        def name = "power"
        def result = createEvent(name: name, value: value)
        log.debug "Parse returned ${result?.descriptionText}"
        return result
	} 
    else {
		def name = description?.startsWith("on/off: ") ? "switch" : null
		def value = name == "switch" ? (description?.endsWith(" 1") ? "on" : "off") : null
		def result = createEvent(name: name, value: value)
		log.debug "Parse returned ${result?.descriptionText}"
		return result
	}
}

def meter() {
    [
        "delay 3000", "st rattr 0x${device.deviceNetworkId} ${endpointId} 0x0702 0X0400"
    ]
}

def refresh() {
  	log.debug "Refresh Method called";	
    [
		"st rattr 0x${device.deviceNetworkId} 1 6 0", "delay 500",    
        "st rattr 0x${device.deviceNetworkId} 1 0x0702 1024", , "delay 500"
	]
}


def configure() {

	log.debug "Configure Method called"

	String zigbeeId = swapEndianHex(device.hub.zigbeeId)
	
	def configCmds = [	
  
        //Switch Reporting
        "zcl global send-me-a-report 6 0 0x10 0 3600 {01}", "delay 500",
        "send 0x${device.deviceNetworkId} 1 1", "delay 1000",
        
        //bind to cluster 0x702. Power Consumption
        "zdo bind 0x${device.deviceNetworkId} 1 1 0x0702 {${device.zigbeeId}} {}", "delay 500",
        
        //read attribute 1024Dec/400Hex.
        //"st rattr 0x${device.deviceNetworkId} 1 0x0702 1024"
        
	]
    return configCmds + refresh() // send refresh cmds as part of config
}


def parseDescriptionAsMap(description) {
	(description - "read attr - ").split(",").inject([:]) { map, param ->
		def nameAndValue = param.split(":")
		map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
	}
}

private hex(value, width=2) {
	def s = new BigInteger(Math.round(value).toString()).toString(16)
	while (s.size() < width) {
		s = "0" + s
	}
}

private Integer convertHexToInt(hex) {
	Integer.parseInt(hex,16)
}


private String swapEndianHex(String hex) {
    reverseArray(hex.decodeHex()).encodeHex()
}



private byte[] reverseArray(byte[] array) {
    int i = 0;
    int j = array.length - 1;
    byte tmp;
    while (j > i) {
        tmp = array[j];
        array[j] = array[i];
        array[i] = tmp;
        j--;
        i++;
    }
    return array
}

Thank you all for your help with this.

Ok so nevermind about that I got it working.

So I pushed the configure button and this is what shows up in the logs

64c66fce-9138-49b7-b3c6-a8f2030fc98f 2:02:09 PM: trace data: [92, 130]
64c66fce-9138-49b7-b3c6-a8f2030fc98f 2:02:08 PM: info catchall: 0000 8021 00 00 0140 00 66A2 00 00 0000 00 00 5C82
64c66fce-9138-49b7-b3c6-a8f2030fc98f 2:02:08 PM: trace data: [91, 130]
64c66fce-9138-49b7-b3c6-a8f2030fc98f 2:02:08 PM: info catchall: 0000 8021 00 00 0140 00 66A2 00 00 0000 00 00 5B82

Any idea what that means?

So i’m pretty positive that the last hexadecimal there is the energy reading. I’m trying to figure out what changes need to be made to have that reading be displayed in the device.

Here is where I’m at

/*

*/

metadata {
	// Automatically generated. Make future change here.
	definition (name: "Energy Hub Energy Meter", namespace: "thefuzz4", author: "Jason Hamilton") {
		capability "Power Meter"
		capability "Configuration"
		capability "Sensor"
		capability "Refresh"
	fingerprint profileId: "0104", deviceId: "0100", inClusters: "0000,0003,0004,0005,0006,0702", outClusters: "000A"
	}

	// simulator metadata
	//simulator {
	
	// UI tile definitions
	tiles {

		standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat") {
			state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
		}
		valueTile("power", "device.power", inactiveLabel: false, decoration: "flat") {
			state "power", label: '${currentValue} W'
		}
        
        standardTile("configure", "device.power", inactiveLabel: false, decoration: "flat") {
			state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
		}

		
		main(["power"])
		details(["power", "refresh", "configure"])
	}
}


// Parse incoming device messages to generate events
def parse(String description) {

	log.debug "Parse Method Called"
	log.trace description
    
	if (description?.startsWith("catchall:")) {
		def msg = zigbee.parse(description)
		log.trace "data: $msg.data"

	} else if (description?.startsWith("read attr -")) {
		def descMap = parseDescriptionAsMap(description)
        log.debug "Desc Map:"
        log.debug descMap
		
        if (descMap.cluster == "0006" && descMap.attrId == "0000") {
                name = "switch"
                value = descMap.value.endsWith("01") ? "on" : "off"
                def result = createEvent(name: name, value: value)
                log.debug "Parse returned ${result?.descriptionText}"
                return result
        } else if(descMap.cluster =="0140" && descMap.attrId == "0600") {
            
            def value = convertHexToInt(descMap.value[-4..-1])/10 
            // Reading the last 4 characters of the string...Maybe 4 are needed. Needs further test.
            // Dividing by 10 as the Divisor is 10000 and unit is kW for the device. AttrId: 0302 and 0300. Simplifying to 10
            log.debug value
            def name = "power"
            def result = createEvent(name: name, value: value)
            log.debug "Parse returned ${result?.descriptionText}"
            return result 
        }
    } 
}

def refresh() {
  	log.debug "Refresh Method called";	
    [
		"st rattr 0x${device.deviceNetworkId} 1 6 0", "delay 500",    
        "st rattr 0x${device.deviceNetworkId} 1 0x140 1024", , "delay 500"
	]
}


def configure() {

	log.debug "Configure Method called"

	String zigbeeId = swapEndianHex(device.hub.zigbeeId)
	
	def configCmds = [	

        
        //bind to cluster 0x140. Power Consumption
        "zdo bind 0x${device.deviceNetworkId} 1 1 0x140 {${device.zigbeeId}} {}", "delay 500",
        
        //read attribute 1024Dec/400Hex.
        "st rattr 0x${device.deviceNetworkId} 1 0x140 1024"
        
	]
    return configCmds + refresh() // send refresh cmds as part of config
}


def parseDescriptionAsMap(description) {
	(description - "read attr - ").split(",").inject([:]) { map, param ->
		def nameAndValue = param.split(":")
		map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]}
}

private hex(value, width=2) {
	def s = new BigInteger(Math.round(value).toString()).toString(16)
	while (s.size() < width) {
		s = "0" + s
	}
	s
}

private Integer convertHexToInt(hex) {
	Integer.parseInt(hex,16)
}


private String swapEndianHex(String hex) {
    reverseArray(hex.decodeHex()).encodeHex()
}



private byte[] reverseArray(byte[] array) {
    int i = 0;
    int j = array.length - 1;
    byte tmp;
    while (j > i) {
        tmp = array[j];
        array[j] = array[i];
        array[i] = tmp;
        j--;
        i++;
    }
    return array
}

If someone could lend me a hand with this I would be forever in your debt :). I think that I am now super close thanks to @bortuzar for his code. I can see that I’m getting stuff back from the sensor but I just don’t know how to take that and tell ST to display this hex result as the kw value.