Fingerprint (of device)

Could someone help explain something more about the Z-wave Device Raw Description

I have, as mentioned in a few posts now, a FGRM-222 Fibaro blinds controller. With the thanks of the ST team, I have this detected and the basics of a device type running. I am currently expanding its functionality, and have other questions raised about this.

However, I’d like to understand a little more about how the Raw Description is made up
This is how it is identified on my ST.
0 0 0x1106 0 0 0 12 0x72 0x86 0x70 0x85 0x25 0x73 0x32 0x31 0x7A 0x25 0x91 0x75 0xEF 0x32 0x31 0x91 0x2B 0x26

And here are the CommandClasses mapped to friendl(y)/(ier) names.

  • 0x72 V1 0x72 Manufacturer Specific
  • 0x86 V1 0x86 Version
  • 0x70 XX 0x70 Configuration
  • 0x85 V2 0x85 Association
  • 0x25 V1 0x25 Switch Binary
  • 0x32 V2 0x32 Meter
  • 0x31 V2 0x31 Sensor Multilevel
  • 0x25 V1 0x25 Switch Binary
  • 0x32 V2 0x32 Meter
  • 0x31 V2 0x31 Sensor Multilevel
  • 0x26 V3 0x26 Switch Multilevel
  • 0x25 V1 0x25 Switch Binary

What I have noticed is that some of the CommandClasses repeat (0x25)? Can someone explain that? Do they relate to the device effectively have multiple targets for each of those command classes? I understand there are device types specifically to “multi-instance” and “multi-channel”, so do not understand the duplication here?
Also if anyone can explain more the rest of the break down.

“0x72 0x86 0x70 0x85 0x25 0x73 0x32 0x31 0x7A 0x25 0x91 0x75 0xEF 0x32 0x31 0x91 0x2B 0x26”=CommandClasses

I think @duncan is the best to answer this. My swag at it is that they can return different Byte sized payloads, so you will need to parse the return accordingly.

1 Like

I don’t have the stomach to go into the full story of how the Raw Description is formatted and why. Just know that it was designed for ZigBee devices and Z-Wave was shoehorned in later.

What you need to know is that the command classes that come before 0xEF COMMAND_CLASS_MARK are the supported classes – what the device accepts, more or less – and the ones after the mark are the controlled classes – what the device sends to others.

For fingerprinting, we match the supported classes against the inClusters parameter and the controlled against outClusters.


I saw some “manufacturer” and “model” in the fingerprinting too. Is this advisable to use if known?

1 Like

Hi @duncan, I’ve been working on getting an off the shelf NXP module (ZigBee) to communicate well with ST. I have it talking now and am working on getting bindings correct etc. But one thing that would be nice is if the configure() ran automatically and my understanding from @urman is that it runs just once after pairing. If I don’t have my device type being identified though on pair (as is the case today) then doesn’t it lose it’s chance to run configure()?

So I have 2 related questions:

  1. is there a log or something that I can spit out when I pair a device to see what ST hub saw and used for it’s fingerprinting attempt? I’m guessing that’s probably not something you have today except internally but figured I would ask.

  2. If inClusters and outClusters match multiple Device Types how do you chose which one to use? I know there are other things like profileId and deviceId in the fingerprint statement, but you didnt mention those being used in the fingerprint process?

If the answer to (1) is there is no way, then I’m stuck either sniffing (and I don’t yet have a sniffer) or maybe I can log it out of the ZCL on the device side. Or I could try JTAG also but I don’t have JTAG. In which case I may just try to keep guessing for a while. :stuck_out_tongue:


  1. There is not that I know of. However I THINK you can get the cluster list by doing something like "zdo active 0x${device.deviceNetworkId}" in a device type and it should show in the live logging tab.

  2. If there is an issue with devices matching inCluster and outCluster than you can request manufacturer, model, and application that match to the response from the basic cluster attributes.

Ok, thanks. I tried this and no luck, but I’ll keep playing with it.

You could try adding this code:

def updated() {

That should run configure when the device type is changed.

1 Like

what are your values for manufacture, model, and application ?

From the NXP source, I believe they are setup as below:

void vAPP_ZCL_DeviceSpecific_Init()
    /* Initialise the strings in Basic */
    memcpy(sSensor.sBasicServerCluster.au8ManufacturerName, "NXP", CLD_BAS_MANUF_NAME_SIZE);
    memcpy(sSensor.sBasicServerCluster.au8ModelIdentifier, "ZHA-OccupancySensor", CLD_BAS_MODEL_ID_SIZE);
    memcpy(sSensor.sBasicServerCluster.au8DateCode, "20140604", CLD_BAS_DATE_SIZE);
    memcpy(sSensor.sBasicServerCluster.au8SWBuildID, "4000-0001", CLD_BAS_SW_BUILD_SIZE);
    /* Initialise the strings in Occupancy Cluster */
    sSensor.sOccupancySensingServerCluster.eOccupancySensorType = E_CLD_OS_SENSORT_TYPE_PIR;
    sSensor.sOccupancySensingServerCluster.u8Occupancy = 0;
    sSensor.sOccupancySensingServerCluster.u8PIRUnoccupiedToOccupiedThreshold = OCCUPANCY_SENSOR_UNOCCUPIED_TO_OCCUPIED_THRESHOLD;
    sSensor.sOccupancySensingServerCluster.u8PIRUnoccupiedToOccupiedDelay = OCCUPANCY_SENSOR_UNOCCUPIED_TO_OCCUPIED_DELAY;
    sSensor.sOccupancySensingServerCluster.u16PIROccupiedToUnoccupiedDelay = OCCUPANCY_SENSOR_OCCUPIED_TO_UNOCCUPIED_DELAY;

I will try and confirm/use this in my Device Type (“NXP” and “ZHA-OccupancySensor”)

Thanks, that will help during development for sure, and it’s great to know about functions like updated(). Eventually of course it would be nice to also get the fingerprinting working too.

@duncan Just thought about this. So does updated() run once AFTER the device type is changed? Just making sure, because otherwise the first time I pair and then change to my own device type it would have been “unknown” Thing so this update() wouldn’t be my version of it.

updated() runs after any device settings are changed, including the device type. So make sure it’s something that is okay to run multiple times.

Sorry, I know this is an old thread but don’t want to start a new one with the same topic.

I am trying to write my first device handler for a zigbee switch. Still learning about device handlers and groovy. Looking at the documentation, it mentions about fingerprinting which led me to this topic.

If I understood correctly what was in the documentation and the earlier discussions on this thread, there seems to be a relationship between the “Raw Description” and the “Fingerprint”. If that is so, what would be the correct fingerprint, inClusters and outClusters of the following raw description?

01 0104 0104 00 03 0000 0003 FC20 04 0006 0008 0003 0019

Is it safe to assume that it will be as follows?
fingerprint profileId: “0104”, inClusters: “0000,0003,FC20”, outClusters: “0006,0008,0003,0019”

Or, am I totally way-off on my assumption?

Hoping to learn from this community. :slight_smile:

1 Like

looks like you got yourself a lightbulb/dimmer switch

Actually, it is a Quirky Smart Switch. :slight_smile:

Hi @ericpatdu

Can you give me a little bit more detail on how you got this info/used it?


I know this is old, but I am working on the same issue. I am trying to write a device handler for an old zigbee device I have that keeps pairing as a thing. Is there a way I can get the Raw description to print.