Representation Property and Configuration Parameters

I am doing some work on extending a binding, and I need to better understand the Representation Property.

If you use discovery processes to discover a thing, you can call .withProperty() with a property name/value pair and call .withRepresentationProperty() to inform the core that the respective property name is its Representation Property.

The name of the Representation Property is also identified in the thing-types.xml file.

But how does it work when you create a thing manually in a .things file, or otherwise via the UI? When you do that, you can set the Configuration Parameters, but there seems to be no way to set its Representation Property. I have a gut feeling that if there is a Configuration Parameter with the same name as the Representation Property then the core will ‘auto-magically’ use the Configuration Parameter value as the Representation Property. => Is that true? (If so, it is not well documented).

In the binding that I am working on, the Representation Property was not implemented in auto discovery, and not described in thing-types.xml. However the Configuration Parameters is implemented Ok. So if I fix the auto discovery code, and the thing-types.xml, is it safe to assume that the above ‘auto-magic’ would retroactively fill Representation Property = Configuration Parameter on any “legacy” things in the users system?

The best practic is to choose a representation property for the device which additionally identifies it on the vendors side (e.g. serial number, IP, MAC or similar). There is no need to set it when adding things via text file or via UI (REST-API). At the time you define a thing-type for your new thing the framework applies the thing-type definition automatically and thus a representation property is available. Discovery service will recognize and consider the manually added things too.

Is it maybe used to determine if result is duplicate or not? I see that representation property is used in paperui, however its not entirely clear to me what it does.

I always thought that since discovered things have own random thing identifiers (which are different than ones created via things file) representation property is some kind of correlation criteria. If there is a thing with same value of representationProperty discovery result is not shown as it overlaps with thing already present in the system.

You are right. That is not clearly written down in our docs. From Thing Discocery section:

openHAB offers a service to automatically ignore discovery results in the inbox, whenever a Thing is created manually, that represents the same Thing, as the respective discovery result would create. This Thing would either have the same Thing UID or the value of its representation property is equal to the representation property’s value in the discovery result.

But no details in Implementing a Discovery Service.

1 Like

Many thanks @cweitkamp that makes it much clearer.

Please correct me if I am wrong, but I think this implies that when a Thing is created manually, its UID must have the form below. i.e. the RepresentationProperty value must be the last segment in the total UID. Or ??

bindingId:thingTypeId:hubId:<RepresentationPropertyValue>

Will you raise a PR for this, or shall I?

Absolutely not. We do not want to tell a user how to name his Thing. The “id” can be whatever a user wants it to be. And THAT is - at least one reason - why we need the representationProperty.

Feel free to do so. Your help will be appreciated. I do not know if I will find the time in the near future to add it. Just mention me in your PR for review.

Ok. That makes sense.

So the question is what IS the common attribute that identifies a) things which are created by auto discovery (which have a representation property), and b) things that are created manually (which don’t).

You say this common attribute is not part of the UID. So I guess it must be a Configuration Parameter. (This was the essence of my first question).

If so, this is also not described at all in the documentation.

It is:

No sir, it is not. There is no explanation about how representationProperty on an auto discovered thing may be used to prevent an already manually created thing from being added to the inbox. I guess it is via a config param, but it is NOT mentioned in the docu.

Most often, the representation property is a configuration setting of the thing and so is defined when you create the thing manually.

Look at the Sonos binding xml files for example, it has set <representation-property>udn</representation-property>.

If you manually define a thing and set udn="whatever", and then run discovery a discovered thing that has “whatever” as the udn should be ignored and not added to inbox.

Edit: what might be missing from the docs is that the representation-property can be set as a configuration parameter. For the DiscoveryResult, properties and configuration parameters are both set with the .withProperty() method.

Certainly, that is my suspicion. But I am concerned about your words “most often”. It is also my suspicion that if you define a representation property for auto discovery having a defined name and content type, then you must also define a config parameter of the same name and content type. I want to clarify this explicitly, and then I will add it to the docu.

Exactly.

Content type has not to be defined.

You can define as representation property a simple thing property too.

^
Yup.

Following is the actual code from AutomaticInboxProcessor.java – which says that representationProperty may be either a) a Property, or b) a Configuration Parameter of the same name…

private @Nullable String getRepresentationPropertyValueForThing(Thing thing) {
    ThingType thingType = thingTypeRegistry.getThingType(thing.getThingTypeUID());
    if (thingType != null) {
        String representationProperty = thingType.getRepresentationProperty();
        if (representationProperty == null) {
            return null;
        }
        Map<String, String> properties = thing.getProperties();
        if (properties.containsKey(representationProperty)) {
            return properties.get(representationProperty);
        }
        Configuration configuration = thing.getConfiguration();
        if (configuration.containsKey(representationProperty)) {
            return String.valueOf(configuration.get(representationProperty));
        }
    }
    return null;
}

PS this answers my own question.

PPS and I will update the docu accordingly…

Not true.

The name of the representationProperty is defined in thing-types.xml, but not its type; so when you implement a representationProperty in the auto discovery code, you can only implement a string value.

However, if you use a Configuration Parameter to fulfil that, then it’s type is defined in thing-types.xml, and when you implement that in code, I think it must also be of a type that converts to a string.

So, to give a crass example, if representationProperty is implemented as an IP address, then the Configuration Parameter must be declared in thing-types.xml as type="text" and <context>network-address</context>.

I don’t now for example what would happen if the Configuration Parameter would be of type="integer" (say) … perhaps the core is clever enough to use toString() implicitly, in this example; but I am pretty sure it would not work if you tried to combine (say) an IPv4 IP address and an IPv6 address.

Pull request for docu changes here

The withRepresentationProperty method takes a String as argument, yes, but the String should be the name of the parameter, not the value.

Sorry but I think you misunderstood me.

The method Thing.setProperty(name, value) only accepts String arguments – so this constraint applies to both the property name and the property value.

OTOH Thing Configuration Parameters can usually be of any type, but if you use a Configuration Parameter as the accessor for the representationProperty of a manually created thing, then the content type of that particular Configuration Parameter is consequently constrained to be a String too.

The method signature is withProperty(String key, Object value). Or you can set all properties with withProperties(Map<String, Object> properties).
https://www.openhab.org/javadoc/v2.5/org/eclipse/smarthome/config/discovery/discoveryresultbuilder

Edit: Thing.setProperty() implies that the Thing is already created. This is different from when creating a DiscoveryResult in the discovery service. The difference is that the DiscoveryResult only has “properties” which can then be mapped to either “properties” of the thing (which can only be Strings) or configuration parameters (which can be any Object) when the thing is created.