Hi everyone,

 

As everyone knows already, the main way to define Properties inside the EMS Java SDK is to use annotations at the beginning of the VirtualThing class implementation.

There are some use-cases when we need to define those properties dynamically, at runtime, like for example when we use a VirtualThing to push a sensor's data from a Device Cloud to the ThingWorx server, for multiple customers.

In this case, the number properties differ based on customers, and due to the large number of variations, we need to be able to define programmatically the Properties themselves.

The following code will do just that:

 

 

for (int i = 0; i < int_PropertiesLength; i++) {

    Node nNode = device_Properties.item(i);

    PropertyDefinition pd;

    AspectCollection aspects = new AspectCollection();

    if (NumberUtils.isNumber(str_NodeValue))

    {

        pd = new PropertyDefinition(nNode.getNodeName(), " ", BaseTypes.NUMBER);

    }

    else if (str_NodeValue=="true"|str_NodeValue=="false")

    {

        pd = new PropertyDefinition(nNode.getNodeName(), " ", BaseTypes.BOOLEAN);

    }

    else

    pd = new PropertyDefinition(nNode.getNodeName(), " ", BaseTypes.STRING);

    aspects.put(Aspects.ASPECT_DATACHANGETYPE,    new StringPrimitive(DataChangeType.VALUE.name()));

    //Add the dataChangeThreshold aspect

    aspects.put(Aspects.ASPECT_DATACHANGETHRESHOLD, new NumberPrimitive(0.0));

    //Add the cacheTime aspect

    aspects.put(Aspects.ASPECT_CACHETIME, new IntegerPrimitive(0));

    //Add the isPersistent aspect

    aspects.put(Aspects.ASPECT_ISPERSISTENT, new BooleanPrimitive(false));

    //Add the isReadOnly aspect

    aspects.put(Aspects.ASPECT_ISREADONLY, new BooleanPrimitive(true));

    //Add the pushType aspect

    aspects.put("pushType", new StringPrimitive(DataChangeType.ALWAYS.name()));

    aspects.put(Aspects.ASPECT_ISLOGGED,new BooleanPrimitive(true));

    //Add the defaultValue aspect if needed...

    //aspects.put(Aspects.ASPECT_DEFAULTVALUE, new BooleanPrimitive(true));

    pd.setAspects(aspects);

    super.defineProperty(pd);

}   

//you need to comment initializeFromAnnotations() and use instead the initialize() in order for this to work.

//super.initializeFromAnnotations();

  super.initialize();

 

Please put this code in the Constructor method of your VirtualThing extending implementation. It needs to be run exactly once, at any instance creation.

This method relies on the manual discovery of the sensor properties that you will do before this.

Depending on the implementation you can either do the discovery of the properties here in this method (too slow), or you can pass it as a parameter to the constructor (better).

 

Hope it helps!