Showing results for 
Search instead for 
Did you mean: 
Showing results for 
Search instead for 
Did you mean: 

The PTC Community email address has changed to Learn more.

Creating dynamic Property Definitions on a Virtual Thing in the Edge Java SDK

No ratings

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);



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

    aspects.put(Aspects.ASPECT_DATACHANGETYPE,    new StringPrimitive(;

    //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(;

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

    //Add the defaultValue aspect if needed...

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



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



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!


Thanks, what about if i want to define a service ? i used this code:

ServiceDefinition serviceDef = new ServiceDefinition("AddNum","Add two numbers");

FieldDefinitionCollection parameterFields = new FieldDefinitionCollection();

parameterFields.addFieldDefinition(new FieldDefinition("p1","The first addend of the operation",BaseTypes.NUMBER));

parameterFields.addFieldDefinition(new FieldDefinition("p2","The second addend of the operation",BaseTypes.NUMBER));

FieldDefinition resultField = new FieldDefinition(CommonPropertyNames.PROP_RESULT,"The sum of the two parameters",BaseTypes.NUMBER); serviceDef.setParameters(parameterFields);

i declared AddNum ouside the main:

            public Double AddNum(Double p1, Double p2) throws Exception {          return p1 + p2;      }  

but when bind in thingworx i get : Unable to Invoke Service AddNum on asdasd : Service Handler For [AddNum] Does Not Exist On Thing [SteamSensor9877]

Solution in CS227697 should help.

Yes Thanks, i've opened a case and this is the answer

Version history
Last update:
‎Jan 31, 2017 03:56 AM
Updated by:
Labels (1)