cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 
Sort by:
  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
  GUIDE CONCEPT   This guide introduces connecting an Allen-Bradley PLC to ThingWorx Kepware Server.   YOU'LL LEARN HOW TO   Create and run a simple ladder logic application on an Allen-Bradley PLC Connect the PLC to ThingWorx Kepware Server   NOTE: The estimated time to complete this guide is 30 minutes.      Step 1: Learning Path Overview   Assuming you are using this guide as part of the   Rockwell Automation Learning Path, then you have now completed each of the following installations:        1. Connected Components Workbench       2. ThingWorx Kepware Server       3. ThingWorx Foundation (for Windows)   In this continued step, you'll now connect an   Allen-Bradley PLC   to   Connected Components Workbench   and then to   ThingWorx Kepware Server.   In a later guide, we'll propogate that information further from ThingWorx Kepware Server into ThingWorx Foundation.   NOTE: Both Rockwell Automation's Connected Components Workbench and ThingWorx Kepware Server are time-limited trials. If significant time has passed while persuing this Learning Path, you may need to reinitialize them. Consult the Troubleshooting step of this guide for more information.       Step 2: Setup PLC   This guide uses an inexpensive Allen-Bradley Micro820 PLC as a demonstration.   ThingWorx Kepware Server offers drivers for hundreds of devices, making this step the only one that contains device-specific instructions.   Read and understand installation instructions before making any electrical connections to the PLC.   1. Connect the postive lead of a 24V power supply along with a 6" test lead to Terminal 1 of the output terminal block.   2. Connect the negative lead of the power supply to Terminal 2.     3. Confirm the test lead is secure from making contact with anything conductive; it will be  connected to +24V. Power on the supply and confirm the LEDs briefly light.       4. Carefully touch the test lead to the Input 1 terminal and confirm the indicator LED for Input 1 turns on.     5. Power off the supply before continuing to the next step.       Step 3: Create PLC Project   In this step, you will create a simple PLC application. This application will connect to a ThingWorx Mashup in subsequent guides in the Learning Path.    1. After opening Connected Components Workbench, click New... in the Project section.   2. Enter ThingWorxGuide in the Name field and click Create.   3. Browse to the PLC model you are using and click Select, then Add to Project.     4. Right-click Program, then left-click Add > New LD: Ladder Diagram     5. Double-click Prog1 to open the ladder window.     Ladder Logic   You will create a simple application that will turn on output 2 when there is a signal on input 2.    1.. Right-click in the box to the left of the rung, hover over Insert Ladder Elements, then click on Direct Coil   .     2.  Click the  I/O - Micro820 tab  towards the right and select an  output coil  - this guide uses  _IO_EM_DO_02 . Then click  OK                  3. Add an input contact by right-clicking in the   box to the left of the rung, hover over   Insert Ladder Elements, then click on   Direct Contact.   4.  Click the  I/O - Micro820 tab  and scroll down to select an  input  - this guide uses  _IO_EM_DI_02 . Then click  OK .        5. The program window should now look like this:     Upload   Next, you will propagate the program to the PLC.   1. Secure the test lead then apply power to the PLC.   2. Connect an ethernet cable directly between the PLC and your Windows computer.   3. Click Device > Connect to connect to the PLC; a pop-up will appear saying the project does not match the program in the controller.     NOTE: When either your PLC or computer are restarted, they may be assigned a new IP address, requiring you to reconfigure the connection. Click the tab labled with your PLC, then click the pencil icon next to connection path, click Browse, expand the Ethernet driver, highlight the active controller, and click OK. Click Close and then Connect.       4. Click Download current project to the controller   5. Confirm overwriting any program in the controller by clicking Download.   6. After your project is downloaded, run it on the controller by clicking Yes.     7. Touch the test lead to the I-02 terminal, and your program will turn on the #2 output. You can confirm your project is working by both hearing the soft click from the PLC and seeing the output indicator turn on.       Step 4: Configure ThingWorx Kepware Server   Now that you have a simple project running on the PLC, you need to configure ThingWorx Kepware Server to monitor it.   1. Open   ThingWorx Kepware Server, right-click on   Connectivity, and click   New Channel.   2. Select   Allen-Bradley Micro800 Ethernet   from the drop-down, then click   Next.       3. Click Next to accept the defaults, and click Finish to create Channel2.   4. Click Click to add a device below Channel2, enter myPLC in the name field, and click Next.   5. Enter the IP address of your PLC, then click Next. The IP address of your PLC is shown in Connected Components Workbench in Device > Configure.       NOTE: The IP address of the PLC may change when it is power cycled and must be updated in ThingWorx Kepware Server to match   6. Click Next to accept default values for each pop-up, and click Finish to create the myPLC device.       7. Click the Click to add a static tag message.   8. Enter Coil2 in the Name field, _IO_EM_DO_02 in the Address field, change the Data Type drop-down to Boolean, and click OK.  The address must exactly match a variable name in the PLC.       9. Create a second tag by right-clicking on myPLC again and clicking New Tag.   10. Enter Coil3 in the Name field, _IO_EM_DO_03 in the Address field, select Boolean from the Data Type drop-down, and click OK.         Step 5: Troubleshooting   1. If the connection to the PLC stops working and there is a   Thumbs Down   icon next to your Properties, the   ThingWorx Kepware Server   trial edition drivers are not connected to your PLC. The trial edition stops running after 2 hours and must be stopped and restarted. Right-click on ThingWorx icon in system tray.     Click Stop Runtime service. Wait a minute for the process to stop, then click Start Runtime service.   2.  If Connected Components Workbench does not connect to PLC, check the IP address of the PLC using RS Linx Classic software that was installed as part of Connected Components  Workbench. RS Linx Classic is located Start > All Programs > Rockwell Software > RSLinx > RSLinx Classic Click AB_ETHIP-1, Ethernet and IP addresses of connected PLCs will be discovered   NOTE: A changed PLC IP Address (typically seen through Connected Components Workbench) will require an IP Address change in ThingWorx Kepware Server settings.       Step 6: Next Steps   Congratulations! You've successfully completed the   Connect to an Allen-Bradley PLC   tutorial. You've learned how to:   Create and upload a simple ladder logic application to a PLC Connect a PLC to ThingWorx Kepware Server   The next guide in the Using an Allen-Bradley PLC with ThingWorx learning path is Create an Application Key.   Learn More   Capability Resource Analyze Monitor an SMT Assembly Line     Additional Resources   For additional information on ThingWorx Kepware Server:   Resource Link Website Connecting & Managing Industrial Assets Documentation Kepware documentation Support Kepware Support site
View full tip
  Step 7: 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 { deviceId = "alstestedgething" iotHubHostname = "alsiot.azure-devices.net" registryPolicyName = "registryReadWrite" 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 8: 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:   If you're following the Azure MXChip Development Kit learning path, the next guide is Create a Thing Shape.    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 11: Users   Access to functions and information on the ThingWorx Foundation server is controlled by Users. The REST API can be used to create, list, and delete Users.   Get Usernames of all Users   The REST API exposes the ability to retrieve collections of Entities so that a UI can be dynamically updated with current data.   Required Parameters   AppKey created by your Foundation server Request   Construct the URL. Include the hostname and authentication credentials for your specific ThingWorx server as described below. The Usernames of all Users can be returned by making a GET request to this endpoint: 〈Server IP:port〉/Thingworx/Users 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... Send request parameters. Other than authentication, no other parameters are used in this GET request. Response   It is possible for the content to 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/Users appKey==64b879ae-2455-4d8d-b840-5f5541a799ae Accept:text/csv       Step 12: Troubleshooting   You should expect to get back the status code of   200 - OK   either with or without content. In the case of an error, you will receive an error message. You can use the following table to diagnose the issue.   Response Code Definition  401   - Unauthorized appKey is incorrect or missing 403   - Forbidden Content-Type request header is not set to application/json Sometimes returned instead of a 404 A Property with that name already exists on the platform 404   - Not Found Incorrect URL or API endpoint Thing or Property has not been created Incorrect ThingTemplate name Required parameter missing from request 405   - Invalid Request Incorrect request verb; for example a GET was used instead of PUT or POST 406   - Not Acceptable Invalid JSON in PUT or POST request Thing [   Thing name   ] already exists: A Thing with that name already exists on the platform 500   - Internal Server Error Content-Type request header is not set for a service execution POST, required even without a POST body Content-Type request header is not set for DELETE request, required despite the fact that DELETE does not send any content 503   - Service Unavailable Thing [] is not running RestartThing endpoint must be called Thing [] is not enabled EnableThing endpoint must be called       Step 13: Authentication Tags   There are different ways to authorize requests.   AppKey in HTTP Request Header   We recommend you place the appKey in the HTTP request header rather than passing the appKey as a URL parameter. This prevents the appKey from being written into server log files that may be seen by someone who is not authorized to modify the ThingWorx server.   HTTPie example:   http -v -j http://iotboston.com:8887/Thingworx/Things/aTestThing/Properties/CurrentTemp appKey:d0a68eff -2 cb4 -4327 -81 ea -7 e71e26 Full request headers:   GET /Thingworx/ Things /AllenTestThingFour/ Properties /CurrentTemp HTTP/ 1.1 Accept: application /json, */ * Accept- Encoding: gzip, deflate Connection: keep-alive Content- Type: application/json Host: iotboston. com: 8887 appKey: d0a68eff -2 cb4 -4327 -81 ea -7e71 e26bb   AppKey In URL as Parameter   To send an appkey in a URL request string parameter, check the   Allow Application Key as URL Parameter   checkbox in the   PlatformSubsystem   Configuration. If the ThingWorx server is using HTTPS, the parameter will be encrypted in transit, however the appKey may be comprised because full request URLs are often written to server log files.   HTTPie example:   http -v -j http://iotboston.com:8887/Thingworx/Things/AllenTestThingFour/Properties/CurrentTemp appKey==d0a68eff -2 cb4 -4327 -81 ea -7 e71e26bb645 Full request headers:   GET /Thingworx/ Things /aTestThing/ Properties /CurrentTemp?appKey=d0a68eff-2cb4-4327-81ea-7e71e26 HTTP/ 1.1 Accept: application /json, */ * Accept- Encoding: gzip, deflate Connection: keep-alive Content- Type: application/json Host: iotboston. com: 8887   HTTP Basic Auth   We do not recommend Basic Auth, because the username and password used are NOT encrypted and could be used to log into the ThingWorx platform. To demonstrate that username and password are not encrypted, copy the string in the Authorization line after   Basic   to   Base64 Decode   then click   DECODE.   HTTPie example:   http -v -j http: //i otboston.com: 8887 /Thingworx/ Things /aTestThing/ Properties /CurrentTemp -a Administrator:password1 Full request headers:   GET /Thingworx/ Things /AllenTestThingFour/ Properties /CurrentTemp HTTP/ 1.1 Accept: application /json, */ * Accept- Encoding: gzip, deflate Authorization: Basic QWRtaW5pc3RyYXRvcjpwYXNzd29yZDE= Connection: keep-alive Content- Type: application/json Host: iotboston. com: 8887     Step 14: Next Steps   Congratulations! You've successfully completed the   Use REST API to Access ThingWorx   guide. You learned how to use the REST API to:   Create new Things on a ThingWorx Foundation Server Add Properties to Things Access Property values Execute custom Services   The next guide in the Connect and Configure Industrial Devices and Systems learning path is Java SDK Tutorial.   Learn More   We recommend the following resources to continue your learning experience:      Capability Guide Build Data Model Introduction   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource    Link Community Developer Community Forum Support REST API Help Center    
View full tip
    Send data from an MXChip Developer kit to your Azure IoT Hub   GUIDE CONCEPT   Users of the MXChip IoT DevKit (a.k.a. MXChip), follow these quick steps to send temperature and humidity data from built-in IoT DevKit sensors to the Azure IoT Hub.   YOU'LL LEARN HOW TO   Connect the IoT DevKit to a wireless access point Create an Azure IoT Hub and register a device for the IoT DevKit Connect IoT Devkit to Azure IoT Hub   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 80 minutes   Step 1: Create an Azure IoT Hub   Choose +Create a resource, then choose   Internet of Things. Click   Iot Hub   from the list on the right. You see the first screen for creating an IoT hub.   Fill in the fields.   Subscription: Select the subscription to use for your IoT hub.   Resource Group: You can create a new resource group or use an existing one. To create a new one, click   Create new   and fill in the name you want to use. To use an existing resource group, click   Use existing   and select the resource group from the dropdown list.   Region: This is the region in which you want your hub to be located. Select the location closest to you from the dropdown list.   IoT Hub Name: Put in the name for your IoT Hub. This name must be globally unique. If the name you enter is available, a green check mark appears.         3. Click   Next: Size and scale   to continue creating your IoT hub.     On this screen, you can take the defaults and just click   Review + create   at the bottom.   Pricing and scale tier: You can choose from several tiers depending on how many features you want and how many messages you send through your solution per day. The free tier is intended for testing and evaluation. It allows 500 devices to be connected to the IoT hub and up to 8,000 messages per day. Each Azure subscription can create one IoT Hub in the free tier.   IoT Hub units: The number of messages allowed per unit per day depends on your hub’s pricing tier. For example, if you want the IoT hub to support ingress of 700,000 messages, you choose two S1 tier units.   Advanced / Device-to-cloud partitions: This property relates the device-to-cloud messages to the number of simultaneous readers of the messages. Most IoT hubs only need four partitions.               4. Click   Review + create   to review your choices. You see something similar to this screen.           5. Click   Create   to create your new IoT hub. Creating the hub takes a few minutes.     Step 2: Create IoT device   Navigate to the IoT Hub created and in the   IoT Devices   page, click   + New.   2. Enter the device ID used by the demo MXChip application   MyNodeDevice. Use the default settings for auto-generating authentication keys and connecting the new device to your hub. Click   Save.   3. Navigate to the device created and make a note of the device connection string, which looks like:   HostName={YourIoTHubName}.azure-devices.net;DeviceId=MyNodeDevice;SharedAccessKey={YourSharedAccessKey}.   Create Azure Storage   The ThingWorx Azure IoT Connector we will install in the next guide requires an Azure Storage Account. Follow the Microsoft documentation to   create an Azure Storage account. NOTE: Select Blob storage as the account type and the Hot Access Tier.     Step 3: Connect to Azure IoT Hub   Download the latest version of   GetStarted firmware   for IoT DevKit. Connect IoT DevKit to your computer via USB. In Windows you see a new USB mass storage device in Windows Explorer called   AZ3166. Drag and drop the   .bin   file you downloaded from step 1 into the disk named   AZ3166   and wait for IoT Devkit to restart. Internet connectivity is required to connect to Azure IoT Hub. Use AP Mode on the DevKit to configure and connect to Wi-Fi.Hold down button   B, push and release the   Reset   button, and then release button   B. Your IoT DevKit enters AP mode for configuring the Wi-Fi connection. The screen displays the service set identifier (SSID) of the DevKit and the configuration portal IP address:     5. Use a Web browser on a different Wi-Fi enabled device (computer or mobile phone) to connect to the IoT DevKit SSID displayed in the previous step. If it asks for a password, leave it empty.     6. Open   192.168.0.1   in the browser. Select or input the Wi-Fi network that you want the IoT DevKit to connect to, type the password for the Wi-Fi conection and input the device connection string you made notge of in step 1. Then click   Connect.     7. The WiFi credentials and device connection string will be saved in the IoT DevKit even after power cycliong. The following page will be displayed in the browser:     8. The IoT DevKit reboots in a few seconds. You then see the assigned Wi-Fi IP address on the screen of the IoT DevKit:     9. Wait for the IoT DevKit to connect to Azure IoT Hub and you will see it sending telemetry data including temperature and humidity value to Azure IoT Hub. The screen of the IoT Devkit would show message count and temperature/humidity data.       Step 4: Next Steps   Congratulations! You've successfully completed the   Connect MXChip to Azure IoT   guide. By following the steps in this lesson, you created an Azure IoT Hub and device.     The next guide in the Azure MXChip Development Kit learning path is Create an Application Key.   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Analyze Build a Predictive Analytics Model Build Get Started with ThingWorx for IoT   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Azure Support Page    
View full tip
  Utilize the C SDK to build an app that creates a secure connection to ThingWorx with low level device access.   Guide Concept   This project will cover using the ThingWorx C SDK to develop applications for the purpose of secure and low level development.   Following the steps in this this guide, you will be ready to develop your own IoT application with the ThingWorx C SDK.   We will teach you how to use the C programming language to connect and build IoT applications to be used with the ThingWorx Platform.       You'll learn how to   Establish and manage a secure connection with a ThingWorx server, including SSL negotiation and connection maintenance. Enable easy programmatic interaction with the Properties, Services, and Events that are exposed by Entities running on a ThingWorx server. Basic concepts of the C Edge SDK How to create an application that can communicate with other devices   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL parts of this guide is 60 minutes       Step 1: Completed Examples   Download the completed files attached to this tutorial: C_SDK.zip.   This tutorial will guide you through working with the C SDK on differing levels. Utilize this file to see a finished example and return to it as a reference if you become stuck creating your own fully flushed out application. With the C SDK, you can connect to whatever device you have at a level most programming languages wouldn't be able to. Now think of your secure system, your fighter jet, or even you communication devices. All these systems and levels need to have a way to secure transfer data and the C SDK is how we do it.   Keep in mind, this download uses the exact names for entities used in this tutorial. If you would like to import this example and also create entities on your own, change the names of the entities you create.     Step 2: Environment Setup   In order to compile C code, download the attached C compiler:  C-SDK-2-2-12-1052.zip .    Operating System          Notes Windows You will need a 3rd party compiler such as MinGW GCC, Cygwin GCC or you can follow these Microsoft instructions to download and use the Microsoft Visual C++ Build Tool. Mac Download the Apple Developer Tools. Linux/Ubuntu A compiler is included by default.   NOTE: You can use CMake, version 2.6.1 or later to build projects or make files, which then are used to build the applications that you develop with the C SDK. Before you can begin developing with the ThingWorx C SDK, you need to generate an Application Key and modify the source code file. You can use the Create an Application Key as a reference.   Modify Source File   Extract the files from the C SDK samples zip file. At the top level of the extracted files, you will see a folder called examples, which provides examples of how to utilize the C SDK. Open a terminal, go to your workspace, and create a new project. After you've created this project in your workspace, import the entire C SDK downloaded from the PTC Support site for ease of use (mainly the src folder and the CMakeList.txt file). You can start creating your connection code or open the main.c source file in the examples\SteamSensor\src directory for an example.    Operating System        Code Linux/Ubuntu gedit main.c OR vi main.c Mac open –e main.c Windows start main.c   5. Modify the Server Details section at the top with the IP address for your ThingWorx Platform instance and the application key you would like to use. Change the TW_HOST definition accordingly. Change the TW_PORT definition accordingly. Change the TW_APP_KEY definition to the keyId value saved from the last step. /* Server Details */ #define TW_HOST "https://pp-XXXXXXXXX.devportal.ptc.i" #define TW_PORT 80 #define TW_APP_KEY "e1d78abf-cfd2-47a6-92b7-37dc6dd34618" NOTE: Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a user and place the user as a member of Admins.   Compile and Run Code   To test your connection, you will only need to update the main.c in the SteamSensor example folder.   CMake can generate visual studio projects, make build files or even target IDEs such as Eclipse, or XCode. CMake generates a general description into a build for your specific toolchain or IDE.   If you have not downloaded and installed CMake, do it now at the CMake website. NOTE: CMake comes as a command line and a GUI application. The steps in this guide use the command line version only. Inside the specific example folder you would like to run, ie SteamSensor. Create a directory to build in, for this example call it cmake. mkdir cmake cd cmake 4. Run the CMake command listed below. This assumes CMake is already on your PATH. cmake -G "Visual Studio 15 2012" .. 5. CMake has now produced a set of project files which should be compatible with your development environment.  Operating System    Command                                        Notes Unix command-> make A set of make files Windows **msbuild tw-c-sdk.sln /t:build** A visual studio solution NOTE: CMake does its best to determine what version of Visual Studio you have but you may wish to specify which version to use if you have more than one installed on your computer. Below is an example of forcing CMake to use a specific version of Visual Studio: cmake -G "Visual Studio 15 2017" .. If your version of Visual Studio or other IDE is unknown, use cmake -G to see a list of supported IDEs.   You also have the alternative of opening the tw-c-sdk.sln from within Visual Studio and building in this IDE.   NOTE: By default, CMake will generate a build for the creation of a release binary. If you want to generate a debug build, use the command-> cmake -DBUILD_DEBUG=ON.   6. Once your build completes you will find the build products in the cmake directory. From here, open the project in your IDE of choice. NOTE: You should receive messages confirming successful binding, authentication, and connection after the main.c file edits have been made.       Step 3: Run Sample Code   The C code in the sample download is configured to run and connect to the Entities provided in the ThingWorxEntitiesExport.xml file. Make note of the IP address of your ThingWorx Composer instance. The top level of the exported zip file will be referred to as [C SDK HOME DIR]. Navigate to the [C SDK HOME DIR]/examples/ExampleClient/src directory. Open the main.c source file.  Operating System      Command Linux/Ubuntu gedit main.c OR vi main.c Mac open –e main.c Windows start main.c   3. Modify the Server Details section at the top with the IP address for your ThingWorx Platform instance and the Application Key you would like to use. Change the TW_HOST definition accordingly. NOTE: By default, TW_APP_KEY has been set to the Application Key from the admin_key in the import step completed earlier. Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a user and place the user as a member of the Admins security group. /* Server Details */ #define TW_HOST "127.0.0.1" #define TW_APP_KEY "ce22e9e4-2834-419c-9656-e98f9f844c784c"   4. If you are working on a port other than 80, you will need to update the conditional statement within the main.c source file. Search for and edit the first line within the main function. Based on your settings, set the int16_t port to the ThingWorx platform port. 5. Click Save and close the file. 6. Create a directory to build in, for this example call it bin.  Operating System            Command Linux/Ubuntu mkdir bin Mac mkdir bin Windows mkdir bin   7. Change to the newly created bin directory.  Operating System              Command Linux/Ubuntu cd bin Mac cd bin Windows cd bin   8. Run the CMake command using your specific IDE of choice. NOTE: Include the two periods at the end of the code as shown below. Use cmake -G to see a list of supported IDEs. cmake ..   9. Once your build completes, you will find the build products in the bin directory, and you can open the project in your IDE of choice. NOTE: You should receive messages confirming successful binding, authentication, and connection after building and running the application. 10. You should be able to see a Thing in your ThingWorx Composer called SimpleThing_1 with updated lastConnection and isConnected properties. SimpleThing_1 is bound for the duration of the application run time.   The below instructions will help to verify the connection.   Click Monitoring. Click Remote Things from the list to see the connection status. You will now be able to see and select the Entity within the list.       Step 4: ExampleClient Connection   The C code provided in the main.c source file is preconfigured to initialize the ThingWorx C Edge SDK API with a connection to the ThingWorx platform and register handlers. In order to set up the connection, a number of parameters must be defined. This can be seen in the code below.   #define TW_HOST "127.0.0.1" #define TW_APP_KEY "ce22e9e4-2834-419c-9656-ef9f844c784c #if defined NO_TLS #define TW_PORT = 80; #else #define TW_PORT = 443; #endif   The first step of connecting to the platform: Establish Physical Websocket, we call the twApi_Initialize function with the information needed to point to the websocket of the ThingWorx Composer. This function:   Registers messaging handlers Allocates space for the API structures Creates a secure websocket err = twApi_Initialize(hostname, port, TW_URI, appKey, NULL, MESSAGE_CHUNK_SIZE, MESSAGE_CHUNK_SIZE, TRUE); if (TW_OK != err) { TW_LOG(TW_ERROR, "Error initializing the API"); exit(err); }   If you are not using SSL/TLS, use the following line to test against a server with a self-signed certificate: twApi_SetSelfSignedOk();   In order to disable HTTPS support and use HTTP only, call the twApi_DisableEncryption function. This is needed when using ports such as 80 or 8080. A call can be seen below:   twApi_DisableEncryption();   The following event handlers are all optional. The twApi_RegisterBindEventCallback function registers a function that will be called on the event of a Thing being bound or unbound to the ThingWorx platform. The twApi_RegisterOnAuthenticatedCallback function registered a function that will be called on the event the SDK has been authenticated by the ThingWorx Platform. The twApi_RegisterSynchronizeStateEventCallback function registers a function that will be called after binding and used to notify your application about fields that have been bound to the Thingworx Platform.   twApi_RegisterOnAuthenticatedCallback(authEventHandler, TW_NO_USER_DATA); twApi_RegisterBindEventCallback(NULL, bindEventHandler, TW_NO_USER_DATA); twApi_RegisterSynchronizeStateEventCallback(NULL, synchronizeStateHandler, TW_NO_USER_DATA);   NOTE: Binding a Thing within the ThingWorx platform is not mandatory, but there are a number of advantages, including updating Properties while offline.    You can then start the client, which will establish the AlwaysOn protocol with the ThingWorx Composer. This protocol provides bi-directional communication between the ThingWorx Composer and the running client application. To start this connection, use the line below:   err = twApi_Connect(CONNECT_TIMEOUT, RETRY_COUNT); if(TW_OK != err){ exit(-1); }   Click here to view Part 2 of this guide.      
View full tip
    Step 8: Tasks   If you are using the built-in Tasker to drive data collection or other types of repetitive or periodic activities, create a function for the task. Task functions are registered with the Tasker and then called at the rate specified after they are registered. The Tasker is a very simple, cooperative multitasker, so these functions should not take long to return and most certainly must not go into an infinite loop.   The signature for a task function is found in [C SDK HOME DIR]/src/utils/twTasker.h. The function is passed a DATETIME value with the current time and a void pointer that is passed into the Tasker when the task is registered. After creating this function, it will need to be registered using the twApi_CreateTask function after the connection is created. Below shows an example of creating this function, registering this function, and how this function can be used.   #define DATA_COLLECTION_RATE_MSEC 2000 void dataCollectionTask(DATETIME now, void * params) { /* TW_LOG(TW_TRACE,"dataCollectionTask: Executing"); */ properties.TotalFlow = rand()/(RAND_MAX/10.0); properties.Pressure = 18 + rand()/(RAND_MAX/5.0); properties.Location.latitude = properties.Location.latitude + ((double)(rand() - RAND_MAX))/RAND_MAX/5; properties.Location.longitude = properties.Location.longitude + ((double)(rand() - RAND_MAX))/RAND_MAX/5; properties.Temperature = 400 + rand()/(RAND_MAX/40); /* Check for a fault. Only do something if we haven't already */ if (properties.Temperature > properties.TemperatureLimit && properties.FaultStatus == FALSE) { twInfoTable * faultData = 0; char msg[140]; properties.FaultStatus = TRUE; properties.InletValve = TRUE; sprintf(msg,"%s Temperature %2f exceeds threshold of %2f", thingName, properties.Temperature, properties.TemperatureLimit); faultData = twInfoTable_CreateFromString("message", msg, TRUE); twApi_FireEvent(TW_THING, thingName, "SteamSensorFault", faultData, -1, TRUE); twInfoTable_Delete(faultData); } /* Update the properties on the server */ sendPropertyUpdate(); } … twApi_CreateTask(DATA_COLLECTION_RATE_MSEC, dataCollectionTask); … while(1) { char in = 0; #ifndef ENABLE_TASKER DATETIME now = twGetSystemTime(TRUE); twApi_TaskerFunction(now, NULL); twMessageHandler_msgHandlerTask(now, NULL); if (twTimeGreaterThan(now, nextDataCollectionTime)) { dataCollectionTask(now, NULL); nextDataCollectionTime = twAddMilliseconds(now, DATA_COLLECTION_RATE_MSEC); } #else in = getch(); if (in == 'q') break; else printf("\n"); #endif twSleepMsec(5); }      Step 9: File Transfer Example    To handle file transfers, a virtual directory is created in the SteamSensor1 entity and in the [C SDK HOME DIR]/examples/FileTransferExample application directory. The source code used for this example is found in [C SDK HOME DIR]/examples/FileTransferExample/src/main.c.   Inside of the [C SDK HOME DIR]/examples/FileTransferExample folder, create the folder structure shown below: /transfer/ /transfer/incoming/ /transfer/outgoing/ Inside of the /transfer/outgoing/ directory, create and open a file with the name outgoing.txt. Once the outgoing.txt document is open, add the following text, save, and close the file: Hello. This is a file coming from the client application. Navigate to the [C SDK HOME DIR]/examples/FileTransferExample/src/main.c code and update the lines below with the appropriate information for your IP, port, and the “admin_key” Application Key’s keyId value in the ThingWorx Composer: /* Server Details */ #define TW_HOST "127.0.0.1" #define TW_PORT 80 #define TW_APP_KEY "ce22e9e4-2834-419c-9656-ef9f844c784c" To support file transfers in your client application, you must use the twFileManager_AddVirtualDir function in order to create the virtual directories in the entity with such a capability. It will also define the directories available for file operations. A virtual directory maps a unique name to an absolute path of a directory in the file system. All subdirectories of the specified directory are exposed to the server. You can define multiple virtual directories. The directories do not need to be contiguous.   Staging Directory   As an optional, but recommended step, you should set the directory that the application should use for staging when performing file transfers. This can be seen in the line below and should be done before initializing the FileManager. The default directory of the FileManager is most likely owned by root and will require a change to either the location of the staging directory and the ownership of the staging directory, or running the application as a User with the correct permissions.   twcfg.file_xfer_staging_dir = "staging"; The example provided uses the TW_SHARE_DIRECTORY macro to create two virtual directories that will act as the root directories in the virtual file system of this application are added. The client is then started as follows with the necessary TW_ADD_FILE_TRANSFER_SHAPE function being called: TW_ADD_FILE_TRANSFER_SHAPE(); TW_SHARE_DIRECTORY("in", "/transfer/incoming/"); TW_SHARE_DIRECTORY("out", "/transfer/outgoing/"); The creations of the payloads used to create the remote directories on the platform have been moved to a helper function below to make the design cleaner: int setupSystemRepo(const char * remoteInPath, const char * remoteOutPath, const char * remoteFile); After our remote directories and files have been setup, it is time to perform the file transfers. Normally, this would mean invoking the Copy service for a Subsystem, but two functions have been created to make this process easier: int twFileManager_GetFile(const char * sourceRepo, const char * sourcePath, const char * sourceFile, const char * targetRepo, const char * targetPath, const char * targetFile, uint32_t timeout, char asynch, char ** tid) int twFileManager_SendFile(const char * sourceRepo, const char * sourcePath, const char * sourceFile, const char * targetRepo, const char * targetPath, const char * targetFile, uint32_t timeout, char asynch, char ** tid) The table below displays an example of the first set of parameters:    Parameter     Example                             Description sourceRepo SystemRepository The name of FileRepository or RemoteThing to transfer the file FROM. sourcePath outgoing The path specifying the location of the source file. sourceFile The name of the source file.   targetRepo SteamSensor1 The name of FileRepository or RemoteThing to transfer the file TO. targetPath incoming The path specifying the destination location of the file. targetFile incoming.txt The name of the file at the target. This name can differ from the sourceName. timeout 15,000 The amount of time (in seconds) to wait for a synchronous transfer to complete before cancelling the transfer. async false If false, the service call will block for timeout seconds or until the transfer completes. tid incoming0123 The unique TID associated with the file.   The C SDK also provides the ability to create a FileCallback function that the FileManager will call that function when any file transfer events occur. You can provide a wildcard filter so that only file transfer Events of files that match the filter call the callback function. In addition, callbacks can be set up as “one-shots” such that the callback is unregistered automatically after it is invoked the first time.   NOTE: An optional file transfer callback is registered in the code and provided. You will see the output from the function as files are sent and received.   After running this application, you will notice a new file in the transfer/incoming folder after refreshing. This is the file that we created in the ThingWorx Composer file system for the SystemRepository Entity and was able to copy from that location to our local project. We have also sent a file to the server’s SystemRepository. The BrowseFileSystem and GetFileListing services can be used to check for the folders and files created.   twFileManager_RegisterFileCallback(fileCallbackFunc, NULL, FALSE, NULL);     Step 10: Support Other Platforms   All Websocket errors indicate some general issue communicating with the ThingWorx platform. If you experience an issue connecting, refer to the table below for a list of websocket errors, their corresponding codes, and an explanation of the issue.    Code     Message                                                                      Troubleshooting 200 TW_UNKNOWN_WEBSOCKET_ERROR An unknown error occurred on the websocket. 201 TW_ERROR_INITIALIZING_WEBSOCKET An error occurred while initializing the websocket. Check your websocket configuration parameters for validity. 202 TW_TIMEOUT_INITIALIZING_WEBSOCKET A timeout occurred while initializing the websocket. Check the status of the connection to ThingWorx. 203 TW_WEBSOCKET_NOT_CONNECTED The websocket is not connected to ThingWorx. The requested operation cannot be performed. 204 TW_ERROR_PARSING_WEBSOCKET_DATA An error occurred while parsing websocket data. The parser could not break down the data from the websocket. 205 TW_ERROR_READING_FROM_WEBSOCKET An error occurred while reading data from the websocket. Retry the read operation. If necessary, resend the data. 206 TW_WEBSOCKET_FRAME_TOO_LARGE The SDK is attempting to send a websocket frame that is too large. The Maximum Frame Size is set when calling twAPI_Initialize and should always be set to the Message Chunk Size (twcfg.message_chunk_size). 207 TW_INVALID_WEBSOCKET_FRAME_TYPE The type of the frame coming in over the websocket is invalid. 208 TW_WEBSOCKET_MSG_TOO_LARGE The application is attempting to send a message that has been broken up in to chunks that are too large to fit in a frame. You should not see this error. 209 TW_ERROR_WRITING_TO_WEBSOCKET An error occurred while writing to the Web socket. 210 TW_INVALID_ACCEPT_KEY The Accept key sent earlier from ThingWorx is not valid.     Step 11: Next Steps   Congratulations! You've successfully completed the Low Level Device Connect Guide, and learned how to utilize the resources provided in the Edge SDK to create your own application.   The next guide in the Utilizing ThingWorx to Secure Your Aerospace and Defense Systems learning path is Tracking Activities and Statistics.    Learn More   We recommend the following resources to continue your learning experience:    Capability      Guide 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 6: Building the Data Model   You can build your data model using different methods. You can build your data model where the Data Shapes match with your tables, but what you'll realize over time is that you will often need custom Data Shapes. When you query for data, you will often need data from differing tables to be in one result set. Because of this, I suggest against making your data model based on the tables. You can start the basis for your model with the tables in mind, but know that this won't be the basis for long.   Create Data Shapes   Let's start by setting up two queries and the Data Shapes to match. The first query will be to find the list of classes a student is assigned to and query will be completed here. The second query will be to find all student in an active class and we'll ask you to create it based on how we did the first one.   1. In the ThingWorx Composer, click the  + New  button in the top left.    2.  In the dropdown list, click  Data Shapes .   3. Name the Data Shape  DataShape.StudentCourses   4. Add the set of fields below. You may notice, we included information from the Person table that we might already have. This is perfectly fine based on how much data you expect to come back. This will allow you to reuse this database for other purposes later where the person information might change. This can be very beneficial when you're calling a service with this Data Shape (or InfoTable based on this Data Shape). Allowing you to keep the input simple.    Name Base Type  Additional Info   id  STRING Primary Key   person_key  STRING  N/A   person_name_first  STRING  N/A   person_name_last  STRING  N/A   course_key  STRING  N/A   course_name  STRING  N/A   course_professor  STRING  N/A   Let's add in our database query and use our new Data Shape.    1. Open the DatabaseController.Facilities entity and go to the Services tab. If you have not done so as yet, add the configuration information to allow your queries to connect to a database. 2. Create a new service of type SQL (Query) called GetStudentEnrollment. 3. Click Save and Continue to save your changes.   4. Add a parameter to the service title email. It will have a String base type and be required. 5. Add the following query to the canvas.       SELECT person_key, person_name_first, person_name_last, course_key, course_name, course_professor FROM Person person INNER JOIN PersonCourses pc ON person.person_key = pc.person_key INNER JOIN Courses courses ON courses.course_key = pc.course_key WHERE person.person_email = [[email]]​         6. For the output of the service, InfoTable should be there by default. If not, switch the output to be an InfoTable. For the Data Shape, set it to the Data Shape we just created,  DataShape.StudentCourses.   You now have a database where you can run your queries and use the responses to bind to Widgets in Mashups.    We have our database connection and a data model setup to handle our current queries. This might be where you begin to question if you would like to add Data Tables. This is more of a design choice. You might want to keep datasets in a Data Table for quick access or separation. Nevertheless, if you already have you database, you won't need many (if any) Data Tables.     Step 7: Next Steps   Congratulations! You've successfully completed the guide for   Connecting to an External Database, and learned how to use the ThingWorx Platform to connect to database, query for data, and write new data.   The next guide in the Utilizing ThingWorx to Secure Your Aerospace and Defense Systems learning path is Low Level Device Connection.   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Design Your Data Model Build Configure Permissions   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum
View full tip
  Leverage the REST API to create Things, modify Properties, execute Services and more.   GUIDE CONCEPT   This project will introduce you to the REST API utilized by the ThingWorx platform.   Following the steps in this guide, you will be able to connect to the ThingWorx platform and make REST calls to call Services, update Properties, and perform a number of actions for your IoT applications.   We will teach you how to use the ThingWorx REST API to create a more robust application. With the REST API you can leverage the full power of the ThingWorx Foundation server with simple HTTP requests. The REST API can easily be explored using a command line tool such as curl, a browser plugin like Postman, or any preferred programming language.   YOU'LL LEARN HOW TO   Create new Things on a ThingWorx Foundation Server Add Properties to Things Access Property values Execute custom Services   NOTE:   The estimated time to complete ALL 4  parts of this guide is 30 minutes.      Step 1: REST API Design   Almost every Entity and Service of ThingWorx can be accessed through the REST API. This step will review some points that are common to all ThingWorx REST API calls.   REST API Syntax   The endpoint URLs used by the REST API follow the consistent pattern shown in the diagram below.   The following table describes the individual pieces of the URL for the REST API calls.   Term Description Optional/Required? http method GET, PUT, DELETE, POST required scheme http, https required host server IP address where ThingWorx is running required port port on which the Web Server is listening for requests (default is 80) optional entity collection One of the built-in entity collection types proprietary to ThingWorx required entity name that identifies a specific characteristic required characteristic collection Names such as Property Definition, Properties VTQ, ThingName, and Service Definition optional characteristic name of the Service or Property on which to execute optional accept header format of HTTP content being requested; must be   application/json   or   text/xml   or   text/html optional content type header format of HTTP content being provided; must be   application/json,   text/csv   or   text/html required content   optional query parameters   optional   Requests   The ThingWorx REST API uses HTTP request verbs in ways common to many REST APIs:   GET   to   retrieve   information POST   for both creating a   new entity   and   executing   a service DELETE   to   remove   a Thing or Property PUT   to   change the value   of an existing entity When a REST API request requires parameters to be sent, the Content-Type header must be set to match the format of the request body.   Discovering and using Services requires using a dedicated URL. To list available Services and see their definitions, issue a   GET   to   ``` <server_ip:port>/Thingworx/Things/<name of thing>/ServiceDefinitions ``` In order to execute a listed Service issue a   POST   to   ``` <server_ip:port>/Thingworx/Things/<name of thing>/Services/<service name> ```   NOTE: The Content-Type header of a POST that executes a Service must always be set to application/json or text/xmleven if the service does not take any parameters and no content is being sent.   Responses   The following tables describe the valid Accept and Content-Type header values when making a REST API calls.   Accept Headers   If the request sends either an invalid Accept header, or no Accept header is supplied, the default response will be in text/html format.   Value Syntax JSON application/json XML text/xml HTML text/html (or omit Accept header) CSV text/csv   Content Type Headers   A Content-Type header indicating the format of data sent to ThingWorx, is required. Some POST requests require a content type header even when no data is being sent.   Value Syntax JSON application/json XML text/xml     Step 2: REST Client   In order to make calls to any REST API you need a client software. A web browser can be used to make some GET calls, but you must install extensions to modify headers or to make POST or PUT calls.   Client software options include:   cURL   is a venerable command line tool and library that is a Swiss Army Knife of dealing with web requests. And like an old Swiss Army Knife you can make it work but you might wind up hurting yourself.   Httpie   is a modern command line tool with easy to use, intuitive options. Server responses are shown in color with easy to read formatting. The examples will be given as HTTPie commands.   NOTE: The following steps in this guide use Httpie as the client software.     Step 3: Create Application Key   In this Quickstart, you will use   ThingWorx Composer   to generate an   Application Key. A device must be authenticated to send data to, or recieve data from ThingWorx. One of the most common authentication methods used with ThingWorx is by using a security token called an Application Key or   appKey. These tokens are associated with a particular user and have the same permissions as that user.   Create an Application Key   On the Home screen of Composer click   + New. In the dropdown list, click   Applications Key.   Give your Application Key a name (ie,   MyAppKey). Set the   User Name Reference   to a User you created. Update the   Expiration Date   field, otherwise it will default to   1 day. Click   Save.   A   Key ID   has been generated and can be used to make secure connections.   BEST PRACTICE: We recommend you create separate keys for every connected device, User or system. This allows better security in case of situations where you may need to revoke access from one of them.     Step 4: Create New Thing   A Thing is a basic building block used to model applications in the ThingWorx Foundation Server. All Things are based on a Thing Template, either a built-in system template or a custom Template that was previously created. With the REST API, you can create, modify, list, and delete Things. After a Thing has been created by using an API call, it must be enabled and restarted with additional API calls before it can be used.   Required Parameters   AppKey created by your ThingWorx server A name for the new Thing The name of a valid ThingTemplate that will be used to create the new Thing Request   An HTTP POST request to ThingWorx is assembled from 3 components: a URL A POST body Authentication credentials A request to ThingWorx can be made only after these 3 components are properly configured.         1.  Construct the URL.   Create a new Thing by making an   HTTP POST   to the endpoint.   <server_ip:port>/Thingworx/Resources/EntityServices/Services/CreateThing NOTE: The server_ip is the ip address of your ThingWorx Core server.        2. Required POST body parameters.   Send the name of the Thing and the name of the ThingTemplate that will define the new thing in the body of the   POST   as a JSON object. For example, the JSON object below will create a new Thing named SomeTestThing using the system template GenericThing. { "name": "SomeTestThing", "thingTemplateName": "GenericThing" }   TIP: When creating Things that will be used with the REST API, use the GenericThing ThingTemplate or a ThingTemplate based GenericThing. A RemoteThing should only be used with devices that make an AlwaysOn™ connection to a ThingWorx server using the Edge MicroServer or one of the AlwaysOn™ SDKs.        3. 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... Refer to Step 13: Authentication Tags for an overview of different authentication methods. Response   A successful call to the   CreateThing   service does not return any content in the body of the response, only an   HTTP 200   is returned.   Examples HTTPie example:   http -v http://52.201.57.6/Thingworx/Resources/EntityServices/Services/CreateThing appKey==64b879ae-2455-4d8d-b840-5f5541a799ae name=SomeTestThing thingTemplateName=GenericThing   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.   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 CreateThing endpoint has a JSON body so the header must be set to match the format of the request body.   cURL example   curl -v -H "Content-Type: application/json" -X POST -d '{"name": "SomeTestThing","thingTemplateName": "GenericThing"}' http://52.201.57.6/Thingworx/Resources/EntityServices/Services/CreateThing?appKey=d0a68eff-2cb4-4327-81ea-7e71e26bb645 Note: cURL explicitly sets the Content-Type header to application/json.     Validate   The Thing you just created is now available in the ThingWorx Composer, however before anything else can be done with your new Thing through the REST API it must be enabled and started. Follow these steps to validate that the new Thing has been created and enabled.   From the home page of Composer, click   Things, select the name of the Thing you just created, then click   General Information.   NOTE: You will see the Active checkbox is not checked indicating this Thing is not Enabled.       2. Execute EnableThing Service.   To enable your newly created Thing, make an 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/EnableThing HTTPie example   http -v -j POST http://52.201.57.6/Thingworx/Things/SomeTestThing/Services/EnableThing appKey==64b879ae-2455-4d8d-b840-5f5541a799ae         3.  Confirm new Thing is Enabled.   To update the   General Information   section of your new Thing and confirm the   Active   checkbox is now checked, refresh the page with the browser or close and re-open your Thing.         4. Restart your Thing.   After a Thing is created and whenever any changes are made to its structure, the Thing has to be restarted. Start you new Thing 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     Click  here  to view  Part 2  of this guide
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
  Send voice and text messages with Twilio.   GUIDE CONCEPT   This project will demonstrate how you can create applications that provide information to users, even when they are away from their computer. Users who are on the go can benefit from your application by receiving text and voice messages.   Following the steps in this guide, you will learn how to configure and use the Twilio Widget and explore it’s ability to send messages.   We will teach you how data can be used to send pertinent information to any cell phone.   YOU'LL LEARN HOW TO   Download and import the Twilio Widget extension Create a Thing using the Twilio Thing Template Configure the Twilio Thing to use your Twilio account Send text messages using a Service   NOTE:  The estimated time to complete this guide is 30 minutes.     Step 1: Install Twilio Extension   Download the  Twilio Extension from IQNOX.com. Note:  IQNOX is a PTC Partner and will be maintaining and supporting specific extensions going forward.  It will be necessary to create an account on the IQNOX website, but the ThingWorx extensions are free. In the lower-left side of Composer, click   Import/Export, then   Import.   In the Import From File pop-up, under   Import Option   select   Extension   from the drop-down, then click   Browse. Navigate to the .zip file you downloaded.   Click   Import   in the Import From File pop-up, then click   Close   after file is successfully imported.     Step 2: Create Twilio Thing   In this step, you will create a Thing that represents a connection with the Twilio service.   Start on the Browse, folder icon tab on the far left of ThingWorx Composer.  Under the Modeling tab, hover over Things then click the + button. Type   twilio-connector in the   Name   field.   NOTE : This name, with matching capitalization, is required for the example code which will be entered in a later step. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. In the Base Thing Template text box, click the + and select   Twilio.     Click Save.     Step 3: Configure Twilio Thing   Now that we have created a Thing to represent the Twilio connection, we will configure it with your Twilio account credentials.   When the Twilio Extension is installed, it does not include the Twilio account credentials required to send messages.   You will need Twilio account credentials to complete this step. If you do not already have a Twilio account, you can click on this link to   create a Twilio account.   Open the   twilio-connection   Thing if it is not already open. Click on the   Configuration   tab. Click the pencil icon next to the authToken   field.   Copy your AUTH TOKEN from your Twilio account dashboard.   Paste your AUTH TOKEN into the New Password and Confirm Password fields under authToken.   Click the pencil icon next to the accountSID   field. Copy your ACCOUNT SID from your Twilio account dashboard, and paste it into the New Password and Confirm Password fields under accountSID. Follow the steps in your Twilio account dashboard to get a trial phone number.   Copy your PHONE NUMBER from your Twilio account dashboard, and paste it into the callerID field.   Click Save.     Step 4: Test Twilio Thing   Now that we have created a Thing to represent the Twilio connection and configured it with Twilio account credentials, we will confirm that everything is working.   Click the   Services   tab at the top of the   twilio-connector   Thing.     Click the link to the SendSMSMessage   Service in the Services Name   column. Enter a phone number in the   to   field. Enter a test message in the   text   field.   Click the   Execute   button to send the SMS message. The service should execute without any errors within a couple of seconds and the phone number will receive your message. Click   Close   to end testing the service.     Step 5: Sample Alerting App   At this point, you have created and tested a Thing that can send text messages. This step will demonstrate sending a message when a Property Value is out of the desired range.   Import Simulated Freezer Thing   Download and unzip the attached sample Things_freezer.zip. In Composer, click the   Import/Export   icon at the lower-left of the page.   Click   Import. Leave all default values and click Browse to select the Things_freezer.twx file that you just downloaded. Click   Open, then   Import. When you see the success message, click   Close.   Explore Imported Entities   Navigate to the   freezer Thing by using the search bar at the top of the screen. Click the   Subscriptions   tab.   Click   reportFreezer under   Name. Open the   Subscription Info   tab. Select the   Enabled   checkbox.   Click   Done   then   Save   to save any changes.   Verify Data Simulation   Open the   freezer Thing and click   Properties and Alerts   tab. Click the   Set value   in the   alertedPhone Property row, in the Value column.   Enter a phone number to receive the SMS alert, then click the   Check   icon above where you entered the phone number. Click the   pencil icon   in the   temp   Property row, in the Value column. Enter a value for the temp property that is greater than 30, and click the   Check   icon. In a couple seconds, the phone number you entered will receive an alert that includes the value you entered.      Step 6: Next Steps   Congratulations!   In this guide, you learned how to:   Create a Thing using the Twilio Thing Template Configure the Twilio Thing to use your Twilio account Send text messages using a Service   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Twilio Extension Help Center
View full tip
    Step 12: Connect to Temperature Sensor   This step is optional. Additional instructions are provided for developers who are interested in interfacing with sensors.   The DHT11 and DHT22 digital temperature and humidity sensors are inexpensive and available from several sources: Adafruit Sparkfun SeeedStudio The Raspberry Pi does not come with any built-in analog to digital conversion capability and because these sensors are digital they can be interfaced easily with a Raspberry Pi. We will be using a Python library developed by Adafruit that simplifies interfacing with these sensors.   Install Adafruit Python Library for Sensors   We will use Git to download the Adafruit DHT11 Python from GitHub. Check if Git is already installed by opening a command window and typing the command: git If you see a "command not found" error message use this command to install Git: sudo apt-get install git-core If you get an error installing Git, run the command: sudo apt-get update then try to install Git again. Change into the EMS directory: cd microserver Download the Adafruit library with this command: git clone https://github.com/adafruit/Adafruit_Python_DHT.git Change into the directory that was just downloaded: cd Adafruit_Python_DHT Install Python build libraries: sudo apt-get install build-essential python-dev Build and install the library with this command: sudo python setup.py install   Connect Sensor to Raspberry Pi Power down the Raspberry Pi before making any wire connections. To prevent any flash memory corruption, enter the command shutdown -h now then wait a few seconds for it to complete before disconnecting the power supply. Use female-to-female jumper wires to connect the sensor as shown below. The black wire is connected to ground, the red wire is 5v or VCC, and the yellow wire carries is the digital signal. WARNING: Double check your connections before applying power. Mistakes can destroy the sensor and the Raspberry Pi!   3. Apply power and boot the Raspberry Pi. 4. Change into the EMS directory:   cd microserver 5. Test the sensor with this commmand:   ./Adafruit_Python_DHT/examples/AdafruitDHT.py 11 4   In a few a seconds the current temperature and humidity will be displayed. Change the 11 parameter to 22 if you are using the DHT22 sensor. The 4 parameter is the GPIO pin number of the Raspberry Pi that is conneCted to the sensor's signal pin. This command is the same command the luaScriptResource will use to get temperature and humidity readings.   Modify Lua template file A dozen lines need to be added to the file PiTemplate.lua file in the /microserver/etc/custom/templates directory.   After the line: properties.cpu_volt = { baseType="NUMBER", pushType="ALWAYS", value=0 } Add the two lines: properties.temp = { baseType="NUMBER", pushType="ALWAYS", value=0 } properties.humidity = { baseType="NUMBER", pushType="ALWAYS", value=0 } After the line: local voltCmd = io.popen("vcgencmd measure_volts core") Add the line: local sensorCmd = io.popen("./Adafruit_Python_DHT/examples/AdafruitDHT.py 11 4") After the line: properties.cpu_volt.value = s Add these 9 lines: -- set property temp and humidity local sensor = sensorCmd:read("*a") log.debug("[PiTemplate]",string.format("raw sensor %s", sensor)) s = string.match(sensor,"Temp=(%d+\.%d+)"); log.debug("[PiTemplate]",string.format("scaled temp %.1f", s)) properties.temp.value = s s = string.match(sensor,"Humidity=(%d+\.%d+)"); log.debug("[PiTemplate]",string.format("scaled humidity %.1f", s)) properties.humidity.value = s Stop and then restart luaScriptResource by using the following commands. ps -efl Will list all running processes, note the number in the PID column for ./lusScriptResource kill -9 PID# Replace PID# with number noted above and the process will be ended. Run LuaScriptResource by executing the following command: sudo ./luaScriptResource   Update Properties of PiThing   Log onto ThingWorx Foundation server. Click on the Home icon in Composer then broswse to Things > PiThing > Properties and click Manage Bindings button.   Click on the Remote tab, then drag and drop the temp and humidity Properties one at a time to the green plus sign next to Create new Properties. Click Done to close the binding window, then click Save. NOTE: The temp and humidity Properties will be updated every 30 seconds.     Step 13: Next Steps   Congratulations! You've successfully completed the Connect Raspberry Pi to ThingWorx guide, and learned how to:   Set up Raspberry Pi Install, configure and launch the EMS Connect a remote device to ThingWorx   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Manage Data Model Introduction Build Get Started with ThingWorx for IoT   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Edge SDKs and WebSocket-based Edge MicroServer (WS EMS) Help Center External Raspberry Pi Documentation  
View full tip
  Step 8: Configure Template File (Service)   Services are implemented as Lua functions. In our Lua script, Services are divided into two pieces. The first is the Service definition which consists of a Service name, inputs and output. The second part of defining a Service is the service code. The Service code is run when you execute the service.   Create Service Definition Open the PiTemplate.lua file. Append the service definition to the file. Create a service named GetSystemProperties that gets the system properties (cpu temperature, clock frequencies, voltages) from your Raspberry Pi and updates the respective properties on the Thingworx platform. Specify your output type but not the name because the name of every output from a ThingWorx service is always result. serviceDefinitions.GetSystemProperties( output { baseType= "BOOLEAN" , description = "" }, description { "updates properties" } ) NOTE: This service has no input parameters and an output that results in True if the properties were successfully updated on Thingworx.   Create Service code The Service code is run when you execute the Service. Functions in Lua are variables therefore to define the Service code, you will create a variable. The name of the Service has to match the name you specified in the Service definition.   Copy the service code below with comments explaining the logic and add append it to your template file, or download and unzip the full  PiTemplate.zip attached here. services.GetSystemProperties = function (me, headers, query, data) log.trace( "[PiTemplate]" , "########### in GetSystemProperties#############" ) queryHardware() -- if properties are successfully updated, return HTTP 200 code with a true service return value return 200 , true end function queryHardware () -- use the vcgencmd shell command to get raspberry pi system values and assign to variables -- measure_temp returns value in Celsius -- measure_clock arm returns value in Hertz -- measure_volts returns balue in Volts local tempCmd = io .popen( "vcgencmd measure_temp" ) local freqCmd = io .popen( "vcgencmd measure_clock arm" ) local voltCmd = io .popen( "vcgencmd measure_volts core" ) -- set property temperature local s = tempCmd:read( "*a" ) s = string .match(s, "temp=(%d+\.%d+)" ); log. debug ( "[PiTemplate]" , string .format( "temp %.1f" ,s)) properties.cpu_temperature.value = s -- set property frequency s = freqCmd:read( "*a" ) log. debug ( "[PiTemplate]" , string .format( "raw freq %s" ,s)) s = string .match(s, "frequency%(..%)=(%d+)" ); s = s/ 1000000 log. debug ( "[PiTemplate]" , string .format( "scaled freq %d" ,s)) properties.cpu_freq.value = s -- set property volts s = voltCmd:read( "*a" ) log. debug ( "[PiTemplate]" , string .format( "raw volts %s" , s)) s = string .match(s, "volt=(%d+\.%d+)" ); log. debug ( "[PiTemplate]" , string .format( "scaled volts %.1f" , s)) properties.cpu_volt.value = s end tasks.refreshProperties = function (me) log.trace( "[PiTemplate]" , "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In tasks.refreshProperties~~~~~~~~~~~~~ " ) queryHardware() end Save the PiTemplate.lua file. cntrl x     Step 9: Run LSR   1. Navigate from installation directory to microserver directory. cd microserver 2. Ensure that wsems is running in a separate terminal session before you start running LuaScriptResource. 3. Ensure that you have ownership to the executable luaScriptResource and executable privileges. To check ownership: Ls -la -rwxrwxr-x 1 pi pi 769058 Jun 9 17:46 luaScriptResourc NOTE: The owner of luaScriptResource should be the user you are logged in as on the Raspberry Pi.   4. Confirm you have executable privileges by running the following command: sudo chmod 775 luaScriptResource 5. Run LuaScriptResource by executing the following command: sudo ./luaScriptResource   6. The output will show an error until we create the corresponding Thing in the next step.     Step 10: Bind Remote Thing Properties   Now we need to register a Thing so your Raspberry Pi can bind to its Properties on the Thingworx Platform.   Create a Thing named PiThing that will bind the scripts.PiThing created in config.lua . Open your Composer screen. Click Things on the left-navigation and the + symbol. Enter PiThing in the Name field and click RemoteThing in the Thing Template field.   Click Save. Ensure that the Remote Thing Property is connected. Click Properties in the left-hand navigation. Verify that the isConnected Property has a value of true. This means that your Raspberry Pi is still connected and now bound to this Thing on Thingworx Platform.   Bind the remote Thing Properties. Make sure the Properties tab is selected and click Edit at the top of the PiThing. Click Manage Bindings. Select the Remote tab at the top.   Click Add All Above Properties or drag and drop the ones you need. Click Done. Click Save. Verify that the Properties were updated with readings from the Raspberry Pi. Both the Value and Default Value for the three Properties will be set to the current reading from the Raspberry Pi. Cover the Raspberry Pi and wait about a minute, then Select the Properties tab and click Refresh. You will see the cpu_temperature value change.     NOTE: The system properties from your Raspberry Pi are now being passed to the server every 30 seconds. Wait a couple of cycles to see if the values from the Raspberry Pi change. If you are impatient, manually change the value of the property using the Set button in the Composer then click Refresh to see the updated value. The value will be temporarily updated for about 30 seconds until the Raspberry Pi reports the current live value.   Troubleshooting Tips   Tip #1 If the properties are not updating, try to stop and start both the wsems and luaScriptResource services.   quit sudo ./wsems or ./luaScriptResource Tip #2 If a wsems and/or luaScriptResource is not shut down gracefully, sometimes the service is still running which can cause issues. You can search and kill any wsems/luaScriptResource services by using the following command. Re-run the GetSystemProperties to test if this fixed the issue.   ps -efl kill -9 <id#>   Step 11: View Data from Devices   In order to demonstrate how ThingWorx can render a visualization of data from connected devices, at this point in the lesson you will import a pre-configured Mashup.   On the ThingWorx server that the EMS is connected to, start on the Home tab of Composer. Import a pre-built Mashup. Download and save the pre-built Mashup XML file attached here: Mashups_PiThingMashup-v91.xml. In Composer, click the Import/Export drop-down at the bottom-left.   Click Import. Leave all default values and click Browse to select the Mashups_PiThingMashup-v91.xml file that you just downloaded. Click Open, then Import, and once you see the success message, click Close. View Mashup displaying live data. Select the home icon in the top left side of Composer, then click Mashups on the left-navigation panel. Click Mashups_PiThingMashup-v91 and you'll see the design view of the Mashup.   Click View Mashup, and you'll see the live Mashup.    TIP: You will need to allow pop-ups in your browser for the Mashup to be displayed.     Click here to view Part 4 of this guide. 
View full tip
  Step 5: Launch the EMS   1. Navigate to the microserver directory. cd .. 2. Ensure that you have ownership to the executable wsems and executable privileges. To check ownership. Ls -la -rwxrwxr-x 1 pi pi 769058 Jun 9 17:46 wsems NOTE: The account that owns the wsems executable should be used to log into the Raspberry Pi.   3. Confirm that you have executable privileges by run the following command: sudo chmod 775 wsems 4. Run the EMS. sudo ./wsems 5. Validate that your EMS successfully connected.   Depending on your logger level, your wsems execution should indicate Websocket connected in the log and the following INFO message: [INFO ] 2016-10-11 14:22:54,770 Main: Succesfully connected. Saving .booted config file   Troubleshoot Connectivity Issues   If the websocket does not connect successfully, check the following:    Issue                                               Solution WEBSOCKET CLOSED - Warning seen immediately after Websocket gets connected. Ensure that the host IP address, port and appKey of the ThingWorx composer instance are accurately set. If in the config.json you have selected the option to validate certification, then make sure the path to the certificate file is correctly set. twWs_Connect - Error trying to connect. Ensure that the host IP address, port running the ThingWorx Composer is accurately set. Check if the certification parameter is set or not. By default the WS EMS validates certificates. To ensure that the validation is performed correctly without errors, ensure that the certificates configuration parameters are set accurately with the correct path to the certificate file. If you do not wish to validate the certificate, you may explicitly set the validate parameter in certificates parameter set to false. twTlsClient_Connect - Error intializing TLS connection. Invalid certificate. Check if the ws_encryption parameter is present in your config.json file. By default, WS EMS enables TLS connection to ThingWorx platform. Ensure that the certificate file mentioned in the config.json is valid and stored in the path specified in the config.json. For debugging purposes, you can set the ssl parameter to none in ws_encryption configuration parameter. [WARN ] ... Main - Unable to connect to server. Trying .booted config file. Ensure that the host is up and running at the IP address and port number mentioned in the config.json file. Ensure that ThingWorx is running on the host address at the correct port number. Ensure that all appropriate networking ports are open and available.     Step 6: Configure Lua Script Resource (LSR)   The Lua Script Resource (LSR) is used to implement Things on the Edge device. Using the Lua Script Resource, you can define for your Raspberry Pi: Data Shapes Properties Services Tasks NOTE: The steps in this guide install the LSR on the same server (Raspberry Pi) as the EMS but it could also be installed on another server.   Launch a new terminal session that will be used to configure and launch the LSR. Navigate to etc folder. cd microserver/etc Create the config.lua file. sudo nano config.lua Set the logger level. scripts.log_level = "INFO" Turn off encryption for connection to EMS. This should only be used for testing. scripts.script_resource_ssl = false scripts.script_resource_authenticate = false Create the Edge RemoteThing. scripts.PiThing = { file = "thing.lua", template = "PiTemplate", scanRate = 1000, taskRate = 30000 }   NOTE: This configuration tells the Lua Script Resource to create a Thing called PiThing whose template definition is in PiTemplate.lua file in the path etc/customs/templates/PiTemplate.lua. You will create the template file PiTemplate.lua in the next section.   Property    Description scanRate Controls how frequently (milliseconds) properties are evaluated and pushed to the server. In our example, the Pi will check every 1 second if the values have changed. If so, the values will be pushed to the server. taskRate Controls how frequently the tasks specified in the Thing's template should be executed. In our example, the task will run every 30 seconds.   7.  Set the IP and port address of the LSR host server. scripts.rap_host = "127.0.0.1" scripts.rap_port = 8080   Sample config.lua File   Here is an example of a complete config.lua that can be used to configure the Lua Script Resource.   scripts.log_level = "INFO" scripts.script_resource_ssl = false scripts.script_resource_authenticate = false scripts.PiThing = { file = "thing.lua", template = "PiTemplate", scanRate = 1000, taskRate = 30000 } scripts.rap_host = "127.0.0.1" scripts.rap_port = 8080     Step 7: Configure Template File (Properties)   The template file is located in the microserver/etc/custom/templates directory. The template file provides a base configuration for defining Properties, Services, tasks, etc. This section will focus on defining the template file and adding Properties.   Navigate from the installation directory to the templates folder at microserver/etc/custom/templates . cd microserver/etc/custom/templates Create the file PiTemplate.lua. sudo nano PiTemplate.lua NOTE: This is the same template filename used in config.lua in the previous section. 3. Define the template. The module statement is used to define the template containing the configuration for the software component of the edge device. module ("templates.PiTemplate", thingworx.template.extend)   Parameter                                   Description templates.PiTemplate refers to the name of the template file: PiTemplate.lua thingworx.template.extend identifies the file as a template and provides base Thingworx template implementation   4. Define the Properties. For this guide, we are going to use the Raspberry Pi’s system properties like CPU temperature, clock frequency and internal voltage as sensor readings for the Remote Thing. Add the properties for these in your PiTemplate.lua file. properties.cpu_temperature={baseType="NUMBER", pushType="ALWAYS", value=0} properties.cpu_freq={baseType="NUMBER", pushType="ALWAYS", value=0} properties.cpu_volt={baseType="NUMBER", pushType="ALWAYS", value=0} NOTE: This code defines the properties cpu_temperature, cpu_freq and cpu_volt with a baseType of NUMBER. Additionally, it sets each default value to null as well as sets the pushType to ALWAYS which means that the property is always pushed to the Thingworx Server from the Raspberry Pi. The pushType can be set to ALWAYS, ON, OFF, NEVER or VALUE.   Sample PiTemplate.lua File   Here is an example of a complete PiTemplate.lua that can be used to configure the Lua Script Resource. module ("templates.PiTemplate", thingworx.template.extend) properties.cpu_temperature={baseType="NUMBER", pushType="ALWAYS", value=0} properties.cpu_freq={baseType="NUMBER", pushType="ALWAYS", value=0} properties.cpu_volt={baseType="NUMBER", pushType="ALWAYS", value=0}     Click here to view Part 3 of this guide. 
View full tip
  Connect a Raspberry Pi to ThingWorx using the Edge Micro Server (EMS).   Guide Concept   This project will introduce you to the Edge MicroServer (EMS) and how to connect your ThingWorx server to a Raspberry Pi device.   Following the steps in this guide, you will be able to connect to the ThingWorx platform with your Raspberry Pi. The coding will be simple and the steps will be very straight forward.   We will teach you how to utilize the EMS for your Edge device needs. The EMS comes with the Lua Script Resource, which serves as an optional process manager, enabling you to create Properties, Services, Events, and Subscriptions for a remote device on the ThingWorx platform.   You'll learn how to   Set up Raspberry Pi Install, configure and launch the EMS Connect a remote device to ThingWorx   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL parts of this guide is 30 minutes.    Step 1: Setup Raspberry Pi   Follow the setup instructions to get your Raspberry Pi up and running with the Raspberry Pi OS operating system. Ensure that your Pi has a valid Ethernet or Wifi connection. If your Pi is connected to a monitor/keyboard, run ifconfig from the Command Line Interface (CLI) to determine the IP address. If you are connecting remotely, probe your local network to find your Pi using one of these methods to determine the IP address. Log into your Raspberry Pi using the userid/password combination pi/raspberry.   Step 2: Install the EMS Download the MED-61060-CD-054_SP10_Microserver-Linux-arm-hwfpu-openssl-5-4-10-1509.zip attached here directly to the Raspberry Pi, or transfer it using a SFTP application such as WinSCP. After downloading the EMS zip file, unzip the archive in a suitable location on the Pi using the command below. Use the Tab key to automatically complete file names. unzip /MED-61060-CD-054_SP9_Microserver-Linux-arm-hwfpu-openssl-5-4-10-1509.zip After unzipping the distribution, a sub-directory named /microserver will be created inside the parent directory. Verify that microserver directory was created with the command ls -l   Switch into the microserver directory with the command cd microserver The microserver directory includes the following files.        File Name                    Description wsems An executable file that runs the Edge MicroServer luaScriptResource The Lua utility that is used to run Lua scripts, configure remote things, and integrate with the host system     Step 3: Create Application Key   In this step, you will be using the ThingWorx Composer to generate an Application Key. The Application Key will be used to identify the Edge Agent. The Application Key is tied to a user and has the same entitlements on the server.   Using the Application Key for the default User (Administrator) is not recommended. If administrative access is absolutely necessary, create a User and place the user as a member of the SecurityAdministrators and Administrators User Groups.   Create the User the Application Key will be assigned to.   On the Home screen of Composer click + New.   In the dropdown list, click Applications Key.   Give your Application Key a name (ie, MyAppKey). Set the User Name Reference to a User you created.   Update the Expiration Date field, otherwise it will default to 1 day. Click Save.   Step 4: Configure the EMS   The EMS consists of two distinct components that do slightly different things and communicate with each other. The first is the EMS which creates an AlwaysOn™ connection to the ThingWorx server. It binds things to the platform and automatically provides features like file transfer and tunneling.   The second is the Lua Script Resource (LSR). It is used as a scripting language so that you can add properties, services, and events to the things that you create in the EMS. The LSR communicates with your sensors or devices. The LSR can be installed on the same device as the EMS or on a separate device. For example, one LSR can be a gateway and send data from several different things to a single EMS.     Open a terminal emulator for the Raspberry Pi. Change directory to microserver/etc. cd microserver/etc Create a config.json file. EMS comes with two sample config files that can be used as a reference for creating your config.json file. The config.json.minimal file provides minimum and basic options for getting started. The config.json.complete provides all of the configuration options.   Create the config.json file in the etc folder. sudo nano config.json Edit the config.json file ws_servers - host and port address of the server hosting the ThingWorx Platform. If you are using a Developer Portal hosted server, your server hostname is listed on the dashboard. {"host":"<TwX Server IP>", "port":443} http_server - host and port address of the machine running the LSR. In this case it will be your localhost running on the raspberry pi. {"host":"127.0.0.1","port":8080, "use_default_certificate": true,"ssl": false, "authenticate": false} appKey - the application key generated from the ThingWorx server. Use the keyId generated in the previous step "Create Application Key". "appKey":"<insert keyId>" logger - sets the logging level for debugging purposes. Set to log at a DEBUG level. ("level":"INFO"} certificates - for establishing a secure websocket connection between the ThingWorx server and the EMS. A valid certificate should be used in a production environment but for debugging purposes you can turn off validation and allow self signed certificates. {"validate":false, "disable_hostname_validation": true} NOTE: To ensure a secure connection, use valid certificates, encryption and HTTPS (port : 443) protocol for establishing a websocket connection between the EMS and the ThingWorx Platform. 5. Exit and Save. ctrl x   Sample config.json File   Replace host and appKey with values from your hosted server.   { "ws_servers": [{ "host": "pp-2007011431nt.devportal.ptc.io", "port": 443 }], "appkey": "2d4e9440-3e51-452f-a057-b55d45289264", "http_server": { "host": "127.0.0.1", "port": 8080, "use_default_certificate": true, "ssl": false, "authenticate": false }, "logger": { "level": "INFO" }, "certificates": { "validate": false, "disable_hostname_validation": true } }     Click here to view Part 2 of this guide. 
View full tip
Connect and Monitor Industrial Plant Equipment Learning Path   Learn how to connect and monitor equipment that is used at a processing plant or on a factory floor.   NOTE: Complete the following guides in sequential order. The estimated time to complete this learning path is 180 minutes.   Create An Application Key  Install ThingWorx Kepware Server Connect Kepware Server to ThingWorx Foundation Part 1 Part 2 Create Industrial Equipment Model Build an Equipment Dashboard Part 1 Part 2
View full tip
  Connect Devices and Equipment Using Industry-Standard Protocol Drivers in ThingWorx   GUIDE CONCEPT   This guide has step-by-step instructions for connecting ThingWorx Kepware Server to ThingWorx Foundation.   This guide will demonstrate the ease of connecting edge industrial equipment to ThingWorx Foundation without installing any software on production equipment.   We will also show how connecting different systems and devices improves operations through the creation of business intelligence.     YOU'LL LEARN HOW TO   Connect ThingWorx Kepware Server to ThingWorx Foundation Secure the connection with an Application Key Create an IndustrialGateway Thing Map ThingWorx Kepware Server Tags to ThingWorx Foundation Thing Properties Visualize Data from connected digital assets   Note: The estimated time to complete this guide is 30 minutes     Step 1: Installation   Download the ThingWorx Kepware Server   executable application from MyKepware. If you desire installation instructions, you may find them in the attached guide:  install-thingworx-kepware-server.zip . Navigate to   START   ->   PTC. Click   ThingWorx Kepware Server 6 Configuration.                           For additional information on ThingWorx Kepware Server, click   Help -> Server Help   on the Menu Bar.         Step 2: Create Gateway   To make a connection between ThingWorx Kepware Server and Foundation Server, you must first create a   Thing.   WARNING: To avoid a timeout error, create a Thing in ThingWorx Foundation BEFORE attempting to make the connection in ThingWorx Kepware Server.   In ThingWorx Foundation Composer, click   Browse > Modeling -> Things.   Click   + NEW. In the   Name   field, type   IndConn_Server, including matching capitalization. In the   Description   field, enter an appropriate description, such as   Industrial Gateway Thing to connect to ThingWorx Kepware Server. If the Project field is not already set, search for and select PTCDefaultProject. In the   Base Thing Template   field, search for and select   IndustrialGateway.   Click   Save.     Step 3: Create an AppKey   To secure the connection between ThingWorx Foundation and ThingWorx Kepware Server, you need to utilize an   Application Key.   In ThingWorx Foundation, click   Browse > Security -> Applications Keys.   Click   + New. In the   Name   field, type   IndConn_AppKey. If Project is not already set, search for and select PTCDefaultProject. Set   User Name Reference   to the   Administrator   User. Click   Yes   on the warning pop-up.   Assign an   Expiration Date   that is far enough in the future to not interfere with your trial.   Click   Save.   Under   Key ID, click the   page   icon to the right of the Application Key string to copy it.     Step 4: Connect to Foundation   Now that you’ve created an IndustrialGateway Thing and an Application Key, you can configure ThingWorx Kepware Server to connect to ThingWorx Foundation.   Return to the   ThingWorx Kepware Server   Windows application. Right-click   Project. Select   Properties….   In the   Property Editor   pop-up, click   ThingWorx. In the   Enable   field, select   Yes   from the drop-down. In the   Host   field, enter the   IP address   or   URL   of your ThingWorx Foundation server. Enter the   Port   number. If you are using the "hosted" Developer Portal trial, enter   443.     In the   Application Key   field, copy and paste the Application Key you just created. In the   Trust self-signed certificates   field, select   Yes   from the drop-down. In the   Trust all certificates   field, select   Yes   from the drop-down. In the   Disable encryption   field, select   No   from the drop-down if you are using a secure port. Select   Yes   if you are using an http port. Type   IndConn_Server   in the   Thing name   field, including matching capitalization. If you are connecting with a remote instance of ThingWorx Foundation and you expect any breaks or latency in your connection, enable   Store and Forward. Click   Apply   in the pop-up. Click   Ok.   In the ThingWorx Kepware Server   Event   window at the bottom, you should see a message indicating   Connected to ThingWorx.     NOTE: If you do not see the "Connected" message, repeat the steps above, ensuring that all information is correct. In particular, check the Host, Port, and Thing name fields for errors.     Click  here  to view  Part 2  of this guide.
View full tip
  Step 5: Bind Industrial Tag   Now that you've established a connection, you can use ThingWorx Foundation to inspect all available information on ThingWorx Kepware Server.   ThingWorx Kepware Server includes some information by default to assist you with verifying a valid connection with ThingWorx Foundation.   Create New Thing   In ThingWorx Foundation, click   Browse > Modeling > Industrial Connections.   Click   IndConn_Server. At the top, click   Discover. The Discover option is exclusive to Things inheriting the   IndustrialGateway Thing Template   and displays information coming from ThingWorx Kepware Server.   Expand   Channel1. Click   Device1. On the right, you’ll see Tag1 and Tag2, which are pre-defined Tags to assist with connectivity testing.   Click the checkbox next to   Tag1. Click   Bind to New Entity.   In the   Choose Template   pop-up, select   RemoteThing   and click   OK.   Finalize New RemoteThing   You’ll now be in an interface to create a new Thing with a predefined Property based on ThingWorx Kepware Server Tag1.   Type   IndConn_Tag1   in the   Name   field. In the   Description   field, enter an appropriate description, such as   Thing with a property fed from an Kepware Server Tag. The   Base Thing Template   has been automatically set to   RemoteThing. The   Implemented Shapes   has been automatically set to   IndustrialThingShape.   If Project is not already set, search for and select PTCDefaultProject.   Click   Save.   Test Connection   The IndConn_Tag1 Thing you created now has a Property with a value that will change with each update from ThingWorx Kepware Server.   The Tag1 we utilized is a 'ramp' and therefore, the value will increase at regular intervals.   At the top, click   Properties and Alerts. Under   Inherited Properties, you will see entries for both   RemoteThing   and   IndustrialThingShape. The Property   isConnected   is checked, indicating a connection from Foundation to ThingWorx Kepware Server. The Property   IndustrialThing   has been automatically set to   IndConn_Server. Notice the predefined Property named   Channel1_Device1_Tag1.   Click   Refresh   repeatedly. You’ll see the value increase with each Refresh. This represents data being simulated in ThingWorx Kepware Server.   Step 6: Log to Value Stream   Now that you have explored the Properties of   IndConn_Tag1, you’ve seen how ThingWorx Kepware Server feeds information to ThingWorx Foundation.   To get an even better indication of changes and confirm continued connectivity, we will log the changes to a Value Stream in order to record the values with a TimeStamp.   Create Value Stream   In ThingWorx Foundation, click   Browse > Data Storage > Value Streams.   Click   + New.   In the   Choose Template   pop-up, select   ValueStream. Click   OK. Type   IndConn_ValueStream   in the   Name   field. In the   Description   field, enter an appropriate description, such as   Value Stream to record changes from ThingWorx Kepware Server. If Project is not already set, search for and select PTCDefaultProject. Click   Save.   Bind Value Stream   Return to the   IndConn_Tag1   Thing. At the top, select   General Information. In the   Value Stream   field, search for and select   IndConn_ValueStream.   At the top, select   Properties and Alerts.   Click   Channel1_Device1_Tag1. A new set of options will expand from the right.   Check the box for   Persistent. Check the box for   Logged.   In the top-right, click the   Check   button to close the expanded options. Click   Save.   All changes to the Tag1 Property fed from ThingWorx Kepware Server are now stored and TimeStamped to the   IndConn_ValueStream.     Step 7: Visualize the Data   We'll now create a Mashup to visualize the record of information from ThingWorx Kepware Server.   In ThingWorx Foundation, click   Browse > Visualization > Mashups.   Click   +New.   In the   New Mashup   pop-up, leave the default selections and click   OK.   In the   Name   field, type   IndConn_Mashup. If Project is not already set, search for and select PTCDefaultProject.  At the top, click   Save.   At the top, click   Design.   At the top-left, ensure the   Widgets   tab is selected.   In the   Filter Widgets   field at the top-left, type   line. Drag-and-drop a   Line Chart   onto the central canvas area.     Add Data   At the top-right, ensure the   Data   tab is active.   Click the   +   button.   In the   Entity Filter   field, search for and select   IndConn_Tag1. In the   Services Filter   field, type   queryprop. Click the   right-arrow   button beside   QueryPropertyHistory. The QueryPropertyHistory Service of the IndConn_Tag1 Thing will appear on the right in the Selected Services field. Check the box under   Execute on Load   in the Selected Services field.   Click   Done. Note that the   QueryPropertyHistory Service   now appears on the right side Data tab. On the top-right Data tab, expand   Things_IndConn_Tag1 > QueryPropertyHistory > Returned Data.   Drag-and-drop   All Data   from the QueryPropertyHistory Service from the right onto the   Line Chart   in the center.   In the   Select Binding Target   pop-up, select   Data.   Configure Chart Properties   Click the   Line Chart   to select it. In the bottom-left Properties, type   xaxisfield   in the filter. Expand the drop-down for   XAxisField.   Select   timestamp. At the top, click   Save. Click   View Mashup. (You may have to enable pop-ups in your browser.)   The IndConn_Mashup will show you the recorded history of Property changes that came from ThingWorx Kepware Server.   Because the Tag1 Example is a ramp, you’ll notice a slowly-increasing value in the Line Chart.   Reload   the Mashup's browser-tab to see the value increase even further.   NOTE: If the Mashup visualization is blank, confirm your connection to ThingWorx Kepware Server. Return to the Test Connection section of the "Bind Industrial Tag" step.     Step 8: Next Steps   Congratulations! You've successfully completed the   Connect Industrial Devices and Systems   guide.   You've learned how to:   Connect ThingWorx Kepware Server to ThingWorx Foundation Secure the connection with an Application Key Create an IndustrialGateway Thing Map ThingWorx Kepware Server Tags to ThingWorx Foundation Thing Properties Visualize Data from connected digital assets   Learn More   Capability Resource Connect Connect to an Allen-Bradley PLC   Additional Resources   For additional information on ThingWorx Kepware Server:   Resource Link Documentation Kepware documentation Support Kepware Support site
View full tip
  Connect an ESP8266 WiFi module using the Arduino programming environment and the ThingWorx REST API.   Guide Concept   This project will introduce the utilities ThingWorx provides for connections to an Adafruit Feather.   Following the steps in this guide, you will have a fully configured setup between your Adafruit Feather and the ThingWorx platform to begin your IoT development.   We will teach you how to utilize the ThingWorx REST API and the Arduino programming language to connect your Adafruit Feather for IoT application development.   You'll learn how to   Connect an ESP8266 WiFi module to a ThingWorx server Use the Arduino programming environment with the ThingWorx REST API   NOTE:  The estimated time to complete this guide is 30 minutes.      Step 1: Install Software   Arduino   There are three pieces of software to install before getting started with the ThingWorx-specfic code: Install FTDI USB driver. If you have connected development boards to your PC in the past you probably already have this installed. The latest Arduino IDE full install will also install the driver. NOTE: SparkFun has an excellent FTDI Driver Installation guide.   3. Arduino IDE - version 1.6.4 or later recommended. 4. Install ESP8266 addon into Arduino IDE. 5. The SparkFun Setting Up the Arduino IDE Tutorial is a great guide to getting started with their board. 6. Adafruit also has a great with their board Testing a Wifi Connection Tutorial.   When everything is set-up correctly and you are able to upload and see the Blink demo flashing the LED on the board you are ready to move to the next step.   ThingWorx Foundation Server   Start, and Launch your ThingWorx Foundation server. Log into Composer.  You will need a ThingWorx appKey to authorize the board.  Follow these instructions in Create an Application Key to create an appKey that you will copy into the source code in the next step.       Step 2: Set up Arduino IDE, Developer Board, and ThingWorx Server   Once you are able to run the blink test sketch, your IDE and board are set-up correctly. To learn how to run the blink test, read the SparkFun Board Instructions and the Adafruit board instructions.   Arduino IDE   Before you will be able to run the code below that connects a developement board to a ThingWorx Foundation server, you will need to modify the code with four pieces of information specific to your environment. You will need:   A WiFi access point SSID The correct password for the WiFi access point The IP address or URL of a ThingWorx Foundation Server A valid appKey created by your ThingWorx Foundation Server. To create an appKey, follow these instructions to Create An Application Key   Create a new sketch in the Arduino IDE then copy and paste the code below into the IDE.   Modify the WiFi Definitions and the ThingWorx server definitions shown in the code with your specficic information then save the sketch with a new name. The next step will describe what you should see when you upload and run the code on your developer board.   /** * * ESP8266_ThingWorx_REST_Demo.ino * * * (c) PTC, Inc. 2016-2020 * */ #include <Arduino.h> #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <WiFiClientSecureBearSSL.h> ////////////////////// // WiFi Definitions // ////////////////////// const char WiFiSSID[] = "Liberty454"; // WiFi access point SSID const char WiFiPSK[] = "Flutie22"; // WiFi password - empty string for open access points ////////////////////////////////////////////// // ThingWorx server definitions // // modify for a specific platform instance // ////////////////////////////////////////////// const char TWPlatformBaseURL[] = "https://pp-2007011431nt.devportal.ptc.io"; const char appKey[] = "2d4e9440-3e51-452f-a057-b55d45289264"; //////////////////////////////////////////////////////// // Pin Definitions - board specific for Adafruit board// //////////////////////////////////////////////////////// const int RED_LED = 0; // Thing's onboard, red LED - const int BLUE_LED = 2; // Thing's onboard, blue LED const int ANALOG_PIN = A0; // The only analog pin on the Thing const int OFF = HIGH; const int ON = LOW; // this will set as the Accept header for all the HTTP requests to the ThingWorx server // valid values are: application/json, text/xml, text/csv, text/html (default) #define ACCEPT_TYPE "text/csv" ///////////////////// //Attempt to make a WiFi connection. Checks if connection has been made once per second until timeout is reached //returns TRUE if successful or FALSE if timed out ///////////////////// boolean connectToWiFi(int timeout){ Serial.println("Connecting to: " + String(WiFiSSID)); WiFi.begin(WiFiSSID, WiFiPSK); // loop while WiFi is not connected waiting one second between checks uint8_t tries = 0; // counter for how many times we have checked while ((WiFi.status() != WL_CONNECTED) && (tries < timeout) ){ // stop checking if connection has been made OR we have timed out tries++; Serial.printf(".");// print . for progress bar Serial.println(WiFi.status()); delay(2000); } Serial.println("*"); //visual indication that board is connected or timeout if (WiFi.status() == WL_CONNECTED){ //check that WiFi is connected, print status and device IP address before returning Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); return true; } else { //if WiFi is not connected we must have exceeded WiFi connection timeout return false; } } ////////////////////////// //create a name for the board that is probably unique by appending last two bytes of MAC address //return name as a String /////////////////////////////// String getUniqueDeviceName(){ String uniqueName; uint8_t mac[WL_MAC_ADDR_LENGTH]; WiFi.macAddress(mac); // WiFi does NOT need to be connected for this call String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) + String(mac[WL_MAC_ADDR_LENGTH - 1], HEX); macID.toUpperCase(); uniqueName = "ESP8266Board-" + macID; Serial.println("DeviceID>" + uniqueName); return uniqueName; } /////////////////////////////// // make HTTP GET to a specific Thing and Propertry on a ThingWorx server // thingName - Name of Thing on server to make GET from // property - Property of thingName to make GET from // returns HTTP response code from server and prints full response /////////////////////////////// int httpGetPropertry(String thingName, String property){ std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure); client->setInsecure(); HTTPClient https; int httpCode = -1; String response = ""; Serial.print("[httpsGetPropertry] begin..."); String fullRequestURL = String(TWPlatformBaseURL) + "/Thingworx/Things/"+ thingName +"/Properties/"+ property +"?appKey=" + String(appKey); https.begin(*client,fullRequestURL); https.addHeader("Accept",ACCEPT_TYPE,false,false); Serial.println("GET URL>" + fullRequestURL +"<"); // start connection and send HTTP header httpCode = https.GET(); // httpCode will be negative on error if(httpCode > 0) { response = https.getString(); Serial.printf("[httpGetPropertry] response code:%d body>",httpCode); Serial.println(response + "<\n"); } else { Serial.printf("[httpGetPropertry] failed, error: %s\n\n", https.errorToString(httpCode).c_str()); } https.end(); return httpCode; } /////////////////////////////// // makes HTTP POST to platform to CreateThing service using input string as the new Things's name. // Returns server response code /////////////////////////////// int createThing(String nameOfThing){ std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure); client->setInsecure(); HTTPClient https; int httpCode = -1; String response = ""; Serial.print("[createThing] begin..."); String fullRequestURL = String(TWPlatformBaseURL) + "/Thingworx/Resources/EntityServices/Services/CreateThing?appKey=" + String(appKey); https.begin(*client,fullRequestURL); https.addHeader("Accept",ACCEPT_TYPE,false,false); https.addHeader("Content-Type","application/json",false,false); Serial.println("POST URL>" + fullRequestURL + "<"); // start connection and send HTTP header httpCode = https.POST("{\"name\": \""+ nameOfThing +"\",\"thingTemplateName\": \"GenericThing\"}"); // httpCode will be negative on error if(httpCode > 0) { response = https.getString(); Serial.printf("[createThing] response code:%d body>",httpCode); Serial.println(response + "<\n"); } else { Serial.printf("[createThing] POST... failed, error: %s\n\n", https.errorToString(httpCode).c_str()); } https.end(); return httpCode; } /////////////////////////////// // make HTTP POST to ThingWorx server Thing service // nameOfThing - Name of Thing to POST to // endPoint - Services URL to invoke // postBody - Body of POST to send to ThingWorx platform // returns HTTP response code from server /////////////////////////////// int postToThing(String nameOfThing, String endPoint, String postBody){ std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure); client->setInsecure(); HTTPClient https; int httpCode = -1; String response = ""; Serial.print("[postToThing] begin..."); String fullRequestURL = String(TWPlatformBaseURL) + "/Thingworx/Things/"+ nameOfThing +"/Services/"+ endPoint +"?appKey=" + String(appKey); Serial.println("URL>" + fullRequestURL + "<"); https.begin(*client,fullRequestURL); https.addHeader("Accept",ACCEPT_TYPE,false,false); https.addHeader("Content-Type","application/json",false,false); Serial.println("[postToThing] POST body>" + postBody + "<"); // start connection and send HTTP header httpCode = https.POST(postBody); // httpCode will be negative on error if(httpCode > 0) { response = https.getString(); Serial.printf("[postToThing] response code:%d body>",httpCode); Serial.println(response + "<\n"); } else { Serial.printf("[postToThing] POST... failed, error: %s\n\n", https.errorToString(httpCode).c_str()); } https.end(); return httpCode; } void setup() { pinMode(RED_LED, OUTPUT); pinMode(BLUE_LED, OUTPUT); Serial.begin(115200); Serial.setDebugOutput(true); Serial.println(); Serial.println(); Serial.println(); Serial.printf("Starting...\n"); for(uint8_t t = 4; t > 0; t--) { Serial.printf(" WAIT %d...\n", t); Serial.flush(); delay(1000); } connectToWiFi(10); } void loop() { String thingName = getUniqueDeviceName(); //unique name for this Thing so many work on one ThingWorx server while (WiFi.status() == WL_CONNECTED) { //confirm WiFi is connected before looping as long as WiFi is connected int getResponseCode = httpGetPropertry(thingName, "SomeNumber"); if (getResponseCode == 404){ // a 404 means connected, but either no Thing or no property // first we will try to create a new Thing on the platform int postResp = createThing(thingName); // saving the response code for retry logic in the future // the newly crated Thing has to be enabled postResp = postToThing(thingName,"EnableThing",""); //POST to EnableThing endpoint with no body // after the new Thing is enabled it must be restarted postResp = postToThing(thingName,"RestartThing",""); //POST to RestartThing endpoint with no body // add a property to the Thing 3rd parameter is ugly because required quotes are escaped with backslashes postResp = postToThing(thingName,"AddPropertyDefinition", "{\"name\":\"SomeNumber\",\"type\":\"NUMBER\"}"); //POST body contains JSON object with property name and property type // after changes to a Thing's structure it must be restarted postResp = postToThing(thingName,"RestartThing",""); //POST to RestartThing endpoint with no body } delay(2000); }// end WiFi connected while loop Serial.printf("****Wifi connection dropped****\n"); WiFi.disconnect(true); delay(10000); connectToWiFi(10); }     Step 3: Run Arduino Demo   Click on the right arrow in the Arduino IDE toolbar to upload and start the sketch. Note:The compile and upload process will take almost a minute and will show [ 100% ] when it is completed successfully. 2. After the upload is complete, click on Tools > Serial Monitor and select 115200 baud from the drop down in the lower right.            Check Connection on ThingWorx Server   Open the Composer window of your ThingWorx Foundation server and click on the browse folder icon, then Things.   You will see a Thing named "ESP8266Board-XXXX" with XXXX replaced by the last 4 digits of your boards WiFi MAC address. Click on the Thing then click the Properties and Alerts tab in the left column. Click the pencil "Set value" icon in the value column and enter a number in the text box. Click the "Check" button to set the value.   Open the Arduino Serial monitor window, and you will see the value you just entered on the platform shown in the serial output.   Step 4: Next Steps   Congratulations! You've successfully completed the Connect an Arduino Developer Board Quickstart.   This guide has given you the basic tools to:   Set up Arduino IDE Run Arduino demo Check connection on ThingWorx Server   Learn More   We recommend the following resources to continue your learning experience:    Capability Guide Connect Use REST API to Access ThingWorx Build Data Model Introduction   Additional Resources   If you have questions, issues, or need additional information, refer to:    Resource Link Community Developer Community Forum Support REST API Help Center
View full tip
    Step 4: Write Data to External Database You’ve connected to the database, you’re able to query the database. Now let’s handle inserting new data into the database. The update statements 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 an Insert 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 your shared execution service. In the   DatabaseController   entity, go to the   Services   tab.   Create a new service of type SQL (Command) called   RunDatabaseCommand. Keep the Output as   Integer. Add the following parameter:  Name           Base Type       Required command String True 5. Add the following code to your new service: <<command>> 6. Click   Save and Continue. Your service signature should look like the below example. You now have a service that can run commands to the database. Run your service with a simple insert. There are two ways to 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 the helper. In the Services tab of the   DatabaseController   entity, create a new service of type JavaScript. Name the service   JavaScriptInsert_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 command = "INSERT INTO Persons (person_key, person_name_first, person_name_last, person_email, person_company_name, " + "person_company_position, person_addr1_line1, person_addr1_line2, person_addr1_line3, person_addr1_city, person_addr1_state, " + "person_addr1_postal_code, person_addr1_country_code, person_addr1_phone_number, person_addr1_fax_number, person_created_by, " + "person_updated_by, person_created_date, person_updated_date) VALUES ('" + key + "', '" + name_first + "', '" + name_last + "', '" + email + "', '" + company_name + "', '" + company_position + "', '" + addr1_line1 + "', '" + addr1_line2 + "', '" + addr1_line3 + "', '" + addr1_city + "', '" + addr1_state + "', '" + addr1_postal_code + "', '" + addr1_country_code + "', '" + addr1_phone_number + "', '" + addr1_fax_number + "', '" + created_by + "', '" + updated_by + "', '" + created_date + "', '" + updated_date + "')"; logger.debug("DatabaseController.JavaScriptInsert_PersonsTable(): Query - " + command); var result = me.RunDatabaseCommand({command: command}); } catch(error) { logger.error("DatabaseController.JavaScriptInsert_PersonsTable(): Error - " + error.message); } 5. Add the following parameter:  Name                                   Base Type           Required key String True name_first String True name_last String True company_name String True company_position String True addr1_line1 String True addr1_line2 String True addr1_line3 String True addr1_city String True addr1_state String True addr1_postal_code String True addr1_country_code String True addr1_phone_number String True addr1_fax_number String True created_by String True updated_by String True created_date String True updated_date String True 6. Click   Save and Continue. Any parameter, especially those that were entered by users, that is being passed into a 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. Now, let’s utilize a second method to create a query directly to the database. You can use open and close brackets for parameters for the insert. You can also use   <>   as a method to mark a value that will need to be replaced. As you build your insert statement, use [[Parameter Name]] for parameters/variables substitution and <<string replacement >> for string substitution. In the Services tab of the   DatabaseController   entity, create a new service of type SQL (Command).   Name the service   SQLInsert_PersonsTable. Add the following code to your new service: INSERT INTO Persons (person_key ,person_name_first ,person_name_last ,person_email ,person_company_name ,person_company_position ,person_addr1_line1 ,person_addr1_line2 ,person_addr1_line3 ,person_addr1_city ,person_addr1_state ,person_addr1_postal_code ,person_addr1_country_code ,person_addr1_phone_number ,person_addr1_fax_number ,person_created_by ,person_updated_by ,person_created_date ,person_updated_date) VALUES ([[key]] ,[[name_first]] ,[[name_last]] ,[[email]] ,[[company_name]] ,[[company_position]] ,[[addr1_line1]] ,[[addr1_line2]] ,[[addr1_line3]] ,[[addr1_city]]]] ,[[addr1_state]] ,[[addr1_postal_code]] ,[[addr1_country_code]] ,[[addr1_phone_number]] ,[[addr1_fax_number]] ,[[created_by]] ,[[updated_by]] ,[[created_date]] ,[[updated_date]]); 4. Add the following parameter:  Name                                  Base Type       Required key String True name_first String True name_last String True company_name String True company_position String True addr1_line1 String True addr1_line2 String True addr1_line3 String True addr1_city String True addr1_state String True addr1_postal_code String True addr1_country_code String True addr1_phone_number String True addr1_fax_number String True created_by String True updated_by String True created_date String True updated_date String True 5. Click   Save and Continue. Examples of insert services can be seen in the provided downloads.   Step 5: Executing Stored Procedures There will be times when a singular query will not be enough to get the job done. This is when you'll need to incorporate stored procedures into your database design. ThingWorx is able to use the same SQL Command when executing a stored procedure with no data return and a SQL query when executing a stored procedure with an expected result set. Before executing these services or stored procedures, ensure they exist in your database. They can be found in the example file provided. Execute Stored Procedure Now, let's create the service to handle calling/executing a stored procedure. If you are expecting data from this stored procedure, use   EXEC   to execute the stored procedure. If you only need to execute the stored procedure and do not expect a result set, then using the   EXECUTE   statement is good enough. You're also able to use the string substitution similar to what we've shown you in the earlier steps. In the   DatabaseController   entity, go to the   Services   tab. Create a new service of type SQL (Command) called   RunAssignStudentStoredProcedure. Add the following parameter:  Name                      Base Type        Required student_key String True course_key String True 4. Add the following code to your new service: EXECUTE AddStudentsToCourse @person_key = N '<<person_key>>' , @course_key = N '<<course_key>>' ;   You can also perform this execute in a service based on JavaScript using the following code: try { var command = "EXECUTE AddStudentsToCourse " + " @student_key = N'" + student_key + "', " + " @course_key = N'" + course_key + "'" ; logger.debug( "DatabaseController.RunAssignStudentStoredProcedure(): Command - " + command); var result = me .RunDatabaseCommand({command:command}); } catch( error ) { logger. error ( "DatabaseController.RunAssignStudentStoredProcedure(): Error - " + error .message); } 5. Click   Save and Continue. Execute Stored Procedure for Data Let's create the entity you will use for both methods. This can be seen in the example below:   In the   DatabaseController   entity, go to the   Services   tab. Create a new service of type SQL (Query) called   GetStudentCoursesStoredProcedure. Set the Output as   InfoTable, but do not set the DataShape for the InfoTable. Add the following parameter:  Name                    Base Type        Required course_key String True 5. Add the following code to your new service: EXEC GetStudentsInCourse @course_key = N '<<course_key>>'   You can also perform this execute in a service based on JavaScript using the following code: try { var query = "EXEC GetStudentsInCourse " + " @course_key = N'" + course_key + "'" ; logger.debug( "DatabaseController.GetStudentCoursesStoredProcedure(): Query - " + query ); var result = me.RunDatabaseQuery({ query : query }); } catch( error ) { logger. error ( "DatabaseController.GetStudentCoursesStoredProcedure(): Error - " + error .message); } 6. Click   Save and Continue. You've now created your first set of services used to call stored procedures for data. Of course, these stored procedures will need to be in the database before they can successfully run. Step 6: Next Steps Congratulations! You've successfully completed the guide for   External Database, and learned how to use the ThingWorx Platform to connect to database, query for data, and write new data. Learn More We recommend the following resources to continue your learning experience:  Capability       Guide Build Design Your Data Model Build Configure Permissions Additional Resources If you have questions, issues, or need additional information, refer to:  Resource           Link Community Developer Community Forum
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