Need guidance for decoding Zigbee message

Hi,
I've had no success decoding the ADC message from a Zigbee board.

I'm working with a TI cc2530 Zigbee board. This is similar to Dr Haas Thingshield. I've found some firmware for the board on a Zigbee2MQTT website. I've loaded this firmware and have paired it to my hub. This firmware has a Switch input (which is working) and an ADC which is what I cannot decode. The log results are below. I've not been able to understand the significance of the attrid:0055 and encoding:39. This may be the key but I've looked in every Zigbee document I could find and have come up with nothing useful.

Any suggestions would be very welcome.
Thanks
John

dev:12021-01-11 18:55:17.283 debugParse returned null
dev:12021-01-11 18:55:17.266 debugMap Value=000000006F0018001C00420156
dev:12021-01-11 18:55:17.263 debugRead Map= [raw:962B03000C20550039000000006F0018001C00420156, dni:962B, endpoint:03, cluster:000C, size:20, attrId:0055, encoding:39, command:0A, value:000000006F0018001C00420156]

My code such as it is.

    /**
 *   cc2530 Simple Test
 *
 *	Date: 2021-01-10
 */

metadata {
	definition (name: "cc2503", namespace: "johnrob", author: "johnrob") {
		capability "Actuator"
		capability "Switch"
		capability "Configuration"
		capability "Refresh"
		capability "Sensor"
	}

}  // --- metadata ---

// Parse incoming device messages to generate events
def parse(String description) {
	log.debug "Parse description= $description"
	def name = null
	def value = null
	if (description?.startsWith("read attr -")) {
		def descMap = parseDescriptionAsMap(description)
		log.debug "Read Map= $descMap"

		if (descMap.cluster == "000C" && descMap.attrId == "0055") {
			name = "ADC"
			value = descMap.value
            			log.debug "Map Value=${value}"
		}
	}
	def result = createEvent(name: name, value: value)
	log.debug "Parse returned ${result?.descriptionText}"
	return result
}

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

0x39 is FLOAT4 "Single precision", so either we're not parsing it correctly or the payload is corrupt.
I'll let you know when I find out...

1 Like

FWIW:

Below are the values for 0 Volts in and 1.42 Volts in.
If I understand the CC2530, 1.42V in should be ~1762 decimal counts

  0V  raw: 962B03000C20550039000000006F0018F31C00420156, value: 000000006F0018F31C00420156
  0V  raw: 962B03000C20550039000000006F0018001C00420156, value: 000000006F0018001C00420156
  0V  raw: 962B03000C20550039000000006F0018001C00420156, value: 000000006F0018001C00420156
  0V  raw: 962B03000C20550039000000006F0018001C00420156, value: 000000006F0018001C00420156
  0V  raw: 962B03000C20550039000000006F0018DA1C00420156, value: 000000006F0018DA1C00420156
  0V  raw: 962B03000C20550039000000006F0018F51C00420156, value: 000000006F0018F51C00420156
  0V  raw: 962B03000C20550039000000006F0018F51C00420156, value: 000000006F0018F51C00420156
  0V  raw: 962B03000C20550039000000006F0018DA1C00420156, value: 000000006F0018DA1C00420156
  0V  raw: 962B03000C20550039000000006F0018001C00420156, value: 000000006F0018001C00420156
  0V  raw: 962B03000C20550039000000006F0018F51C00420156, value: 000000006F0018F51C00420156
  0V  raw: 962B03000C20550039000000006F0018001C00420156, value: 000000006F0018001C00420156
  0V  raw: 962B03000C20550039000000006F0018F51C00420156, value: 000000006F0018F51C00420156
  0V  raw: 962B03000C20550039000000006F0018001C00420156, value: 000000006F0018001C00420156
1.4V  raw: 962B03000C20550039004070446F0018F51C00420156, value: 004070446F0018F51C00420156
1.4V  raw: 962B03000C20550039004070446F0018F51C00420156, value: 004070446F0018F51C00420156

it appears that the payload is invalid for data type 0x39 single precision (the frame is being parsed correctly) but it's supposed to be 4 octets, this device is sending 13
I see a pattern starting from the right, perhaps there are three single precision values and one extra byte at the beginning?
No idea.
Info on how to parse these data types starts at page 2-45, section 2.6.2.9 in the Zigbee Cluster library specification revision 6, Zigbee document 07-5123-06

Thats the best I can do right now to help.

1 Like

What firmware are you using?

If I understand the CC2530, 1.42V in should be ~1762 decimal counts

The 0x0055 PresentValue Attribute should contain an actual value, so your firmware should be sending 1.42V as a single float which would be 0x3fb5c28f until you decoded it. And obviously 0V would be 0x00000000

If you have a sniffer to hand you could see what the board is sending ..... but as Mike mentioned it sounds like the board is sending it wrong if that big value is making it into parse() .....

Is the data a response from read attribute? if yes, the format may be defined as in 2.5.2.1 Zigbee cluster library. It could be composed of multiple attributes from the same cluster. The parsing code may need to watch for this possibility.

In my opinion, here are the values.

962B03000C20 55003900000000 6F0018F3 1C00420156

55 00 39 00000000 //this is the float from present value
6F 00 12 F3 //this is status flag
1C 00 42 0156 //this is a description.

00 looks like a successful status.

If I have to guess, this is may be why the values are more than 4 bytes.

1 Like

@mike.maxwell @iharyadi

Thank you both for you time and responses :slight_smile: I try to find out more and if successful will post my findings.

John