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

The community will undergo maintenance on October 16th at 10:00 PM PDT and will be unavailable for up to one hour.

SDK Reference Part 3

No ratings

 

 

Step 2: Java Properties (cont.)

 

Annotation

@ThingworxPropertyDefinitions(properties = {
        @ThingworxPropertyDefinition(name = "Temperature", description = "Current Temperature",
                baseType = "NUMBER", category = "Status", aspects = { "isReadOnly:true" }),
        @ThingworxPropertyDefinition(name = "Pressure", description = "Current Pressure",
                baseType = "NUMBER", category = "Status", aspects = { "isReadOnly:true" }),
        @ThingworxPropertyDefinition(name = "FaultStatus", description = "Fault status",
                baseType = "BOOLEAN", category = "Faults", aspects = { "isReadOnly:true" }),
        @ThingworxPropertyDefinition(name = "InletValve", description = "Inlet valve state",
                baseType = "BOOLEAN", category = "Status", aspects = { "isReadOnly:true" }),
        @ThingworxPropertyDefinition(name = "TemperatureLimit",
                description = "Temperature fault limit", baseType = "NUMBER", category = "Faults",
                aspects = { "isReadOnly:false" }),
        @ThingworxPropertyDefinition(name = "TotalFlow", description = "Total flow",
                baseType = "NUMBER", category = "Aggregates", aspects = { "isReadOnly:true" }), })

 

NOTE: The call to VirtualThing.initializeFromAnnotations is necessary if there are properties, services, and events that are annotated.

 

Code

        //Create the property definition with name, description, and baseType
        PropertyDefinition property1 = new PropertyDefinition(property, "Description for Property1", BaseTypes.BOOLEAN);
        //Create an aspect collection to hold all of the different aspects
        AspectCollection aspects = new AspectCollection();
        //Add the dataChangeType aspect
        aspects.put(Aspects.ASPECT_DATACHANGETYPE, new StringPrimitive(DataChangeType.NEVER.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(false));
        //Add the pushType aspect
        aspects.put("pushType", new StringPrimitive(DataChangeType.NEVER.name()));
        //Add the defaultValue aspect
        aspects.put(Aspects.ASPECT_DEFAULTVALUE, new BooleanPrimitive(true));
        //Set the aspects of the property definition
        property1.setAspects(aspects);
        //Add the property definition to the Virtual Thing
        this.defineProperty(property1);

 

Update Properties

 

Property values can be updated using the provided Macros or using the API directly.

 

The VirtualThing.setPropertyVTQ and VirtualThing.setProperty methods are used to update properties connected to the ThingWorx Platform. It is often easiest to use the setProperty method because it allows the usage of values outside of IPrimitiveType. Using these methods will fire a property changed event and also look to add the update to the pending list of changes to the Platform based on your DataChangeType aspect used for the property. An example of how to use VirtualThing.setProperty can be seen below:

double temperature = 400 + 40 * Math.random();
super.setProperty("Temperature", temperature);

 

NOTE: setPropertyVTQ and setProperty are both methods inside of the VirtualThing class. All objects you would like to have represented in the ThingWorx Platform as an Entity, must extend the VirtualThing class.

 

When finished with updating all property values, use the VirtualThing.updateSubscribedProperties method to send the queue of changes to the Platform. Property value updates will NOT be sent to the platform if this method is not called. An example can be seen below:

 

super.updateSubscribedProperties(15000);

 

Retrieve Properties

 

Property values can be retrieved using the provided Macros or using the API directly.

 

The VirtualThing.getProperty and VirtualThing.getCurrentPropertyValue methods are used to retrieve properties connected to the ThingWorx Platform. The VirtualThing.getProperties returns a PropertyCollection which provides a collection type behavior for all properties initialized within your implementation. An example of how to use VirtualThing.getProperty can be seen below:

 

double temperatureLimit = (Double) getProperty("TemperatureLimit").getValue().getValue();

 

NOTE: getProperty and getCurrentPropertyValue are both methods inside of the VirtualThing class. All objects you would like to have represented in the ThingWorx Platform as an Entity, must extend the VirtualThing class.

 

Synchronize Updates

 

The VirtualThing.synchronizeState method is called when a connect or reconnect occurs. If property values are not synced with the ThingWorx Platform on a regular basis, this method should be overridden with a call to sync properties. An example of this is shown below:

public void synchronizeState() {
    super.synchronizeState();
    super.syncProperties();
}

 

Scan Cycles

The VirtualThing.processScanRequest method should be overridden and used to perform the tasks that should occur during a scan cycle. A scan cycle could be considered a reoccurring period in which a task is performed. This should be called and performed after a connection is made and while the application is still connected to the ThingWorx Platform. An example is as follows:

while (!client.isShutdown()) {
    if (client.isConnected()) {
        for (VirtualThing thing : client.getThings().values()) {
            try {
                thing.processScanRequest();
            } catch (Exception exception) {
                System.out.println("Error Processing Scan Request for [" + thing.getName() + "] : " + exception.getMessage());
            }
        }
    }

    Thread.sleep(1000);
}
 
 
 

Step 3: Java - Data Shapes

 

DataShapes are used for Events, Services, and InfoTables.

In order to create a DataShape, you will use the FieldDefinitionCollection class with a FieldDefinition object to set each aspect and field type for the DataShape.

The VirtualThing.defineDataShapeDefinition method adds the recently created definition to the Entities list of DataShapes.

If the DataShape is located on the ThingWorx Platform, utilize the ConnectedThingClient.getDataShapeDefinition method in order to retrieve it.

An example is shown below of how to create a DataShape and store it to the list of available DataShapes:

// Data Shape definition that is used by the delivery stop event
// The event only has one field, the message
FieldDefinitionCollection fields = new FieldDefinitionCollection();
fields.addFieldDefinition(new FieldDefinition(ACTIV_TIME_FIELD, BaseTypes.DATETIME));
fields.addFieldDefinition(new FieldDefinition(DRIVER_NAME_FIELD, BaseTypes.STRING));
fields.addFieldDefinition(new FieldDefinition(TRUCK_NAME_FIELD, BaseTypes.BOOLEAN));
fields.addFieldDefinition(new FieldDefinition(TOTAL_DELIVERIES_FIELD, BaseTypes.NUMBER));
fields.addFieldDefinition(new FieldDefinition(REMAIN_DELIVERIES_FIELD, BaseTypes.NUMBER));
fields.addFieldDefinition(new FieldDefinition(LOCATION_FIELD, BaseTypes.LOCATION));
defineDataShapeDefinition("DeliveryTruckShape", fields);
 
 
 

Step 4: Java - Info Tables

 

Infotables are used for storing and retrieving data from service calls.

 

The provided InfoTable object uses a DataShapeDefinition object to describe the name, base type, and additional information about each field within the table.

 

The InfoTable class is a collection of ValueCollection entries for each row based on the DataShapeDefinition. When reading values from an InfoTable or loading an InfoTable with data, you will need to use the ValueCollection class.

 

Create and Load

 

The code below shows how to utilize these classes in order to create and add data to an InfoTable:

DataShapeDefinition dsd = (DataShapeDefinition) this.getDataShapeDefinitions().get("SteamSensorReadings");
InfoTable table = new InfoTable(dsd);
ValueCollection entry = new ValueCollection();
DateTime now = DateTime.now();

try {
    // entry 1
    entry.clear();
    entry.SetStringValue(SENSOR_NAME_FIELD, "Sensor Alpha");
    entry.SetDateTimeValue(ACTIV_TIME_FIELD, now.plusDays(1));
    entry.SetNumberValue(TEMPERATURE_FIELD, 50);
    entry.SetNumberValue(PRESSURE_FIELD, 15);
    entry.SetBooleanValue(FAULT_STATUS_FIELD, false);
    entry.SetBooleanValue(INLET_VALVE_FIELD, true);
    entry.SetNumberValue(TEMPERATURE_LIMIT_FIELD, 150);
    entry.SetNumberValue(TOTAL_FLOW_FIELD, 87);
    table.addRow(entry.clone());

    // entry 2
    entry.clear();
    entry.SetStringValue(SENSOR_NAME_FIELD, "Sensor Beta");
    entry.SetDateTimeValue(ACTIV_TIME_FIELD, now.plusDays(2));
    entry.SetNumberValue(TEMPERATURE_FIELD, 60);
    entry.SetNumberValue(PRESSURE_FIELD, 25);
    entry.SetBooleanValue(FAULT_STATUS_FIELD, true);
    entry.SetBooleanValue(INLET_VALVE_FIELD, true);
    entry.SetNumberValue(TEMPERATURE_LIMIT_FIELD, 150);
    entry.SetNumberValue(TOTAL_FLOW_FIELD, 77);
    table.addRow(entry.clone());
} catch (Exception e) {
    e.printStackTrace();
}

 

Read

 

This code shows how to read a value from an InfoTable.

InfoTable result = client.readProperty(ThingworxEntityTypes.Things, "SteamSensor", "name", 10000);
String name = result.getFirstRow().getStringValue("name");

 

The example highlighted below showcases one way to get a property reading from a Thing in the ThingWorx Platform.

InfoTable result = client.readProperty(ThingworxEntityTypes.Things, "SteamSensor", "name", 10000);
ValueCollection entry = result.getFirstRow();
String name = entry.getStringValue("name");
 
 
Click here to view Part 4 of this guide.
 
Version history
Last update:
‎Mar 07, 2023 08:16 AM
Updated by:
Labels (1)