ThingWorx Model Definition and Composer > Thing Templates > Remote Templates > Thing Presence > Thing Presence: Custom Reporting Strategy Created in Java with the ThingWorx Extension SDK
  
Thing Presence: Custom Reporting Strategy Created in Java with the ThingWorx Extension SDK
This tutorial does not cover the basics of creating ThingWorx extensions. It assumes that
You know how to build a ThingWorx Extension.
You have the Extension SDK, v.8.4.0 or later, which includes reporting objects.
You know how to build and import an extension into the ThingWorx platform.
A custom strategy thing may be created in Java, or in JavaScript and XML. First, you need to create a strategy thing template and implement and override the ReportingAlgorithm method. Then you create a strategy thing. The rest of this topic explains all of these steps for Java. To create a strategy thing using JavaScript, see Thing Presence: Using ThingWorx Composer to Create a Custom ReportingStrategy Thing.
Create a Strategy Thing Template
Implement and Override the ReportingAlgorithm Method
Sample Custom Strategy Thing Template
Create a Strategy Thing
Executing a Strategy
Create a Strategy Thing Template
To create a custom strategy in Java, first create a strategy Thing Template. The Thing Template serves as the code base for a Java-based algorithm. The class definition for the Thing Template should look like the following:
@ThingworxBaseTemplateDefinition(name = "ReportingStrategy")
public class MyJavaStrategy extends ReportingStrategy {
Implement and Override the ReportingAlgorithm Method
Next, you need to implement and override the ReportingAlgorithm method. This method contains a number of annotations that are required to function properly. The simplest solution to ensuring correct implementation would be to copy the following code:
@Override
@ThingworxServiceDefinition(name = ReportingConstants.REPORTING_ALGORITHM_SERVICE_NAME, isAllowOverride = true,
description = "Evaluates a Thing to determine if it is Present")
@ThingworxServiceResult(name = CommonPropertyNames.PROP_RESULT, baseType = "BOOLEAN",
description = "Whether the parameters describe a Device that is Reporting normally")
public Boolean ReportingAlgorithm(
@ThingworxServiceParameter(
name = ReportingConstants.EVENT_NAME,
description = "Name of the event",
baseType = "STRING" ) String eventName,
@ThingworxServiceParameter(
name = ReportingConstants.EVENT_TIME,
description = "Time event is triggered",
baseType = "DATETIME" ) DateTime eventTime,
@ThingworxServiceParameter(
name = ReportingConstants.SOURCE,
description = "Name of Thing that triggered event",
baseType = "STRING" ) String source,
@ThingworxServiceParameter(
name = ReportingConstants.SOURCE_PROPERTY,
description = "Soure property",
baseType = "STRING" ) String sourceProperty,
@ThingworxServiceParameter(
name = ReportingConstants.EVENT_DATA,
description = "Parameters necessary for the algorithm to determine if a Thing is reporting",
baseType = "INFOTABLE") InfoTable eventData) {
// specifically boolean primitive; this method should never return null
boolean result = false;

// TODO: Custom Strategy implementation here

return result;
}
Back to Top
Sample Custom Strategy Thing Template
All together, a sample custom strategy thing template would look like the following example. In this example, the custom strategy would mark the thing as present when it is not connected and not present when it is connected.

import org.joda.time.DateTime;
import org.slf4j.Logger;

import com.thingworx.logging.LogUtilities;
import com.thingworx.metadata.annotations.ThingworxBaseTemplateDefinition;
import com.thingworx.metadata.annotations.ThingworxServiceDefinition;
import com.thingworx.metadata.annotations.ThingworxServiceParameter;
import com.thingworx.metadata.annotations.ThingworxServiceResult;
import com.thingworx.things.connected.reportable.ReportingConstants;
import com.thingworx.things.connected.reportable.ReportingStrategy;
import com.thingworx.types.InfoTable;
import com.thingworx.types.constants.CommonPropertyNames;

@ThingworxBaseTemplateDefinition(name = "ReportingStrategy")
public class MyJavaStrategy extends ReportingStrategy {

private static final Logger logger =
LogUtilities.getInstance().getApplicationLogger(MyJavaStrategy.class);

@Override
@ThingworxServiceDefinition(name = ReportingConstants.REPORTING_ALGORITHM_SERVICE_NAME,
isAllowOverride = true,
description = "Evaluates a Thing to determine if it is Present")
@ThingworxServiceResult(name = CommonPropertyNames.PROP_RESULT, baseType = "BOOLEAN",
description = "Whether the parameters describe a Device that is Reporting normally")
public Boolean ReportingAlgorithm(
@ThingworxServiceParameter(
name = ReportingConstants.EVENT_NAME,
description = "Name of the event",
baseType = "STRING" ) String eventName,
@ThingworxServiceParameter(
name = ReportingConstants.EVENT_TIME,
description = "Time event is triggered",
baseType = "DATETIME" ) DateTime eventTime,
@ThingworxServiceParameter(
name = ReportingConstants.SOURCE,
description = "Name of Thing that triggered event",
baseType = "STRING" ) String source,
@ThingworxServiceParameter(
name = ReportingConstants.SOURCE_PROPERTY,
description = "Soure property",
baseType = "STRING" ) String sourceProperty,
@ThingworxServiceParameter(
name = ReportingConstants.EVENT_DATA,
description = "Parameters necessary for the algorithm to determine if a Thing is reporting",
baseType = "INFOTABLE") InfoTable eventData) {
// specifically boolean primitive; this method should never return null
boolean result;
try {
boolean isBound = (Boolean) eventData.getFirstRow().getValue(ReportingConstants.PROP_ISBOUND);
result = !isBound;
logger.info("Custom strategy has is bound [" + isBound + "].
Setting reporting to [" + result + "]");
} catch (Exception e) {
logger.error("Caught exception while evaluating reporting algorithm.
Marking as not reporting");
result = false;
}
return result;
}

}
Back to Top
Create a Strategy Thing
The Strategy thing will extend your custom strategy template and allow you to set it as the reporting algorithm in the Reporting configuration table on a remote entity.
To create a thing, your project must have the Entities folder path as follows <Project Root>/Entites/Things and your things must have the following naming convention Things_ThingName.xml where ThingName is the name of your custom Thing.
In this example, the thing name is "CustomStrategyJava" so the file name is Things_CustomStrategyJava.xml and the content is shown below. You will need to edit lines 14, 19, and 23 accordingly based on your ThingPackage, ThingName, and ThingTemplate names respectively.
* 
After you copy the lines below into your IDE or XML editor, you will see the proper line numbers.
<?xml version="1.0" encoding="UTF-8"?>
<Entities
<Things>
<Thing
effectiveThingPackage="MyStrategyPackage"
enabled="true"
name="CustomStrategyJava"
published="false"
thingTemplate="MyJavaStrategy"
</Thing>
</Things>
</Entities>
Back to Top
Executing a Strategy
As of ThingWorx 8.4.0, the isReporting state of a remote thing is re-evaluated whenever the thing binds or unbinds from the ThingWorx platform.This state may also be re-evaluated at any time (for example, by a Timer) by executing the EvaluateReporting service available on the remote thing.
Back to Top