openhab/org.openhab.binding.zigbee

Support manufacturer-specific clusters, commands and attributes

Opened this issue · 12 comments

There is ongoing work for supporting manufacturer-specific clusters, commands and attributes in zsmartsystems/com.zsmartsystems.zigbee#498. One example where support for manufacturer-specific clusters is needed in this binding is the Centralite 3310 temperature/humidity sensor (see #359), as it uses a manufacturer-specific cluster for the humidity measurements.

This issue is for discussing how to integrate the support for manufacturer-specific clusters into this binding.

@cdjackson, as discussed it might be best to not make the ZSS library automatically add manufacturer-specific clusters to the instances of ZigBeeEndpoint or manufacturer-specific commands and attributes to the instances of ZclCluster, because without context about the node the library cannot be sure what to add. Instead, clients of the ZSS library (like this binding) who know more about the node should be responsible for adding them.

I think that the straightforward place for adding the manufacturer-specific extensions to the node is probably the thing handler during node initialisation (i.e., within doNodeInitialisation, before initializing the device via the channel converters). But: How can we ensure that the thing handler knows during node initialisation which manufacturer-specific extensions to add? The only way I see to ensure this is by adding the information to the thing type (as properties), requiring the use of static thing types. But: One would have to specify the implementation classes for manufacturer-specific clusters and commands in those thing properties, and then load those via reflection - and this would - to my knowledge - require those classes to lie within the core bundle of the binding (preventing solutions from adding implementations for manufacturer-specific extensions).

Hence, I think that the better option is to add the manufacturer-specific extensions via a provider concept: Providers would be OSGi services that implement some interface for specifying (a) which manufacturer-specific extensions are provided, and (b) to which things they should be added (e.g., via a boolean-valued function on things). The providers would then be made available to the thing handlers, so that the thing handlers can find out which manufacturer-specific extensions to add. The disadvantage of using providers is that one cannot be sure that all providers are available when a thing handler initializes. In consequence, it would be necessary to do additional initialization in the thing handler as soon as new providers become available.

Any thoughts, Chris? I will also give this more thoughts, but maybe you already have ideas based on what I wrote above.

I have played around with this some more, and it works quite well using thing properties in static thing types to define manufacturer-specific clusters, commands, and attributes.

My suggestion is the following:

  • Each manufacturer-specific cluster is specified by a property with prefix manufacturer_specific_cluster.

  • Each manufacturer-specific command is specified by a property with prefix manufacturer_specific_command.

  • Each manufacturer-specific attribute is specified by a property with prefix manufacturer_specific_attribute.

  • The values are a comma-separated lists of key=value pairs specifying the cluster/command/attribute using the following keys:

  • For clusters:

    Key Value
    endpoint the ID of the endpoint to which the cluster is added
    clusterid the ID of the cluster
    manufacturer the manufacturer code for the cluster
    name a human-readable name for the cluster
    direction server for a server cluster, client for a client cluster
  • For commands

    Key Value
    endpoint the ID of the endpoint with the cluster to which the command is added
    clusterid the ID of the cluster to which the command is added
    clusterdirection thee direction of the cluster to which the command is added - server or client
    commandid the ID of the command
    commanddirection the direction of the command - clienttoserver or servertoclient
    commandclass the FQN of a subclass of ZclCluster that implements the command
  • For attributes

    Key Value
    endpoint the ID of the endpoint with the cluster to which the attribute is added
    clusterid the ID of the cluster to which the attribute is added
    clusterdirection thee direction of the cluster to which the attribute is added - server or client
    attributeid the ID of the attribute
    manufacturer the manufacturer code for the attribute
    name a human-readable name for the attribute
    datatype the datatype of the attribute, specified using a name from the ZclDataType enum
    mandatory boolean flag whether the attribute is mandatory
    readable boolean flag whether the attribute is readable
    writable boolean flag whether the attribute is writable
    reportable boolean flag whether the attribute is reportable

Here's an example how this would look like for CentraLite's 3310-D temperature/humidity sensor which uses a manufacturer-specific cluster for humidity measurement:

        <properties>
            <property name="manufacturer_specific_cluster">endpointid=1, id=0xFC45, manufacturer=0x104E, name=Centralite Relative Humidity, direction=server</property>
            
            <property name="manufacturer_specific_attribute_1">endpointid=1, clusterid=0xFC45, clusterdirection=server, id=0x0000, manufacturer=0x104E, name=Measured Value,     datatype=UNSIGNED_16_BIT_INTEGER, mandatory=true,  readable=true, writeable=false, reportable=true</property>
            <property name="manufacturer_specific_attribute_2">endpointid=1, clusterid=0xFC45, clusterdirection=server, id=0x0001, manufacturer=0x104E, name=Min Measured Value, datatype=UNSIGNED_16_BIT_INTEGER, mandatory=true,  readable=true, writeable=false, reportable=false</property>
            <property name="manufacturer_specific_attribute_3">endpointid=1, clusterid=0xFC45, clusterdirection=server, id=0x0002, manufacturer=0x104E, name=Max Measured Value, datatype=UNSIGNED_16_BIT_INTEGER, mandatory=true,  readable=true, writeable=false, reportable=false</property>
            <property name="manufacturer_specific_attribute_4">endpointid=1, clusterid=0xFC45, clusterdirection=server, id=0x0003, manufacturer=0x104E, name=Tolerance,          datatype=UNSIGNED_16_BIT_INTEGER, mandatory=false, readable=true, writeable=false, reportable=true</property>
        </properties>

Any progress on this?

Seems like the underlying library PR has been merged few months ago.

Yes, as per the linked issue #498 this was merged a few months back.

I have not tested these features, but please feel free to try.

@cdjackson I think you linked the wrong PR.

Support manufacturer-specific zigbee was merged in the underlying library, but I don't know if someone implemented it here in the binding, is it?

Yes, you're right - sorry.

Hi people, what is the status of this? I have several 3310-G that I want to use but as per Openhab 2.5.2.1 it seems that this is not ready yet on stable branch because I don-t get any Humidity channel from cluster 0xFC45, just Temperature from the standard zigbee temp cluster. Is there a way to test it?

@cdjackson , my suggestion is to implement this via static thing types, see my proposal here.

I could provide a pull request - or do you think that this should be approached in a different way?

@hsudbrock I hope you're all doing well. Is this something you still intend to provide a PR for?

Thanks Chris, doing well under the circumstances... I still intend to provide a PR for that; unfortunately, since all kindergardens were closed in Germany about one month ago, my free screen time has been pretty much reduced, but I will try to squeeze it in. Is there some date where it would be good to have it before?