ThingWorx Edge SDKs: Tutorial > Creating and Pushing Property Changes
Creating and Pushing Property Changes
As your device collects data, property values change. Changes in property values can come from device interrupts and from polled values. The event handlers of the ThingWorx Edge SDKs let you know when synchronization with the ThingWorx Platform is complete. After that, you can start pushing property values to the platform.
You can use either of two services to push property values to the ThingWorx Platform:
SetSubscribedProperty()
SetSubscribedPropertyVTQ()
The second service uses a VTQ (value, time, quality) structure for properties.
Push Types
You can specify when each property should be pushed up to the ThingWorx Platform. The default push type is NEVER The other valid values are ALWAYS and VALUE. What you need to know:
A pushType of NEVER does not push data to the ThingWorx platform instance, so when a property with pushType=NEVER is queried on the ThingWorx Platform instance, the ThingWorx instance queries the software of the edge device for the data value.
A pushType of ALWAYS pushes the data every time the property is read at the edge device, which is determined by the scanRate parameter. If the scanRate is not set on the property, the scanRate from the Lua Script Resource configuration file is used. If not defined in either location, a default of 60000 milliseconds (1 minute) is used. The Edge device pushes all properties that have a pushType of ALWAYS and the same scan rate in one call, rather than make individual calls per property.
For NUMBER or INTEGER property types, a pushType of VALUE pushes data to the ThingWorx Platform only when the data value change exceeds the dataChangeThreshold setting.
Retrieving History of Property Values
To retrieve the history of value changes for a given property, you can use the QueryPropertyHistory() service from ThingWorx Composer. Log in to Composer, navigate to your thing, and select Services. Locate the QueryPropertyHistory service, and select to run it (Execute icon). Enter the name of the property and any other criteria for the search. To minimize the time for the search and the load on the server, limit the query as much as possible.
Registering Properties in Java
The ThingWorx Edge Java SDK uses an object-oriented approach to registering properties. Java annotations map Java Bean properties. Class instances map to Things on the ThingWorx Platform. You bind instances of things. Not that it does not matter when you bind an edge device to a Thing. You can do it before or after connecting. If you are binding multiple Things, it is faster to bind before connecting. Here is an example or registering properties using the Java SDK:
Example 7. Registering Properties in Java SDK
In Java, just create and annotate a Class:

package com.thingworx.sdk.steam;
import com.thingworx.communications.client.ConnectedThingClient;
import com.thingworx.communications.client.things.VirtualThing;
import
com.thingworx.metadata.annotations.ThingworxPropertyDefinition; import
com.thingworx.metadata.annotations.ThingworxPropertyDefinitions;
@ThingworxPropertyDefinitions(properties = {
@ThingworxPropertyDefinition(name="Temperature", baseType="NUMBER"),
@ThingworxPropertyDefinition(name="SerialNumber", baseType="STRING")
))
public class JavaSDKExampleThing extends VirtualThing
VirtualThing (
public JavaSDKExampleThing(final String name,final ConnectedThingClient client)(super(name, null, client);
)
)
...
JavaSDKExampleThing steamSensorThing = new
JavaSDKExampleThing("SdkSampleThing",client); client.bindThing(steamSensorThing);
Changes in C SDK 2.0 and Later for Declaring Properties, Events, and Services
As of v.2.0.0, the C SDK provides Edge Extensions. These extensions provide macros that you can use to establish properties. Property handlers are replaced with a Standard property handler. This change provides a convenience that the ThingWorx Edge Java SDK handles with Annotations. Here are examples of using the new macros for registering properties and events:
/*************************Declare Properties**************************/
TW_MAKE_THING(thingName, TW_THING_TEMPLATE_GENERIC);
TW_PROPERTY("Pressure", TW_NO_DESCRIPTION, TW_NUMBER);
TW_ADD_BOOLEAN_ASPECT("Pressure", TW_ASPECT_ISREADONLY,TRUE);
TW_ADD_BOOLEAN_ASPECT("Pressure", TW_ASPECT_ISLOGGED,TRUE);
TW_PROPERTY("Temperature", TW_NO_DESCRIPTION, TW_NUMBER);
TW_ADD_BOOLEAN_ASPECT("Temperature", TW_ASPECT_ISREADONLY,TRUE);
TW_ADD_BOOLEAN_ASPECT("Temperature", TW_ASPECT_ISLOGGED,TRUE);
/*************************Declare Events******************************/
TW_EVENT("SteamSensorFault",
"Steam Sensor event",
TW_MAKE_DATASHAPE(
"SteamSensorFault",
TW_DS_ENTRY("message",TW_NO_DESCRIPTION,TW_STRING)
)
);
Here is an example of registering services using the macros:
/*************************Register Services*******************************/
TW_SERVICE("GetSteamSensorReadings",
"Returns a set of readings in an InfoTable",
TW_NO_PARAMETERS,
TW_INFOTABLE,
TW_MAKE_DATASHAPE(DATASHAPE_NAME_SENSOR_READINGS,
TW_DS_ENTRY("ActivationTime", TW_NO_DESCRIPTION, TW_DATETIME),
TW_DS_ENTRY("SensorName", TW_NO_DESCRIPTION, TW_NUMBER),
TW_DS_ENTRY("Temperature", TW_NO_DESCRIPTION, TW_NUMBER),
TW_DS_ENTRY("Pressure", TW_NO_DESCRIPTION, TW_NUMBER),
TW_DS_ENTRY("FaultStatus", TW_NO_DESCRIPTION, TW_BOOLEAN),
TW_DS_ENTRY("InletValve", TW_NO_DESCRIPTION, TW_BOOLEAN),
TW_DS_ENTRY("TemperatureLimit", TW_NO_DESCRIPTION, TW_NUMBER),
TW_DS_ENTRY("TotalFlow", TW_NO_DESCRIPTION, TW_INTEGER)
),
getSteamSensorReadingsService
);
Using a Property Change Listener to Detect Property Changes
When using TW_SET_PROPERTY() and twExt_GenericPropertyHandler(), which is an Edge Extension for the C SDK, for your property handler, you can take advantage of the Observer pattern. You can declare C functions that will be notified when the value of a property has changed, either on the server or locally as the result of a TW_SET_PROPERTY() command. To do this, use the following set of C SDK functions:
void twExt_AddPropertyChangeListener(char* entityName, char* propertyName,
propertyChangeListenerFunction PropertyChangeListenerFunction);
void twExt_RemovePropertyChangeListener
(propertyChangeListenerFunction PropertyChangeListenerFunction);
By calling twExt_AddPropertyChangeListener(), you can designate a function with the parameters shown below. This function is called when a property on the thing specified in the entityName parameter changes. If propertyName is set to NULL or the constant TW_OBSERVE_ALL_PROPERTIES, this function is notified on all property changes. If a specific property is passed in the propertyName field, the function is called only if that property changes. Here is an example:
void simplePropertyObserver(const char * entityName,
const char * thingName,twPrimitive* newValue){
printf("My Value has changed\n");
}

void test_simplePropertyChangeListener() {
{
TW_MAKE_THING("observedThing",TW_THING_TEMPLATE_GENERIC);
TW_PROPERTY("TotalFlow", TW_NO_DESCRIPTION, TW_NUMBER);
}

twExt_AddPropertyChangeListener("observedThing",TW
_OBSERVE_ALL_PROPERTIES,simplePropertyObserver);
TW_SET_PROPERTY("observedThing","TotalFlow",TW_MAKE_NUMBER(50));
twExt_RemovePropertyChangeListener(simplePropertyObserver);
}
twExt_AddPropertyChangeListener() can be called multiple times, allowing multiple observers to be attached to a single Thing. twRemovePropertyChangeListener() removes a function as a change listener.
Was this helpful?