UintABC - Reading as Little Endian and printing as Big Endian

@nayelyz , could you please ask devs whether there is any specific reason to read unsigned integers as Little Endian and print as Big Endian ?
It took me the whole morning until I found out it was just printing issue. :smiling_face_with_tear:
It is in the /st/zigbee/data_types/base_defs/UintABC.lua

Format Strings for Pack and Unpack

The first argument to string.pack, string.packsize, and string.unpack is a format string, which describes the layout of the structure being created or read.

A format string is a sequence of conversion options. The conversion options are as follows:

  • <: sets little endian
  • >: sets big endian

https://www.lua.org/manual/5.3/manual.html#6.4.2


Also, it would be great if UintABC could receive endianness parameter to determine which type we need.
Of course, it would demand printing something like “data: 0x4700 (BE)” or “data: 0x0047 (LE)”

1 Like

It was done this way because that felt like the more natural way people think of numbers. I.e. if I’m seeing a value of 0x0001 and 0x0100, without being very familiar with the specific details of how the messages are transferred over the air, 0x0100 looks bigger than 0x0001 but if we were printing LE that would be false. And similarly in the case where the value is showing up as an attributes such as the temperature, if someone is unfamiliar with hex and wants to copy paste to convert, the defaults for most things will assume BE if there is even an option to choose. So copying a 0x0100 from the log message to see what that value is in decimal, we wanted that to be natural. And finally when attempting to use the values that have been deserialized from a message if you are doing uintarg.value it made more sense for that value to line up with what is printed, as opposed to a raw number that would require further processing to use for the real world application (i.e. requiring every end user of a uint attribute value to have to manually do the LE->BE conversion to use the number as a number). If you are extending the UIntABC class for custom data types, you can override the pretty_print function on your type to print however you wish.

I do see that the documentation of this fact is pretty minimal and is mostly buried as just a couple of examples listed here: Zigbee Data Types — SmartThings Edge Device Drivers documentation which is certainly not ideal, and I will create a ticket to improve that documentation.

As for allowing for additional functionality of the data type to be either endianness I am curious what your use case is, as AFAIK all Zigbee values would be LE over the air.

4 Likes

That is because I am trying to make a device to work that I already own.
It uses 0xEF00 tuya cluster that is documented here: Zigbee Generic Interfaces-Tuya IoT Development Platform-Tuya Developer

length={
  byte_length=2, 
  field_name="length", 
  little_endian=false, 
  value=1, 
},
seqno={
  byte_length=2, 
  field_name="seqno", 
  little_endian=false, 
  value=189, 
},

Both as expected. Thanks!

Tuya uses Big Endian for some of their proprietary clusters, even though the devices are Zigbee-certified. They also put two values in one cluster in some cases. It’s allowed under the spec because manufacturer proprietary is allowed, but it’s really annoying. :thinking: