ThingWorx Edge SDK Extensions for the C SDK > Macros for the Edge Extensions > Declaring Edge Things
  
Declaring Edge Things
Now that you can construct the common primitives, you can use a macro to declare an EdgeThing with a name and a collection of properties, each having a primitive type.
* 
Do NOT declare more than one EdgeThing in a single macro.
Use the following commands:
TW_MAKE_THING(thingName,thingTemplate,...), where thingName is a String of type char*. Only one instance of TW_MAKE_THING can be used in a stack declared context. To construct more than one thing with a single call, use curly braces ({}) with TW_MAKE_THING. The TW_MAKE_THING macro declares a variable, char*_tw_thing_name, that is used by other commands such as TW_PROPERTY.
TW_PROPERTY(propertyName,description,type), where:
propertyName is a String that gives the property its name. Note that the name must conform to the property naming rules of the ThingWorx platform.
description is an optional sentence that describes the property. If you do not provide a description, substitute the command TW_NO_DESCRIPTION for description.
type is one of the ThingWorx primitive types as described in Macros to Create Data Shapes and Single Columns.
TW_PROPERTY_LONG(propertyName,description,type,pushType,threshold) can be substituted for TW_PROPERTY() when more control over property options is required. The additional options available with this command are as follows:
pushType can be either PUSH_TYPE_ALWAYS or PUSH_TYPE_VALUE to control twAspects that specify when the property should be pushed to ThingWorx platform.
threshold depends on the value of pushType:
PUSH_TYPE_ALWAYS—The value of threshold should be PUSH_THRESHOLD_NONE.
PUSH_TYPE_VALUE—The value of threshold is an absolute value that defines the minimum change that causes this property to be pushed to the platform. This value should be either a C double or the macro command PUSH_THRESHOLD_NONE.
Here is an example of the declaration of a Thing that has only properties. This example includes binding that thing to the current connection:
{
TW_MAKE_THING("sampleThing",TW_THING_TEMPLATE_GENERIC);

TW_PROPERTY("category", "What category of business this is.", TW_STRING);
TW_PROPERTY("firstName", "Your First Name", TW_STRING);
TW_PROPERTY("lastName", "Your Last Name", TW_STRING);
TW_PROPERTY("address", "Where this business is located", TW_STRING);
TW_PROPERTY("city", TW_NO_DESCRIPTION, TW_STRING);
TW_PROPERTY("state",TW_NO_DESCRIPTION, TW_STRING);
TW_PROPERTY("zip",TW_NO_DESCRIPTION, TW_STRING);
TW_PROPERTY("yearsAtLocation", "", TW_NUMBER);
TW_BIND();
}
Note the use of curly braces ({ }) around the TW_MAKE_THING command. The use of the curly braces limits the scope of the _tw_thing_name variable mentioned above so that more than one EdgeThing can be declared within a single function. Also note that no static data structure is required to support this declaration. The above commands declare all thread-safe storage that is required to set or modify values on this thing later. This storage is also required to update these subscribed property values as they change. All these tasks must be managed manually when using the ThingWorx API directly. You do not need to define a property handler function because all TW_PROPERTY() based properties use a common handler function that the C SDK provides.
The equivalent call to TW_MAKE_THING in the underlying C API follows:
twExt__CreateThingFromTemplate(thingName,templateName,
##__VA_ARGS__,VAR_ARG_END)
The equivalent call to TW_PROPERTY() or TW_PROPERTY_LONG() in the underlying C API follows:
int twExt_Api_RegisterProperty(
enum entityTypeEnum entityType, char * entityName,
char * propertyName, enum BaseType propertyType,
char * propertyDescription, char * propertyPushType,
double propertyPushThreshold, property_cb cb,
void * userdata);
Note that when you use TW_PROPERTY() or TW_PROPERTY_LONG() to declare a property, your callback function (property_cb cb) will always be set to:
enum msgCodeEnum twExt_StandardPropertyHandler(
const char * entityName,
const char * propertyName,
twInfoTable ** value,
char isWrite,
void * userdata);
This callback is provided as part of the C SDK. twExt_GenericPropertyHandler() assumes that you will be using the hashed, heap-based storage of properties that is provided by the TW_SET_PROPERTY() function (which is described in Modifying Property Values at Runtime). If you intend to provide your own property callback, do not use the TW_PROPERTY() macro.