Step 8: C - Properties (cont.) Register Properties Registering properties and services with the API: Tells the API what callback function to invoke when a request for that property or service comes in from ThingWorx. Gives the API information about the property or service so that when ThingWorx browses the Edge device, it can be informed about the availability and the definition of that property or service. If you used the TW_PROPERTY macro, your property has been registered. If using function calls, to register a property, use the twApi_RegisterProperty. The documentation for this function can be found in [C SDK HOME DIR]/src/api/twApi.h. NOTE: If you used the provided Macros to create your property, it has already been registered. Bind the Thing in order for your property to be bound. An example of registering a property is as follows: twApi_RegisterProperty(TW_THING, “SimpleThing_1”, "FaultStatus", TW_BOOLEAN, NULL, "ALWAYS", 0, propertyHandler, NULL);
twApi_RegisterProperty(TW_THING, “SimpleThing_1”, "InletValve", TW_BOOLEAN, NULL, "ALWAYS", 0, propertyHandler, NULL);
twApi_RegisterProperty(TW_THING, “SimpleThing_1”, "Pressure", TW_NUMBER, NULL, "ALWAYS", 0, propertyHandler, NULL);
twApi_RegisterProperty(TW_THING, “SimpleThing_1”, "Temperature", TW_NUMBER, NULL, "ALWAYS", 0, propertyHandler, NULL);
twApi_RegisterProperty(TW_THING, thingName, "BigGiantString", TW_STRING, NULL, "ALWAYS", 0, propertyHandler, NULL);
twApi_RegisterProperty(TW_THING, thingName, "Location", TW_LOCATION, NULL, "ALWAYS", 0, propertyHandler, NULL); Update Properties Property values can be updated using the provided Macros or using the API directly. NOTE: Update a property does not send it to the server. To Push a property after updates have been made, use the TW_PUSH_PROPERTIES_FOR function that can be found in the [C SDK HOME DIR]/src/api/twMacro.h header file. With Macros The TW_SET_PROPERTY macro updates a property in ThingWorx and can be found in the [C SDK HOME DIR]/src/api/twMacro.h header file. The usage can be seen in the example below: TW_SET_PROPERTY(thingName, "FlowCount", TW_MAKE_NUMBER(5));
TW_SET_PROPERTY(thingName, "TotalFlow", TW_MAKE_NUMBER(rand() / (RAND_MAX / 10.0)));
TW_SET_PROPERTY(thingName, "Pressure", TW_MAKE_NUMBER(18 + rand() / (RAND_MAX / 5.0)));
TW_SET_PROPERTY(thingName, "Location", TW_MAKE_LOC(gpsroute[location_step].latitude,gpsroute[location_step].longitude,gpsroute[location_step].elevation));
Without Macros The twInfoTable_CreateFrom and twApi_SetSubscribedProperty functions updates a property in ThingWorx and can be found in the [C SDK HOME DIR]/src/api/twApi.h header file. The usage can be seen in the example below: if (strcmp(propertyName, "count") == 0) {
twInfoTable_GetInteger(*value, propertyName, 0, &properties.count);
twApi_SetSubscribedProperty(entityName, propertyName, twPrimitive_CreateFromNumber(properties.count), FALSE, TRUE);
} if (strcmp(propertyName, "InletValve") == 0)
twInfoTable_GetBoolean(*value, propertyName, 0, &properties.InletValve);
Retrieve Properties Property values can be retrieved using the provided Macros or using the API directly. With Macros The TW_GET_PROPERTY macro retrieves a property in ThingWorx and can be found in the [C SDK HOME DIR]/src/api/twMacro.h header file. The usage can be seen in the example below: double temp = TW_GET_PROPERTY(thingName, "Temperature").number; NOTE: You can use the macro TW_GET_PROPERTY_TYPE to get the property type. The signature and function information can be found in the [C SDK HOME DIR]/src/api/twMacro.h header file. Without Macros The twInfoTable_Get functions updates a property in ThingWorx and can be found in the [C SDK HOME DIR]/src/api/twApi.h header file. The usage can be seen in the example below: twInfoTable **inletValue = NULL;
twInfoTable **temp = NULL;
twInfoTable **location = NULL;
*inletValue = twInfoTable_CreateFromBoolean(propertyName, properties.InletValve);
*temp = twInfoTable_CreateFromNumber(propertyName, properties.Temperature);
*location = twInfoTable_CreateFromLocation(propertyName, &properties.Location);
Property Change Listeners Using the Observer pattern, you are able to take advantage of the property change listener functionality. With this pattern, you are able to create functions that will be notified when a value of a property has been changed (whether on the server or locally by your program when the TW_SET_PROPERTY macro is called). Add a Property Change Listener In order to add a property change listener, you will call the twExt_AddPropertyChangeListener function using the name of the Thing (entityName), the property this listener should watch, and the function that will be called when the property has changed. The usage can be seen in the example below: 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));
} NOTE: Setting the propertyName parameter to NULL or TW_OBSERVE_ALL_PROPERTIES, the function specified by the propertyChangeListenerFunction parameter will be used for ALL properties. Remove a Property Change Listener When releasing the memory for your application or done with utilizing listeners for the property, call the twExt_RemovePropertyChangeListener function. This usage can be seen in the example below: void simplePropertyObserver(const char * entityName, const char * thingName,twPrimitive* newValue){
printf("My Value has changed\n");
}
twExt_RemovePropertyChangeListener(simplePropertyObserver); Step 9: C - Data Shapes DataShapes are used for Events, Services, and InfoTables. In order to create a DataShape, you can do so with the provided macros or functions. Define With Macros In order to define a DataShape using a macro, use TW_MAKE_DATASHAPE. NOTE: The macros are all defined in the twMacros.h header file. TW_MAKE_DATASHAPE("SteamSensorReadingShape",
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)
);
Define Without Macros In order to define a DataShape without using a macro, use the twDataShape_CreateFromEntries function. twDataShape * ds = 0;
ds = twDataShape_Create(twDataShapeEntry_Create("ID", NULL, TW_INTEGER));
twDataShape_SetName(ds, "StringMap");
twDataShape_AddEntry(ds, twDataShapeEntry_Create("Value", NULL, TW_STRING));
Click here to view Part 8 of this guide
View full tip