Read Attributes Response Squelched from Cluster 0x0003?

I’m working on adding support in the DTH for control over the “Retain State” setting of the Peanut Plug. I used Zshark with the ConBee to sniff out the commands used by the manufacturer’s hub to see how to control this feature. I can see that the feature is controlled by writing to cluster 0x0003 attribute 0x0000 (write 0x0000 to retain state, 0x1111 to forget state). When I try to read cluster 0x0003 attr 0x0000 from ST, I can see the Read and Read Response via Zshark sniffing. However, I don’t get any messages from cluster 0x0003 in the ST live logging. Is this something that is being squelched before parse() is called, or could something else be going on?

My read command (in a refresh function):
zigbee.readAttribute(0x0003,0x0000)

The relevant portion of my parse function - the info never shows up in the log:
def parse(String description) {
log.debug “description is $description”
if (description?.contains(“0003”)) {
log.info “Mentions 0003: $description”
}
// more code that works fine
}

Is this cluster in the fingerprint or device raw description?

Great question, I had to look to make sure. Yes, 0003 is listed both in inClusters and outClusters.

Full code (feature branch) here:

Why do you need to use readAttribute?

You could set an initial value when the plug is paired, and the DTH can track the setting using a state variable or preference setting.

Does the writeAttribute command successfully change the “Retain State” setting if you add it to the DTH?

The hub actually does consume all messages to the cluster 0x0003 and doesn’t pass them along to the DTH. That’s something that we can look at changing in the future but in the meantime I’d recommend trying @veeceeoh suggestion:

1 Like

Thanks for the reply, @tpmanley! It’s good to know what is going on so that I can program around it using @veeceeoh’s suggestion.

I’m not sure how many devices out there misuse the various ZCL/ZHA defined clusters, but it would be good to be able to interact with non-conforming devices. I wouldn’t want to interfere with the internal functionality of the hub, but to the degree possible, it would be nice to have as many messages as possible available to the DTH. Here is a dump of the packet being consumed:

ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
    Frame Control Field: Data (0x40)
        .... ..00 = Frame Type: Data (0x0)
        .... 00.. = Delivery Mode: Unicast (0x0)
        ..0. .... = Security: False
        .1.. .... = Acknowledgement Request: True
        0... .... = Extended Header: False
    Destination Endpoint: 1
    Cluster: Identify (0x0003)
    Profile: Home Automation (0x0104)
    Source Endpoint: 1
    Counter: 32
ZigBee Cluster Library Frame, Command: Read Attributes Response, Seq: 88
    Frame Control Field: Profile-wide (0x08)
        .... ..00 = Frame Type: Profile-wide (0x0)
        .... .0.. = Manufacturer Specific: False
        .... 1... = Direction: Server to Client
        ...0 .... = Disable Default Response: False
    Sequence Number: 88
    Command: Read Attributes Response (0x01)
    Status Record
        Attribute: Identify Time (0x0000)
        Status: Success (0x00)
        Data Type: 16-Bit Unsigned Integer (0x21)
        Identify Time: 0 seconds

That’s weird that it’s not even specifying it’s a Manufacturer Specific message in the ZCL Frame Control field. Zigbee makes it really easy to add manufacturer specific behavior in a compliant way but they don’t appear to have done that for some reason.

Sorry, that was the message that I generated to read the value. The Almond hub never sends a Read Attribute message. Here’s a Write Attribute and a Write Attribute Response that were generated using the manufacturer’s hardware. I think the net result is the same, and I was getting correct responses to my Read Attribute requests. It’s also very curious that it sends the message to the broadcast Endpoint on the node instead of the specific application’s endpoint number. But I just send the message with zigbee.writeAttribute, and it gets where it needs to without bothering to use a broadcast.

ZigBee Application Support Layer Data, Dst Endpt: 255, Src Endpt: 1
    Frame Control Field: Data (0x40)
        .... ..00 = Frame Type: Data (0x0)
        .... 00.. = Delivery Mode: Unicast (0x0)
        ..0. .... = Security: False
        .1.. .... = Acknowledgement Request: True
        0... .... = Extended Header: False
    Destination Endpoint: 255
    Cluster: Identify (0x0003)
    Profile: Home Automation (0x0104)
    Source Endpoint: 1
    Counter: 19
ZigBee Cluster Library Frame, Command: Write Attributes, Seq: 24
    Frame Control Field: Profile-wide (0x00)
        .... ..00 = Frame Type: Profile-wide (0x0)
        .... .0.. = Manufacturer Specific: False
        .... 0... = Direction: Client to Server
        ...0 .... = Disable Default Response: False
    Sequence Number: 24
    Command: Write Attributes (0x02)
    Attribute Field
        Attribute: Identify Time (0x0000)
        Data Type: 16-Bit Unsigned Integer (0x21)
        Identify Time: 4369 seconds

ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
    Frame Control Field: Data (0x40)
        .... ..00 = Frame Type: Data (0x0)
        .... 00.. = Delivery Mode: Unicast (0x0)
        ..0. .... = Security: False
        .1.. .... = Acknowledgement Request: True
        0... .... = Extended Header: False
    Destination Endpoint: 1
    Cluster: Identify (0x0003)
    Profile: Home Automation (0x0104)
    Source Endpoint: 1
    Counter: 220
ZigBee Cluster Library Frame, Command: Write Attributes Response, Seq: 24
    Frame Control Field: Profile-wide (0x08)
        .... ..00 = Frame Type: Profile-wide (0x0)
        .... .0.. = Manufacturer Specific: False
        .... 1... = Direction: Server to Client
        ...0 .... = Disable Default Response: False
    Sequence Number: 24
    Command: Write Attributes Response (0x04)
    Status Record
        Status: Success (0x00)

@jamesham, I apologise that I missed this and didn’t respond until now. Were you able to get it working?

Yes, thanks. I ended up not worrying about reading the state, and instead storing the intended setting in a preference. At configuration, if there isn’t a saved preference, I assume the default state of the device from the factory (retainState = true), and explicitly set it on the device. Overwrite as needed when the user’s preference changes.

Community code is here:

Makes sense - glad you got it working