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 Tips

Sort by:
Hi everyone, As everyone knows already, the main way to define Properties inside the EMS Java SDK is to use annotations at the beginning of the VirtualThing class implementation. There are some use-cases when we need to define those properties dynamically, at runtime, like for example when we use a VirtualThing to push a sensor's data from a Device Cloud to the ThingWorx server, for multiple customers. In this case, the number properties differ based on customers, and due to the large number of variations, we need to be able to define programmatically the Properties themselves. The following code will do just that: for (int i = 0; i < int_PropertiesLength; i++) {     Node nNode = device_Properties.item(i);     PropertyDefinition pd;     AspectCollection aspects = new AspectCollection();     if (NumberUtils.isNumber(str_NodeValue))     {         pd = new PropertyDefinition(nNode.getNodeName(), " ", BaseTypes.NUMBER);     }     else if (str_NodeValue=="true"|str_NodeValue=="false")     {         pd = new PropertyDefinition(nNode.getNodeName(), " ", BaseTypes.BOOLEAN);     }     else     pd = new PropertyDefinition(nNode.getNodeName(), " ", BaseTypes.STRING);     aspects.put(Aspects.ASPECT_DATACHANGETYPE,    new StringPrimitive(DataChangeType.VALUE.name()));     //Add the dataChangeThreshold aspect     aspects.put(Aspects.ASPECT_DATACHANGETHRESHOLD, new NumberPrimitive(0.0));     //Add the cacheTime aspect     aspects.put(Aspects.ASPECT_CACHETIME, new IntegerPrimitive(0));     //Add the isPersistent aspect     aspects.put(Aspects.ASPECT_ISPERSISTENT, new BooleanPrimitive(false));     //Add the isReadOnly aspect     aspects.put(Aspects.ASPECT_ISREADONLY, new BooleanPrimitive(true));     //Add the pushType aspect     aspects.put("pushType", new StringPrimitive(DataChangeType.ALWAYS.name()));     aspects.put(Aspects.ASPECT_ISLOGGED,new BooleanPrimitive(true));     //Add the defaultValue aspect if needed...     //aspects.put(Aspects.ASPECT_DEFAULTVALUE, new BooleanPrimitive(true));     pd.setAspects(aspects);     super.defineProperty(pd); }  //you need to comment initializeFromAnnotations() and use instead the initialize() in order for this to work. //super.initializeFromAnnotations();   super.initialize(); Please put this code in the Constructor method of your VirtualThing extending implementation. It needs to be run exactly once, at any instance creation. This method relies on the manual discovery of the sensor properties that you will do before this. Depending on the implementation you can either do the discovery of the properties here in this method (too slow), or you can pass it as a parameter to the constructor (better). Hope it helps!
View full tip
  Step 8: Call Custom Service   In order to execute a Service of a specific Thing with the REST API, you can use the POST verb.   Required Parameters:   AppKey created by your ThingWorx server Name of the Thing that implements a custom Service Name of the custom Service Names of inputs, if any, required by the Service Request   Construct the URL. To call a custom Service of an existing Thing, make an HTTP POST to this endpoint: <server_ip:port>/Thingworx/Things/<name of Thing>/Services/<name of Service> Substitute <name of Thing> with the actual name of a Thing that exists on the ThingWorx server, and <name of Service> with an existing Service. Send request parameters The names of the inputs along with their values are sent in the body of the POST as a JSON object. For example, the JSON object below will send a parameter named 'firstNumber' with a value of 35 and a parameter named secondNumber with a value of 711. { "firstNumber": "35", "secondNumber": "711" } NOTE: The full request must include a header with the appKey for your specific ThingWorx server.   Response   A successful call to a Service will return a JSON object in the body of the response containing both a DataShape object and an array named rows. Inside the array, an object named result will have the value returned by the custom Service. Here is an example response:   { "dataShape": { "fieldDefinitions": { "result": { "aspects": {}, "baseType": "NUMBER", "description": "", "name": "result", "ordinal": 0 } } }, "rows": [ { "result": 746.0 } ] } WARNING for other HTTP clients: Most HTTP clients do not set a Content-Type header by default, without this header set the server will return an error message. The POST request to the Service endpoint has a JSON body so the header must be set to match the format of the request body.   Step 9: Import and Export Entities   Collections of Entities that perform a function can be grouped then shared by exporting from a server. These entity collections are called Extensions and can be uploaded using the REST API. You can create custom Extensions or download Extensions created by other developers. You can use the REST API to automate the process of uploading an Extension to a ThingWorx server.   Required Parameters   AppKey created by your Foundation server Path to properly formatted zip file containing extension Entities Request   Construct the URL. Upload an Extension by making an HTTP POST to the endpoint: <Server IP:port〉Thingworx/ExtensionPackageUploader Send request parameters. The zip file that contains the extension entities is uploaded as a multi-part POST. The name of the file parameter is upload. Use a library to properly format the multi-part POST request You must also send this header: X-XSRF-TOKEN:TWX-XSRF-TOKEN-VALUE Authenticate the Request. All API requests to the ThingWorx server must be authenticated either with a username and password or with an appKey. For this example we will authenticate by passing the appKey as a URL query string parameter. The parameter appKey is recognized by the ThingWorx server as an authentication credential in requests, it can be passed either as a URL query string parameter .../CreateThing?appKey=64b87... , or as request header appKey: 64b87...   Response   A successful call to upload an Extension will return a description of the Entities that were successfully uploaded in the body of the response.   HTTPie example: http -f POST iotboston.com:8887/Thingworx/ExtensionPackageUploader upload@/home/ec2-user/extension.zip X-XSRF-TOKEN:TWX-XSRF-TOKEN-VALUE appKey:d0a68eff-2cb4-4327-81ea-7e71e26bb645 cURL example: curl -v --header X-XSRF-TOKEN:TWX-XSRF-TOKEN-VALUE --header appKey:d0a68eff-2cb4-4327-81ea-7e71e26bb645 -F upload=@extension.zip iotboston.com:8887/Thingworx/ExtensionPackageUploader?purpose=import&validate=false     Download Things By Name   The REST API can be used to export a file representation of Things on a ThingWorx Foundation server. The downloaded file can be imported to another ThingWorx server making the Thing available for use.   Required Parameters   AppKey created by your Foundation server Name of the Thing Request   Construct the URL. Retrieve the components of a Thing by making an HTTP GET to the endpoint. Substitute <name of Thing> with the actual name of a Thing that exists on the ThingWorx server that wil be downloaded. <Server IP:port>/Thingworx/Exporter/Things/<name of Thing> Send request parameters. No parameters are sent. Authenticate the Request. All API requests to the ThingWorx server must be authenticated either with a username and password or with an appKey. For this example we will authenticate by passing the appKey as a URL query string parameter. The parameter appKey is recognized by the ThingWorx server as an authentication credential in requests, it can be passed either as a URL query string parameter .../CreateThing?appKey=64b87... , or as request header appKey: 64b87...   Response   It is possible for the content to be returned in two different formats by sending an Accept header with the request.   Desired Response Type  Accept Header Values JSON application/json XML text/xml HTML text/html (or omit Accept Header) CSV text/csv   A successful call to download a Thing will return a file in the body of the response suitable for importing into a ThingWorx Foundation server.   HTTPie example:   http -v GET iotboston.com:8081/Thingworx/Exporter/Things/PiThing appKey==d0a68eff-2cb4-4327-81ea-7e71e26bb645 Accept:text/xml     Download Things By Tag   The REST API can be used to export a file representation of Things on a ThingWorx Foundation server. This file can be imported to another ThingWorx server making the Thing available for use.   Required Parameters   AppKey created by your Foundation server Name of the Tag Request   Construct the URL. Retrieve the components of a Thing by making an HTTP GET to the endpoint <Server IP:port〉/Thingworx/Exporter/Things Send request parameters. The Tag name is sent as a request parameter named: searchTags Authenticate the Request. All API requests to the ThingWorx server must be authenticated either with a username and password or with an appKey. For this example we will authenticate by passing the appKey as a URL query string parameter. The parameter appKey is recognized by the ThingWorx server as an authentication credential in requests, it can be passed either as a URL query string parameter .../CreateThing?appKey=64b87... , or as request header appKey: 64b87...   Response   It is possible for the content to be returned in two different formats by sending an Accept header with the request.   Desired Response Type  Accept Header Values JSON application/json XML text/xml HTML text/html (or omit Accept Header) CSV text/csv   A successful call to download a Thing will return a file in the body of the response suitable for importing into a ThingWorx Foundation server   HTTPie example:   http -v GET iotboston.com:8081/Thingworx/Exporter/Things searchTags==Applications:Raspberry_light appKey==d0a68eff-2cb4-4327-81ea-7e71e26bb645 Accept:text/xml     Step 10: Authentication Tags   A Tag is composed of two parts: a Vocabulary, and a specific vocabulary term. A Tag is shown as Vocabulary:VocabularyTerm. Almost every ThingWorx entity can be tagged. Tags can be used to create a relationship between many different ThingWorx Entities.   Create New Tag   You can use the REST API to create a new dynamic Tag vocabulary.   Required Parameters   AppKey created by your Foundation server Name of Tag Vocabulary   Request   Construct the URL. Create a new Tag Vocabulary by making an HTTP PUT to this endpoint: 〈Server IP:port〉/Thingworx/ModelTags Send Request Parameters. The name of the new DataShape and the name of the base DataShape that the new DataShape extends are sent in the body of the POST as a JSON object. For example, the JSON object below will create a new DataShape named SomeTestDataShape using the system template GenericThing. { "name": "SecondTest", "isDynamic": "true" } Authenticate Request. All API requests to the ThingWorx server must be authenticated either with a username and password or with an appKey. For this example we will authenticate by passing the appKey as a URL query string parameter. The parameter appKey is recognized by the ThingWorx server as an authentication credential in requests, it can be passed either as a URL query string parameter .../CreateThing?appKey=64b87... , or as request header appKey: 64b87...   Response   A successful call to the ModelTag Service does not return any content in the body of the response, only an HTTP 200 is returned.   HTTPie example:   http -v -j PUT http://52.201.57.6/Thingworx/ModelTags name=SecondTest isDynamic=true appKey==64b879ae-2455-4d8d-b840-5f5541a799ae     Warning for other HTTP clients: Most HTTP clients do not set a Content-Type header by default, without this header set the server will return an error message. The PUT request to the ModelTags endpoint has a JSON body so the header must be set to match the format of the request body. The Content-Type header does not appear in the sample HTTPie call because HTTPie sets the Accept and Content-type request headers to application/json by default. Below is an example cURL call that explicitly sets the Content-Type header to application/json.   curl -v -H "Content-Type: application/json" -X PUT -d '{"name": "SecondTest", "isDynamic":"true"}' http://52.201.57.6/Thingworx/ModelTags?appKey=d0a68eff-2cb4-4327-81ea-7e71e26bb645   Add Tag to Thing   You can use the REST API to add a Tag to a Thing. There must be a Thing and a Dynamic Tag Vocabulary already created on your Foundation Server before you can add a Tag.   Required Parameters   AppKey created by your Foundation server Name of the Thing to be tagged Name of Dynamic Tag Vocabulary Name of for Tag to be assigned to Thing Request   Construct the URL. Substitute 〈name of Thing〉 with the actual name of a Thing that exists on the ThingWorx server that will have the Tag added. Add a new Tag to an existing Thing by making an HTTP POST to this endpoint: 〈Server IP:port〉/Thingworx/Things/〈name of Thing〉/Services/AddTags Send request parameters. The name of the new field to be added and type of the field are sent in the body of the POST as a JSON object. For example, the JSON object below will create a new field named SomeNumber using the ThingWorx base type NUMBER. Some other commonly used types are STRING, INTEGER, and BOOLEAN. Include a header in the full request with the appKey for your specific ThingWorx server. { "tags" : "SecondlightTest:RaspberryTest", }   Response   A successful call to the AddTags Service does not return any content in the body of the response. Only an HTTP 200 is returned.   HTTPie example:   http -v -j http://52.201.57.6/Thingworx/Things/SomeTestThing/Services/AddTags appKey==64b879ae-2455-4d8d-b840-5f5541a799ae tags=SecondTest:RaspberryTest curl -v -H "Content-Type: application/json" -X POST -d '{"tags": "SecondlightTest:RaspberryTest"}' http://52.201.57.6/Thingworx/Things/PiThing/Services/AddTags?appKey=d0a68eff-2cb4-4327-81ea-7e71e26bb645 Warning for other HTTP clients: Most HTTP clients do not set a Content-Type header by default, without this header set the server will return an error message. The POST request to the AddPropertyDefinition endpoint has a JSON body so the header must be set to match the format of the request body. The Content-Type header does not appear in the sample HTTPie call because HTTPie sets the Accept and Content-type request headers to application/json by default. Below is an example cURL call that explicitly sets the Content-Type header to application/json.   curl -v -H "Content-Type: application/json" -X POST -d '{"tags": "SecondlightTest:RaspberryTest"}' http://52.201.57.6/Thingworx/Things/PiThing/Services/AddTags?appKey=d0a68eff-2cb4-4327-81ea-7e71e26bb645      Click here to view Part 4 of this guide.  
View full tip
  Step 5: Add Property to Thing   Property values are associated with a specific Thing, and are used to store data that changes over time. Required Parameters   AppKey created by your ThingWorx server Name of the Thing to which the Property will be added Name for the new Property and data type of the Property's value   Request   Construct the URL. A new Property can be added to an existing Thing by making an HTTP POST to this endpoint. Substitute <name of Thing> with the actual name of a Thing that exists on the ThingWorx server that will have the Property added. <server_ip:port>/Thingworx/Things/<name of Thing>/Services/AddPropertyDefinition       2. Send request parameters. The name of the new Property to be added and type of the Property are sent in the body of the POST as a JSON object. For example, the JSON object below will create a new Property named SomeNumber using the ThingWorx base type NUMBER. Some other commonly used types are STRING, INTEGER, and BOOLEAN. { "name" : "SomeNumber", "type" : "NUMBER" }   NOTE: The full request must include a header with the appKey for your specific ThingWorx server.   Response   A successful call to the AddPropertyDefinitionservice does not return any content in the body of the response. Only an HTTP 200 is returned.   HTTPie example:   http -v -j http://52.201.57.6/Thingworx/Things/SomeTestThing/Services/AddPropertyDefinition appKey==64b879ae-2455-4d8d-b840-5f5541a799ae name=SomeNumber type=NUMBER   WARNING for other HTTP clients: Most HTTP clients do not set a Content-Type header by default, without this header set the server will return an error message. The POST request to the AddPropertyDefinition endpoint has a JSON body so the header must be set to match the format of the request body.   The Content-Type header does not appear in the sample HTTPie call because HTTPie sets the Accept and Content-type request headers to application/json by default. Below is an example cURL call that explicitly sets the Content-Type header to application/json.   curl -v -H "Content-Type: application/json" -X POST -d '{"name": "SomeNumber","type": "NUMBER"}' http://52.201.57.6/Thingworx/Things/SomeTestThing/Services/AddPropertyDefinition?appKey=d0a68eff-2cb4-4327-81ea-7e71e26b     Validate   View new Property on Server. The Property you just added is now available in the ThingWorx Composer. Before anything else can be done with your new Property through the REST API, the Thing must be restarted. To confirm your Property was added to your Thing, open Composer and click Things, select the name of the Thing you just created, then click Properties and Alerts. You will see the new Property listed. You may need to refresh to see the changes.             2. Execute RestartThing Service. Restart your Thing with the added Property by making a HTTP POST to the endpoint below. Substitute <name of Thing> with the actual name of the Thing you created. No body is required in the POST, however, the Content-Type header of a POST that executes a Service must always be set to application/json or text/xml even if the service does not take any parameters and no content is being sent. No body is returned upon success, only an HTTP 200 response code. <server_ip:port>/Thingworx/Things/<name of Thing>/Services/RestartThing   HTTPie example:   http -v -j POST http://52.201.57.6/Thingworx/Things/SomeTestThing/Services/RestartThing appKey==64b879ae-2455-4d8d-b840-5f5541a799ae      Step 6: Set Property Value   You can set the value of a specific Property with the REST API using the PUT verb. Required Parameters:   AppKey created by your Foundation server A Name of valid Thing and name of Property New Property value   Request   Construct the URL. A Property value can be set by making an HTTP PUT call to this endpoint: <server_ip:port>/Thingworx/Things/<name of Thing>/Properties/<name of Property> Substitute <name of Thing> with the actual name of a Thing that exists on the ThingWorx server and <name of Property> with the name of a Property that has been added to the Thing.       2. Send request parameters.   The name of the Property to be set is duplicated in the body of the PUT and is sent along with the value as a JSON object. The example below will set the Property SomeNumber to 34.4 { "SomeNumber" : 34.4 } NOTE: The full request must include authentication credentials for your specific ThingWorx server.   Response   A successful call to set a Property does not return any content in the body of the response. Only an HTTP 200 is returned.   HTTPie example   http -v -j PUT http://52.201.57.6/Thingworx/Things/SomeTestThing/Properties/SomeNumber appKey==64b879ae-2455-4d8d-b840-5f5541a799ae SomeNumber=34.4   WARNING for other HTTP clients: By default HTTPie sets the Accept and Content-type request headers to application/json. A PUT request to the Properties endpoint has a JSON body so the Content-Type header must be set to match the format of the request body.   Most HTTP clients do not set the correct header by default and it must be set explicitly. Below is an example cURL call that sets the Content-Type header to application/json   curl -v -H "Content-Type: application/json" -X PUT -d '{"SomeNumber":12.34}' http://52.201.57.6/Thingworx/Things/SomeTestThing/Properties/SomeNumber?appKey=d0a68eff-2cb4-4327-81ea-7e71e26b     Validate   To confirm your Property was changed for your Thing, go to Composer and click Things. Select the name of the Thing you just created, then click Properties and Alerts tab. Click on the circular arrow Refresh to see the updated Property value.       Step 7: Get Latest Property Value   You can retrieve Property values of a specific Thing with the REST API using the GET verb.   Required Parameters:   AppKey created by your ThingWorx server Name of Thing and name of Property   Request   Construct the URL. To get the current value for a property, make a GET request to this endpoint: <server_ip:port>/Thingworx/Things/<name of Thing>/Properties/<name of property> Substitute <name of thing> with the actual name of a Thing that exists on the ThingWorx server and <name of Property> with the name of a Property that has been added to the Thing.   NOTE: The full request will also need to include the hostname and authentication credentials for your specific ThingWorx server.         2. Send request parameters. Other than authentication, no other parameters are used in  this GET request.   Response   The content can be returned in four different formats by sending an Accept header with the request.   Desired Response Type Accept Header Values JSON application/json XML text/xml HTML text/html (or omit Accept Header) CSV text/csv   HTTPie example:   http -v -j http://52.201.57.6/Thingworx/Things/SomeTestThing/Properties/SomeNumber appKey==64b879ae-2455-4d8d-b840-5f5541a799ae     Click here to view Part 3 of this guide.
View full tip
I have put together a small sample of how to get property values from a Windows Powershell command into Thingworx through an agent using the Java SDK. In order to use this you need to import entities from ExampleExport.xml and then run SteamSensorClient.java passing in the parameters shown in run-configuration.txt (URL, port and AppKey must be adapted for your system). ExampleExport.xml is a sample file distributed with the Java SDK which I’ve also included in the zipfile attached to this post. You need to go in Thingworx Composer to Import/Export … Import from File … Entities … Single File … Choose File … Import. Further instructions / details are given in this short video: Video Link : 2181
View full tip
Previously Installing & Connecting C SDK to Federated ThingWorx with VNC Tunneling to the Edge device Installing and configuring Web Socket Tunnel Extension on ThingWorx Platform Overview     Using the C SDK Edge client configuration we did earlier, we'll now create above illustrated setup. In this C SDK Client we'll push the data to ThingWorx Publisher with servername : TW802Neo to ThingWorx Subscriber servername : TW81. Notice that the SteamSensor2 on the pulisher server is the one binding to the C SDK client and the FederatedSteamThing on subscriber is only getting data from the SteamSensor2. Let's crack on!   Content   Configure ThingWorx to publish Configure ThingWorx to subscribe Publish entities from Publisher to the Subscriber Create Mashup to view data published to the subscriber Pre-requisite Minimum requirement is to have two ThingWorx servers running. Note that both ThingWorx systems can be publisher & subscriber at the same time.   Configure ThingWorx Publisher   Configuring Federation Subsystem   1. Navigate to ThingWorx Composer > Subsystems > Federation Subsystems and configure the following highlighted sections   Essentially its required to configure the Server Identification, i.e. My Server name (FQDN / IP) , My Server Description (optional) Federation subscribers this server publishes to, i.e. all the server you want to publish to from this server. Refer to the Federation Subsystem doc in the Help Center to check detail description on each configurable parameter.   2. Save the federation subsystem   Configuring a Thing to be published   1. Navigate back to the Composer home page and select the entity which you'd like to publish 2. In this case I'm using SteamSensor2 which is created to connect to the C SDK client 3. To publish edit the entity and click on Publish checkbox, like so 4. Save the entity   Configure ThingWorx Subscriber     Configuring Federation Subsystem   1. Navigate to ThingWorx Composer > Subsystems > Federation Subsystems and configure the following highlighted sections   Essentially its required to configure the Server Identification, i.e. My Server name (FQDN / IP) , My Server Description (optional) Refer to help center doc on Federation Subsystems should you need more detail on the configurable parameter If you only want to use this server as a subscriber of entities from the publishing ThingWorx Server, in that case you don't have to Configure the section Federation subscribers this server publishes to, I've configured here anyway to show that both servers can work as publishers and subscribers   2. Save the federation subsystem   Configuring a Thing to subscribe to a published Thing 1. Subscribing to an entity is fairly straight forward, I'll demonstrate by utilizing the C SDK client which is currently pushing values to my remote thing called SteamSensor2 on server https://tw802neo:443/Thingworx 2. I have already Published the StreamSensor2, see above section Configuring a Thing to be published 3. Create a Thing called FederatedStreamThing with RemoteThingWithTunnels as ThingTemplate, 4. Browser for the Identifier and select the required entity to which binding must be done, like so   5. Navigate to the Properties section for the entity, click Manage Bindings to search for the remote properties like so for adding them to this thing:     6. Save the entity and then we can see the values that were pushed from the client C SDK     7. Finally, we can also quickly see the values pulled via a Mashup created in the subscriber ThingWorx , below a is a simple mashup with grid widget pulling values using QueryPropertyHistory service  
View full tip
  Guidelines for selecting the optimal method for connecting to ThingWorx   GUIDE CONCEPT   In the world of IoT application development, connectivity refers to the infrastructure and protocols which connect devices to the cloud or network. Edge devices handle the interface between the physical world and the cloud.   ThingWorx provides you with several different tools for connecting to the Thingworx platform.   This guide is designed as an introduction to these tools, and will help you determine which to choose based on your specific requirements.   YOU'LL LEARN HOW TO   Pros and cons of different connection methods The connection method best suited for some typical applications Where to find detailed information about any connection method   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes   Step 1: Connectivity Method Options   There are many factors that will influence your decision about the ideal mechanism to connect to ThingWorx. On this page we compare and contrast different methods and give examples for where each one is a natural fit.   Connectivity Method Developer Benefit REST API Integrate seamlessly using dynamically-generated API calls Azure IoT Hub Connector Connect devices that use Azure IoT Hub Edge SDKs Build full-featured integrations for any platform ThingWorx Kepware Server Connect out-of-the-box with over 150 protocol drivers for industrial equipment Edge MicroServer Establish bi-directional connectivity with this complete, ready-to-run agent   REST API   Pros Cons Typical use case Skills Required Connection Type  Web developer can easily create integration ThingWorx cannot trigger action on the edge Push data from small devices to ThingWorx REST API development Request/Response   Using the ThingWorx REST API is an easy way for low-capability devices to connect with a ThingWorx platform. Any edge device that can make an HTTP POST can read and update properties or execute services on a ThingWorx platform. The disadvantage of this method is that it is one way from edge to platform. There is no way for the platform to initiate a service on the remote device and properties are only updated when the edge device initiates a connection with ThingWorx.   Learn more about the ThingWorx REST API:   Use REST API to Access ThingWorx Using the Connect an Arduino Developer Board tutorial REST API Documentation   Azure IoT Hub Connector   Pros Cons Typical use Case Skills Required Connection Type  Easily connect devices that use Azure IoT Hub Adds dependency and cost to application Add ThingWorx for devices connected with the Azure cloud Azure edge development AlwaysOn™   The diagram illustrates device-to-cloud integration with the Azure IoT Hub.   The ThingWorx Azure IoT Hub Connector establishes network connections to both ThingWorx Foundation and the Azure IoT Hub. Data flows in from devices, through the Azure IoT Hub hosted in the cloud, to the ThingWorx Azure IoT Hub Connector configured for a specific ThingWorx instance. The ThingWorx Azure IoT Hub Connector translates messages from the Azure IoT Hub format, to the native ThingWorx format and uses an established AlwaysOn connection to forward the information to ThingWorx Foundation.   Azure IoT Hub   Connect Azure IoT Devices   Edge SDKs   Pros Cons Typical Use case Skill Required Connection Type  Fully integrate device or remote system with ThingWorx platform Most developer flexibility All functionality must be developed by programmer Full customization or tight integration required Application development in Java, C, or .Net AlwaysOn™   These SDKs are developer tools that wrap the protocol used to connect to the ThingWorx Platform. There are SDK's available for Java, C, and .Net languages. The Edge MicroServer uses the C SDK internally. All SDKs use the ThingWorx AlwaysOn binary protocol together with the HTTP WebSocket protocol for transport. WebSocket connections can operate through a firewall allowing two-way, low latency communication between the device and server. The SDKs support the following key concepts that allow a Thing developed with an SDK to be a full-fledged entity in the ThingWorx environment:   Remote properties — Entities that define the types, identities, and values from a device or remote system Services — Actions that can be performed on demand by a device or remote system Events — Data that is sent to a subscribed device or remote system whenever the Event is triggered   You can choose from any of the SDK's to create a custom application that meets their exact requirements.   C SDK   The C SDK is the most lightweight of all the SDKs and will result in an application that uses the least amount of RAM, frequently requiring less than 200kB. It is the only SDK that is distributed as source code, allowing compilation of C SDK applications on any platform even those without an operating system.   Learn more about the C SDK:   C SDK Tutorial C SDK Documentation   Java SDK   The Java SDK is designed for portability and simplicity to ease connecting any Java-enabled device or system to ThingWorx. The Java SDK is provided as .jar files and sample Java source code. Any system that can run Java 1.7.51 or later should be able to build and run the example applications.   Learn more about the Java SDK:   Java SDK Tutorial Java SDK Documentation   .Net SDK   The .Net SDK is provided as .dll files with sample Visual C# project files and source code. Any system that can run Microsoft NET 3.5 SP1 Framework development environment should be able to build and run the example applications.   Learn more about the .Net SDK:   .Net SDK Documentation   ThingWorx Kepware Server   Pros Cons Typical Use case Skill Required Connection Type  Easily connect to hundreds of different types of industrial equipment Requires computer running Windows physically connected to device Adding ThingWorx to an industrial setting Configure settings AlwaysOn™   The ThingWorx Kepware Server Windows client lets users quickly and easily connect real-time, bi-directional industrial controls data to the ThingWorx IoT Platform via the ThingWorx AlwaysOn protocol. ThingWorx services enable users to browse, read, write, and interact with ThingWorx Kepware Server, and includes intuitive tools that simplify the modeling of industrial things.   Learn more about the ThingWorx Kepware Server:   Connect Industrial Devices and Systems ThingWorx Kepware Server Documentation ThingWorx Kepware Server Manual   Edge MicroServer   Pros Cons Typical Use case Skill Required Connection Type  Easily connect with simple scripting Requires a device running Windows or Linux Customization with Lua scripting Connecting gateway router to ThingWorx Configure settings AlwaysOn™   The ThingWorx Edge MicroServer is a binary executable available for Windows and Linux running on either ARM or x86 processors. The EMS establishes an AlwaysOn, bi-directional connection to a destination ThingWorx platform when it is started. The EMS is configured by editing a json text file to specify the target platform and credentials. The EMS uses the always on connection to provide a local HTTP server that is a reflection of the platform REST API. This local copy of the platform API allows devices that are not capable of making encrypted connections across the open internet to securely interact with the platform. The EMS package also includes the Lua Script Resource application. This application extends the ThingWorx Foundation server by connecting through the EMS HTTP server and provides a Lua interpreter that can be used to connect local resources to the ThingWorx server.   Learn more about the ThingWorx Edge MicroServer:   Connect a Raspberry Pi to ThingWorx using the Edge MicroServer Edge MicroServer Documentation   Step 2: Next Steps   Congratulations! You've successfully completed the Choose a Connectivity Method guide.   At this point, you can make an educated decision regarding which connection methods are best suited for your application and infrastructure.   The next guide in the Connect and Configure Industrial Devices and Systems learning path is Use REST API to Access ThingWorx   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Connect ThingWorx Application Development Reference Build Get Started with ThingWorx for IoT 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 ThingWorx Connectors Help Center
View full tip
This zip file contains my slides and buildable project from my Liveworx 207 developer chat presentation featuring the Thing-e Robot and raspberry pi zero integration with ThingWorx using the C SDK.
View full tip
This document provides API information for all 51.0 releases of ThingWorx Machine Learning.
View full tip
  Connect to an existing database and design a connected data model.   GUIDE CONCEPT   There are times you already have your database designed and only need to integrate the ThingWorx environment.   These concepts and steps will allow you to focus on development of your application while still allowing the ability to utilize the power of ThingWorx!   We will teach you how to create a data model around your database design and connect to that database.     YOU'LL LEARN HOW TO   How to connect an external database and created services to be used with it How to design and implement a new data model based on an external resource Using data models with database services   Note: The estimated time to complete this guide is 30 minutes.      Step 1: Examples and Strategy   If you’d like to skip ahead, download and unzip the completed example of the Aerospace and Defense learning path attached to this guide:  AerospaceEntitiesGuide1.zip.   By now, you likely know how to create a data model from scratch. You have likely already created services that work with Info Tables. What you might not have completed, is combining both a new data model, handling data in services, and connecting it all to an external database.   Our organization, PTC Defense Department, has existed for years and has an existing database setup. Developers in our organization refuse to remodel the database, so we must model the ThingWorx data model to our database schema. With ThingWorx, this is not a difficult task, but there are numerous decisions and options that we will explore in this guide.     Step 2: Database Connections   ThingWorx is based on the Java programming language and can make connections to any database that supports a Java-based connection. Dropping the JAR file for the database JDBC driver to the lib folder of Tomcat is all that is needed for connection to the ThingWorx Platform. Follow the below steps to get started creating the connection.   To establish the connection and begin working with an external database, you will need to create a Database Thing and configure the connection string and credentials. Let us start with our database connection. If you have not done so already, download the Aerospace and Defense database scripts: DatabaseApplication.zip. Use the README.txt file to create the database schema. It is based on Microsoft SQL Server, but you can configure the scripts to your database preferences.   NOTE: You will not need to connect to a database to utilize this guide as a learning utility. For your services to work, you will need to connect to a database.   1. In ThingWorx Composer, click the + New at the top-left of the screen.     2. Select Thing in the dropdown.     3. Name the Thing `DatabaseController.Facilities` and select Database as the Base Thing Template.     4.Click Save and go to the Configurations tab.   In this tab, you will enter the class name of your driver, the connection string for that database connection, and the credentials to access the database.   Keep in mind, the JDBC Driver Class Name, JDBC Connection String, and the connection Validation String values are all database type specific. For example, to connect to a SQL Server database, the below configuration can be used.   Title Description  Example   JDBC Driver Class Name  The specific class name of the driver being used for the connection.  net.sourceforge.jtds.jdbc.Driver (SQL Server) or oracle.jdbc.driver.OracleDriver (Oracle)  JDBC Connection String  The connection string to locate the database by host/port/database name.  jdbc:jtds:sqlserver://server:port/databaseName (SQL Server) or jdbc:oracle:thin:@hostname:port:databaseName (Oracle)  connectionValidationString  A simple query that should always work in a database.  SELECT GetDate() (SQL Server) or SELECT SYSDATE FROM DUAL (Oracle)   5. After entering credentials, click Save.     6. Go the Properties and Alerts tab.   The connected Property should be checked. This property informs us of the current connection to the database. The lastConnection Datetime Property should show a current timestamp. This property informs us of the last time there was a valid connection to the database. This is an easy way to confirm the connection to the database.   If you do not have a connection, work on your configurations in the Configurations tab and validate the credentials being used. If you are still having troubles, see the examples section below or use the next section for help to try a query of the database.   Help and Troubleshooting   For help finding the correct configuration for you, check out these JDBC Configuration Examples or try out this Connection String Reference for help with your connection string.   You have just established your first database connection! Now jump to the next section and let us begin to build a data model to match the database schema.   Step 3: Query Data from External Database   Now that you're connected to the database, you can begin querying the database for information and the flow of data. The queries and data shown below are based on the table scripts provided in the download.   Examples of how the ThingWorx entity should look can be seen in the SQLServerDatabaseController and OracleDatabaseController entities.   Running a Query   As you may have noticed by working in ThingWorx and developing applications, an InfoTable is often used to work with large sets of data. An InfoTable is also how data is returned from a database query. If you're expecting only 1 value in the result set, the data will be held in the first index of the InfoTable. If you're expecting rows of data coming back, expect there to be rows of information inside of the InfoTable.   Follow the steps below to set up a helper service to perform queries for the database. While other services might generate the query to be used, this helper service will be a shared execution service.   In the DatabaseController entity, go to the Services tab. Create a new service of type SQL (Query) called RunDatabaseQuery.           3. Set the Output as InfoTable, but do not set the DataShape for the InfoTable.       4. Add the following parameter: Name Base Type Required query String True       5. Add the following code to the new service:   <<query>>       6. Click Save and Continue. Your service signature should look like the below example.       You now have a service that can run queries to the database. This is also a simple method to test/troubleshoot the database connection or a quick query.   Run your service with a simple query. You might notice that no matter the fields in the result set, the InfoTable will match it based on field type and field name.   There are two ways you can go from here. You can either query the database using services that call this service, or you can create more SQL command services that query the database directly. Let's go over each method next, starting with a service to call our helper.   In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service JavaScriptQuery_PersonsTable. Set the Output as InfoTable, but do not set the DataShape for the InfoTable. Add the following code to your new service: try { var query = "SELECT * FROM Persons"; logger.debug("DatabaseController.JavaScriptQuery_PersonsTable(): Query - " + query); var result = me.RunDatabaseQuery({query:query}); } catch(error) { logger.error("DatabaseController.JavaScriptQuery_PersonsTable(): Error - " + error.message); }       5. Click Save and Continue.   Any parameter, especially those that were entered by users, that is being passed into an SQL Statement using the Database Connectors should be fully validated and sanitized before executing the statement! Failure to do so could result in the service becoming an SQL Injection vector.   This is a simple way to query the database since much of your development inside of ThingWorx was already based in JavaScript.   Now, let's utilize the second method to create a query directly to the database. You can use open and close brackets to create parameters for your query. You can also use <> as a method to mark a value that will need to be replaced. As you build your query, use [[Parameter Name]] for parameters/variables substitution and <> for string substitution.   In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service SQLQuery_GetPersonByEmail. Ensure the Output is InfoTable. Add the following code to your new service: SELECT * FROM Persons WHERE person_email = [[email]];       5. Add the following parameter:   Name Base Type Required email String True         6. Click Save and Continue.   An example of using the string replacement is as follows: DELETE FROM <> WHERE (FieldName = '[[MatchName]]'); DELETE FROM << TableName >> WHERE ( FieldName = [[MatchNumber]]);       Click here to view Part 2 of this guide.
View full tip
Procedure to configure a secure connection between Windchill and Thingworx server. Assuming Windchill and Thingworx are already configured with SSL, this video consists of detailed steps for setting up Thingworx and Windchill to trust each other.     For full-sized viewing, click on the YouTube link in the player controls.   Visit the Online Success Guide to access our Expert Session videos at any time as well as additional information about ThingWorx training and services.
View full tip
Procedure on how to configure Single Sign On (SSO) with Thingworx and Windchill, where users will be able to access Thingworx/Navigate with their  Windchill credentials. This video consist of demo and architecture of how SSO works.     For full-sized viewing, click on the YouTube link in the player controls.   Visit the Online Success Guide to access our Expert Session videos at any time as well as additional information about ThingWorx training and services.
View full tip
When I tried to set String property values with Chinese letters by using C SDK, I could see only broken characters in Thingworx. The cause of the problem is simple and it's encoding. In order to solve this problem, you need to convert encoding to UTF-8 in your C code. I used 'libiconv' library to do it. This guide is for Win32 version. If you want to make a library for other platforms such as Linux, you can create or get a library for your own by googling. How to Get the Source Code of libiconv At the moment, the most recent version of libiconv is 1.15. You can download the source code of libiconv from here. How to Build I used MS Visual Studio 2012, but the explanation can be applied to the earlier versions of MS Visual Studio and express editions. Step 1. Download the most recent version of libiconv and unzip the file. Step 2. Make a new Win32 Project. Let's say "libiconv" as the project name. Check to create directory for solution. Choose DLL as the application type and check Empty Project for additional options. Click the button "Finish" to generate the new project. Step 3. Copy files from the folders of libiconv to project folders. To build "libiconv", you need to compile three files "localcharset.c", "relocatable.c" and "iconv.c". That's the key! Copy three files "relocatable.h", "relocatable.c" and "iconv.c" in the folder "...\libiconv-1.15\lib\" to the project folder "...\libiconv\libiconv\". Copy "...\libiconv-1.15\libcharset\lib\localcharset.c" to the project folder "...\libiconv\libiconv\". Copy "...\libiconv-1.15\libcharset\include\localcharset.h.build.in" to the project folder "...\libiconv\libiconv\" and then, rename the copied "localcharset.h.build.in" to "localcharset.h". Copy "...\libiconv-1.15\windows\libiconv.rc" to the project folder "...\libiconv\libiconv\". Make folder "include" under the project folder "...\libiconv\". Copy "...\libiconv-1.15\include\iconv.h.build.in" to the project include folder "...\libiconv\include" and then, rename the copied "iconv.h.build.in" to "iconv.h". Copy "...\libiconv-1.15\config.h.in" to the project include folder "...\libiconv\include" and then, rename the copied "config.h.in" to "config.h". Copy all the header files (*.h) and definition files (*.def) in the folder "...\libiconv-1.15\lib" to the project include folder "...\libiconv\include". Step 4. Add existing items. Execute "project > Add Existing items..." at the main menu to add existing items to the project. Step 5. Project Settings. You can make 64-bit platform through configuration manager in order to generate libiconv.dll for 64-bit system. You can also make two other configurations "ReleaseStatic" and "DebugStatic" in order to generate libiconvStatic.lib as a static link library. At the project properties, change Output Directory as "$(SolutionDir)$(Configuration)_$(Platform)\" and Intermediate Directory as "$(SolutionDir)obj\$(ProjectName)\$(Configuration)_$(Platform)\". Change Include Directories as "..\include;$(IncludePath)": You have to add "BUILDING_LIBICONV" and "BUILDING_LIBCHARSET" to Peprocessor Definitions of all Platforms and of all configurations. You'd better set Runtime Library to "Multi-threaded" when building dynamic link library libiconv.dll. Then, the dependency on VC Runtime library can be controlled by the applications that will be built and dynamically linked with libiconv.dll because libiconv.dll does not need VC Runtime library but only the application that uses libiconv.dll may or may not need VC Runtime library. However, when building the static link library libiconvStatic.lib, you can choose Runtime Library option for libiconvStatic.lib depending on the application that uses libiconvStatic.lib. You have to change Precompiled Header option to "Not Using Precompiled Headers". Step 6. Tweak the source code. libiconv.rc Open libiconv.rc with text editor or the source code editor of Visual Studio IDE by double-clicking libiconv.rc in the Solution explorer and insert some code at line 4 as follows: /////////////    ADD    ///////////// #define PACKAGE_VERSION_MAJOR 1 #define PACKAGE_VERSION_MINOR 14 #define PACKAGE_VERSION_SUBMINOR 0 #define PACKAGE_VERSION_STRING "1.14" ///////////////////////////////////// You may be asked to change Line endings to "Windows (CR LF)". Then, let it do so. It will be more convenient for you if you mainly use Windows. localcharset.c Open localcharset.c and delete or comment the lines 80 - 83 as follows: //////////////////  DELETE //////////////// ///* Get LIBDIR.  */ //#ifndef LIBDIR //# include "configmake.h" //#endif /////////////////////////////////////////// iconv.c Open iconv.c and delete or comment the lines 250 - 252 and add three lines there as follows: ///////////////////////// DELETE /////////////////////// //size_t iconv (iconv_t icd, //              ICONV_CONST char* * inbuf, size_t *inbytesleft, //              char* * outbuf, size_t *outbytesleft) /////////////////////////   ADD   ////////////////////// size_t iconv (iconv_t icd,               const char* * inbuf, size_t *inbytesleft,               char* * outbuf, size_t *outbytesleft) //////////////////////////////////////////////////////// localcharset.h Open localcharset.h and delete or comment the lines 21 - 25 and add 7 lines there as follows: /////////////////////////   DELETE  //////////////////////// //#if @HAVE_VISIBILITY@ && BUILDING_LIBCHARSET //#define LIBCHARSET_DLL_EXPORTED __attribute__((__visibility__("default"))) //#else //#define LIBCHARSET_DLL_EXPORTED //#endif /////////////////////////    ADD    ////////////////////// #ifdef BUILDING_LIBCHARSET #define LIBCHARSET_DLL_EXPORTED __declspec(dllexport) #elif USING_STATIC_LIBICONV #define LIBCHARSET_DLL_EXPORTED #else #define LIBCHARSET_DLL_EXPORTED __declspec(dllimport) #endif //////////////////////////////////////////////////////////////////// config.h Open config.h in the project include folder "...\libiconv\include" and delete or comment the lines 29 - 30 as follows: ///////////////////////// DELETE /////////////////////// ///* Define as good substitute value for EILSEQ. */ //#undef EILSEQ //////////////////////////////////////////////////////// Otherwise you can redefine EILSEQ as good substitute value. iconv.h Open iconv.h in the project include folder "...\libiconv\include" and delete or comment the line 175 and add 1 line as follows: /////////////////////////  DELETE  /////////////////////// //#if @HAVE_WCHAR_T@ /////////////////////////    ADD   ////////////////////// #if HAVE_WCHAR_T //////////////////////////////////////////////////////////////////////////////// Delete or comment the line 128 and add 1 line as follows: /////////////////////////  DELETE  /////////////////////// //#if @USE_MBSTATE_T@ /////////////////////////   ADD   ////////////////////// #if USE_MBSTATE_T //////////////////////////////////////////////////////////////////////////////// Delete or comment the lines 107-108 and add 2 lines as follows: /////////////////////////  DELETE  /////////////////////// //#if @USE_MBSTATE_T@ //#if @BROKEN_WCHAR_H@ /////////////////////////  ADD  ////////////////////// #if USE_MBSTATE_T #if BROKEN_WCHAR_H //////////////////////////////////////////////////////////////////////////////// Delete or comment the line 89 and add 2 lines as follows: /////////////////////////  DELETE /////////////////////// //extern LIBICONV_DLL_EXPORTED size_t iconv (iconv_t cd, @ICONV_CONST@ char* * inbuf, //size_t *inbytesleft, char* * outbuf, size_t *outbytesleft); /////////////////////////    ADD   ////////////////////// extern LIBICONV_DLL_EXPORTED size_t iconv (iconv_t cd, const char* * inbuf,   size_t *inbytesleft, char* * outbuf, size_t *outbytesleft); //////////////////////////////////////////////////////////////////////////////// Delete or comment the lines 25 - 30 and add 8 lines as follows: /////////////////////////  DELETE /////////////////////// //#if @HAVE_VISIBILITY@ && BUILDING_LIBICONV //#define LIBICONV_DLL_EXPORTED __attribute__((__visibility__("default"))) //#else //#define LIBICONV_DLL_EXPORTED //#endif //extern LIBICONV_DLL_EXPORTED @DLL_VARIABLE@ int _libiconv_version; /* Likewise */ /////////////////////////    ADD   ////////////////////// #if BUILDING_LIBICONV #define LIBICONV_DLL_EXPORTED __declspec(dllexport) #elif USING_STATIC_LIBICONV #define LIBICONV_DLL_EXPORTED #else #define LIBICONV_DLL_EXPORTED __declspec(dllimport) #endif extern LIBICONV_DLL_EXPORTED int _libiconv_version; /* Likewise */ //////////////////////////////////////////////////////////////////////////////// How to Use When you use newly built libiconv, the only header file that you need is iconv.h. You will need to link either the import library libiconv.lib or the static library libiconvStatic.lib in your project property or write the code in one of your source file as follows: #pragma comment (lib, "libiconv.lib") or #pragma comment (lib, "libiconvStatic.lib") In the source of the application that uses this library either libiconv.dll or libiconvStatic.lib, if you don't define anything but only include iconv.h, your application will use libiconv.dll while it will use libiconvStatic.lib if you define USING_STATIC_LIBICONV before you include iconv.h in your application as follows: //#define USING_STATIC_LIBICONV #include <iconv.h> And in C SDK code, I used a "SteamSensorWithFileTransferAndTunneling" sample code and added codes in the "dataCollectionTask" function as below. void dataCollectionTask(DATETIME now, void * params) {   iconv_t ic;   char* in_buf = "Hi, 文健英";   char *to_chrset = "UTF-8";   char *from_chrset = "EUC-KR";   size_t in_size = strlen(in_buf);   size_t  out_size = sizeof(wchar_t) * in_size * 4;   char* out_buf = malloc(out_size);   // Caution: iconv's inbuf, outbuf are double pointers, so need to define separate pointers and pass addresses.   char* in_ptr = in_buf;   char* out_ptr = out_buf;   size_t out_buf_left;   size_t result;   memset(out_buf, 0x00, out_size);      ic = iconv_open(to_chrset, from_chrset);   if (ic == (iconv_t) -1)   {         printf("Not supported code \n");         exit(1);   }   printf("input len = %d, %s\n", in_size, in_buf);   out_buf_left = out_size;   iconv(ic, &in_ptr, &in_size, &out_ptr, &out_buf_left);   //printf("input len = %d, output len=%d %s\n", in_size, out_size - out_buf_left, out_buf);   iconv_close(ic);   /* 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);   properties.BigGiantString = out_buf; // Set values for String property   /* 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(); }
View full tip
Wanting to build a simple environment with ThingWorx, using a Raspbery Pi mini-computer and an Edge MicroServer (EMS), one has to bear in mind some apparently insignificant tips, that can make a huge difference in a well-connected platform.    The Raspbery Pi can have either a few sensors attached on it and/or a Sense HAT integrated with it. A Sense HAT is an add-on board for Raspbery Pi that has an 8x8 LED matrix, a five-button joystick and a sensor, gyroscope. Tips: The ThingWorx guide "Connecting ThingWorx EMS with Rasberry Pi Quickstart" can be expanded to read Sense HAT specific sensor information A Sense HAT integrated with Raspberry Pi can be accessed from anywhere, using the existing APIs to read/write Getting location information while using the Pi board (because The Sense HAT doesn't have this feature): The Raspberry Pi has several USB ports, therefore inserting a USB GPS can be used as a workaround for connecting and reading location information (or the GPIO pins could be used to connect a GPS board) To include services and properties to read Sense HAT sensors data, start from the existing LUA example.lua template and built a Pi specific one. The EMS is a pre-built application that can be installed on Windows or Linux and it provides a bridge between the remote device and the ThingWorx platform, using the REST API AlwaysOn protocol. Tips: To read data from a sensor, it is important to use the corresponding library for that sensor; if LUA scripting is used, then this library has to be easily integrated with LUA (LSR is optional with EMS; EMS can be used standalone). Using the correct library, the EMS will be able to gather the data and push it to ThingWorx. The LSR sends properties to the EMS over the HTTP(s) protocol, which converts it to the AlwaysOn Protocol, and sends it to the Platform LUA is a process manager useful if having to integrate devices from different vendors using different modes to interact To test if the LSR is working: go to Composer -> Properties tab of the remote thing, click "Manage Bindings", select the "Remote" tab, next to "Local" - here can be seen all the remote properties added to the thing by the LSR. For creating and biding more things: create the remote thing in ThingWorx and then add them to the config.lua file in the same way you have the gateway Listing any "Remote Things" that are ready to be connected, and are not associated with any Thing, yet: Monitoring; one method to try to bind them: type the name of the thing in the Identifier section of General Information of the Thing To request a local REST API call to the default EMS port 8000, from a LSR, make sure that the GET works fine (i.e for a property update:  localhost:8000/Thingworx/Things/MyThing/Properties/myString It should return you something like this: {"rows":[{"myString":""}],"fieldDefinitions":{"myString":{"name":"myString","description":"","type":"STRING","aspects":{}}}}
View full tip
Hi,   I have just been playing around with the Edge MicroServer on a couple of Raspberry Pi's.  I obviously want them connected to ThingWorx, however they stop when the SSH session closes which isn't ideal.  I thought about doing something really quick and dirty using 'nohup', but this could have lead to many running processes, and wouldn't still not have started automatically when the Pi booted.  So, I did it right instead using init.d daemon configurations.   There are two files; one for the EMS and one for the Lua Script Resource.  You need to put these in /etc/init.d, then make sure they are owned by root.   sudo chown root /etc/init.d/thingworx* sudo chgrp root /etc/init.d/thingworx*   You'll need to modify the paths in the first lines of these files to match where you have your microserver folder.  Then you need to update the init.d daemon configs and enable the services.   sudo update-rc.d thingworx-ems defaults sudo update-rc.d thingworx-ems enable sudo update-rc.d thingworx-lsr defaults sudo update-rc.d thingworx-lsr enable   You can then start (stop, etc.) like this:   sudo service thingworx-ems start sudo service thingworx-lsr start   They should both also start automatically after a reboot.   Regards,   Greg
View full tip
When using the Auto-bind section of an EMS configuration it is very important to note the difference between "gateway":true and "gateway":false. Using either gateway value, when used with a valid "name" field, will result in the EMS attempting to bind the Thing with the ThingWorx platform, and will allow the EMS to respond to file transfer and tunnel services related to the auto-bound things, but this is around where the similarities end. Non-Gateway: This type of auto-bound thing can be thought of as a placeholder because the EMS will still require a LuaScriptResource to be bound in order to respond to property/service/event related messages. There must be a corresponding Thing based on the RemoteThing template (or any RemoteThing derived template e.g. RemoteThingWithFileTransfer) on the ThingWorx server in order for the bind to succeed. There are many reasons to use this type of auto-bound thing, but the most common is to bind a simple thing that can facilitate file transfer and tunnel services but does not need any custom services, properties, or events that would be provided by custom lua scripts within the LuaScriptResource. Gateway: An auto-bound gateway can be bound to the ThingWorx platform ephemerally if there is no Thing present to bind with on the platform. To clarify, if no Things exist with the matching Thing Name on the platform, and the EMS is attempting to bind a Gateway, a Thing will be automatically created on the platform to bind with the auto-bound gateway. This newly created ephemeral thing will only be accessible through the ThingWorx REST API, and once the EMS unbinds the gateway the ephemeral thing will be deleted If there is a pre-existing Thing on the ThingWorx server, then it must be based off of the EMSGateway template in order for the bind to succeed. The EMSGateway template, used both normally and ephemerally, will provide some gateway specific services that would otherwise be inaccessible to a normal remote thing. See EMSGateway Class Documentation for more details.
View full tip
Video Author:                      Asia Garrouj Original Post Date:            June 13, 2017 Applicable Releases:        ThingWorx Analytics 8.0   Description: This video is the first of a 3 part series walking you through how to setup ThingWatcher for Anomaly Detection. In this first video you will learn the basics of how to establish connectivity between KEPServer and the ThingWorx Platform.    
View full tip
Do you trust me? if (true) { why } else      { !why } Communication between client and server can be encrypted or not. Communication between client and server can be between trusted parties or not. Both statements are independant of each other. There's no need to trust a server - but still traffic can be encrypted. There's no need to encrypt traffic - but still a server can be trusted. For secure and safe communication in an IoT environment encryption as well as trust should be an integral part of exchanging data. ​ Trust Certificates and Chains of Trust Trust establishes the identity of the parties involved, e.g. is server I'm contacting really the server it pretends to be? This can be ensured with server certificates. On the other hand, client certificates ensure that the client is actual the client it pretends to be. This can be used as an authentication approach and if the identity of the server as well as the client is confirmed, this is also known as mutual authentication. Trust is usually invoked through certificates. Certificates have a subject, usually the servername that the certificate belongs to. This can also be a wildcard subject like *.myserver.com which will be valid for all subdomains of myserver.com. A certificate can be digitally signed to ensure its identity. Usually a Certificate Authority (CA) signs the certificate. This CA can in turn be signed by another CA and so an, creating a whole chain of CAs. This chain is commonly known as the Chain of Trust or the certification path. If a certificate is not signed by a CA it's called a "self-signed certificate". These are mostly used for test scenarios, but should never be used in real production environments. Certificates can also expire by using dates like "Valid From" and "Valid To" to determine if a certificate is valid or not. In case a certificate or CA is expired, all following certificates in the Chain of Trust will no longer be considered as valid. For "commercial" certificates, certificates that are signed by an official CA like Google, Let's Encrypt or VeriSign, a Certificate Signing Request (CSR) is used. For this a key-pair is generated and the CSR is signed with the private key. The CSR contains the public key and is sent to and finally signed by the CA itself, returning the public certificate e.g. signed by VeriSign. This mechanism allows to generate certificates by preparing the main information and just having the CA sign it as a trusted authority. Key-pair All certificates consist of a key-pair - a private key and a public key. The private key is indeed very private to the server and MUST NOT be shared with anyone else. The public key is indeed very public and can be shared with anyone. The key-pair consists of mainly two very large prime numbers and some mathematical magic allows for a mathematical one-way function ​with a trap door. This function allows to en-crypt any message with the public key and to de-crypt this message with the private key. So by giving out the public key to anyone, anyone can en-crypt a message to the server but only the server alone can de-crypt it with its private key. Therefore it's important that the private key is not shared with anyone, otherwise messages can be de-crypted by anyone possessing the private key and secure communication can be compromised. This method is called public-key encryption, or asymmetric encryption (as the key for en- and de-crypting are different). For more information, check out https://en.wikipedia.org/wiki/Public-key_cryptography This key-pair is not related to any encryption while sending data between client and server. Encryption on a transport level is accomplished by using different, random keys. It's just used to generate a unique certificate with a unique fingerprint as a public certificate. The private key part is amongst other things used for signing other certificates in the Chain of Trust. Tomcat needs access to the private key of the server specific certificate, to actually verify that the certificate is authentic. However, certificates can also be used for e.g. emails where the private key is in fact used to en- or decrypt the mail on a content level! ThingWorx ThingWorx is mainly configured for server side trust. In this case all connecting clients can ensure that the identity of the ThingWorx server is a trusted one - and not a fake server or an untrusted source. Certificates and trust are usually triggered when a secure connection is established, via TLS / SSL - e.g. by calling https://<myserver.com>:443/Thingworx The default port for a HTTPS (HTTP Secure / over TLS) connection is 443. For "normal" HTTP configuration, certificates are not required. Keystore To establish trust, any client needs to know the public certificate of the ThingWorx server. This is usually stored in a keystore. In ThingWorx, Tomcat needs to be configured with the location and the password of the keystore containing the certificate. For each web-request Tomcat will then present the server certificate to the client. The client can then verify through its own keystore if the certificate is trusted or not. When operating in browsers, this is done via e.g. the Windows-Keystore. For devices a custom, e.g. a Java-Keystore is required. The keystore must contain the whole Chain of Trust as well as the server specific certificate and its key. If the Chain of Trust is not stored completely in the keystore, or the key is missing / not accessible, the certificate validation process will already fail on server side. Certificates in Windows The default Windows-Keystore is actually pre-filled with lots of Root-Certificates, which start the Chain of Trust - such as Google, VeriSign or Microsoft. Trust needs to start somewhere… If the browser can trace the CAs of certificate back to a trusted Root CA, it's indicated by a green lock and the server will be trusted. If the Root CA cannot be found, it's indicated by a red lock (not a purse) - meaning that the server is not trusted. The server can still be contacted anyway, by manually acknowleding the risks (like identity theft or credit card scams). As an example, here's the certificate for Wikipedia and its Chain of Trust, starting with the GlobalSign Root CA: Trustworthy? In the end, certificates only clarify the identity of a server. If it is trusted or not, is completely up to the user / device. This trustful relationship all comes down to the client keystore / truststore. While the presenting server holds its certificate in the keystore, the verifying client holds the trusted certificates in the truststore. Any certificate in the truststore will ensure the correct server identity. Any unknown certificate will trigger a "Are you sure?" question in the browser. And as devices usually cannot respond to such a question, communication with an untrusted server can be forbidden by default. There are also products, like PTC Navigate which will require a client certificate to not only ensure server identity, but also ensure that also specific clients are able to connect to the server. Encryption No matter if a server is trusted or not, as soon as HTTPS is used as a protocol, communication will be encrypted. The certificate plays a role, but no matter if it's in the client's truststore, TSL forces encryption. Client Hello Usually the client contacts the server and sends a Client Hello. With this it also sends a list of available cipher suites, the intended receiver (server name) and a list of available Signature Hash Algorithms to be used. Cipher suites are used to determine which algorithms are used to establish a connection. The Signature Hash Algorithms define the Hash function, like SHA256 and the key / signature, like RSA. In my environment usually the Elliptic Curve Diffie-Hellman key exchange is used to transfer public keys between server and client. During the Client Hello information about the elliptic curves are also transferred. For more information on these topics, see https://en.wikipedia.org/wiki/SHA-2 https://en.wikipedia.org/wiki/RSA_(cryptosystem) https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange https://www.youtube.com/watch?v=YEBfamv-_do (Diffie-Hellman explained) https://en.wikipedia.org/wiki/Elliptic_curve_cryptography Server Hello After receiving the Client Hello, the server sends back the Server Hello. This consists of multiple handshakes. In this phase, the server sends the preferred cipher suite (intersection of client and server suites) including the Signature Hash Algorithm to be used. In the same step the server is sending off the certificate to the client for identity validation. For establishing trust and validating the certificate, the server needs to know the private key for the server specific certificate. The server also announces in the server key exchange what public key it's using for encryption to the client. This key is not related to the certificate, but a random number from a newly generated key-pair. Keys are exchanged between server and client and vice versa via the Diffie-Hellman key exchange. Client Response The client now sends in the client key exchange what public key it's using for encryption to the server. This is also a random key transmitted via the Diffie-Hellman key exchange. Initiating Communication After announcing the public keys, both server and client will now communicate encrypted by using their custom key-pairs for asymmetric encryption of the payloads. This can also include an additional change of the cipher specification. As the public keys have been exchanged via the Diffie-Hellman key exchange, server and client are now bi-directionally communicating using each other's public key to en-crypt a message and each's own private key to de-crypt the message again. For more information, also see https://tools.ietf.org/html/rfc5246 Trust & Encryption - Hands On Do you trust me now? if (true) { why } else      { !why } To see how this all works in a ThingWorx enviroment, and how easy it actually set up what has been discussed above, see also Trust &amp; Encryption - Hands On
View full tip
Hello, Since there have been discussions regarding SNMP capabilities when using the ThingWorx platform, I have made a guide on how you can manage SNMP content with the help of an EMS. Library used: SNMP4J - http://www.snmp4j.org/ Purpose: trapping SNMP events from an edge network, through a JAVA SDK EdgeMicroServer implementation then forwarding the trap information to the ThingWorx server. Background: There are devices, like network elements (routers, switches) that raise SNMP traps in external networks. Usually there are third party systems that collect this information, and then you can query them, but if you want to catch directly the trap, you can use this starter-kit implementation. Attached to this blog post you can find an archive containing the source code files and the entities that you will need for running the example, and a document with information on how to setup and run and the thought process behind the project. Regards, Andrei Valeanu
View full tip
Hello Developer Community, We are pleased to announce pre-release availability of the ThingWorx Edge SDK for Android! The Android SDK beta is built off the Java SDK code base, but replaces the Netty websocket client with Autobahn for compatibility with Android OS.  Those familiar with the Java SDK API will feel very much at home in the Android SDK.  We recommend beginning with the included sample application.  Please watch this thread for upcoming beta releases.  b4 adds file transfers between the ThingWorx platform and Android devices and an example application. We welcome your questions and comments in the thread below!  Happy coding! Regards, ThingWorx Edge Products Team
View full tip
Developing with Axeda Artisan (for Axeda Platform, v6.8 and later) Axeda Artisan is a development tool based on the Apache Maven build system. Artisan includes authoring, management, and deployment mechanisms that define and manage the development of Axeda Platform extension points, allowing you to flexibly install, update, and uninstall many types of objects on the Axeda Platform. The Components of Artisan The Artisan framework is comprised of several components: The Axeda Platform Each instance of the Axeda Platform contains libraries and sample Artisan Projects (archetypes) that are downloaded by developers to author and deploy their own Artisan Projects. The Artisan Project An Artisan Project is a collection of content and configuration files that are used to define a set of objects that will be installed on the Axeda Platform. The Artisan Installer The Artisan Installer is a flexible, configurable application that uses the Apache Maven build life-cycle to upload the contents of an Artisan Project to the Axeda Platform. Axeda Platform APIs The Artisan Installer interacts with the Axeda Platform and uses Axeda APIs to install, upgrade, or uninstall ArtisanProjects. How You Work With Artisan The goal of using Artisan is to develop an Artisan Project that will become an object or application that runs on the Axeda Platform. There are several phases involved in creating an Artisan Project: Preparing Your Development Environment – When first working with Artisan, you need to prepare your development environment by installing or configuring Java, Apache Maven, and any other required development tools. Creating an Artisan Project – Artisan uses archetypes as the basis for Artisan Projects. Archetypes are used to generate an Artisan Project that contains the correct type of development framework, which you then modify to create your own Artisan Project: The Hello World archetype provides a sample project you can use to create common objects on the Axeda Platform. The Machine Streams archetype provides a sample project you can use to configure machine streams for your Axeda Platform. Installing an Artisan Project on the Axeda Platform – The Artisan Installer packages the contents of the Artisan Project, and deploys them on the Axeda Platform. Testing the Artisan Project – Once installed, you can test your Artisan Project to verify its functionality and identify any issues that need to be addressed. It is common for an Artisan Project to be installed on the Axeda Platform several times as issues are identified and corrected during development. Creating a Stand-alone Installer – Once ready for deployment to production, the Artisan Installer is used to create a stand-alone installer for distributing the project contents to other instances of the Axeda Platform. Where to Go from Here To begin working with the Artisan framework to create your own projects, refer to the following: Artisan Landing Page – A page hosted on the Axeda Platform that introduces Artisan and serves as a starting point for creating an Artisan Project. The Artisan Landing Page can be found at the following location: http://instance_name:port/artisan                     Where instance_name:port/ is the ip address and port of an instance of the Axeda Platform. Axeda® Artisan Developer’s Guide – A reference that introduces Artisan, describes how to prepare your development environment, and provides detailed technical information concerning creating an Artisan Project and configuring the Artisan Installer. The Axeda® Artisan Developer’s Guide is available with all Axeda product documentation from the PTC Support site, http://support.ptc.com/
View full tip
Introduction to the base EMS connections and settings, what and how the websocket connections work, security, data transfer and bandwidth.     For full-sized viewing, click on the YouTube link in the player controls.   Visit the Online Success Guide to access our Expert Session videos at any time as well as additional information about ThingWorx training and services.
View full tip
Announcements