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

Community Tip - Did you know you can set a signature that will be added to all your posts? Set it here! X

IoT Tips

Sort by:
Presentation by Michael Anderson highlighting new capabilities and features in the ThingWorx Manufacturing and Service Apps 8.2
View full tip
DataShape Simply put, it represents the data in your model giving your application an in-built sense on how to represent the data in different scenarios. DataShape is defined with set of field definitions and related metadata e.g. DataType. DataShapes are must have (except for ValueStream) when creating entities that deal with data storage i.e. DataTable & Stream. For more detail on  DataShapes and the DataTypes see DataShapes in ThingWorx Help Center   Note: See ThingShape : Nuances, Tips & Tricks  for ThingShape vs DataShape   Ways to create DataShape   Via the ThingWorx Composer Navigate to ThingWorx Composer click on New > DataShape Provide a unique name to the DataShape entity DataShape creation in ThingWorx Composer Navigate to the Field Definition and add required Field Definition Defining Field for the DataShape Via a custom service in ThingWorx Navigate to an entity under which the service is to be created, e.g. Thing Switch to Services section for the Thing and click Add to create new service OOTB available service CreateDataShape can be used from the Resources > EntityService // snippet creating the infotable with the var params = { infoTableName : "InfoTable", dataShapeName : "DemoDataShape" }; // CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(DemoDataShape) var result = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape(params); // snippet creating the DataShape using the Infotable queried above which returns the field and the metadata on those fields // DSName used below is created as the Resources["EntityServices"].CreateDataShape({ name: DSName /* STRING */, description: "Custom created DataShape" /* STRING */, fields: result /* INFOTABLE */, tags: undefined /* TAGS */ }); Here's how it'd appear in the Service editor :   DataShape creation with JavaScript service in ThingWorx Via the ThingWorx Extension SDK   Following example snippet shows the creation and usage of the DataShape while creating custom extension with the Extension SDK    @ThingworxConfigurationTableDefinitions(tables = { @ThingworxConfigurationTableDefinition(name = "ConfigTableExample1", description = "Example 1 config table", isMultiRow = false, dataShape = @ThingworxDataShapeDefinition(fields = { @ThingworxFieldDefinition(name = "field1", description = "", baseType = "STRING"), @ThingworxFieldDefinition(name = "field2", description = "", baseType = "NUMBER") })) }) Note: Refer to the ThingShape : Nuances, Tips & Tricks for Tips & Tricks   Other related reads How are DataShape used while storing the data in ThingWorx How to pass a DataShape as parameter Can two DataShapes have the same service name if used on the same thing in ThingWorx? DataShape in ThingWorx Help Center
View full tip
ThingShape   Much like the ThingTemplate, ThingShapes are one of the basic entities for modeling the business logic within the ThingWorx composer. They are best used for describing the relationships between the objects within your IoT model being designed in ThingWorx platform. See ThingShape in Help Center for more   Note: Additional helpful read ThingTemplate : Nuances, Tips & Tricks   ThingShape vs ThingTemplate   While both ThingShape and ThingTemplate are basic building blocks for IoT model in ThingWorx platform; they differ to an extent in terms of the usage and logic   ThingShapes could be seen as bit more basic building block compared to the ThingTemplate ThingTemplates can implement one or more ThingShapes, this is not possible vice versa ThingShapes are ought to be used for implementing more generalised business logic as opposed to ThingTemplate There's no requirement to select ThingTemplate while creating a ThingShape A Thing inherits a ThingShape via the ThingTemplate which it is implementing   ThingShape vs DataShape   While ThingShape is used for defining the relationships within your IoT model in ThingWorx, DataShapes are targeted towards structuring and giving shapes & definition to the data model and how it will be represented. DataShapes are also used for describing a data set e.g. when there's a requirement on fetching result in a specific format when querying InfoTable.   Methods to create ThingShape   There are quite a few possibilities to create ThingShape   Via the ThingWorx Composer Navigate to the ThingWorx Composer > New > ThingShape Add an unique name to the ThingShape Notice during creation there's no ThingTemplate needed for selection, however behind the scene all Things in ThingWorx draw from base template called GenericThing Under Properties and Alerts section add required properties Finally, Save the entity Creating ThingShape via ThingWorx Composer Via the custom ThingWorx Service within the Composer ThingShape can also be created via the OOTB available JavaScript service under the Resources > Entity Service > CreateThingService. To use this service Navigate to a Thing > Services > Snippets > Search for ThingShape And add the CreateThingShape service, which will look like this var params = { name: "DemoThingShape" /* STRING */, description: "Custom ThingShape Creation Script" /* STRING */, tags: undefined /* TAGS */ }; // no return Resources["EntityServices"].CreateThingShape(params); Via the ThingWorx Extension SDK as custom extension for ThingWorx ThingWorx Extension SDK allows users to extend and add functionalities to ThingWorx that may not be available OOTB.   @ThingworxBaseTemplateDefinition(name = "GenericThing") public class DemoThingShape102 extends Thing { /** * custom thingShape created using Extension SDK to display most basic * structure for the class. * Note that the class is annotated with ThingworxBaseTemplateDefinition to * define GenericThing Template */ public DemoThingShape102() { // TODO Auto-generated constructor stub } } This simple example can be extended by adding couple of properties, similar to what's defined in the ThingShape created in ThingWorx Composer. Properties are defined with annotation ThingworxPropertyDefinitions like so :   @ThingworxPropertyDefinitions(properties = { @ThingworxPropertyDefinition(name = "Prop1", description = "defined in Extension SDK ; and is persistent", category = "", baseType = "STRING", isLocalOnly = false, aspects = { "isPersistent:true", "dataChangeType:VALUE" }), @ThingworxPropertyDefinition(name = "Prop2", description = "defined in Extension SDK", category = "", baseType = "NUMBER", isLocalOnly = false, aspects = { "dataChangeType:VALUE" }) }) Putting it all toegther :   @ThingworxBaseTemplateDefinition(name = "GenericThing") @ThingworxPropertyDefinitions(properties = { @ThingworxPropertyDefinition(name = "Prop1", description = "defined in Extension SDK ; and is persistent", category = "", baseType = "STRING", isLocalOnly = false, aspects = { "isPersistent:true", "dataChangeType:VALUE" }), @ThingworxPropertyDefinition(name = "Prop2", description = "defined in Extension SDK", category = "", baseType = "NUMBER", isLocalOnly = false, aspects = { "dataChangeType:VALUE" }) }) public class DemoThingShape102 extends Thing { /** * */ public DemoThingShape102() { // TODO Auto-generated constructor stub } }   Tips & Tricks   Adding new entities while developing custom extension via the Extension SDK would require adding those entities to the metadata.xml Failing to appropriately update metadata.xml will lead to either failure in importing the extension whithin ThingWorx or Entities might not appear correctly Custom extension development process can be greatly accelerated and extension project correctly configured using the Eclipse Plugin for ThingWorx Extensions available for download from ThingWorx Marketplace Eclipse Plugin for ThingWorx Extensions ensures that custom entities are correctly organized under metadata.xml - this update to the metadata.xml file is applied automatically as the user go about creating entities within the project's scope Users might prefer to write custom entities over creating them in ThingWorx for the reasons custom entities and code used for creating custom services under the extension - are hidden when they are built into an extension and imported into ThingWorx Other related reads Remote properties, services and events can be created on a ThingShape, but they won't properly, unless the ThingShape is applied to a RemoteThing How  can I update  the  thing template's properties or  thing shape's  properties by C SDK? How to create ThingShapes and ThingTemplates in an Extension ThingShape in ThingWorx Help Center
View full tip
  Step 8: Tasks If you are using the built-in Tasker to drive data collection or other types of repetitive or periodic activities, create a function for the task. Task functions are registered with the Tasker and then called at the rate specified after they are registered. The Tasker is a very simple, cooperative multitasker, so these functions should not take long to return and most certainly must not go into an infinite loop. The signature for a task function is found in [C SDK HOME DIR]/src/utils/twTasker.h. The function is passed a DATETIME value with the current time and a void pointer that is passed into the Tasker when the task is registered. After creating this function, it will need to be registered using the twApi_CreateTask function after the connection is created. Below shows an example of creating this function, registering this function, and how this function can be used. #define DATA_COLLECTION_RATE_MSEC 2000 void dataCollectionTask(DATETIME now, void * params) { /* TW_LOG(TW_TRACE,"dataCollectionTask: Executing"); */ properties.TotalFlow = rand()/(RAND_MAX/10.0); properties.Pressure = 18 + rand()/(RAND_MAX/5.0); properties.Location.latitude = properties.Location.latitude + ((double)(rand() - RAND_MAX))/RAND_MAX/5; properties.Location.longitude = properties.Location.longitude + ((double)(rand() - RAND_MAX))/RAND_MAX/5; properties.Temperature = 400 + rand()/(RAND_MAX/40); /* Check for a fault. Only do something if we haven't already */ if (properties.Temperature > properties.TemperatureLimit && properties.FaultStatus == FALSE) { twInfoTable * faultData = 0; char msg[140]; properties.FaultStatus = TRUE; properties.InletValve = TRUE; sprintf(msg,"%s Temperature %2f exceeds threshold of %2f", thingName, properties.Temperature, properties.TemperatureLimit); faultData = twInfoTable_CreateFromString("message", msg, TRUE); twApi_FireEvent(TW_THING, thingName, "SteamSensorFault", faultData, -1, TRUE); twInfoTable_Delete(faultData); } /* Update the properties on the server */ sendPropertyUpdate(); } … twApi_CreateTask(DATA_COLLECTION_RATE_MSEC, dataCollectionTask); … while(1) { char in = 0; #ifndef ENABLE_TASKER DATETIME now = twGetSystemTime(TRUE); twApi_TaskerFunction(now, NULL); twMessageHandler_msgHandlerTask(now, NULL); if (twTimeGreaterThan(now, nextDataCollectionTime)) { dataCollectionTask(now, NULL); nextDataCollectionTime = twAddMilliseconds(now, DATA_COLLECTION_RATE_MSEC); } #else in = getch(); if (in == 'q') break; else printf("\n"); #endif twSleepMsec(5); }   Step 9: File Transfer Example To handle file transfers, a virtual directory is created in the SteamSensor1 entity and in the [C SDK HOME DIR]/examples/FileTransferExample application directory. The source code used for this example is found in [C SDK HOME DIR]/examples/FileTransferExample/src/main.c. Inside of the [C SDK HOME DIR]/examples/FileTransferExample folder, create the folder structure shown below: /transfer/ /transfer/incoming/ /transfer/outgoing/ Inside of the /transfer/outgoing/ directory, create and open a file with the name outgoing.txt. Once the outgoing.txt document is open, add the following text, save, and close the file: Hello. This is a file coming from the client application. Navigate to the [C SDK HOME DIR]/examples/FileTransferExample/src/main.c code and update the lines below with the appropriate information for your IP, port, and the “admin_key” Application Key’s keyId value in the ThingWorx Composer: /* Server Details */ #define TW_HOST "127.0.0.1" #define TW_PORT 80 #define TW_APP_KEY "ce22e9e4-2834-419c-9656-ef9f844c784c" To support file transfers in your client application, you must use the twFileManager_AddVirtualDir function in order to create the virtual directories in the entity with such a capability. It will also define the directories available for file operations. A virtual directory maps a unique name to an absolute path of a directory in the file system. All subdirectories of the specified directory are exposed to the server. You can define multiple virtual directories. The directories do not need to be contiguous.   Staging Directory As an optional, but recommended step, you should set the directory that the application should use for staging when performing file transfers. This can be seen in the line below and should be done before initializing the FileManager. The default directory of the FileManager is most likely owned by root and will require a change to either the location of the staging directory and the ownership of the staging directory, or running the application as a User with the correct permissions. twcfg.file_xfer_staging_dir = "staging"; The example provided uses the TW_SHARE_DIRECTORY macro to create two virtual directories that will act as the root directories in the virtual file system of this application are added. The client is then started as follows with the necessary TW_ADD_FILE_TRANSFER_SHAPE function being called: TW_ADD_FILE_TRANSFER_SHAPE(); TW_SHARE_DIRECTORY("in", "/transfer/incoming/"); TW_SHARE_DIRECTORY("out", "/transfer/outgoing/"); The creations of the payloads used to create the remote directories on the platform have been moved to a helper function below to make the design cleaner: int setupSystemRepo(const char * remoteInPath, const char * remoteOutPath, const char * remoteFile); After our remote directories and files have been setup, it is time to perform the file transfers. Normally, this would mean invoking the Copy service for a Subsystem, but two functions have been created to make this process easier: int twFileManager_GetFile(const char * sourceRepo, const char * sourcePath, const char * sourceFile, const char * targetRepo, const char * targetPath, const char * targetFile, uint32_t timeout, char asynch, char ** tid) int twFileManager_SendFile(const char * sourceRepo, const char * sourcePath, const char * sourceFile, const char * targetRepo, const char * targetPath, const char * targetFile, uint32_t timeout, char asynch, char ** tid) The table below displays an example of the first set of parameters:   Parameter     Example                              Description sourceRepo SystemRepository The name of FileRepository or RemoteThing to transfer the file FROM. sourcePath outgoing The path specifying the location of the source file. sourceFile The name of the source file.   targetRepo SteamSensor1 The name of FileRepository or RemoteThing to transfer the file TO. targetPath incoming The path specifying the destination location of the file. targetFile incoming.txt The name of the file at the target. This name can differ from the sourceName. timeout 15,000 The amount of time (in seconds) to wait for a synchronous transfer to complete before cancelling the transfer. async false If false, the service call will block for timeout seconds or until the transfer completes. tid incoming0123 The unique TID associated with the file.   The C SDK also provides the ability to create a FileCallback function that the FileManager will call that function when any file transfer events occur. You can provide a wildcard filter so that only file transfer Events of files that match the filter call the callback function. In addition, callbacks can be set up as “one-shots” such that the callback is unregistered automatically after it is invoked the first time.   NOTE: An optional file transfer callback is registered in the code and provided. You will see the output from the function as files are sent and received.   After running this application, you will notice a new file in the transfer/incoming folder after refreshing. This is the file that we created in the ThingWorx Composer file system for the SystemRepository Entity and was able to copy from that location to our local project. We have also sent a file to the server’s SystemRepository. The BrowseFileSystem and GetFileListing services can be used to check for the folders and files created. twFileManager_RegisterFileCallback(fileCallbackFunc, NULL, FALSE, NULL);   Step 10: Support Other Platforms All Websocket errors indicate some general issue communicating with the ThingWorx platform. If you experience an issue connecting, refer to the table below for a list of websocket errors, their corresponding codes, and an explanation of the issue.   Code   Message                                                                       Troubleshooting 200 TW_UNKNOWN_WEBSOCKET_ERROR An unknown error occurred on the websocket. 201 TW_ERROR_INITIALIZING_WEBSOCKET An error occurred while initializing the websocket. Check your websocket configuration parameters for validity. 202 TW_TIMEOUT_INITIALIZING_WEBSOCKET A timeout occurred while initializing the websocket. Check the status of the connection to ThingWorx. 203 TW_WEBSOCKET_NOT_CONNECTED The websocket is not connected to ThingWorx. The requested operation cannot be performed. 204 TW_ERROR_PARSING_WEBSOCKET_DATA An error occurred while parsing websocket data. The parser could not break down the data from the websocket. 205 TW_ERROR_READING_FROM_WEBSOCKET An error occurred while reading data from the websocket. Retry the read operation. If necessary, resend the data. 206 TW_WEBSOCKET_FRAME_TOO_LARGE The SDK is attempting to send a websocket frame that is too large. The Maximum Frame Size is set when calling twAPI_Initialize and should always be set to the Message Chunk Size (twcfg.message_chunk_size). 207 TW_INVALID_WEBSOCKET_FRAME_TYPE The type of the frame coming in over the websocket is invalid. 208 TW_WEBSOCKET_MSG_TOO_LARGE The application is attempting to send a message that has been broken up in to chunks that are too large to fit in a frame. You should not see this error. 209 TW_ERROR_WRITING_TO_WEBSOCKET An error occurred while writing to the Web socket. 210 TW_INVALID_ACCEPT_KEY The Accept key sent earlier from ThingWorx is not valid.   Next Steps Congratulations! You've successfully completed the C SDK Tutorial, and learned how to utilize the resources provided in the Edge SDK to create your own application.   This is the last guide in the Connect and Configure Industrial Devices and Systems Learning Path.  If you wish to return to the Learning Path, click the link.   Additional Resources If you have questions, issues, or need additional information, refer to:  Resource Link Community Developer Community Forum Support C Edge SDK Help Center
View full tip
  Step 5: Properties In the Delivery Truck application, there are three Delivery Truck Things. Each Thing has a number of Properties based on its location, speed, and its deliveries carried out. In this design, when a delivery is made or the truck is no longer moving, the Property values are updated. The deliveryTruck.c helper C file is based on the DeliveryTruck Entities in the Composer. After calling the construct function, there are a number of steps necessary to get going. For the SimpleThing application, there are a number of methods for creating Properties, Events, Services, and Data Shapes for ease of use. Properties can be created in the client or just registered and utilized. In the SimpleThingClient application, Properties are created. In the DeliveryTruckClient application, Properties are bound to their ThingWorx Platform counterpart. Two types of structures are used by the C SDK to define Properties when it is seen fit to do so and can be found in [C SDK HOME DIR]/src/api/twProperties.h:   Name                    Structure             Description Property Definitions twPropertyDef Describes the basic information for the Properties that will be available to ThingWorx and can be added to a client application. Property Values twProperty Associates the Property name with a value, timestamp, and quality. NOTE: The C SDK provides a number of Macros located in [C SDK HOME DIR]/src/api/twMacros.h. This guide will use these Macros while providing input on the use of pure function calls.   The Macro example below can be found in the main source file for the SimpleThingClient application and the accompanying helper file simple_thing.c. TW_PROPERTY("TempProperty", "Description for TempProperty", TW_NUMBER); TW_ADD_BOOLEAN_ASPECT("TempProperty", TW_ASPECT_ISREADONLY,TRUE); TW_ADD_BOOLEAN_ASPECT("TempProperty", TW_ASPECT_ISLOGGED,TRUE); NOTE: The list of aspect configurations can be seen in [C SDK HOME DIR]/src/api/twConstants.h. Property values can be set with defaults using the aspects setting. Setting a default value in the client will affect the Property in the ThingWorx platform after binding. It will not set a local value in the client application.   For the DeliveryTruckClient, we registered, read, and update Properties without using the Property definitions. Which method of using Properties is based on the application being built.   NOTE: Updating Properties in the ThingWorx Platform while the application is running, will update the values in the client application. To update the values in the platform to match, end the Property read section of your property handler function with a function to set the platform value.   The createTruckThing function for the deliveryTruck.c source code takes a truck name as a parameter and is used to register the Properties, functions, and handlers for each truck. The updateTruckThing function for the deliveryTruck.c source code takes a truck name as a parameter and is used to either initialize a struct for DeliveryTruck Properties, or simulate a truck stop Event, update Properties, then fire an Event for the ThingWorx platform. Connecting properties to be used on the platform is as easy as registering the property and optionally adding aspects. The following shows the properties that correlate to those in the DeliveryTruck entities in the Composer. To do this within the code, you would use the TW_PROPERTY macro as shown in the deliveryTruck.c. This macro must be proceeded by either TW_DECLARE_SHAPE, TW_DECLARE_TEMPLATE or TW_MAKE_THING because these macros declare variables used by the TW_PROPERTY that follow them. //TW_PROPERTY(propertyName,description,type) TW_PROPERTY(PROPERTY_NAME_DRIVER, NO_DESCRIPTION, TW_STRING); TW_PROPERTY(PROPERTY_NAME_DELIVERIES_LEFT, NO_DESCRIPTION, TW_NUMBER); TW_PROPERTY(PROPERTY_NAME_TOTAL_DELIVERIES, NO_DESCRIPTION, TW_NUMBER); TW_PROPERTY(PROPERTY_NAME_DELIVERIES_MADE, NO_DESCRIPTION, TW_NUMBER); TW_PROPERTY(PROPERTY_NAME_LOCATION, NO_DESCRIPTION, TW_LOCATION); TW_PROPERTY(PROPERTY_NAME_SPEED, NO_DESCRIPTION, "TW_NUMBER); Read Properties Reading Properties from a ThingWorx platform Thing or the returned Properties of a Service can be done using the TW_GET_PROPERTY macro. Examples of its use can be seen in all of the provided applications. An example can be seen below: int flow = TW_GET_PROPERTY(thingName, "TotalFlow").number; int pressue = TW_GET_PROPERTY(thingName, "Pressure").number; twLocation location = TW_GET_PROPERTY(thingName, "Location").location; int temperature = TW_GET_PROPERTY(thingName, "Temperature").number; Write Properties Writing Properties to a ThingWorx platform Thing from a variable storing is value uses a similarly named method. Using the TW_SET_PROPERTY macro will be able to send values to the platform. Examples of its use can be seen in all of the provided applications. An example is shown below: 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)); This macro utilizes the twApi_PushSubscribedProperties function call to pushe all property updates to the server. This can be seen in the updateTruckThing function in deliveryTruck.c. Property Change Listeners Using the Observer pattern, you can take advantage of the Property change listener functionality. With this pattern, you 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, call the twExt_AddPropertyChangeListener function using the: Name of the Thing (entityName) Property this listener should watch Function that will be called when the property has changed 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 In order to release the memory for your application when done with utilizing listeners for the Property, call the twExt_RemovePropertyChangeListener function. void simplePropertyObserver(const char * entityName, const char * thingName,twPrimitive* newValue){ printf("My Value has changed\n"); } twExt_RemovePropertyChangeListener(simplePropertyObserver);   Step 6: Data Shapes Data Shapes are an important part of creating/firing Events and also invoking Services. Define With Macros In order to define a Data Shape 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 Data Shape without using a macro, use the twDataShape_CreateFromEntries function. In the example below, we are creating a Data Shape called SteamSensorReadings that has two numbers as Field Definitions. twDataShape * ds = twDataShape_Create(twDataShapeEntry_Create("a",NULL,TW_NUMBER)); twDataShape_AddEntry(ds, twDataShapeEntry_Create("b",NULL,TW_NUMBER)); /* Name the DataShape for the SteamSensorReadings service output */ twDataShape_SetName(ds, "SteamSensorReadings");   Step 7: Events and Services Events and Services provide useful functionality. Events are a good way to make a Service be asynchronous. You can call a Service, let it return, then your Entity can subscribe to your Event and not keep the original Service function waiting. Events are also a good way to allow the platform to respond to data when it arrives on the edge device without it having to poll the edge device for updates. Fire Events To fire an Event you first need to register the Event and load it with the necessary fields for the Data Shape of that Event using the twApi_RegisterEvent function. Afterwards, you would send a request to the ThingWorx server with the collected values using the twApi_FireEvent function. An example is as follows: twDataShape * ds = twDataShape_Create(twDataShapeEntry_Create("message", NULL,TW_STRING)); /* Event datashapes require a name */ twDataShape_SetName(ds, "SteamSensorFault"); /* Register the service */ twApi_RegisterEvent(TW_THING, thingName, "SteamSensorFault", "Steam sensor event", ds); …. struct { char FaultStatus; double Temperature; double TemperatureLimit; } properties; …. properties. TemperatureLimit = rand() + RAND_MAX/5.0; properties.Temperature = rand() + RAND_MAX/5.0; properties.FaultStatus = FALSE; if (properties.Temperature > properties.TemperatureLimit && properties.FaultStatus == FALSE) { twInfoTable * faultData = 0; char msg[140]; properties.FaultStatus = TRUE; sprintf(msg,"%s Temperature %2f exceeds threshold of %2f", thingName, properties.Temperature, properties.TemperatureLimit); faultData = twInfoTable_CreateFromString("message", msg, TRUE); twApi_FireEvent(TW_THING, thingName, "SteamSensorFault", faultData, -1, TRUE); twInfoTable_Delete(faultData); } Invoke Services In order to invoke a Service, you will use the twApi_InvokeService function. The full documentation for this function can be found in [C SDK HOME DIR]/src/api/twApi.h. Refer to the table below for additional information.   Parameter         Type                   Description entityType Input The type of Entity that the service belongs to. Enumeration values can be found in twDefinitions.h. entityName Input The name of the Entity that the service belongs to. serviceName Input The name of the Service to execute. params Input A pointer to an Info Table containing the parameters to be passed into the Service. The calling function will retain ownership of this pointer and is responsible for cleaning up the memory after the call is complete. result Input/Output A pointer to a twInfoTable pointer. In a successful request, this parameter will end up with a valid pointer to a twInfoTable that is the result of the Service invocation. The caller is responsible for deleting the returned primitive using twInfoTable_Delete. It is possible for the returned pointer to be NULL if an error occurred or no data is returned. timeout Input The time (in milliseconds) to wait for a response from the server. A value of -1 uses the DEFAULT_MESSAGE_TIMEOUT as defined in twDefaultSettings.h. forceConnect Input A Boolean value. If TRUE and the API is in the disconnected state of the duty cycle, the API will force a reconnect to send the request.   See below for an example in which the Copy service from the FileTransferSubsystem is called:   twDataShape * ds = NULL; twInfoTable * it = NULL; twInfoTableRow * row = NULL; twInfoTable * transferInfo = NULL; int res = 0; const char * sourceRepo = "SimpleThing_1"; const char * sourcePath = "tw/hotfolder/"; const char * sourceFile = "source.txt"; const char * targetRepo = "SystemRepository"; const char * targetPath = "/"; const char * targetFile = "source.txt"; uint32_t timeout = 60; char asynch = TRUE; char * tid = 0; /* Create an infotable out of the parameters */ ds = twDataShape_Create(twDataShapeEntry_Create("sourceRepo", NULL, TW_STRING)); res = twDataShape_AddEntry(ds, twDataShapeEntry_Create("sourcePath", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("sourceFile", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("targetRepo", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("targetPath", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("targetFile", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("async", NULL, TW_BOOLEAN)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("timeout", NULL, TW_INTEGER)); it = twInfoTable_Create(ds); row = twInfoTableRow_Create(twPrimitive_CreateFromString(sourceRepo, TRUE)); res = twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(sourcePath, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(sourceFile, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(targetRepo, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(targetPath, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(targetFile, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromBoolean(asynch)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromInteger(timeout)); twInfoTable_AddRow(it,row); /* Make the service call */ res = twApi_InvokeService(TW_SUBSYSTEM, "FileTransferSubsystem", "Copy", it, &transferInfo, timeout ? (timeout * 2): -1, FALSE); twInfoTable_Delete(it); /* Grab the tid */ res = twInfoTable_GetString(transferInfo,"transferId",0, &tid); Bind Event Handling You may want to track exactly when your edge Entities are successfully bound to or unbound from the server. The reason for this is that only bound items should be interacting with the ThingWorx Platform and the ThingWorx Platform will never send any requests targeted at an Entity that is not bound. A simple example that only logs the bound Thing can be seen below. After creating this function, it will need to be registered using the twApi_RegisterBindEventCallback function before the connection is made. void BindEventHandler(char * entityName, char isBound, void * userdata) { if (isBound) TW_LOG(TW_FORCE,"BindEventHandler: Entity %s was Bound", entityName); else TW_LOG(TW_FORCE,"BindEventHandler: Entity %s was Unbound", entityName); } …. twApi_RegisterBindEventCallback(thingName, BindEventHandler, NULL); OnAuthenticated Event Handling You may also want to know exactly when your Edge device has successfully authenticated and made a connection to the ThingWorx platform. Like the bind Event handling, this function will need to be made and registered. To register this handler, use the twApi_RegisterOnAuthenticatedCallback function before the connection is made. This handler form can also be used to do a delay bind for all Things. void simplePropertyObserver(const char * entityName, const char * thingName,twPrimitive* newValue){ printf("My Value has changed\n"); } twExt_RemovePropertyChangeListener(simplePropertyObserver);   Click here to view Part 4 of this guide. 
View full tip
  Step 3: Run Sample Code The C code in the sample download is configured to run and connect to the Entities provided in the ThingWorxEntitiesExport.xml file. Make note of the IP address of your ThingWorx Composer instance. The top level of the exported zip file will be referred to as [C SDK HOME DIR]. Navigate to the [C SDK HOME DIR]/examples/ExampleClient/src directory. Open the main.c source file. Operating System          Command Linux/Ubuntu gedit main.c OR vi main.c Mac open –e main.c Windows start main.c Modify the Server Details section at the top with the IP address for your ThingWorx Platform instance and the Application Key you would like to use. Change the TW_HOST definition accordingly. NOTE: By default, TW_APP_KEY has been set to the Application Key from the admin_key in the import step completed earlier. Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a user and place the user as a member of the Admins security group.   /* Server Details */ #define TW_HOST "127.0.0.1" #define TW_APP_KEY "ce22e9e4-2834-419c-9656-e98f9f844c784c" If you are working on a port other than 80, you will need to update the conditional statement within the main.c source file. Search for and edit the first line within the main function. Based on your settings, set the int16_t port to the ThingWorx platform port. Click Save and close the file. Create a directory to build in, for this example call it bin. Operating System           Command Linux/Ubuntu mkdir bin Mac mkdir bin Windows mkdir bin Change to the newly created bin directory. Operating System          Command Linux/Ubuntu cd bin Mac cd bin Windows cd bin Run the CMake command using your specific IDE of choice. NOTE: Include the two periods at the end of the code as shown below. Use cmake -G to see a list of supported IDEs.         cmake ..​           Once your build completes, you will find the build products in the bin directory, and you can open the project in your IDE of choice. NOTE: You should receive messages confirming successful binding, authentication, and connection after building and running the application. You should be able to see a Thing in your ThingWorx Composer called SimpleThing_1 with updated lastConnection and isConnected properties. SimpleThing_1 is bound for the duration of the application run time.     The below instructions will help to verify the connection. Click Monitoring. Click Remote Things from the list to see the connection status.   You will now be able to see and select the Entity within the list.   Step 4: ExampleClient Connection The C code provided in the main.c source file is preconfigured to initialize the ThingWorx C Edge SDK API with a connection to the ThingWorx platform and register handlers. In order to set up the connection, a number of parameters must be defined. This can be seen in the code below. #define TW_HOST "127.0.0.1" #define TW_APP_KEY "ce22e9e4-2834-419c-9656-ef9f844c784c #if defined NO_TLS #define TW_PORT = 80; #else #define TW_PORT = 443; #endif The first step of connecting to the platform: Establish Physical Websocket, we call the twApi_Initialize function with the information needed to point to the websocket of the ThingWorx Composer. This function: Registers messaging handlers Allocates space for the API structures Creates a secure websocket err = twApi_Initialize(hostname, port, TW_URI, appKey, NULL, MESSAGE_CHUNK_SIZE, MESSAGE_CHUNK_SIZE, TRUE); if (TW_OK != err) { TW_LOG(TW_ERROR, "Error initializing the API"); exit(err); } If you are not using SSL/TLS, use the following line to test against a server with a self-signed certificate: twApi_SetSelfSignedOk(); In order to disable HTTPS support and use HTTP only, call the twApi_DisableEncryption function. This is needed when using ports such as 80 or 8080. A call can be seen below: twApi_DisableEncryption(); The following event handlers are all optional. The twApi_RegisterBindEventCallback function registers a function that will be called on the event of a Thing being bound or unbound to the ThingWorx platform. The twApi_RegisterOnAuthenticatedCallback function registered a function that will be called on the event the SDK has been authenticated by the ThingWorx Platform. The twApi_RegisterSynchronizeStateEventCallback function registers a function that will be called after binding and used to notify your application about fields that have been bound to the Thingworx Platform. twApi_RegisterOnAuthenticatedCallback(authEventHandler, TW_NO_USER_DATA); twApi_RegisterBindEventCallback(NULL, bindEventHandler, TW_NO_USER_DATA); twApi_RegisterSynchronizeStateEventCallback(NULL, synchronizeStateHandler, TW_NO_USER_DATA); NOTE: Binding a Thing within the ThingWorx platform is not mandatory, but there are a number of advantages, including updating Properties while offline.   You can then start the client, which will establish the AlwaysOn protocol with the ThingWorx Composer. This protocol provides bi-directional communication between the ThingWorx Composer and the running client application. To start this connection, use the line below:   err = twApi_Connect(CONNECT_TIMEOUT, RETRY_COUNT); if(TW_OK != err){ exit(-1); }   Click here to view Part 3 of this guide.   
View full tip
  Use the C SDK to build an app that connects to ThingWorx with persistent bi-directional communication   Guide Concept This project will introduce more complex aspects of the ThingWorx C SDK and help you to get started with development.  Following the steps in this this guide, you will be ready to develop your own IoT application with the ThingWorx C SDK.  We will teach you how to use the C programming language to connect and build IoT applications to be used with the ThingWorx Platform.   You'll learn how to Establish and manage a secure connection with a ThingWorx server, including SSL negotiation and connection maintenance Enable easy programmatic interaction with the Properties, Services, and Events that are exposed by Entities running on a ThingWorx server Create applications that can be directly used with your device running the C programming language Basic concepts of the C Edge SDK How to use the C Edge API to build a real-world application How to utilize resources provided in the Edge SDK to help create your own application NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL 3 parts of this guide is 60 minutes.   Step 1: Completed Examples Download the completed files for this tutorial: ThingWorx C Edge SDK Sample Files.zip.  This tutorial will guide you through working with the C SDK on differing levels. Utilize this file to see a finished example and return to it as a reference if you become stuck creating your own fully fleshed out application.  Keep in mind, this download uses the exact names for Entities used in this tutorial. If you would like to import this example and also create Entities on your own, change the names of the Entities you create.   Step 2: Environment Setup In order to compile C code, you need a C compiler and the ThingWorx C Edge SDK available in the PTC Support download site.  It will be helpful to have CMake installed on your system. CMake is a build tool that will generate make or project files for many different platforms and IDEs.   Operating System      Notes Windows You will need a 3rd party compiler such as MinGW GCC, Cygwin GCC or you can follow these Microsoft instructions to download and use the Microsoft Visual C++ Build Tool. Mac Download the Apple Developer Tools. Linux/Ubuntu A compiler is included by default.   NOTE: You can use CMake, version 2.6.1 or later to build projects or make files, which then are used to build the applications that you develop with the C SDK.     Before you can begin developing with the ThingWorx C SDK, you need to generate an Application Key and modify the source code file. You can use the Create an Application Key guide as a reference.   Modify Source File Extract the files from the C SDK samples zip file. At the top level of the extracted files, you will see a folder called examples. This directory provides examples of how to utilize the C SDK. Open a terminal, go to your workspace, and create a new directory. You can also just switch to the unzipped directory in your system. After you've created this directory in your workspace, copy the downloaded files and folders into your new directory. You can start creating your connection code or open the main.c source file in the examples\SteamSensor\src directory for an example. Operating System      Code Linux/Ubuntu gedit main.c OR vi main.c Mac open –e main.c Windows start main.c Modify the Server Details section at the top with the IP address for your ThingWorx platform instance and the Application Key you would like to use. Change the TW_HOST definition accordingly. Change the TW_PORT definition accordingly. Change the TW_APP_KEY definition to the keyId value saved from the last step.         /* Server Details */ #define TW_HOST "https://pp-XXXXXXXXX.devportal.ptc.i" #define TW_PORT 80 #define TW_APP_KEY "e1d78abf-cfd2-47a6-92b7-37ddc6dd34618"​         NOTE: Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a User and place the user as a member of Admins.   Compile and Run Code To test your connection, you will only need to update the main.c in the SteamSensor example folder. CMake can generate Visual Studio projects, make build files or even target IDEs such as Eclipse, or XCode. CMake generates a general description into a build for your specific toolchain or IDE.   Inside the specific example folder you would like to run, ie SteamSensor. Create a directory to build in, for this example call it bin. mkdir bin  cd bin Run the CMake command listed below. This assumes CMake is already on your PATH.         cmake ..​           CMake has now produced a set of project files which should be compatible with your development environment. Operating System        Command                                            Notes Unix make A set of make files Windows msbuild tw-c-sdk.sln /t:build A visual studio solution   NOTE: CMake does its best to determine what version of Visual Studio you have but you may wish to specify which version to use if you have more than one installed on your computer. Below is an example of forcing CMake to use a specific version of Visual Studio: cmake -G "Visual Studio 15 2017" .. If your version of Visual Studio or other IDE is unknown, use cmake -G to see a list of supported IDEs.   You also have the alternative of opening the tw-c-sdk.sln from within Visual Studio and building in this IDE.   NOTE: By default, CMake will generate a build for the creation of a release binary. If you want to generate a debug build, use the command:           cmake -DBUILD_DEBUG=ON ..           Once your build completes you will find the build products in the CMake directory (see example below). From here, open the project in your IDE of choice.   NOTE: You should receive messages confirming successful binding, authentication, and connection after the main.c file edits have been made.   Operating System Files Description Unix ./bin/src/libtwCSdk_static.a  Static Library Unix ./bin/src/libtwCSdk.so  Shared Library Unix ./bin/examples/SteamSensor/SteamSensor   Sample Application Windows .\bin\src\<Debug/Release>\twCSdk_static.lib  Static Library Windows .\bin\src\<Debug/Release>\twCSdk.dll  Shared Library Windows .\bin\examples\<Debug/Release>\SteamSensor\SteamSensor.exe  Sample Application   Click here to view Part 2 of this guide.  
View full tip
Connect and Monitor Industrial Plant Equipment Learning Path   Learn how to connect and monitor equipment that is used at a processing plant or on a factory floor.   NOTE: Complete the following guides in sequential order. The estimated time to complete this learning path is 180 minutes.   Create An Application Key  Install ThingWorx Kepware Server Connect Kepware Server to ThingWorx Foundation Part 1 Part 2 Create Industrial Equipment Model Build an Equipment Dashboard Part 1 Part 2
View full tip
  Operationalize an Analytics Model Guide Part 1   Overview   This project will introduce ThingWorx Analytics Manager. Following the steps in this guide, you will learn how to deploy the model which you created in the earlier Builder guide. We will teach you how to utilize this deployed model to investigate whether or not live data indicates a potential engine failure. NOTE: This guide’s content aligns with ThingWorx 9.3. The estimated time to complete ALL 2 parts of this guide is 60 minutes.    Step 1: Analytics Architecture   You can leverage product-based analysis Models developed using PTC and third-party tools while building solutions on the ThingWorx platform. Use simulation as historical basis for predictive Models Create a virtual sensor from simulation Design-time versus operational-time intelligence It is important to understand how Analytics Manager interacts with the ThingWorx platform.   Build Model   In an IoT implementation, multiple remote Edge devices feed information into the ThingWorx Foundation platform. That information is stored, organized, and operated-upon in accordance with the application's Data Model. Through Foundation, you will upload your dataset to Analytics Builder. Builder will then create an Analytics Model.     Operationalize Model   Analytics Manager tests new data through the use of a Provider, which applies the Model to the data to make a prediction. The Provider generates a predictive result, which is passed back through Manager to ThingWorx Foundation. Once Foundation has the result, you can perform a variety of actions based on the outcome. For instance, you could set up Events/Subscriptions to take immediate and automatic action, as well as alerting stakeholders of an important situation.       Step 2: Simulate Data Source   For any ThingWorx IoT implementation, you must first connect remote devices via one of the supported connectivity options, including Edge MicroServer (EMS), REST, or Kepware Server. Edge Connectivity is outside the scope of this guide, so we'll use a data simulator instead. This simulator will act like an Engine with a Vibration Sensor, as described in Build a Predictive Analytics Model. This data is subdivided into five frequency bands, s1_fb1 through s1_fb5. From this data, we will attempt to predict (through the engine's vibrations) when a low grease emergency condition is occuring.   Import Entities   Import the engine simulator into your Analytics Trial Edition server. Download and unzip the attached amqs_entities.zip file. At the bottom-left of ThingWorx Composer, click Import/Export > Import.     Keep the default options of From File and Entity, click Browse, and select the amqs_entities.twx file you just downloaded.   Click Import, wait for the Import Successful message, and click Close.   From Browse > All, select AMQS_Thing from the list.   At the top, click Properties and Alerts to see the core functionality of the simulator. NOTE: The InfoTable Property is used to store data corresponding to the s1_fb1 through s1_fb5 frequency bands of the vibration sensor on our engine. The values in this Property change every ten seconds through a Subscription to the separate AMQS_Timer Thing. The first set of values are good, in that they do NOT correspond to a low grease condition. The second set of values are bad, in that they DO correspond to a low grease condition. These values will change whenever the ten-second timer fires.   View Mashup   We have created a sample Mashup to make it easier to visualize the data, since analyzing data values in the Thing Properties is cumbersome. Follow these steps to access the Mashup. On the ThingWorx Composer Browse > All tab, click AMQS_Mashup.   At the top, click View Mashup.    Observe the Mashup for at least ten-seconds. You'll see the values in the Grid Advanced Widget change from one set to another at each ten-second interval.     NOTE: These values correspond to data entries from the vibration dataset we utilized in the pre-requisite Analytics Builder guide. Specifically, the good entry is number 20,040... while the bad entry is number 20,600. You can see in the dataset that 20,400 corresponds to a no low grease condition, while 20,600 corresponds to a yes, low grease condition.   Step 3: Configure Provider   In ThingWorx terminology, an Analysis Provider is a mathematical analysis engine. Analytics Manager can use a variety of Providers, such as Excel or Mathcad. In this quickstart, we use the built-in AnalyticsServerConnector, an Analysis Provider that has been specifically created to work seamlessly in Analytics Manager and to use Builder Models. From the ThingWorx Composer Analytics tab, click ANALYTICS MANAGER > Analysis Providers, New....   In the Provider Name field, type Vibration_Provider. In the Connector field, search for and select TW.AnalysisServices.AnalyticsServer.AnalyticsServerConnector.   4. Leave the rest of the options at default and click Save.   Step 4: Publish Analysis Model   Once you have configured an Analysis Provider, you can publish Models from Analytics Builder to Analytics Manager. On the ThingWorx Composer Analytics tab, click ANALYTICS BUILDER > Models.   Select vibration_model_s1_only and click Publish.   On the Publish Model pop-up, click Yes. A new browser tab will open with the Analytics Manager's Analysis Models menu.      4. Close that new browser tab, and instead click Analytics Manager > Analysis Models in the ThingWorx Composer Analytics navigation. This is the same interface as the auto-opened tab which you closed.   False Test   It is recommended to test the published Model with manually-entered sample data prior to enabling it for automatic analysis. For this example, we will use entry 20,400 from the vibration dataset. If the Model is working correctly, then it will return a no low grease condition. In Analysis Models, select the model you just published and click View.   Click Test.   In the causalTechnique field, type FULL_RANGE. In the goalField field, type low_grease. For _s1_fb1 through _s1_fb5, enter the following values: Data Row Name Data Row Value _s1_fb1 161 _s1_fb2 180 _s1_fb3 190 _s1_fb4 176 _s1_fb5 193 6. Click Add Row. 7. Select the newly-added row in the top-right, then click Set Parent Row. 8. Click Submit Job. 9. Select the top entry in the bottom-left Results Data Shape field. 10. Click Refresh Job. Note that _low_grease is false and and _low_grease_mo is well below 0.5 (the threashold for a true prediction).   You have now successfully submitted your first Analytics Manager job and received a result from ThingPredictor. ThingPredictor took the published Model, used the no low grease data as input, and provided a correct analysis of false to our prediction.   True Test Now, let's test a true condition where our engine grease IS LOW, and confirm that Analytics Manager returns a correct prediction. In the top-right, select the false data row we've already entered and click Delete Row. For _s1_fb1 through _s1_fb5, change to the following values: Data Row Name Data Row Value _s1_fb1 182 _s1_fb2 140 _s1_fb3 177 _s1_fb4 154 _s1_fb5 176 3. Select the top entry in the bottom-left Results Data Shape field. 4. Click Refresh Job. Note that _low_grease is true and and _low_grease_mo is above 0.5.                 5. Click Submit Job.         6. Select the top entry in the bottom-left Results Data Shape field.         7. Click Refresh Job. Note that _low_grease is true and and _low_grease_mo is above 0.5.          You've now manually submitted yet another job and received a predictive score. Just like in the dataset Entry 20,600, Analytics Manager predicts that the second s1_fb1 through s1_fb5 vibration frequencies correspond to a low grease condition which needs to be addressed before the engine suffers catastrophic failure.   Enable Model   Since both false and true predictions made by the Model seem to match our dataset, let's now enable the Model so that it can be used for automatic predictions in the future. In the top-left, expand the Actions... drop-down box.   Select Enable.     Click here to view Part 2 of this guide.   
View full tip
  Step 5: Create Services   Below shows how we can create the GetCustomerPackages Service for the PTCDeliversBusinessLogic Thing.   Create Service Definition   On the home page, filter and select the PTCDeliversBusinessLogic Thing. Switch to the Services tab. Click + Add.   Enter the name of the Service, GetCustomerPackages. Switch to the Output tab of the Service. Select InfoTable from the list as the Base Type. When prompted for the DataShape, select CustomerDataShape. Switch to the Inputs tab of the Service. Click the + Add button.   Enter the name CustomerId. Check the Required checkbox. Click Done.   Add Service Functionality   Switch to the Me/Entities tab. Switch the radio option to Other Entity. Filter and select PackageDataTable as the Entity. A list of all accessible Services for the PackageDataTable will appear. In the search bar for Services, enter QueryDataTableEntries in the Services section and click the arrow next to it. Update the inserted code to use the input parameter, CustomerId, in the query. An example is below and more information can be found on queries on our Query Help Page. Click Done and save your work.             / Provide your filter using the format as described in the help topic "Query Parameter for Query Services" var query = { "filters": { "type": "EQ", "fieldName": "CustomerId", "value": CustomerId } }; // result: INFOTABLE dataShape: "" var result = Things["PackageDataTable"].QueryDataTableEntries({ maxItems: undefined /* NUMBER */, values: undefined /* INFOTAB             After saving changes and closing the Service edit view, you can test the method by selecting the Execute play button.   The Service we created will query PackageDataTable for any packages with the CustomerId you entered. If no data has been added to the DataTable as yet, open PackageDataTable's Services tab and execute the AddDataTableEntries Service with test data.       Step 6: Create Subscriptions   Subscriptions are based on tracking the firing of an Event. When the Event is triggered or fired, all entities with a Subscription to the Event will perform the script as defined. The JavaScript interface and script tabs are the same as those utilized for the Services interface.   Subscriptions are a great resource for making updates in other Entities, Databases, or even just logging this information to your liking. On the home page, filter and select the PTCDeliversBusinessLogic Thing. Switch to the Subscriptions tab. Click + Add.   For Source, select *Other Entity. Filter and select PackageStream. Check the Enabled checkbox. Using a Stream to track events in the application allows for one source to watch for activity. The source for a Subscription can be other Entities if a single Entity is wanted. In order to capture all source data from the PackageStream, you will need to set it as the Stream for the Entity you would like to track. Switch to the Inputs tab. Select the Event drop-down and pick the PackageDelivered Event. This PackageDelivered Event only exists in the completed download. If you are not using that download, create your own Event based on the PackageDataShape. Update the script area of the Subscription using the below code. This JavaScript code will take the information from the triggered Event and add it to the DeliveryDataTable.           / tags:TAGS var tags = new Array(); // values:INFOTABLE(Datashape: PackageDataShape) var values = Things["DeliveryDataTable"].CreateValues(); values.Customer = eventData.Customer; // THINGNAME values.Content = eventData.Content; // STRING values.ID = eventData.ID; // INTEGER [Primary Key] values.Weight = eventData.Weight; // NUMBER // location:LOCATION var location = new Object(); location.latitude = 0; location.longitude = 0; location.elevation = 0; location.units ="WGS84"; var params = { tags : tags, source : me.name, values : values, location : location }; // AddOrUpdateDataTableEntry(tags:TAGS, source:STRING("me.name"), values:INFOTABLE(DeliveryDataTable), location:LOCATION):STRING var id = Things["DeliveryDataTable"].AddOrUpdateDataTableEntry(params);                 Step 7: Next Steps   Congratulations! You've successfully completed the Implement Services, Events and Subscriptions guide.   In this guide you learned how to to create Events, Services and Subscriptions you can utilize to monitor and optimize your IoT applications.   The next guide in the Design and Implement Data Models to Enable Predictive Analytics learning path is Build a Predictive Analytics Model.    The next guide in the Monitor Factory Supplies and Consumables learning path is Build a Predictive Analytics Model.   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Create Custom Business Logic Guide Secure Configure Permissions Connect SDK Reference   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Help Center  
View full tip
Data Model Implementation Guide Part 1   Overview   This project will introduce you to methods for creating the data model that you have designed and are ready to implement. Following the steps in this guide, you will implement the Data Model you've already designed. After having insight into your desired Data Model, this guide will provide instructions and examples on how to build out your application using the ThingWorx platform. We will teach you how to utilize the ThingWorx platform to implement your fully functional IoT application. NOTE: This guide’s content aligns with ThingWorx 9.3. The estimated time to complete ALL 3 parts of this guide is 60 minutes. All content is relevant but there are additional tools and design patterns you should be aware. Please go to this link for more details.     Step 1: Completed Example   Download the completed files for this tutorial:  DataModelEntities.xml. The DataModelEntities.xml file provided to you contains a completed example of the completed data model implementation. Utilize this file to see a finished example and return to it as a reference if you become stuck during this guide and need some extra help or clarification. Keep in mind, this download uses the exact names for entities used in this tutorial. If you would like to import this example and also create entities on your own, change the names of the entities you create.   Step 2: Data Model Scenario   This guide will implement the scenario shown in the Data Model Design guide. Let's revisit our Smart Factory example scenario. Name Description Operations User to keep the line running and make sure that it’s producing quality products Maintenance User to keep machines up and running so that the operator can crank out products Management User in charge of dispatching production orders and making sure the quotas are being met Conveyor Belts Thing on factory line to pass items along to the next stage Pneumatic Gate Thing on factory line Robotic Arm Thing on factory line Quality Check Camera Final Thing on factory line to ensure quality In order to add this to our solution, we will want to build a "connector" between ThingWorx and the existing system. These connectors will be Things as well. Internal system connection Thing for Production Order System Internal system connection Thing for Maintenance Request System Operator   Required Functionality Description 1 File Maintenance Request 2 Get quality data from assets on their line 3 Get performance data for the whole line 4 Get a prioritized list of production orders for their line 5 Create Maintenance Requests   Required Information Description 1 Individual asset performance metrics 2 Full line performance metrics 3 Product quality readings   Maintenance   Required Functionality Description 1 Get granular data values from all assets 2 Get a list of maintenance requests 3 Update maintenance requests 4 Set triggers for automatic maintenance request generation 5 Automatically create maintenance requests when triggers have been activated   Required Information Description 1 Granular details for each asset: In order to better understand healthy asset behavior 2 Current alert status for each asset: to know if there is something going wrong with an asset 3 When the last maintenance was performed on an asset 4 When the next maintenance is scheduled for an asset 5 Maintenance request info: Creation date, due date, progress notes   Management   Required Functionality Description 1 Create production orders 2 Update production orders 3 Cancel Production orders 4 Access line productivity data 5 Elevate maintenance request priority   Required Information Description 1 Production line productivity levels (OEE) 2 List of open Maintenance requests   Overlapping Matrix   This matrix represents all of the overlapping Components that are shared by multiple types of Things in our system:   Unique Matrix   This matrix represents the unique Components to each type of Thing:     Step 3: LineAsset Thing Template   After prioritizing and grouping common functionality and information, we came up with the list below for the first Thing Template to create, LineAsset with five Properties, one Event, and one Subscription. The breakdown for the LineAsset Thing Template is as follows:   Follow the below instruction to create this Entity and get the implementation phase of your development cycle going.   Line Asset Properties   Let's build out our Properties. In the ThingWorx Composer, click the + New at the top of the screen. Select Thing Template in the dropdown.        3. In the name field, enter LineAsset and set the Project (ie, PTCDefaultProject). 4. For the Base Thing Template field, select GenericThing.     5. Click Save.  6. Switch to the Properties and Alerts tab.  7. Click the plus button to add a new Property.   The Properties for the LineAsset Thing Template are as follows: Name Base Type Aspects Data Change Type State String Persistent and Logged ALWAYS SerialNumber String Persistent, Read Only, and Logged NEVER LastMaintenance DATETIME Persistent and Logged VALUE NextMaintenance DATETIME Persistent and Logged VALUE PowerConsumption NUMBER, Min Value: 0 Persistent and Logged ALWAYS Follow the next steps for all the properties shown in our template property table. Click Add. Enter the name of the property (ie, State). Select the Base Type of the proprty from the dropdown. Check the checkboxes for the property Aspects. Select the Data Change Type from the dropdown.   Click Done when finished creating the property. Your properties should match the below configurations.     Line Asset Event   Switch to the Events tab. Click Add. Enter the name of the Event (ie, Error). Select AlertStatus as the Data Shape. This DataShape will allow us to provide simple information including an alert type, the property name, and a status message.   Click Done. Your Event should match the below configurations.          Line Asset Subscription   Switch to the Subscriptions tab. Click Add. Check the Enabled checkbox. Switch to the Inputs tab. Select the name of the Event (ie, Error). Click Done. Your Subscription should match the below configurations.             Challenge Yourself   We have left the Subscription code empty. Think of a way to handle Error Events coming from your line asset and implement it in this section.   Click here to view Part 2 of this guide. 
View full tip
Data Model Implementation Guide Part 2   Step 4: SystemConnector Thing Template   After grouping our second set of common functionality and information, we came up with the list below for the second Thing Template to create, SystemConnector with 3 Properties. The breakdown for the SystemConnector Thing Template is as follows:   Follow the below instruction to create this Entity and get the implementation phase of your development cycle going.   System Connector Properties   Let's jump right in. In the ThingWorx Composer, click the + New at the top of the screen.        2. Select Thing Template in the dropdown. 3. In the name field, enter SystemConnector and select a Project (ie, PTCDefaultProject). 4. For the Base Thing Template field, select GenericThing. 5. Click Save. 6. Switch to the Properties and Alerts tab. 7. Click the plus button to add a new Property.   The Properties for the SystemConnector Thing Template are as follows: Name Base Type Aspects Data Change Type EndPointConfig String Persistent and Logged VALUE OperatorCredentials PASSWORD Persistent VALUE ProdManagerCredentials PASSWORD Persistent VALUE Follow the next steps for all the Properties shown in our template property table. Click Add. Enter the name of the property (ie, EndPointConfig). Select the Base Type of the proprty from the dropdown. Check the checkboxes for the property Aspects. Select the Data Change Type from the dropdown.   Click Done when finished creating the property. Your Properties should match the below configurations.            Step 5: HazardousAsset Thing Template     After another round of prioritizing and grouping common functionality and information, we came up with the third Thing Template to create, HazardousAsset. It is a child of the LineAsset Thing Template with one added Service. The breakdown for the HazardousAsset Thing Template is as follows:   Hazardous Asset Service   In the ThingWorx Composer, click the + New at the top of the screen. 2. Select Thing Template in the dropdown. 3. For the Base Thing Template field, select LineAsset and select a Project (PTCDefaultProject). 4. In the name field, enter HazardousAsset. 5.  Click Save then edit to store all changes now. 6.  Switch to the Services tab. 7.  Click Add. 8.  Enter EmergencyShutdown as the name of the service. 9. Switch to the Me/Entities tab. 10. Expand Properties. 11. Click the arrow next to the State property. 12. Modify the generated code to match the following:       me.State = "Danger!! Emergency Shutdown";       Your first Service is complete! 13. Click Done. 14. Click Save to save your changes. Your Service should match the below configurations.     Step 6: InventoryManager Thing Shape   This time around, we will create our first ThingShape, InventoryManager with 1 Property. The breakdown for the InventoryManager Thing Shape is as follows:   Follow the below instruction to create this Entity and get the implementation phase of your development cycle going. System Connector Properties The properties for the InventoryManager Thing Shape are as follows: Name Base Type Aspects Data Change Type ProductCount INTEGER Min Value:0 Persistent and Logged ALWAYS In the ThingWorx Composer, click the + New at the top of the screen. Select Thing Shape in the dropdown. In the name field, enter InventoryManager and select a Project (ie, PTCDefaultProject).       4. Click Save then Edit to store all changes now.         5. Switch to the Properties tab.        6. Click Add.       7. Enter ProductCount as the name of the property.       8. Select the Base Type of the proprty from the dropdown (ie, INTEGER).       9. Check the checkboxes for the property Aspects.      10. Select the Data Change Type from the dropdown.            11. Click Done when finished creating the property. Your Properties should match the below configurations.   Add Thing Shape to Template   We can see that there is some overlap in the components of our HazardousAsset and LineAsset ThingTemplates. In particular, both want information about the product count. Because HazardousAsset inherits from LineAsset, would only need to change LineAsset. Follow the steps below to perform this change: Open the LineAsset Thing Template. In the Implemented Shapes field, enter and select InventoryManager. Save changes.         Click here to view Part 3 of this guide.   
View full tip
  Design Your Data Model Guide Part 3   Step 7: Prioritize     The first step in the design process is to use the Thing-Component Matrix to identify and prioritize groups of Components that are shared across multiple Things. These groups will be prioritized by number of shared Components, from highest to lowest, enabling is to break out the most commonly used groups of Components and package them into reusable pieces. Let’s examine our example Thing-Component Matrix to identify and prioritize groups. In the table below, we have done this and recognized that there are FOUR groups.   NOTE: Each item in our unique Thing-Component Matrix would also count as a group on its own. This can be dealt with almost separately from our process, though, because there is no overlap between different Things. The "Templates for Unique Components" and "Adding Components Directly to Things" sections in the Iterate step of this guide covers these "one-offs."     Step 8: Largest Group     The base building block we use most often is the Thing Template. To start the design process, the first step is to create a Thing Template for the largest Component group. Applying this to our Smart Factory scenario, we'll take the largest group ("Group 1") and turn it  into a Thing Template using the Entity Relationship Diagram schematic.   Since every item on our production line shares these Components, we will name this Thing Template Line Asset. Now, let's build this using our Entity Relationship Diagram.   The result is a ThingWorx Thing Template with five Properties, one Event, and one Subscription.     Step 9: Iterate     Once an initial base template has been created for the largest group, the rest of the groups can be added by selecting the appropriate entity type (Thing Template, Thing Shape, or directly-instantiated Thing). The following Entity Decision Flowchart explains which entity type is used in which scenario:   Now that we have established our "Line Asset" Thing Template for our largest group, the next step is to iterate through each of our remaining groups. Following the flowchart, we will identify what entity type it should be and add it to our design.   Group 2 - "System Connector"   The second group represents connectors into both of our internal business systems. We will call them System Connectors.   If we look at Group 2 versus our "Largest Group" Thing Template, we can see that there is no overlap between their Components. This represents the third branch of the Entity Decision Flowchart, which means we want to create a new Thing Template.   Following this rule, here is the resulting template:   Group 3 - "Hazardous Asset"   The third group represents line assets that require emergency shutdown capabilities because under certain conditions, the machinery can become dangerous. We will call these Hazardous Assets.   If we look at our two previous Thing Templates, we can see that there is full overlap of these Components with our previous largest group, the "Line Asset" Thing Template. This represents the fourth branch of the Entity Decision Flowchart, which means we want to create a CHILD Thing Template.   Following this rule, here is the resulting Thing Template:   Group 4 - "Inventory Manager"   The fourth group represents line assets that keep track of inventory count, to ensure the number of assembled-products is equal to the number of checked-products for quality.   If we look at our existing Thing Templates, we can see that there is some overlap of the Components in our "Hazardous Asset" and "Line Asset" Thing Templates. This represents the second branch of the Entity Decision Flowchart, which means we want to create a Thing Shape.   Following this rule, here is the resulting Thing Shape:   Templates for Unique Components   Now that we have handled all our shared component groups, we also want to look at the unique component groups. Since we have already established that each group in our Unique Thing-Component Matrix does not share its Components with other Things, we can create Child Thing Templates for these line assets.   NOTE: Refer to the finished design at the bottom to reference all of the inherited Thing Templates and Thing Shapes for these Child Thing Templates.   Adding Components Directly to Things   In many cases, we will have Components that only exist for a single Thing. This frequently occurs when there will be only one of something in a system. In our case, we will only need one "System Connector" for each of the Maintenance System and the Production Order System.   Instantiate Your Things   At this point, the Data Model is fully built. All we need to do now is instantiate the actual Things which represent our real-world machines and digital-connections.     Step 10: Validate     The final step of the model breakdown design process is validation through instantiation. This is the process by which we take our designed Thing Templates / Thing Shapes / Things and actually create them on the ThingWorx platform to ensure they meet all of our requirements. This is done by tracing back through the chain of inheritance for all the Things in the data model to ensure they contain all of the required Components from the Thing-Component Matrix. Once we have verified that each Thing contains all of its requirements, the data model is complete.   Using this technique on each of your Things, you can explicitly prove that all of the requirements have been met.   Step 11: Next Steps   Congratulations! You've successfully completed the Design Your Data Model Guide covering the first three steps of the proposed data model design strategy for ThingWorx. This guide has given you the basic tools to: Create user stories Identify endpoints in your system Break down your data model using an Entity Relationship Diagram Decide when to use Thing Templates vs. Thing Shapes vs. directly-instantiated Things     The next guide in the Design and Implement Data Models to Enable Predictive Analytics learning path is Data Model Implementation.
View full tip
Design Your Data Model Guide Part 2   Step 4: Data Sources – Component Breakout   Component Breakout     Once you have a full list of Things in your system (as well as requirements for each user), the next step is to identify the information needed from each Thing (based on the user's requirements). This involves evaluating the available data and functionality for each Thing. You then align the data and functionality with the user's requirements to determine exactly what you need, while eliminating that which you do not. This is important, as there can be cost and security benefits to only collecting data you need, and leaving what you don't. NOTE: Remember from the Data Model Introduction that a Thing's Components include Properties, Services, Events, and Subscriptions.   Factory Example   Using the Smart Factory example, let’s go through the different Things and break down each Thing's components that are needed for each of our users.   Conveyor Belts   The conveyor belt is simple in operation but could potentially have a lot of available data. Maintenance Engineer - needs to know granular data for the belt and if it has any alerts emergency shutdown (service) machine state (on/off) (property) serial number (property) last maintenance date (property) next scheduled maintenance date(property) power consumption (property) belt speed (property) belt motor temp (property) belt motor rpm (property) error notification (event) auto-generated maintenance requests (subscription) Operator - needs to know if the belt is working as intended belt speed (property) alert status (event) Production Manager - wants access to the data the Operator can see but otherwise has no new requirements   Robotic Arm   The robotic arm has 3 axes of rotation as well as a clamp hand. Maintenance Engineer - needs to know granular data for the arm and if it has any alerts time since last pickup (property): how long it has been since the last part was picked up by this hand? product count (property): how many products the hand has completed emergency shutdown (service) machine state (on/off) (property) serial number (property) last maintenance date (property) next scheduled maintenance date (property) power consumption (property) arm rotation axis 1 (property) arm rotation axis 2 (property) arm rotation axis 3 (property) clamp pressure (property) clamp status (open/closed) (property) error notification (event) 15.auto-generated maintenance requests (subscription) Operator - needs to know if the robotic arm is working as intended clamp status (open/closed) (property) error notification (event) product count (property): How many products has the hand completed? Production Manager - wants access to the data the Operator can see but otherwise has no new requirements   Pneumatic Gate   The pneumatic gate has two states, open and closed. Maintenance Engineer - needs to know granular data for the gate and if it has any alerts emergency shutdown (service) machine state (on/off) (property) serial number (property) last maintenance date (property) next scheduled maintenance date (property) power consumption (property) gate status (open/closed) (property) error notification (event) auto-generated maintenance requests (subscription) Operator - needs to know if the pneumatic gate is working as intended. gate status (open/closed) (property) error notification (event) The Production Manager wants access to the data the Operator can see but otherwise has no new requirements   Quality Control Camera   The QC camera uses visual checks to make sure a product has been constructed properly. Maintenance Engineer - needs to know granular data for the camera and if it has any alerts machine state (property): on/off serial number (property) last maintenance date (property) next scheduled maintenance date (property) power consumption (property) current product quality reading (property) images being read (property) settings for production quality assessment (property) error notification (event) auto-generated maintenance requests (subscription) product count (property): how many products the camera has seen Operator - needs to keep track of the quality check results and if there are any problems with the camera setup settings for production quality assessment (property) error notification (event) bad quality flag (event) product count (property): how many products the camera has seen Production Manager - wants access to the data the Operator can see but otherwise has no new requirements   Maintenance Request System Connector   Determining the data needed from the Maintenance Request System is more complex than from the physical components, as it will be much more actively used by all of our users. It is important to note that the required functionality already exists in our system as is, but it needs bridges created to connect it to a centralized system. Maintenance Engineer - needs to receive and update maintenance requests maintenance engineer credentials (property): authentication with the maintenance system endpoint configuration for connecting to the system (property) get unfiltered list of maintenance requests (service) update description of maintenance request (service) close maintenance request (service) Operator - needs to create and track maintenance requests operator credentials (property): authentication with the maintenance system endpoint configuration for connecting to the system (property) create maintenance request (service) get filtered list of maintenance requests for this operator (service) Production Manager - needs to monitor the entire system - both the creation and tracking of maintenance requests; needs to prioritize maintenance requests to keep operations flowing smoothly production manager credentials (property): authentication with the maintenance system endpoint configuration for connecting to the system (property) create maintenance request (service) get unfiltered list of maintenance requests (service) update priority of maintenance request (service)   Production Order System Connector   Working with the Production Order System is also more complex than the physical components of the lines, as it will be more actively used by two of the three users. It is important to note that the required functionality already exists in our existing production order system as is, but it needs bridges created to connect to a centralized system. Maintenance Engineer - will not need to know anything about production orders, as it is outside the scope of their job needs Operator - needs to know which production orders have been set up for the line, and needs to mark orders as started or completed operator credentials (property): authentication with the production order system endpoint configuration for connecting to the system (property) mark themselves as working a specific production line (service) get a list of filtered production orders for their line (service) update production orders as started/completed (service) Production Manager - needs to view the status of all production orders and who is working on which line production manager credentials (property): authentication with the production order system endpoint configuration for connecting to the system (property) get a list of production lines with who is working them (service) get the list of production orders with filtering options (service) create new production orders (service) update existing production orders for quantity, and priority (service) assign a production order to a production line (service) delete production orders (service)   Step 5: Data Sources – Thing-Component Matrix     Now that you have identified the Components necessary to build your solution (as well as the Things involved in enabling said Components), you are almost ready to create your Data Model design. Before moving onto the design, however, it is very helpful to get a good picture of how these Components interact with different parts of your solution. To do that, we recommend using a Thing-Component Matrix. A Thing-Component Matrix is a grid in which you will list Things in rows and Components in columns. This allows you to identify where there are overlaps between Components. From there, you can break those Components down into reusable Groups. Really, all you're doing in this step is taking the list of individual Things and their corresponding Components and organizing them. Instead of thinking of each item's individually-required functionality, you are now thinking of how those Components might interact and/or be reused across multiple Things.   Sample Thing-Component Matrix   As a generic example, look at the chart presented here.   You have a series of Things down the rows, while there are a series of Components (i.e. Properties, Services, Events, and Subscriptions) in the columns. This allows you to logically visually identify how some of those Components are common across multiple Things (which is very important in determining our recommendations for when to use Thing Templates vs. Thing Shapes vs. directly-instantiated Things). If we were to apply this idea to our Smart Factory example, we would create two sections of our Thing-Component Matrix, i.e. the Overlapping versus Unique Components. NOTE: It is not necessary to divide your Thing Component Matrix between Overlapping vs Unique if you don't wish to do so. It is done here largely for the sake of readability.   Overlapping Matrix   This matrix represents all the overlapping Components that are shared by multiple types of Things in our system:   Unique Matrix   This matrix represents the Components unique to each type of Thing:     Step 6: Model Breakdown         Breaking down your use case into a Data Model is the most important part of the design process for ThingWorx. It creates the basis for which every other aspect of your solution is overlaid. To do it effectively, we will use a multi-step approach. This will allow us to identify parts we can group and separate, leading to a more modular design.   Entity Relationship Diagram   To standardize the represention of Data Models, it is important to have a unified view of what a representation might look like. For this example, we have developed an Entity Relationship Diagram schematic used for Data Model representation. We will use this representation to examine how to build a Data Model.   Breakdown Process   ThingWorx recommends following an orderly system when building the specifics of your Data Model. You've examined your users and their needs. You've determined the real-world objects and systems you want to model. You've broken down those real-world items by their Component functionality. Now, you will follow these steps to build a specific Data Model for your application. Step Description 1 Prioritize the Groups of Components from your Thing-Component Matrix by each Group's Component quantity. 2 Create a base Thing Template for the largest group. 3 Iterate over each Group deciding which entity type to create. 4 Validate the design through instantiation. In the next several pages, we'll examine each of these steps in-depth.   Click here to view Part 3 of this guide.   
View full tip
Design Your Data Model Guide Part 1   Overview   This project will introduce the process of taking your IoT solution from concept to design. Following the steps in this guide, you will create a solution that doesn’t need to be constantly revamped, by creating a comprehensive Data Model before starting to build and test your solution. We will teach you how to utilize a few proposed best practices for designing the ThingWorx Data Model and provide some prescriptive methods to help you generate a high-quality framework that meets your business needs. NOTE: This guide’s content aligns with ThingWorx 9.3. The estimated time to complete ALL 3 parts of this guide is 60 minutes. All content is relevant but there are additional tools and design patterns you should be aware of. Please go to this link for more details.    Step 1: Data Model Methodology   We will start by outlining the overall process for the proposed Data Model Methodology.       Step Description 1 User Stories Identify who will use the application and what information they need. By approaching the design from a User perspective, you should be able to identify what elements are necessary for your system. 2 Data Sources Identify the real-world objects or systems which you are trying to model. To create a solid design, you need to identify what the “things” are in your system and what data or functionality they expose. 3 Model Breakdown Compose a representative model of modular components to enable uniformity and reuse of functionality wherever possible. Break down user requirements and data, identifying how the system will be modeled in Foundation. 4 Data Strategy Identify the sources of data, then evaluate how many different types of data you will have, what they are, and how your data should be stored. From that, you may determine the data types and data storage requirements. 5 Business Logic Strategy Examine the functional needs, and map them to your design for proper business logic implementation. Determine the business logic as a strategic flow of data, and make sure everything in your design fits together in logical chunks. 6 User Access Strategy Identify each user's access and permission levels for your application. Before you start building anything, it is important to understand the strategy behind user access. Who can see or do what? And why? NOTE: Due to the length of this subject, the ThingWorx Data Model Methodology has been divided into multiple parts. This guide focuses on the first three steps = User Stories, Data Sources, and Model Breakdown. Guides covering the last three steps are linked in the final Next Steps page.    Step 2: User Stories     With a user-based approach to design, you identify requirements for users at the outset of the process. This increases the likelihood of user satisfaction with the result. Utilizing this methodology, you consider each type of user that will be accessing your application and determine their requirements according to each of the following two categories: Category Requirement Details Functionality Determine what the user needs to do. This will define what kind of Services and Subscriptions will need to be in the system and which data elements and Properties must be gathered from the connected Things. Information What information do they need? Examine the functional requirements of the user to identify which pieces of information the users need to know in order to accomplish their responsibilities.   Factory Example   Let’s revisit our Smart Factory example scenario. The first step of the User Story phase of the design process is to identify the potential users of your system. In this example scenario, we have defined three different types of users for our solution: Maintenance Operations Management Each of these users will have a different role in the system. Therefore, they will have different functional and informational needs.   Maintenance   It is the maintenance engineer’s job to keep machines up and running so that the operator can assemble and deliver products. To do this well, they need access to granular data for the machine’s operating status to better understand healthy operation and identify causes of failure. They also need to integrate their maintenance request management system to consolidate their efforts and to create triggers for automatic maintenance requests generated by the connected machines. Required Functionality Get granular data values from all assets Get a list of maintenance requests Update maintenance requests Set triggers for automatic maintenance request generation Automatically create maintenance requests when triggers have been activated Required Information Granular details for each asset to better understand healthy asset behavior Current alert status for each asset When the last maintenance was performed on an asset When the next maintenance is scheduled for an asset Maintenance request for information, including creation date, due date, progress notes   Operations   The operator’s job is to keep the line running and make sure that it’s producing quality products. To do this, operators must keep track of how well their line is running (both in terms of speed and quality). They also need to be able to file maintenance requests when they have issues with the assets on their line. Required Functionality File maintenance request Get quality data from assets on their line Get performance data for the whole line Get a prioritized list of production orders for their line Create maintenance requests Required Information Individual asset performance metrics Full line performance metrics Product quality readings   Management   The production manager oversees the dispatch of production orders and ensures quotas are being met. Managers care about the productivity of all lines and the status of maintenance requests. Required Functional Create production orders Update production orders Cancel production orders Access line productivity data Elevate maintenance request priority Required Information Production line productivity levels (OEE) List of open maintenance requests   Step 3: Data Sources – Thing List     Thing List   Once you have identified the users' requirements, you'll need to determine what parts of your system must be connected. These will be the Things in your solution. Keep in mind that a Thing can represent many different types of connected endpoints. Here are some examples of possible Things in your system: Devices deployed in the field with direct connectivity or gateway-connectivity to Foundation Devices deployed in the field through third-party device clouds Remote databases Connections to external business systems (e.g., Salesforce.com, Weather.com, etc.)   Factory Example   In our Smart Factory example, we have already identified the users of the system and listed requirements for each of those users. The next step is to identify the Things in our solution. In our example, we are running a factory floor with multiple identical production lines. Each of these lines has multiple different devices associated with it. Let’s consider each of those items to be a connected Thing. Things in each line: Conveyor belt x 2 Pneumatic gate Robotic Arm Quality Check Camera Let's also assume we already have both a Maintenance Request System and a Production Order System that are in use today. To add this to our solution, we want to build a connector between Foundation and the existing system. These connectors will be Things as well. Internal system connection Thing for Production Order System Internal system connection Thing for Maintenance Request System NOTE: It is entirely possible to have scenarios in which you want to examine more granular-level details of your assets. For example, the arm and the hand of the assembly robot could be represented separately. There are endless possibilities, but for simplicity's sake, we will keep the list shorter and more high-level. Keep in mind that you can be as detailed as needed for this and future iterations of your solution. However, being too granular could potentially create unnecessary complexity and data overload.    Click here to view Part 2 of this guide.
View full tip
Build a Predictive Analytics Model Guide Part 1   Overview   This project will introduce ThingWorx Analytics Builder. Following the steps in this guide, you will create an analytical model, and then refine it based on further information from the Analytics platform. We will teach you how to determine whether or not a model is accurate and how you can optimize both your data inputs and the model itself.   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL 2 parts of this guide is 60 minutes.      Step 1: Scenario   MotorCo manufactures, sells, and services commercial motors. Recently, MotorCo has been developing a new motor, and they already have a working prototype. However, they've noticed that the motor has a chance to FAIL CATASTROPHICALLY if it's not properly serviced to replace lost grease on a key moving part. In order to prevent this type of failure in the field, MotorCo has decided to instrument their motors with sensors which record vibration. The hope is that these sensors can detect certain vibrations which indicate required maintenance before a failure occurs. MotorCo has decided to utilize ThingWorx Analytics to scan their prototype data for any insights they can gain to address this issue. Challenges: There is a known failure mode of a prototype, but it is not currently possible to predict when the failure might happen Until this failure mode is mitigated, the prototype cannot move into full production While connected data is being monitored, what to do with that data is not currently known The additional sensors are adding to the overall cost of the product   Step 2: Settings   If you manually installed the Analytics extension, then you need to complete the steps below to finalize the connection.  On the ThingWorx Composer Analytics tab, click ANALYTICS BUILDER > Settings. In the Analytics Server field, search for and select your Server Thing Entity, such as AnalyticsServer_Thing or localhost-AnalyticsServer. Click Verify Configuration.   Click Save. WARNING: You MUST CLICK SAVE or the configurations will be lost when you move to Data in the next step.   Step 3: Upload Data   We will now load the data that ThingWorx Analytics will use to generate a model. Download the attached analytics_vibration.zip to your computer. Unzip the analytics_vibration.zip file to access the vibration_data_and_header.csv and vibration_metadata.json files. On the left, click ANALYTICS BUILDER > DATA.   Under Datasets, click New.... The New Dataset pop-up will open.         5. In the Dataset Name field, enter vibration_dataset. 6. In the File Containing Dataset Data section, search for and select vibration_data_and_header.csv. 7. In the File Containing Dataset Field Configuration section, search for and select vibration_metadata.json.   8. Click Submit. Note that it will take a variable amount of time for the data-upload to complete, based on the size of your dataset.              Step 4: Signals   The Signals section of ThingWorx Analytics looks for the most statistically correlated single field in the dataset which relates to your selected goal. This doesn't necessarily indicate that it is the cause of your goal, whether maximizing or minimizing. It just means that the dataset indicates that this single field happens to correlate with the goal that you desire. On the left, click ANALYTICS BUILDER > Signals.   At the top, click New…. A New Signals pop up will open.   3. In the Signal Name field, enter vibration_signal. 4. In the Dataset field, select vibration_dataset. 5. Leave the Goal field set to the default of low_grease. 6. Leave the Filter field set to the default of all_data. 7. Leave the Excluded Fields from Signal field set to the default of empty. 8. Click Submit. 9. Wait ~30 seconds for Signal State to change to COMPLETED The results will be displayed at the bottom.             The results show that the five Frequency Bands for Sensor 1 are the most highly correlated with determining our goal of detecting a low grease condition. For Sensor 2, only bands one and four seem to be at all related, and bands two, three, and five are hardly related at all.   Click here to view Part 2 of this guide. 
View full tip
Create Industrial Equipment Model Guide   Overview   This project introduces how to model industrial equipment in ThingWorx Foundation. NOTE: This guide’s content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes.    Step 1: Learning Path Overview   This guide explains the steps to get started modeling industrial equipment in ThingWorx Foundation and is part of the Connect and Monitor Industrial Plant Equipment Learning Path. You can use this guide independent from the full Learning Path. Other guides are available for more complete Data Model Introduction. When using this guide as part of the Industrial Plant Learning Path, you should already have ThingWorx Kepware Server installed and sending data to ThingWorx Foundation. In the next guide in the Learning Path, we'll use Foundation's Mashup Builder to construct a GUI that displays information and from ThingWorx Kepware Server. We hope you enjoy this Learning Path.   Step 2: Create Thing Shape   Thing Shapes are components that contain Properties and Services. In Java programming terms, they are similar to an interface. In this section, you will build Thing Shapes for an electric motor. Motor Start on the Browse folder icon tab of ThingWorx Composer. Under the Modeling section of the left-hand navigation panel, hover over Thing Shapes, then click the + button. Type MotorShape in the Name field. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. Click Save.   Add Properties   Click the Properties and Alerts tab at the top of your Thing Shape.   Click + Add. Enter the Property name from the first row of the table below into the Name field of the Thing Shape. Name Base Type Persistent? Logged? serialNumber String X   currentPower Number   X 4. Select the appropriate Base Type from the drop-down menu. 5. Check Persistent and/or Logged according to the table. NOTE: When Persistent is selected, the Property value will be retained when a Thing is saved. Properties that are not persisted will be reset to the default after every Save of the parent Thing. When Logged is selected, every Property value change will be automatically logged to a specified Value Stream. 6. Click ✓+ button. TIP: When adding multiple Properties at once, click Done and Add after each, once you've entered a Name, selected a Base Type and any other criteria. If adding a single Property, click Done. 7. Repeat steps 2 through 5 for the other Properties in the the table. 8. Click the done ✓ Button. You'll see that these Properties have been created for the Motor Thing Shape. 9. Click Save.   Step 3: Create Thing Template   You can create reusable building blocks called Thing Templates in ThingWorx to maintain scalability and flexibility of your application development. With Thing Templates, you define a set of similar objects by specifying the Properties (characteristics) and Services (behaviors) that are common for all the objects. In Java programming terms, a Thing Template is like an abstract class and can be created by extending other Thing Templates. Once a Thing Template is defined and saved in ThingWorx Foundation Server, you can replicate multiple Things to model a complete set without duplicating effort. In this step, you will create a Thing Template that defines Properties for a pump. This pump Template could be used to create multiple Things that each represent a specific pump used in an industrial facility. Start on the Browse folder icon tab on the far left of ThingWorx Composer. Under the Modeling section of the left-hand navigation panel, hover over Thing Templates and click the + button. Type PumpTemplate in the Name field. NOTE: Thing Template names are case-sensitive.       4. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject.       5. In the Base Thing Template box, click + to choose GenericThing as the Template.              6. In the Implemented Shapes field, click the + to select the MotorShape Thing Shape.              7. Click Save.   Add Properties   In this step, you will specify the Properties that represent the characteristics of a Pump. Some Properties like the location may never change (static), while other Properties like power and temperature information may change every few seconds (dynamic). Select the Properties and Alerts tab under Thing Template: PumpTemplate.   Click the Edit button if the Template is not already open for editing, then click + Add next to My Properties. Enter the Property name in the Name field copied from a row of the table below. Name Base Type Persistent Logged PlantID STRING x   plant_lat_long LOCATION x   watts NUMBER x x 4. Select the Base Type of the Property from the drop down menu. 5. Check the appropriate Persistent and Logged check box. NOTE: When Persistent is selected, the Property value will be retained when the parent Thing is saved. Properties that are not persisted will be reset to the default during a system restart and whenever the Thing is saved. When Logged is selected, every Property value change will be automatically logged to a specified Value Stream. 6. Click the ✓+ button. TIP: When adding multiple Properties at once, click Check+ after each, once you've entered a Name, selected a Base Type and any other criteria. If adding a single Property, click Check button. 7. Repeat steps 3 through 6 for each of the Properties in the rows of the table. 8. After entering the final Property, click the ✓ button. 9. Click Save. You should see the following Properties in your Composer.   In the next guide of this Learning Path, we will create a single Thing based on this Template to represent a specific Pump.     Step 4: Next Steps   Congratulations! You've successfully completed the Create Industrial Equipment Model tutorial, and learned how to: Use Composer to create Thing Shapes and Thing Templates Create Model Tags to keep entities organized   The next guide in the Connect and Monitor Industrial Plant Equipment learning path is Build an Equipment Dashboard.    
View full tip
Build an Equipment Dashboard Guide Part 2   Step 5: Display Data   Now that you have configured the visual part of your application, you need to bind the Widgets in your Mashup to a data source.   Add Services to Mashup   In the top-right, ensure the Data tab is selected. Click the green + symbol. In the Entities Filter field, search for and select MyPump. In the Services Filter field, type GetPropertyValues. Click the right-arrow beside GetPropertyValues. Note how GetPropertyValues was added to the right-side under Selected Services Check the checkbox for Execute on Load. This causes the Service to execute when the Mashup starts.        7. In the Services Filter field, type QueryPropertyHistory. 8. Click the right-arrow beside QueryPropertyHistory. 9. Check the checkbox for Execute on Load. 10. Click Done to close the pop-up. Note how the Services have been added to the Data tab in the top-right.          11. Click Save. Now that we have access to the backend data, we want to bind it to our Widgets.   Value Display   Configure the Value Display to display the SerialNumber of the pump. Under the Data tab, expand GetPropertyValues > Returned Data > All Data. Drag-and-drop GetPropertyValues > serialNumber onto the Value Display Widget in the top section. On the Select Binding Target popup, select Data. Image   We want to use an Image Widget to display a thumbnail picture of the pump for easy reference. To do that, though, you first need to upload an image to Foundation by creating a Media Entity. Right-click the image below, then click "Save image as..." to download. Click Browse > Visualization > Media. Click + New. In the Name field, type pump-thumbnail. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. Under Image, click Change. Navigate to and select the pump-image.png file you just downloaded. On the navigation pop-up, click Open to close the pop-up and confirm the image selection. At the top of Foundation, click Save. Change Image to pump   We will now update the Image Widget to display the ThingWorx Media Entity we just created. Return to the pump-dashboard Mashup. Click the Image Widget to select it, and ensure that the bottom-left Properties tab is active. In the bottom-left Properties' Filter field, type SourceURL. For the SourceURL Property, search for and select pump-thumbnail. Click Save.   Line Chart   Configure the Line Chart to display Property values changing over time. In the top-right Data tab, expand QueryPropertyHistory > Returned Data. Drag and drop QueryPropertyHistory > All Data onto the Line Chart Widget in the bottom-right Canvas section. On the Select Binding Target pop-up, select Data. Ensure the Line Chart Widget is selected. On the Line Chart's Property panel in the bottom-left, in the Filter field, type XAxisField. For the XAxisField Property, select timestamp. In the Filter field, type LegendFilter. Check the checkbox for LegendFilter. Click Save.   Verify Data Bindings   You can see the configuration of data sources bound to Widgets in the bottom-center Connections pane. In the top-right Data tab, click GetPropertyValues. Check the diagram in the bottom-center Connections window to confirm a data source is bound to the Value Display Widget.       2. Also in the top-right Data tab, click QueryPropertyHistory. Confirm that the diagram shows it is bound to the Line Chart.         3. Click Save.     Step 6: Test Application   Browse to your Mashup and click View Mashup to launch the application. NOTE: You may need to enable pop-ups in your browser to see the Mashup. 2. Confirm that data is being displayed in each of the sections. 3. Open the MyPump Thing, then click the Properties and Alerts Tab. 4. Click Set Value on the line of the serialNumber Property. 5. Enter a value for the serial number, then click the Check-mark button. 6. Click Refresh to confirm the value is changed. 7. Refresh the browser window showing the dashboard to see the new serial number value.     Step 7: Next Steps   Congratulations! You've successfully completed the Build an Equipment Dashboard guide, and learned how to: Use Composer to create a Thing Shape and a Thing Template Make a Thing using a custom Thing Template Store Property change history in a Value Stream Create an applicaton UI with Mashup Builder Display data from connected devices Test a sample application   If you like to return to previous guides in the learning path, select Connect and Monitor Industrial Plant Equipment.    
View full tip
Build an Equipment Dashboard Guide Part 1   Overview   This project will introduce you to the principles of ThingWorx Foundation by creating an eqipment dashboard. Following the steps in this guide, you will create the building blocks of your first IoT application, including Things and Streams. We introduce the basics for creating an IoT application. NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL 2 parts of this guide is 30 minutes.    Step 1: Learning Path Overview   This guide explains the steps to create an Industrial Eqipment Dashboard, and is part of the Connect and Monitor Industrial Plant Equipment Learning Path. You can use this guide independently from the full Learning Path. If you want to learn the basics of creating an eqipment dashboard with ThingWorx, this guide will be useful to you.When used as part of the Industrial Plant Learning Path, you should already have ThingWorx Kepware Server installed, and it should be sending data to ThingWorx Foundation. You also need to have previously created the Thing Shape and Thing Template used for this dashboard. We hope you enjoy this Learning Path.   Step 2: Create Thing   A Thing is used to digitally represent a specific component of your application in ThingWorx. In Java programming terms, a Thing is similar to an instance of a class. In this step, you will create a Thing that represents an individual Pump using the Thing Template we created in the previous guide. Using a Thing Template allows you to increase development velocity by creating multiple Things without re-entering the same information each time. In ThingWorx Foundation, navigate to Browse > Modeling > Things. Click + New. In the Name field, type MyPump. NOTE: This name, with matching capitalization, is required for the data display created in a later step.       4. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject.       5. In the Base Thing Template field, search for and select the previously-created PumpTemplate.       6. At the top, click Save.          Manage Property Bindings At the top, click Properties and Alerts. At the top, click Manage Bindings. In the top-left Local > Search Things field, search for and select IndConn_Tag1. Drag-and-drop Simulation_Examples_Functions_Random3's + symbol onto the watts Property on the right. At the bottom-right of the pop-up, click Done. Note how the Tag from ThingWorx Kepware Server is now bound to the the watts Property. Click Save. Click Refresh repeatedly to confirm the watts Property value is changing.     Step 3: Store Data in Value Stream   Now that you have created the MyPump Thing to model your application in ThingWorx, you need a storage Entity to record changing Property values. This step shows how to save time-series data in a Value Stream already created in a previous guide. To learn more, refer to the Methods for Data Storage guide. Navigate to Browse > Modeling > Thing Templates. Click the previously-created PumpTemplate Thing Template to open it. Confirm you are on the General Information tab. If necessary, click Edit to allow changes. In the Value Stream field, search for and select IndConn_ValueStream. Click Save.   Step 4: Create Application UI   ThingWorx Foundation is used to create customized web applications that can display and interact with data from multiple sources. These web applications are called Mashups and are created using the Mashup Builder. The Mashup Builder is where you create your web application by dragging and dropping Widgets such as Grids, Charts, Maps, and Buttons onto a Canvas. All of the user interface elements in your application are Widgets. We will build a web application with three Widgets: Image showing a picture of the pump Value Display showing the pump serial number Line Chart showing the value of watts Property trend over time.   Create New Mashup   Navigate to Browse > Visualization > Mashups.   Click + New.   Keep the defaults and click OK.   In the Name field, type pump-dashboard. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. Click Save.   At the top, click Design.   Define Mashup Areas   At the top-left, ensure the Layout tab is selected. Click Add Bottom to split your UI into two halves.   Click the newly-created bottom-half to select it. Click Add Left.   Click the bottom-left container to select it. In the top-left Layout section, scroll down and select Fixed Size.   Type 200 in the Width text box that appeared, then press your keyboard’s Tab key to record your entry.   Add Widgets   In the top-left, click the Widgets tab.   In the Filter field, type image.   Drag-and-drop an Image Widget onto the lower-left area of the central Canvas. This Widget will show an image of the pump in use. 4. In a similar manner to what was just done with the Image Widget, drag-and-drop a Value Display Widget onto the top area. 5. Likewise, drag-and-drop a Line Chart Widget onto the lower-right area.   6. Click Save.          Click here to view Part 2 of this guide. 
View full tip
    Step 5: Log to Value Stream   Now that you have explored the Properties of IndConn_Tag1, you’ve seen how ThingWorx Kepware Server feeds information to ThingWorx Foundation. To get an even better indication of changes and confirm continued connectivity, we will log the changes to a Value Stream in order to record the values with a TimeStamp.   Create Value Stream   Return to the ThingWorx Foundation New Composer browser. Click Browse. Click Data Storage -> Value Streams. Click + New. In the Choose Template pop-up, select ValueStream. Click OK. Type IndConn_ValueStream in the Name field. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. In the Description field, enter an appropriate description, such as Value Stream to record changes from ThingWorx Kepware Server. Click Save.   Bind Value Stream   Open the IndConn_Tag1 either by clicking on the tab at the top, or by clicking on PTCDefaultProject on the left At the top, select General Information. In the Value Stream field, enter indconn. Select IndConn_ValueStream from the sorted list. At the top, select Properties and Alerts. Click Simulation_Examples_Functions_Random3. A new set of options will expand from the right. Check the box for Persistent. Check the box for Logged. Click the Check button to close the expanded options. Click Save. All changes to the Random3 Tag, fed from ThingWorx Kepware Server, are now stored and TimeStamped in the Simulation_Examples_Functions_Random3 Property.   Step 6: Visualize the Data   We'll now create a Mashup to visualize the record of information from ThingWorx Kepware Server. In ThingWorx Foundation's Browse, click Visualization -> Mashups. Click +New. In the New Mashup pop-up, leave the default selections. Click OK. In the Name field, enter IndConn_Mashup. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. At the top, click Save. At the top, click Design. In the Filter Widgets field at the top-left, enter chart. Drag-and-drop a Line Chart onto the central canvas area. Add Data   On the right-side of the Mashup Builder, click the Data tab. Click the + button on the Data tab.        3. In the Add Data pop-up, enter indconn in the Entity field, overwriting Filter. 4. Select IndConn_Tag1 from the sorted list. 5. In the Filter field below Services, enter queryprop. 6. Click the right arrow button beside QueryPropertyHistory. The QueryPropertyHistory Service of the IndConn_Tag1 Thing will appear on the right in the Selected Services field. 7. Check the box under Execute on Load in the Selected Services field.' 8. Click Done. Note that the QueryPropertyHistory Service now appears on the right side Data tab. 9. Click the arrow to expand QueryPropertyHistory, then click to expand Returned Data. 10. Drag-and-drop All Data from the QueryPropertyHistory Service from the right onto the Time Series Chart in the center. 11. In the Select Binding Target pop-up, select Data.        Configure Chart Properties   In the bottom-left Properties of timeserieschart-1, enter xaxisfield in the Filter Properties field. Expand the drop-down for XAxisField. Select timestamp. Click Save. Click View Mashup. (You may have to enable pop-ups to view the mashup.) The IndConn_Mashup will show you the recorded history of property changes that came from ThingWorx Kepware Server. NOTE: If the Mashup visualization is blank, confirm your connection to IndConn. Return to the Test Connection section of the Bind Industrial Tag step.   Step 7: Next Steps   Congratulations! You've successfully completed the Connect Kepware Server to ThingWorx Foundation guide. You've learned how to: Connect ThingWorx Foundation to ThingWorx Kepware Server Map Tags to Properties     The next guide in the Connect and Monitor Industrial Plant Equipment learning path is Create Industrial Equipment Model. 
View full tip
Configure Permissions Guide Part 2   Step 5: Permissions   These permissions can be accessed on any Entity created on the platform. All Entities have permission control for both design time and run time. Permission Time Control Design time Controls what Users are able to do with Entities themselves while building the solution. Run time Controls what the Users are able to do with the data for an Entity when they use the solution.   Permission Type Description Property Read Read property values Property Write Update property values Service Execute Execute Services in this Entity Event Execute Queue or fire Events in this Entity Event Subscribe Ability to subscribe to Events in this Entity   Access Type Description Allow Allow the User's access to this feature. Deny Deny the User's access to this feature. Inherit Set the User's access to this feature based on permissions in Entities this Entity is based on or the configurations at a higher level.   Add Permissions for an Entity   Once an Entity has been selected for editing, select the Permissions tab. Based on what you would like to edit, select the Visibility, Design Time or Run Time tab. The All Properties, Services, and Events section provides blanket security to all of these features for a User Group or User. The Property, Service, or Event Overrides section is used for any overrides that need to be made for specific features. In the example blow, the User a.jones has the ability to read properties, fire events, and subscribe to events. The User does not have the ability to update a property or execute a Service. In the second section, a.jones is allowed to call the GetConfigurationTable Service (even though he was restricted from doing so in the other section).   To set a permission, filter and select a User/User Group. When their name is in the table, click the Permission Type you would like for this Entity. Default permissions are added to the User or User Group you filtered and selected. This will be full access permissions unless you've changed one of the fields.   Set Permissions Programmatically   In some cases it will be useful to set permissions using a programmable interface. This can be done through a built-in set of services which can be accessed in many different ways including: Internal service call through an entity’s service Service call using the extension framework, or REST API call to a service on the platform. The following is a list of services built into all entities on the platform. Service Name Description AddDesignTimePermission Adds a new design time permission AddRunTimePermission Adds a new run time permission CheckDesignTimePermission Checks to see if an entity has a specific design time permission for the current User CheckDesignTimePermissionForGroup Checks to see if an entity has a specific design time permission for a given User Group CheckDesignTimePermissionForUser Checks to see if an entity has a specific design time permission for a given User CheckPermission Checks to see if the entity has a specific run time permission for the current User CheckTimePermissionForGroup Checks to see if the entity has a specific run time permission for a given User Group CheckDesignTimePermissionForUser Checks to see if the entity has a specific run time permission for a given User DeleteDesignTimePermission Delete a design time permission DeleteRunTimePermission Delete a run time permission GetDesignTimePermission Get a list of design time permissions in Info Table format GetDesignTimePermissionAsJSON Get a list of design time permissions in JSON format GetPermissionsForCurrentUser Get the run time permissions for the current User GetPermissionsForGroup Get the run time permissions for a given User Group GetPermissionsForUser Get the run time permissions for a given User GetRunTimePermissions Get a list of assigned run time permissions in Info Table format GetRunTimePermissionAsJSON Get a list of assigned run time permissions in JSON form SetDesignTimePermissionAsJSON Sets all of the run time permissions for a given Entity to the given JSON list You may want to apply a set of permissions to a large group of Entities at once. This can be done using either the projects or the tags feature on the platform through the EntityServices resource. The EntityServices resource has many useful services in it, but for the purpose of this section, we will only talk about the run time permission service. This will act on all entities with the provided tags or assigned to the given project. Service Name Description SetEntityPermission Sets run time permissions for a set of Entities   Step 6: Application Keys   Application Keys   Application Keys or appKeys are security tokens used for authentication in ThingWorx when not using a standard credentials method of authentication. They are associated with a given user and have all of the permissions granted to the user to which they are associated.   Create an Application Key   Using the Application Key for the default user (Administrator) is not recommended. If administrative access is absolutely necessary, create a user and place the user as a member of the SecurityAdministrators and Administrators user groups. Create the User the Application Key will be assigned to. On the Home screen of Composer click + New. In the dropdown list, click Applications Keys. Use MyAppKey  for the name your Application Key. Set the User Name Reference to a User you created and set the Project field (ie, PTCDefaultProject). The Expiration Date field will default to 1 day. Click Save. A Key ID has been generated and can be used to make secure connections.   IP Whitelisting for Application Keys   One of the features of an Application Key is the ability to set an IP whitelist. This allows the server to specify that only certain IP addresses should be able to use a given Key ID for access. This is a great way to lock down security on the platform for anything that will maintain a static IP address. For example, connected Web-based business systems may have a static IP from which all calls should be made. Similarly, you can use wildcards to specify a network to narrow the range of IP addresses allowed while still offering some flexibility for devices with dynamic IP addresses. Extremely mobile devices should likely not attempt to implement this however as they will often change networks and IP addresses and may lose the ability to connect when the IP whitelist feature is used.   Interact with Application Keys Programmatically   Service Name Description GetKeyID Returns the ID of this application key GetUserName Get the user name associated with this application key IsExpired Returns if this application key is expired ResetExpirationDateToDefault Resets the expiration date of the application key to the default time based on configuration in the UserManagement subsystem SetClientName Sets the client name for this application key SetExpirationDate Sets the expiration date of this application key to a provided date SetIPWhiteList Sets the values for the IP whitelist for this application key SetUserName Sets the associated user name for this application key TIP: To learn more about Application Keys, refer to the Create an Application Key Guide.   Step 7: Organizations   Organizations are hierarchical structures that allow the user to assign visibility to entities in the ThingWorx Model. This model provides the top down structure from the highest level in an organization or department, to the lower levels of said entity. Each level within this structure also allows for users and groups to be added. This provides a greater level of customization to resources within the ThingWorx Composer.   Create an Organization In the ThingWorx Composer, click the + New at the top of the screen. Select Organization in the dropdown. Name your Organization Constructors. Set the Project field (ie, PTCDefaultProject) and click Save Select the Organization tab to see the hierarchy. With the top organization selected, in the Members search bar, search for the user you have created yourself and add them.   Create Organizational Units   Click the green + under the structure you would like to expand. Name your Organization unit UpperManagement. In the Members search bar, search for the user or user group you created and add it. Click Save. Repeat the steps to create the full heirarchy of the organization and its department/unit members.   Setup Entity Visibility   ThingWorx provides added security checks and access control with Entity visibility. Visibility ensures an entity is accessible to members of an organizational unit. Those members will then have access to the entity and the underlying security model determines what specific interaction any users that are members of that organization unit may have with a specific asset. If a user in the system is not granted visibility, then that asset essentially does not exist within that user’s domain. Select the Permissions tab of any custom Thing in Composer. Filter and select Constructors in the Search Organizations field. Click Save. Login Pages for Organization   Creating an Organization automatically creates a login page for you. If you would like to add more to this login screen and customize it to fit your needs, create a Mashup and set it to the Organization's Home Mashup field. If you plan to use a Login Screen, use the View Mashup URL generated from the Login Mashup you create. To view the login page of your application (whether custom or default), type the following URL: [server]/Thingworx/FormLogin/ (ie, localhost/Thingworx/FormLogin/Constructors).     Step 8: Next Steps   Congratulations! You've successfully completed the Configure Permissions guide, and learned how to: Configure and utilize the user access system Control permissions at design time and run time   The next guide in the Getting Started on the ThingWorx Platform learning path is Build a Predictive Analytics Model.    If you are completing the Connect and Configure Industrial Devices and Systems learning path, the next guide is Choose a Connectivity Method.   Learn More   We recommend the following resources to continue your learning experience: Capability Guide Build Design Your Data Model   Additional Resources   If you have questions, issues, or need additional information, refer to: Resource Link Support Help Center    
View full tip
Announcements