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

ThingWorx Navigate is now Windchill Navigate Learn More

IoT & Connectivity Tips

Sort by:
    Step 10: C - Info Tables   Infotables are used for storing and retrieving data from service calls. An infotable has a DataShapeDefinition that describes the names, base types, and additional information about each field within the table.   In order to create an Infotable, you can do so with the provided macros or functions.   Define With Macros   In order to define Infotables using a macro, use TW_MAKE_INFOTABLE or TW_MAKE_IT. Both macros can be used interchangeably.   NOTE: The macros are all defined in the twMacros.h header file. twInfoTable* it; it = TW_MAKE_IT( TW_MAKE_DATASHAPE(DATSHAPE_NAME_SENSOR_READINGS, TW_DS_ENTRY("ActivationTime", TW_NO_DESCRIPTION ,TW_DATETIME), TW_DS_ENTRY("SensorName", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("Temperature", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("Pressure", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("FaultStatus", TW_NO_DESCRIPTION ,TW_BOOLEAN), TW_DS_ENTRY("InletValve", TW_NO_DESCRIPTION ,TW_BOOLEAN), TW_DS_ENTRY("TemperatureLimit", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("TotalFlow", TW_NO_DESCRIPTION ,TW_INTEGER) ), TW_IT_ROW(TW_MAKE_DATETIME_NOW,TW_MAKE_STRING("Sensor Alpha"),TW_MAKE_NUMBER(60),TW_MAKE_NUMBER(25),TW_MAKE_BOOL(TRUE),TW_MAKE_BOOL(TRUE),TW_MAKE_NUMBER(150),TW_MAKE_NUMBER(77)), TW_IT_ROW(TW_MAKE_DATETIME_NOW,TW_MAKE_STRING("Sensor Beta"),TW_MAKE_EMPTY,TW_MAKE_NUMBER(35),TW_MAKE_BOOL(FALSE),TW_MAKE_BOOL(TRUE),TW_MAKE_EMPTY,TW_MAKE_NUMBER(88)), TW_IT_ROW(TW_MAKE_DATETIME_NOW,TW_MAKE_STRING("Sensor Gamma"),TW_MAKE_EMPTY,TW_MAKE_NUMBER(80),TW_MAKE_BOOL(TRUE),TW_MAKE_BOOL(FALSE),TW_MAKE_NUMBER(150),TW_MAKE_NUMBER(99)) );   Define Without Macros   In order to define Infotables without using a macro, use the twDataShape_CreateFromEntries function.   twInfoTable * it = NULL; twInfoTableRow * row = NULL; it = twInfoTable_Create(ds); if (!it) { TW_LOG(TW_ERROR,"createNewThing: Error creating infotable"); twDataShape_Delete(ds); return TW_ERROR_ALLOCATING_MEMORY; } row = twInfoTableRow_Create(twPrimitive_CreateFromString("SimpleThing_2", TRUE)); if (!row) { TW_LOG(TW_ERROR,"createNewThing: Error creating infotable row"); twInfoTable_Delete(it); return TW_ERROR_ALLOCATING_MEMORY; } twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString("A new Thing", TRUE)); twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString("RemoteThing", TRUE)); twInfoTable_AddRow(it, row);   Retrieve With Macros   Many of the calls to services in ThingWorx will return an InfoTable of information. Below is an example of using the TW_GET_NUMBER_PARAM macro to retrieve values from an Infotable: ///Data is stored in the params variable ///Retrieve the a and b values then store them in variables twInfoTable * params double a, b; TW_GET_NUMBER_PARAM(params, "a", 0, &a); TW_GET_NUMBER_PARAM(params, "b", 0, &b);   Retrieve Without Macros   Below is an example of using the twInfoTable_GetNumber function to retrieve values from an Infotable: ///Data is stored in the params variable ///Retrieve the a and b values then store them in variables twInfoTable * params double a, b; twInfoTable_GetNumber(params, "a", 0, &a); twInfoTable_GetNumber(params, "b", 0, &b);       Step 11: C - Events   Event definitions describe interrupts that ThingWorx can subscribe to in order to receive notifications when something happens.   The parameters for an event definition are:   name description dataShape aspects   In order to create an Event, you can do so with the provided macros or functions.   Define With Macros   In order to define an Event using a macro, you will use TW_DECLARE_EVENT or TW_EVENT. Both macros can be used interchangeably. NOTE: The macros are all defined in the twMacros.h header file. TW_EVENT("SteamSensorFault", "Steam sensor event", TW_MAKE_DATASHAPE( "SteamSensorFault", TW_DS_ENTRY("message",TW_NO_DESCRIPTION,TW_STRING) ) );   Define Without Macros   In order to define an Event without using a macro, you will use the twApi_RegisterEvent function. See an example below of how to utilize the twApi_RegisterEvent function and adding a row of data: twApi_RegisterEvent(TW_THING, "SteamSensor", "SteamSensorFault", "Steam sensor event", ds);   Fire With Macros   In order to fire an Event using a macro, you will use TW_FIRE_EVENT.   NOTE: The macros are all defined in the twMacros.h header file. TW_FIRE_EVENT(thingName, "SteamSensorFault", TW_MAKE_IT(TW_MAKE_DATASHAPE( "SteamSensorFault", TW_DS_ENTRY("message", TW_NO_DESCRIPTION, TW_STRING) ), TW_IT_ROW(TW_MAKE_STRING(msg)) ));   Fire Without Macros   In order to fire an Event without using a macro, you will use the twApi_FireEvent function. See an example below of how to utilize the twApi_FireEvent function and adding a row of data: twApi_FireEvent(TW_THING, "SteamSensor", "SteamSensorFault", eventInfoTable, -1, TRUE)       Step 12: C - Services   Service Handler Callbacks The service callback function is registered to be called when a request for a specific service is received from the ThingWorx Platform. These functions must have the same signature as shown here: typedef enum msgCodeEnum (*service_cb) (const char * entityName, const char * serviceName, twInfoTable * params,twInfoTable ** content, void * userdata) Below is an example of a single service that adds two numbers that can be registered with and without macros: /***************** Service Callbacks ******************/ /* Example of handling a single service in a callback */ enum msgCodeEnum addNumbersService(const char * entityName, const char * serviceName, twInfoTable * params, twInfoTable ** content, void * userdata) { double a, b, res; TW_LOG(TW_TRACE,"addNumbersService - Function called"); if (!params || !content) { TW_LOG(TW_ERROR,"addNumbersService - NULL params or content pointer"); return BAD_REQUEST; } twInfoTable_GetNumber(params, "a", 0, &a); twInfoTable_GetNumber(params, "b", 0, &b); res = a + b; *content = twInfoTable_CreateFromNumber("result", res); if (*content) return SUCCESS; else return INTERNAL_SERVER_ERROR; }   NOTE: The return value of the function is TWX_SUCCESS if the request completes successfully or an appropriate error code if not (should be a message code enumeration as defined in twDefinitions.h).   Register Service Callback   In order to register a service handler callback using macros, utilize TW_DECLARE_SERVICE as shown below: TW_MAKE_THING(thingName,TW_THING_TEMPLATE_GENERIC); TW_DECLARE_SERVICE( "AddNumbers", "Add two numbers together", TW_MAKE_DATASHAPE(NO_SHAPE_NAME, TW_DS_ENTRY("a", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("b", TW_NO_DESCRIPTION ,TW_NUMBER)), TW_NUMBER, TW_NO_RETURN_DATASHAPE, addNumbersService );     Click here to view Part 9 of this guide
View full tip
  Step 4: Add Data   We've added a Waterfall Chart Widget to the Mashup, but we still need to bring in backend data.   Ensure the top-right Data tab is active.   Click the green + button.   In the Entity field, search for and select TPWC_Thing. In the Services field, type getprop. Click the right arrow beside GetProperties. On the right, check Execute on Load.   In the bottom-right of the pop-up, click Done.   Under the Data tab on the right, expand GetProperties.   Drag-and-drop Things_TPWC_Thing > GetProperties > InfoTable_Property onto the Waterfall Chart.   On the Select Binding Target pop-up, click Data.     Widget Properties   With the Waterfall Chart bound to data, we now just need to configure a few of the chart's Properties. With the Waterfall Chart selected in the central Canvas area, ensure the Properties tab is active in the bottom-left.   In the Filter field, type xaxis.   In the XAxisField, search for and select month.   In the Filter field, clear the xaxis search and then start a new filter with usetrend.   Check the UseTrendColors box.   At the top, click Save.     Step 5: View Mashup   Up to this point, we've created a Data Shape to format the columns of an Info Table Property. You then created a Thing, as well as an Info Table Property formatted by the Data Shape. As a test, you added some manually-entered data to the Info Table. After creating a Mashup, you added a Waterfall Chart Widget and tied it to that backend data.   The only thing left to do is to visualize your GUI.    Ensure that you're on the Design tab of the TPWC_Mashup.   At the top, click View Mashup. The end result is a visualization of burn up/down as the project is first defined and then implemented.     Step 6: Next Steps   Congratulations! You've successfully completed the Track Progress with Waterfall Chart guide, and learned how to: Create a Data Shape Create a Thing Create an Info Table Property Populate an Info Table with appropriate data for a Waterfall Chart Create a Mashup Utilize a Waterfall Chart to display project progress  Learn More   We recommend the following resources to continue your learning experience: Capability Guide Manage How to Display Data in Charts Additional Resources   If you have questions, issues, or need additional information, refer to: Resource Link Community Developer Community Forum Support Waterfall Chart Help  
View full tip
  Step 8: C - Properties (cont.)   Register Properties   Registering properties and services with the API:   Tells the API what callback function to invoke when a request for that property or service comes in from ThingWorx. Gives the API information about the property or service so that when ThingWorx browses the Edge device, it can be informed about the availability and the definition of that property or service. If you used the TW_PROPERTY macro, your property has been registered. If using function calls, to register a property, use the twApi_RegisterProperty. The documentation for this function can be found in [C SDK HOME DIR]/src/api/twApi.h.   NOTE: If you used the provided Macros to create your property, it has already been registered. Bind the Thing in order for your property to be bound.   An example of registering a property is as follows:   twApi_RegisterProperty(TW_THING, “SimpleThing_1”, "FaultStatus", TW_BOOLEAN, NULL, "ALWAYS", 0, propertyHandler, NULL); twApi_RegisterProperty(TW_THING, “SimpleThing_1”, "InletValve", TW_BOOLEAN, NULL, "ALWAYS", 0, propertyHandler, NULL); twApi_RegisterProperty(TW_THING, “SimpleThing_1”, "Pressure", TW_NUMBER, NULL, "ALWAYS", 0, propertyHandler, NULL); twApi_RegisterProperty(TW_THING, “SimpleThing_1”, "Temperature", TW_NUMBER, NULL, "ALWAYS", 0, propertyHandler, NULL); twApi_RegisterProperty(TW_THING, thingName, "BigGiantString", TW_STRING, NULL, "ALWAYS", 0, propertyHandler, NULL); twApi_RegisterProperty(TW_THING, thingName, "Location", TW_LOCATION, NULL, "ALWAYS", 0, propertyHandler, NULL);   Update Properties   Property values can be updated using the provided Macros or using the API directly.   NOTE: Update a property does not send it to the server. To Push a property after updates have been made, use the TW_PUSH_PROPERTIES_FOR function that can be found in the [C SDK HOME DIR]/src/api/twMacro.h header file.   With Macros   The TW_SET_PROPERTY macro updates a property in ThingWorx and can be found in the [C SDK HOME DIR]/src/api/twMacro.h header file. The usage can be seen in the example below: TW_SET_PROPERTY(thingName, "FlowCount", TW_MAKE_NUMBER(5)); TW_SET_PROPERTY(thingName, "TotalFlow", TW_MAKE_NUMBER(rand() / (RAND_MAX / 10.0))); TW_SET_PROPERTY(thingName, "Pressure", TW_MAKE_NUMBER(18 + rand() / (RAND_MAX / 5.0))); TW_SET_PROPERTY(thingName, "Location", TW_MAKE_LOC(gpsroute[location_step].latitude,gpsroute[location_step].longitude,gpsroute[location_step].elevation));   Without Macros   The twInfoTable_CreateFrom and twApi_SetSubscribedProperty functions updates a property in ThingWorx and can be found in the [C SDK HOME DIR]/src/api/twApi.h header file. The usage can be seen in the example below: if (strcmp(propertyName, "count") == 0) { twInfoTable_GetInteger(*value, propertyName, 0, &properties.count); twApi_SetSubscribedProperty(entityName, propertyName, twPrimitive_CreateFromNumber(properties.count), FALSE, TRUE); } if (strcmp(propertyName, "InletValve") == 0) twInfoTable_GetBoolean(*value, propertyName, 0, &properties.InletValve);   Retrieve Properties   Property values can be retrieved using the provided Macros or using the API directly.   With Macros   The TW_GET_PROPERTY macro retrieves a property in ThingWorx and can be found in the [C SDK HOME DIR]/src/api/twMacro.h header file. The usage can be seen in the example below: double temp = TW_GET_PROPERTY(thingName, "Temperature").number;   NOTE: You can use the macro TW_GET_PROPERTY_TYPE to get the property type. The signature and function information can be found in the [C SDK HOME DIR]/src/api/twMacro.h header file.   Without Macros   The twInfoTable_Get functions updates a property in ThingWorx and can be found in the [C SDK HOME DIR]/src/api/twApi.h header file. The usage can be seen in the example below:   twInfoTable **inletValue = NULL; twInfoTable **temp = NULL; twInfoTable **location = NULL; *inletValue = twInfoTable_CreateFromBoolean(propertyName, properties.InletValve); *temp = twInfoTable_CreateFromNumber(propertyName, properties.Temperature); *location = twInfoTable_CreateFromLocation(propertyName, &properties.Location);   Property Change Listeners   Using the Observer pattern, you are able to take advantage of the property change listener functionality. With this pattern, you are able to create functions that will be notified when a value of a property has been changed (whether on the server or locally by your program when the TW_SET_PROPERTY macro is called).   Add a Property Change Listener   In order to add a property change listener, you will call the twExt_AddPropertyChangeListener function using the name of the Thing (entityName), the property this listener should watch, and the function that will be called when the property has changed. The usage can be seen in the example below: void simplePropertyObserver(const char * entityName, const char * thingName,twPrimitive* newValue){ printf("My Value has changed\n"); } void test_simplePropertyChangeListener() { { TW_MAKE_THING("observedThing",TW_THING_TEMPLATE_GENERIC); TW_PROPERTY("TotalFlow", TW_NO_DESCRIPTION, TW_NUMBER); } twExt_AddPropertyChangeListener("observedThing",TW_OBSERVE_ALL_PROPERTIES,simplePropertyObserver); TW_SET_PROPERTY("observedThing","TotalFlow",TW_MAKE_NUMBER(50)); }   NOTE: Setting the propertyName parameter to NULL or TW_OBSERVE_ALL_PROPERTIES, the function specified by the propertyChangeListenerFunction parameter will be used for ALL properties.   Remove a Property Change Listener   When releasing the memory for your application or done with utilizing listeners for the property, call the twExt_RemovePropertyChangeListener function. This usage can be seen in the example below:   void simplePropertyObserver(const char * entityName, const char * thingName,twPrimitive* newValue){ printf("My Value has changed\n"); } twExt_RemovePropertyChangeListener(simplePropertyObserver);     Step 9: C - Data Shapes   DataShapes are used for Events, Services, and InfoTables. In order to create a DataShape, you can do so with the provided macros or functions.   Define With Macros   In order to define a DataShape using a macro, use TW_MAKE_DATASHAPE.   NOTE: The macros are all defined in the twMacros.h header file. TW_MAKE_DATASHAPE("SteamSensorReadingShape", TW_DS_ENTRY("ActivationTime", TW_NO_DESCRIPTION ,TW_DATETIME), TW_DS_ENTRY("SensorName", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("Temperature", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("Pressure", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("FaultStatus", TW_NO_DESCRIPTION ,TW_BOOLEAN), TW_DS_ENTRY("InletValve", TW_NO_DESCRIPTION ,TW_BOOLEAN), TW_DS_ENTRY("TemperatureLimit", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("TotalFlow", TW_NO_DESCRIPTION ,TW_INTEGER) );   Define Without Macros   In order to define a DataShape without using a macro, use the twDataShape_CreateFromEntries function.   twDataShape * ds = 0; ds = twDataShape_Create(twDataShapeEntry_Create("ID", NULL, TW_INTEGER)); twDataShape_SetName(ds, "StringMap"); twDataShape_AddEntry(ds, twDataShapeEntry_Create("Value", NULL, TW_STRING));     Click here to view Part 8 of this guide
View full tip
  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.     Step 11: 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.   Learn More   We recommend the following resources to continue your learning experience:   Capability Link Build Design Your Data Model Build Implement Services, Events, and Subscriptions   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 4: Launch IoT Hub Connector   Open a shell or a command prompt window. On a Windows machine, open the command prompt as Administrator. The AZURE_IOT_OPTS environment variable must be set before starting the Azure IoT Hub Connector. Below are sample commands using the default installation directory. On Windows: set AZURE_IOT_OPTS=-Dconfig.file=C:\ThingWorx-Azure-IoT-Connector-<version>\azure-iot-<version>-application\conf\azure-iot.conf -Dlogback.configurationFile=C:\ThingWorx-Azure-IoT-Connector-<version>\azure-iot-<version>-application\conf\logback.xml On Linux: export AZURE_IOT_OPTS="-Dconfig.file=/var/opt/ThingWorx-Azure-IoT-Connector-<version>/azure-iot-<version>-application/conf/azure-iot.conf -Dlogback.configurationFile=/var/opt/ThingWorx-Azure-IoT-Connector-<version>/azure-iot-<version>-application/conf/logback.xml" NOTE: You must run the export command each time you open a shell or command prompt window. Change directories to the bin subdirectory of the Azure IoT Hub Connector installation. Start the Azure IoT Hub Connector with the appropriate command for your operating system. On Windows: azure-iot.bat On Linux: /azureiot   NOTE: On Windows you may have to shorten the installation directory name or move the bin directory closer to the root directory of your system to prevent exceeding the Windows limit on the classpath length. The Connection Server should start with no errors or stack traces displayed. If the program ends, check the following: Java version is 1.8.0, update 92 or greater and is Java(TM) not OpenJDK Open azure-iot.conf and confirm ThingWorx Foundation is set to the correct URL and port. Confirm the platform scheme is ws if http is used to access ThingWorx. Confirm all Azure credentials are correct for your Azure account. In ThingWorx Foundation click the Monitoring tab then click Connection Servers. You should see a server named azure-iot-cxserver-{server-uuid}, where {server-uuid} is a unique identifier that is assigned automatically to the server.     Step 5: Import Device from Azure   With the ThingWorx Azure IoT Connector, you can import into ThingWorx any existing devices that are currently provisioned to the Azure IoT Hub.   Add Device Azure IoT Hub If you have not provisioned any devices to your Azure IoT Hub you can learn more about Azure IoT Hub device identity before following the steps below to create a test device. In your Azure Portal, click All Resources, then select the name of your IoT Hub. Under Explorers click IoT devices, then click + Add. Enter a name for your device, then click Save When the device name appears in the list it is ready to us     Import Device into ThingWorx We will manually execute a service in ThingWorx that will import Azure IoT Hub devices into ThingWorx. In ThingWorx Composer, navigate to the ConnectionServicesHub Thing. Click Services tab and scroll to the ImportAzureIotDevices service and click the execute Arrow.   NOTE: The * in the pattern field will act as a wildcard and import all devices, you can enter a string to match that will only import a subset of all available devices.     Click Execute to import the devices then click Done. Click Things in the left column to see the Things that were created.     Step 6: Set-up and Run Demo   The ThingWorx Azure IoT Connector download includes a Java application that simulates a device connecting to your Azure IoT Hub. A ThingTemplate is also included and can be imported into ThingWorx.   Import Demo Templates In ThingWorx Composer, click Import/Export menu, then click From File and browse to ../demo/edgedevice- demo/platform/entities/CPUDemo_AllEntities.xml     Click Import then click Close when the import successful message is displayed. Create a new Thing using the imported template azureDemo1, enter a name for your Thing and click Save. NOTE: You will enter this name in the demo config file in the next step.   Configure Demo Application In the ../demo/edge-device-demo/conf subdirectory, open the edge-device.conf file with a text editor. Edit the deviceId to be the name of the Thing you created in step 3. Edit the iotHubHostName to use the name of your hub plus the domain: azure-devices.net. For example, sample-iot-hub.azuredevices.net. Edit the registryPolicyKey property to use the Primary Key for the registryReadWrite policy in the Azure IoT Hub. Below is an example configuration: // Azure Edge Device Demo configuration azure-edge-device { // Name of the remote thing on the ThingWorx platform, which should match the Azure Device ID deviceId = "alstestedgething" // Name of the hub host in Azure iotHubHostname = "alsiot.azure-devices.net" // Policy name used by this thing (could require services as well in future) registryPolicyName = "registryReadWrite" // The Key related to the policy above registryPolicyKey = "pzXAi2nonYWsr3R7KVX9WuzV/1234567NZVTuScl/Kg=" } Run Demo Script   Open a shell or Command Prompt, set the EDGE_DEVICE_DEMO_OPTS environment variable to refer to the file you just edited: Linux - export EDGE_DEVICE_DEMO_OPTS="-Dconfig.file=../conf/edge-device.conf" Windows - set EDGE_DEVICE_DEMO_OPTS="-Dconfig.file=../conf/edge-device.conf" Launch the demo from the ../demo/edge-device-demo/bin subdirectory, using the edge-device-demo command. Return to the ThingWorx Composer and open the Properties page of the Azure Thing that you created previously. Click the refresh button to see the properties change every five seconds. Open the azure-iot-demo Mashup and view the Load Average and CPU gauges, and the increases in the values of the Cycle and Uptime fields. NOTE: If the edgedevice-demo is running on Windows, the Load Average does not register. Step 7: Next Steps   Congratulations! You've successfully completed the Connect Azure IoT Hub to ThingWorx Quickstart. By following the steps in this lesson, you imported a device created in Azure into ThingWorx and saw how data from an Azure device could be used in a ThingWorx Mashup. Learn More We recommend the following resources to continue your learning experience: Capability Guide Connect Choose a Connectivity Method Build Design Your Data Model Experience Create Your Application UI   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Getting Started with ThingWorx  
View full tip
  Step 5: Add Data   We've added a Pareto Chart Widget to the Mashup, but we still need to bring in backend data.   Ensure the top-right Data tab is active.   Click the green + button.   In the Entity field, search for and select TIPC_Thing. In the Services field, type getprop. Click the right arrow beside GetProperties. On the right, check Execute on Load.   In the bottom-right of the pop-up, click Done.   Under the Data tab on the right, expand GetProperties.   Drag-and-drop Things_TIPC_Thing> GetProperties > InfoTable_Property onto the Pareto Chart.   On the Select Binding Target pop-up, click Data.   With the Pareto Chart selected in the central Canvas area, ensure the Properties tab is active in the bottom-left.   In the Filter field, type xaxis.   In the XAxisField, search for and select month.   At the top, click Save.     Step 6: View Mashup   Up to this point, we've created a Data Shape to format the columns of an Info Table Property. You then created a Thing, as well as an Info Table Property formatted by the Data Shape. As a test, you added some manually-entered data to the Info Table. After creating a Mashup, you added a Pareto Chart Widget and tied it to that backend data.   The only thing left to do is to visualize your GUI.    Ensure that you're on the Design tab of the TIPC_Mashup.   At the top, click View Mashup.   The end result is a visualization of how each of your main issues contribute to your overall downtime.   In particular, this test data shows that excess_temperature is the primary cause of issues, regardless of month.    You could now connect the backend data-storage to live-data from the robotic welding arm to begin an actual determination of your issues.       Step 7: Next Steps   Congratulations! You've successfully completed the Track Issues with Pareto Chart guide, and learned how to:   Create a Data Shape Create a Thing Create an Info Table Property Populate an Info Table with appropriate data for a Pareto Chart Create a Mashup Utilize a Pareto Chart to display issue-aggregation    Learn More   We recommend the following resources to continue your learning experience: Capability  Guide Manage How to Display Data in Charts Additional Resources   If you have questions, issues, or need additional information, refer to: Resource Link Community Developer Community Forum Support Pareto Chart Help  
View full tip
Announcements