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

Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X

IoT Tips

Sort by:
    Use ThingWorx Kepware Server as an OPC UA Client   GUIDE CONCEPT   This guide will explain how ThingWorx Kepware server can function as both an OPC UA Server, and a client to a remote OPC UA Server.   Following the steps in this guide, you will create a OPC UA server in Azure, then we will teach you how to use data from the OPC UA server in ThingWorx.       YOU'LL LEARN HOW TO   Create an OPC UA Server in Azure Configure Kepware as on OPC UA Client Connect Kepware to ThingWorx Foundation Monitor OPC UA data in ThingWorx Composer   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 60 minutes     Step 1: Overview Diagram   In this guide, ThingWorx Kepware Server will serve as both an OPC UA client, and a ThingWorx Foundation client. ThingWorx Kepware Server is able to connect through firewalls to provide a seamless, end-to-end connection from an OPC UA server to ThingWorx Composer. Two ThingWorx Kepware Server instances can be configured to provide a tunnel for transporting machine data across the internet.       This guide will show how to create an OPC UA server in Azure, then browse the server data using Kepware. We will create a ThingWorx Thing with a Property that dynamically represents the value on the remote server.     Step 2: Install ThingWorx Kepware Server   In addition to OPC UA, ThingWorx Kepware Server includes over 150 factory-automation protocols. ThingWorx Kepware Server communicates between industrial assets and ThingWorx Foundation, providing streamlined, real-time access to OT and IT data — whether that data is sourced from on-premise web servers, off-premise cloud applications, or at the edge. This step will download and install ThingWorx Kepware Server. Download the ThingWorx Kepware Server executable installer. Right-click on the installer and select Run as administrator. Click Yes in the pop-up asking if you want to proceed. Select your Language and click OK.     On the "Welcome" screen, click Next.     Accept the End-User License Agreement and click Next.     Set the destination folder for the installation and click Next.     Set the Application Data Folder location and click Next. Note that it is recommended NOT to change this path.     Select whether or not you'd like a Shortcut to be created and click Next.     On the "Vertical Suite Selection" screen, keep the default of Typical and click Next.     On the "Select Features" screen, keep the defaults and click Next.     The "External Dependencies" screen simply lists everything that will be installed; click Next.     On the "Default Application Settings" screen, leave the default of Allow client applications to request data through Dynamic Tag address and click Next.     On the “User Manager Credentials” screen, set a unique strong password for the Administrator account and click Next. Note that skipping setting a password can leave your system less secure and is not recommended in a production environment.     Click Install to being the installation.     Click Finish to exit the installer.       Step 3: Create Industrial Gateway   To make a connection between ThingWorx Kepware Server and ThingWorx Foundation, you must first create a Thing.    In ThingWorx Composer, click Browse. On the left, click Modeling -> Things.     Click + NEW. In the Name field, enter IndConn_Server, including matching capitalization.     If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. In the Base Thing Template field, enter indus, then select the IndustrialGateway Thing template from the sorted list. Click Save.   Step 4: Connect Kepware to ThingWorx   This step will get ThingWorx Kepware Server set-up and connected to ThingWorx Foundation.   Now that you have created an Industrial Gateway Thing, you can configure ThingWorx Kepware Server to connect to ThingWorx Foundation.   Follow the steps to Create an Application Key and note the value. The appKey will be used in the the next step. Open the ThingWorx Kepware Server Configuration Windows application, then right-click on 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 URL or IP address of your ThingWorx Foundation server, without http:// or https://. Enter the Port number.       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 another server that uses TLS - URL begins with https://. Select Yes if you are using a ThingWorx Foundation server without TLS - URL begins with http:// 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.     Step 5: Connect OPC UA Server to Kepware   Now that you have created an Industrial Gateway Thing, and ThingWorx Kepware Server is connected to ThingWorx Foundation, we can connect an OPC UA server to Kepware   Follow the steps to create an OPC UA server in Azure. Enter Resource Group, click Review + create.     Click Create.     In about a minute, the deployment success screen will be displayed.     Click Go to resource, and copy FQDN.     Open ThingWorx Kepware Server Configuration.     Right-click, then click New Channel. Scroll down to select OPC UA Client, then click Next.     Click Next twice to accept default settings, then enter the FQDN copied earlier. Add :50000 to the end of the domain name.     Click Next to accept all defaults. Click Yes to trust the certificate.   Click here to view Part 2 of this guide.
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
  Step 7: Import Extension   In the ThingWorx Composer. in the bottom left, click Import/Export, then select Import.   NOTE: The build produces a zip file in AuthenticatorExample->build->distributions folder. This zip file will be required for importing the extension.          2. For the Import Option field, select Extension.            3. Click Browse and choose the zip file in the distributions folder (located in the Eclipse Project's build directory).       4. Click Import to finalize the import.   Navigate to New Authenticator   Navigate to and select Security > Authenticators.            2. You will now see your CustomizedAuthenticator Authenticator as a option to view/edit.            3. Click Edit or View to see this new Authenticator. You wil notice the priority is 1.   Troubleshooting   If your import did not get through with the two green checks, you may want to modify your metadata.xml or java code to fix it depending on the error shown in the logs.     Issue Solution JAR Conflict arises between two similar jars JAR conflicts arise when a similar jar is already present in the Composer database. Try to remove the respective jar resources from the metadata.xml. Add these jars explicitly in twx-lib folder in the project folder inside the workspace directory. Now, build the project and import the extension in ThingWorx Composer once again. JAR is missing Add the respective jar resource in metadata.xml using the ThingWorx->New Jar Resource. Now, build the project and import the extension in ThingWorx Composer once again. Minimum Thingworx Version [ 7.2.1] requirements are not met because current version is: 7.1.3 The version of SDK you have used to build your extension is higher than the version of the ThingWorx Composer you are testing against. You can manually edit the configfiles->metadata.xml file to change the Minimum ThingWorx version to your ThingWorx Composer version.     Step 8: Integrating Custom Authentication   Integration can be handled in different methods based on your security needs and architecture. The Authenticator we created works with the demo site we provided in the download.   Create ThingWorx User   Let's create the User that we will be processing login attempts.   In the ThingWorx Composer, click the + at the top left of the screen.   Select User in the dropdown.   Set the Project (ie, PTCDefaultProject) and enter the Name for this new user as TwxUser. Enter the Password for the new user to something easy to remember (ie, 2020Password2021).   Click Save.   Create Logger   Create a helpful logger for authentication attempts.   Create a Thing named AuthenticationStamper to go with the LoginHelper variable in the earlier Java source code. Ensure this new Thing inherits from the RemoteThing Match the properties for the AuthenticationStamper with the two properties in the below image.   Save the changes.   Create Login Helper   Create a stream for authentication attempts for helpful tracking. Create a ValueStream named AuthenticationStream and Save the Entity. In the Properties and Alerts section of the ValueStream, click Manage Bindings.   Setup the binding to match the below configurations. Bind the properties to the AuthenticationStamper Thing.   Save the changes made to the ValueStream.   Demo Page Login   With a browser, open the TestSite.html web page found in the Demo directory of the download. You should see a login page similar to that as the below image.   Enter the name of the user we created, TwxUser. Enter the password for the user. We suggested setting this to Password2019. Click Submit. You will now be authenticated and logged in.     Step 9: Next Steps   Congratulations! You've successfully completed the Create An Authentication Extension tutorial, and learned how to:   Install the Eclipse Plugin and Extension SDK Create and configure an Extension project Create Authentication Application Build and import an Extension   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Application Development Tips & Tricks   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Extension Development Guide    
View full tip
  Guidelines for selecting the optimal method for connecting to ThingWorx   GUIDE CONCEPT   In the world of IoT application development, connectivity refers to the infrastructure and protocols which connect devices to the cloud or network. Edge devices handle the interface between the physical world and the cloud.   ThingWorx provides you with several different tools for connecting to the Thingworx platform.   This guide is designed as an introduction to these tools, and will help you determine which to choose based on your specific requirements.   YOU'LL LEARN HOW TO   Pros and cons of different connection methods The connection method best suited for some typical applications Where to find detailed information about any connection method   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes   Step 1: Connectivity Method Options   There are many factors that will influence your decision about the ideal mechanism to connect to ThingWorx. On this page we compare and contrast different methods and give examples for where each one is a natural fit.   Connectivity Method Developer Benefit REST API Integrate seamlessly using dynamically-generated API calls Azure IoT Hub Connector Connect devices that use Azure IoT Hub Edge SDKs Build full-featured integrations for any platform ThingWorx Kepware Server Connect out-of-the-box with over 150 protocol drivers for industrial equipment Edge MicroServer Establish bi-directional connectivity with this complete, ready-to-run agent   REST API   Pros Cons Typical use case Skills Required Connection Type  Web developer can easily create integration ThingWorx cannot trigger action on the edge Push data from small devices to ThingWorx REST API development Request/Response   Using the ThingWorx REST API is an easy way for low-capability devices to connect with a ThingWorx platform. Any edge device that can make an HTTP POST can read and update properties or execute services on a ThingWorx platform. The disadvantage of this method is that it is one way from edge to platform. There is no way for the platform to initiate a service on the remote device and properties are only updated when the edge device initiates a connection with ThingWorx.   Learn more about the ThingWorx REST API:   Use REST API to Access ThingWorx Using the Connect an Arduino Developer Board tutorial REST API Documentation   Azure IoT Hub Connector   Pros Cons Typical use Case Skills Required Connection Type  Easily connect devices that use Azure IoT Hub Adds dependency and cost to application Add ThingWorx for devices connected with the Azure cloud Azure edge development AlwaysOn™   The diagram illustrates device-to-cloud integration with the Azure IoT Hub.   The ThingWorx Azure IoT Hub Connector establishes network connections to both ThingWorx Foundation and the Azure IoT Hub. Data flows in from devices, through the Azure IoT Hub hosted in the cloud, to the ThingWorx Azure IoT Hub Connector configured for a specific ThingWorx instance. The ThingWorx Azure IoT Hub Connector translates messages from the Azure IoT Hub format, to the native ThingWorx format and uses an established AlwaysOn connection to forward the information to ThingWorx Foundation.   Azure IoT Hub   Connect Azure IoT Devices   Edge SDKs   Pros Cons Typical Use case Skill Required Connection Type  Fully integrate device or remote system with ThingWorx platform Most developer flexibility All functionality must be developed by programmer Full customization or tight integration required Application development in Java, C, or .Net AlwaysOn™   These SDKs are developer tools that wrap the protocol used to connect to the ThingWorx Platform. There are SDK's available for Java, C, and .Net languages. The Edge MicroServer uses the C SDK internally. All SDKs use the ThingWorx AlwaysOn binary protocol together with the HTTP WebSocket protocol for transport. WebSocket connections can operate through a firewall allowing two-way, low latency communication between the device and server. The SDKs support the following key concepts that allow a Thing developed with an SDK to be a full-fledged entity in the ThingWorx environment:   Remote properties — Entities that define the types, identities, and values from a device or remote system Services — Actions that can be performed on demand by a device or remote system Events — Data that is sent to a subscribed device or remote system whenever the Event is triggered   You can choose from any of the SDK's to create a custom application that meets their exact requirements.   C SDK   The C SDK is the most lightweight of all the SDKs and will result in an application that uses the least amount of RAM, frequently requiring less than 200kB. It is the only SDK that is distributed as source code, allowing compilation of C SDK applications on any platform even those without an operating system.   Learn more about the C SDK:   C SDK Tutorial C SDK Documentation   Java SDK   The Java SDK is designed for portability and simplicity to ease connecting any Java-enabled device or system to ThingWorx. The Java SDK is provided as .jar files and sample Java source code. Any system that can run Java 1.7.51 or later should be able to build and run the example applications.   Learn more about the Java SDK:   Java SDK Tutorial Java SDK Documentation   .Net SDK   The .Net SDK is provided as .dll files with sample Visual C# project files and source code. Any system that can run Microsoft NET 3.5 SP1 Framework development environment should be able to build and run the example applications.   Learn more about the .Net SDK:   .Net SDK Documentation   ThingWorx Kepware Server   Pros Cons Typical Use case Skill Required Connection Type  Easily connect to hundreds of different types of industrial equipment Requires computer running Windows physically connected to device Adding ThingWorx to an industrial setting Configure settings AlwaysOn™   The ThingWorx Kepware Server Windows client lets users quickly and easily connect real-time, bi-directional industrial controls data to the ThingWorx IoT Platform via the ThingWorx AlwaysOn protocol. ThingWorx services enable users to browse, read, write, and interact with ThingWorx Kepware Server, and includes intuitive tools that simplify the modeling of industrial things.   Learn more about the ThingWorx Kepware Server:   Connect Industrial Devices and Systems ThingWorx Kepware Server Documentation ThingWorx Kepware Server Manual   Edge MicroServer   Pros Cons Typical Use case Skill Required Connection Type  Easily connect with simple scripting Requires a device running Windows or Linux Customization with Lua scripting Connecting gateway router to ThingWorx Configure settings AlwaysOn™   The ThingWorx Edge MicroServer is a binary executable available for Windows and Linux running on either ARM or x86 processors. The EMS establishes an AlwaysOn, bi-directional connection to a destination ThingWorx platform when it is started. The EMS is configured by editing a json text file to specify the target platform and credentials. The EMS uses the always on connection to provide a local HTTP server that is a reflection of the platform REST API. This local copy of the platform API allows devices that are not capable of making encrypted connections across the open internet to securely interact with the platform. The EMS package also includes the Lua Script Resource application. This application extends the ThingWorx Foundation server by connecting through the EMS HTTP server and provides a Lua interpreter that can be used to connect local resources to the ThingWorx server.   Learn more about the ThingWorx Edge MicroServer:   Connect a Raspberry Pi to ThingWorx using the Edge MicroServer Edge MicroServer Documentation   Step 2: Next Steps   Congratulations! You've successfully completed the Choose a Connectivity Method guide.   At this point, you can make an educated decision regarding which connection methods are best suited for your application and infrastructure.   The next guide in the Connect and Configure Industrial Devices and Systems learning path is Use REST API to Access ThingWorx   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Connect ThingWorx Application Development Reference Build Get Started with ThingWorx for IoT Experience Create Your Application UI   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support ThingWorx Connectors Help Center
View full tip
    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 4: Install and Configure   Before you install the plugin, ensure that software requirements are met for proper installation of the plugin.   Open The Eclipse IDE and choose a suitable directory as a workspace. Go to the menu bar of the Eclipse window and select Help->Install New Software… After the Install window opens, click Add to add the Eclipse Plugin repository. Click Archive… and browse to the directory where the Eclipse Plugin zip file is stored and click Open. NOTE: Do not extract this zip file. Enter a name (for example, Eclipse Plugin).   Click OK. Ensure that the Group items by category checkbox is not selected. Select ThingWorx Extension Builder in the items list of the Install window. Click Next and the items to be installed are listed. Click Next and review the license agreement. Accept the license agreement and click Finish to complete the installation process. If a warning for unsigned content is displayed, click OK to complete the installation process. Restart Eclipse. When Eclipse starts again, ensure that you are in the ThingWorx Extension perspective. If not, select Window->Perspective->Open Perspective->Other->ThingWorx Extension, then click OK.     NOTE: Opening any item from File->New->Other…->ThingWorx will also change the perspective to ThingWorx Extension.   You are ready to start a ThingWorx Extension Project!   Step 5: Create Extension Project   In this tutorial, you will create a ThingWorx extension that performs authentication based on your security needs.   While in the ThingWorx Extension Perspective, go to File->New->Project. Click ThingWorx->ThingWorx Extension Project.   Click Next. Enter the Project Name (for example, AuthenticatorExample). Select Gradle or Ant as your build framework. Enter the SDK location by browsing to the directory where the Extension SDK is stored. Enter the Vendor information (for example, ThingWorx Labs). Select the JRE version to 1.8. Click Finish. Your newly created project is added to the Package Explorer tab. The information from ThingWorx Extension Properties is used to populate the metadata.xml file in your project. The metadata.xml file contains information about the extension and details for the various artifacts within the extension. The information in this file is used in the import process in ThingWorx to create and initialize the entities.   Create New Authenticator   Select your project and click New -> Authenticator to create a new Authenticator.   In the new window, enter AwesomeCustomAuthenticator for the Name.   If no Server is available, create a Server using any available option. You will not need that for this guide. This Server option might be utilized based on your later needs. Enter a description to your Authenticator, such as Sample Authenticator that validates against the Thingworx User. Select Finish. You will be able to check these settings within the metadata.xml file inside of the configfiles  directory.   You will now need to add the stubs for the authenticate, issueAuthenticationChallenge, and matchesAuthRequest methods. See below for sample code and descriptions.   Method Description Constructor Needed to instantiate new objects of type AwesomeCustomAuthenticator. Instance member data/variable values in your Authenticator will not be available across requests. initializeEntity This method is called when the Authenticator Thing is saved in ThingWorx Composer, e.g. saving configuration table updates. authenticate The logic/implementation that is used to authenticate a HTTP request. issueAuthenticationChallenge Handles logic which follows authentication failure (e.g. logging an error). matchesAuthRequest This method determines if this Authenticator is valid for the authentication request type.   Below provides more information about each of these methods and some example source code:   Constructor:   A new instance of custom Authenticator class is created to handle each new HTTP request for authentication. Upon importing a custom Authenticator extension, that Authenticator is registered into AuthenticatorManager and can be managed in the ThingWorx Composer with the other system authenticators. When that custom Authenticator is enabled, it will be used in conjunction with the other configured Authenticators to attempt to authenticate HTTP requests. Any static data for each new authentication instance should be thread safe. Best to avoid putting very much logic here, even calls to get configuration or instance data (use authenticate method instead).   initializeEntity:   Read configuration data into properties as needed for Authenticator challenges. Write the LDAP server address to some static property for use across all future instances for use in Authenticator challenges. This would be a way to ensure the LDAP server location is configurable from within ThingWorx Composer. Best to update this only once (e.g. for when the first connection is made).   authenticate:   If the authentication logic/implementation fails to authenticate the HTTP request due to error in the logic or the HTTP request contained invalid data that does not pass authentication, then this implementation should throw an exception.   Example code below:   @Override public void authenticate(HttpServletRequest request, HttpServletResponse response) throws AuthenticatorException { String username = request.getHeader("User"), password = request.getHeader("Password"); if(username.isEmpty() || password.isEmpty()) throw new AuthenticatorException("User login info is empty"); try { // This section logs the latest login time and login user to a thing called MyThing // Subscribing to these properties via DataChange event will allow this information to be stored Thing LoginHelper = (Thing) EntityUtilities.findEntity("MyThing", ThingworxRelationshipTypes.Thing); LoginHelper.setPropertyValue("LatestLoginUser", new StringPrimitive(username)); LoginHelper.setPropertyValue("LatestLoginTime", new DatetimePrimitive(DateTime.now())); _logger.warn(DateTime.now() + " -- " + username + " login attempt"); // Checks that user exists and is enabled; throws exception if can't validate // May want to create user in ThingWorx if they don't exist AuthenticationUtilities.validateEnabledThingworxUser(username); // Checks that user exists and validates credentials through all configured DirectoryServices // (one is the internal directory of ThingWorx users, one could be LDAP if configured); // throws exception if can't validate AuthenticationUtilities.validateCredentials(username, password); // REQUIRED: tells rest of ThingWorx which user is logged in for purposes of permissions, etc. this.setCredentials(username); } }   issueAuthenticationChallenge:   This may not be used at all, or it may be used for alerting or logging. May be used for constructing and sending a response to the client so the client can ask the user to enter credentials again (i.e. authentication challenge). matchesAuthRequest:   Example code below. This sample code for Authenticator to automatically login the user with default username/password when specific URI used in web browser.   @Override public boolean matchesAuthRequest(HttpServletRequest httpRequest) throws AuthenticatorException { String requestURI = httpRequest.getRequestURI(); // Must access it from this URL and not from /Thingworx/Runtime/index.html#mashup=LogoutButtonMashup as // the Request URI in the latter case is always going to show as /Thingworx/Runtime/index.html if (requestURI.equals("/Thingworx/Mashups/LogoutButtonMashup")) return true; else return false; }   Below is another example of how to implement the matchesAuthRequest method. Of course, it’s not a safe method. Nevertheless, it provides input into a different way to handle things.   @Override public boolean matchesAuthRequest(HttpServletRequest request) throws AuthenticatorException { try { // DON'T DO THIS by itself -- getHeader returns null if it can't find the header, // so this is unsafe and may block other authenticators from attempting String value1 = request.getHeader("User"); String value2 = request.getHeader("Password"); // DO ADD THIS - this is safe // Optionally add some logging statement here to inform of missing headers if(value1 == null || value2 == null) return false; return true; } catch(Exception e) { // This won't normally hit. This is really for other, more complicated validation processes throw new AuthenticatorException("Missing headers"); } }   Step 6: Build Extension   You can use either Gradle or Ant to build your ThingWorx Extension Project.   Build Extension with Gradle   Right click on your project ->Gradle (STS)->Tasks Quick Launcher.   Set Project from the drop-down menu to your project name and type Tasks as build. Press Enter. This will build the project and any error will be indicated in the console window.   Your console window will display BUILD SUCCESSFUL. This means that your extension is created and stored as a zip file in your_project->build->distributions folder.   Build Extension with Ant   Go to the Package explorer -> your_project->. Right click on build-extension.xml->Run As->Ant Build.   Your console output will indicate BUILD SUCCESSFUL similar to the below text: build: [echo] Building AuthenticatorExample extension package... BUILD SUCCESSFUL Total time: 770 milliseconds   NOTE: This will build your project and create the extension zip in the AuthenticatorExample->build->distributions folder of your project.     Click here to view Part 3 of this guide.  
View full tip
  Build authentications extensions quickly and add to the security of your application.   GUIDE CONCEPT   Extensions enable you to quickly and easily add new functionality to an IoT solution. Extensions can be service (function/method) libraries, connector templates, functional widgets, and more.   These pointers and steps will enable you to maintain focus on development of your own application and still utilize the power of ThingWorx for other purposes at the same time.   When to Utilize:   You have your own login from outside of ThingWorx but you want to leverage ThingWorx user management You are using an identity provider other than ThingWorx You need to support passing of credentials in headers/query string parameters which ThingWorx doesn’t support out-of-the-box   Concept   Whether you would like ThingWorx to handle the security for your application, have an application you want ThingWorx to pump data into, or would just like to utilize ThingWorx features in your own application, external authentication can be a great way to integrate your application with ThingWorx. This guide will focus in on how to create an authentication middle man between a system you have already developed (or are in the middle of creating) and connect it to the ThingWorx Platform. In a provided demo website, you will login (with the provided credentials) and validate your user profile and password with ThingWorx. This setup shows the simple integration between ThingWorx and an application you would like to connect to the ThingWorx Platform.   YOU'LL LEARN HOW TO   Install the Eclipse plugin and extension SDK Create authentication application Build and import an extension   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 Example   Download the completed files for this tutorial: AuthenticationExtension.zip   This tutorial will guide you through security concepts within ThingWorx. 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.   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. The download contains three directories (Source, CompletedExtension, and Demo). See below for the information about each directory.     Directory Description Source The completed project and source code to be utilized as a comparison or ready to go pre-built extension. CompletedExtension A completed and built extension that is based on the steps utilized in the latter steps. The zip file in this directory can be imported directly. Demo A demo web page that shows easy integration of an external application and ThingWorx authentication.       Step 2: Understanding Authenticators   Authentication between ThingWorx and custom outside applications begins with Authenticators.  Authenticators are the component integration point that allows for custom authentication schemes to be added into the ThingWorx platform. Authenticators can be used to retrieve content, parameters, headers, etc from HTTP requests.   The retrieved data can be verified by the authenticator using its implemented/configured verification  algorithm(s). If that data is of a username/password credential type the authenticator can choose to pass validation of that data to the configured list of Directory Services. For example, the internal ThingWorx username/password store, or delegate to an external Active Directory set of username/passwords.   ThingWorx tries to authenticate in increasing order of priority. In example, starting with  ThingworxBasicAuthenticator, unless a custom authenticator is given higher priority than that, ThingWorx will continue trying enabled authenticators by priority until one succeeds.   If an authenticator has priority 1, it will be consulted first in the chain of authenticators. If the authenticator has a priority of 101, it will be consulted after the ThingworxBasicAuthenticator (with priority of 100) fails to authenticate the HTTP request. There are several built-in authenticators   Authenticator Priority Editable ThingworxBasicAuthenticator 100 No ThingworxMobileTokenAuthenticator 150 Yes ThingworxApplicationKeyAuthenticator 200 No ThingworxSSOAuthenticator 250 Yes ThingworxFormAuthenticator 300 No ThingworxMobileAuthorizationAuthenticator 350 Yes ThingworxHttpBasicAuthenticator 400 No   When all configured and enabled authenticators fail to validate the data provided by an HTTP request, an authentication failure response is sent back to the requesting client. Custom Authenticators can be given priority such that they fit into any part of this process.   For setting the priority follow the instructions below:   Navigate to and select Security > Authenticators.   Select the Authenticator you would like to edit (ie, ThingworxSSOAuthenticator). If you do not see a specific Authenticator you would like to VIEW ONLY, check the Show System Objects checkbox in your search filter.   Update the Priority field with a new value. Click Save.       Step 3: Download Plugin and SDK   The ThingWorx Extension SDK provides supported classes and APIs to build Java-based extensions. The APIs included in this SDK allow manipulation of ThingWorx platform objects to create Java based extensions that can extend the capability of the existing ThingWorx platform.   The Eclipse Plugin assists in working with the Extension SDK to create projects, entities, and samples.   Download the Eclipse Plugin. Download Extensions SDK. Make a note of the directory where the plugin and the extension SDK are stored. The path of the directory will be required in upcoming steps. Do not extract the zip files.     Click here to view Part 2 of this guide.
View full tip
  Step 9: File Transfer Example   To handle file transfers, a virtual directory is created in the SteamSensor1 entity and in the [C SDK HOME DIR]/examples/FileTransferExample application directory. The source code used for this example is found in [C SDK HOME DIR]/examples/FileTransferExample/src/main.c.   Inside of the [C SDK HOME DIR]/examples/FileTransferExample folder, create the folder structure shown below:   /transfer/ /transfer/incoming/ /transfer/outgoing/   Inside of the /transfer/outgoing/ directory, create and open a file with the name outgoing.txt. Once the outgoing.txt document is open, add the following text, save, and close the file: Hello. This is a file coming from the client application. Navigate to the [C SDK HOME DIR]/examples/FileTransferExample/src/main.c code and update the lines below with the appropriate information for your IP, port, and the “admin_key” Application Key’s keyId value in the ThingWorx Composer:   /* Server Details */ #define TW_HOST "127.0.0.1" #define TW_PORT 80 #define TW_APP_KEY "ce22e9e4-2834-419c-9656-ef9f844c784c"   To support file transfers in your client application, you must use the   twFileManager_AddVirtualDir function in order to create the virtual directories in the entity with such a capability. It will also define the directories available for file operations. A virtual directory maps a unique name to an absolute path of a directory in the file system. All subdirectories of the specified directory are exposed to the server. You can define multiple virtual directories. The directories do not need to be contiguous. Staging Directory   As an optional, but recommended step, you should set the directory that the application should use for staging when performing file transfers. This can be seen in the line below and should be done before initializing the FileManager. The default directory of the FileManager is most likely owned by root and will require a change to either the location of the staging directory and the ownership of the staging directory, or running the application as a User with the correct permissions.   twcfg.file_xfer_staging_dir = "staging";   The example provided uses the TW_SHARE_DIRECTORY macro to create two virtual directories that will act as the root directories in the virtual file system of this application are added. The client is then started as follows with the necessary TW_ADD_FILE_TRANSFER_SHAPE function being called:   TW_ADD_FILE_TRANSFER_SHAPE(); TW_SHARE_DIRECTORY("in", "/transfer/incoming/"); TW_SHARE_DIRECTORY("out", "/transfer/outgoing/");   The creations of the payloads used to create the remote directories on the platform have been moved to a helper function below to make the design cleaner:   int setupSystemRepo(const char * remoteInPath, const char * remoteOutPath, const char * remoteFile);   After our remote directories and files have been setup, it is time to perform the file transfers. Normally, this would mean invoking the Copy service for a Subsystem, but two functions have been created to make this process easier:   int twFileManager_GetFile(const char * sourceRepo, const char * sourcePath, const char * sourceFile, const char * targetRepo, const char * targetPath, const char * targetFile, uint32_t timeout, char asynch, char ** tid) int twFileManager_SendFile(const char * sourceRepo, const char * sourcePath, const char * sourceFile, const char * targetRepo, const char * targetPath, const char * targetFile, uint32_t timeout, char asynch, char ** tid)   The table below displays an example of the first set of parameters:   Parameter Example Description sourceRepo SystemRepository The name of FileRepository or RemoteThing to transfer the file FROM. sourcePath outgoing The path specifying the location of the source file. sourceFile The name of the source file.   targetRepo SteamSensor1 The name of FileRepository or RemoteThing to transfer the file TO. targetPath incoming The path specifying the destination location of the file. targetFile incoming.txt The name of the file at the target. This name can differ from the sourceName. timeout 15,000 The amount of time (in seconds) to wait for a synchronous transfer to complete before cancelling the transfer. async false If false, the service call will block for timeout seconds or until the transfer completes. tid incoming0123 The unique TID associated with the file.   The C SDK also provides the ability to create a FileCallback function that the FileManager will call that function when any file transfer events occur. You can provide a wildcard filter so that only file transfer Events of files that match the filter call the callback function. In addition, callbacks can be set up as “one-shots” such that the callback is unregistered automatically after it is invoked the first time.   NOTE: An optional file transfer callback is registered in the code and provided. You will see the output from the function as files are sent and received.   After running this application, you will notice a new file in the transfer/incoming folder after refreshing. This is the file that we created in the ThingWorx Composer file system for the SystemRepository Entity and was able to copy from that location to our local project. We have also sent a file to the server’s SystemRepository. The BrowseFileSystem and GetFileListing services can be used to check for the folders and files created.   twFileManager_RegisterFileCallback(fileCallbackFunc, NULL, FALSE, NULL);     Step 10: Support Other Platforms   All Websocket errors indicate some general issue communicating with the ThingWorx platform. If you experience an issue connecting, refer to the table below for a list of websocket errors, their corresponding codes, and an explanation of the issue.   Code Message Troubleshooting 200 TW_UNKNOWN_WEBSOCKET_ERROR An unknown error occurred on the websocket. 201 TW_ERROR_INITIALIZING_WEBSOCKET An error occurred while initializing the websocket. Check your websocket configuration parameters for validity. 202 TW_TIMEOUT_INITIALIZING_WEBSOCKET A timeout occurred while initializing the websocket. Check the status of the connection to ThingWorx. 203 TW_WEBSOCKET_NOT_CONNECTED The websocket is not connected to ThingWorx. The requested operation cannot be performed. 204 TW_ERROR_PARSING_WEBSOCKET_DATA An error occurred while parsing websocket data. The parser could not break down the data from the websocket. 205 TW_ERROR_READING_FROM_WEBSOCKET An error occurred while reading data from the websocket. Retry the read operation. If necessary, resend the data. 206 TW_WEBSOCKET_FRAME_TOO_LARGE The SDK is attempting to send a websocket frame that is too large. The Maximum Frame Size is set when calling twAPI_Initialize and should always be set to the Message Chunk Size (twcfg.message_chunk_size). 207 TW_INVALID_WEBSOCKET_FRAME_TYPE The type of the frame coming in over the websocket is invalid. 208 TW_WEBSOCKET_MSG_TOO_LARGE The application is attempting to send a message that has been broken up in to chunks that are too large to fit in a frame. You should not see this error. 209 TW_ERROR_WRITING_TO_WEBSOCKET An error occurred while writing to the Web socket. 210 TW_INVALID_ACCEPT_KEY The Accept key sent earlier from ThingWorx is not valid.     Step 11: Next Steps   Congratulations! You've successfully completed the C SDK Tutorial, and learned how to utilize the resources provided in the Edge SDK to create your own application.   Learn More   We recommend the following resources to continue your learning experience:   Capability Link Build Design Your Data Model Build Implement Services, Events, and Subscriptions   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support C Edge SDK Help Center    
View full tip
  Step 6: Data Shapes   Data Shapes are an important part of creating/firing Events and also invoking Services   Define With Macros   In order to define a Data Shape using a macro, use TW_MAKE_DATASHAPE.   NOTE: The macros are all defined in the twMacros.h header file.   TW_MAKE_DATASHAPE("SteamSensorReadingShape", TW_DS_ENTRY("ActivationTime", TW_NO_DESCRIPTION ,TW_DATETIME), TW_DS_ENTRY("SensorName", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("Temperature", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("Pressure", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("FaultStatus", TW_NO_DESCRIPTION ,TW_BOOLEAN), TW_DS_ENTRY("InletValve", TW_NO_DESCRIPTION ,TW_BOOLEAN), TW_DS_ENTRY("TemperatureLimit", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("TotalFlow", TW_NO_DESCRIPTION ,TW_INTEGER) );   Define Without Macros   In order to define a Data Shape without using a macro, use the  twDataShape_CreateFromEntries  function. In the example below, we are creating a Data Shape called SteamSensorReadings that has two numbers as Field Definitions.   twDataShape * ds = twDataShape_Create(twDataShapeEntry_Create("a",NULL,TW_NUMBER)); twDataShape_AddEntry(ds, twDataShapeEntry_Create("b",NULL,TW_NUMBER)); /* Name the DataShape for the SteamSensorReadings service output */ twDataShape_SetName(ds, "SteamSensorReadings");     Step 7: Events and Services   Events and Services provide useful functionality. Events are a good way to make a Service be asynchronous. You can call a Service, let it return, then your Entity can subscribe to your Event and not keep the original Service function waiting. Events are also a good way to allow the platform to respond to data when it arrives on the edge device without it having to poll the edge device for updates.   Fire Events   To fire an Event you first need to register the Event and load it with the necessary fields for the Data Shape of that Event using the twApi_RegisterEvent function. Afterwards, you would send a request to the ThingWorx server with the collected values using the twApi_FireEvent function. An example is as follows:   twDataShape * ds = twDataShape_Create(twDataShapeEntry_Create("message", NULL,TW_STRING)); /* Event datashapes require a name */ twDataShape_SetName(ds, "SteamSensorFault"); /* Register the service */ twApi_RegisterEvent(TW_THING, thingName, "SteamSensorFault", "Steam sensor event", ds); …. struct { char FaultStatus; double Temperature; double TemperatureLimit; } properties; …. properties. TemperatureLimit = rand() + RAND_MAX/5.0; properties.Temperature = rand() + RAND_MAX/5.0; properties.FaultStatus = FALSE; if (properties.Temperature > properties.TemperatureLimit && properties.FaultStatus == FALSE) { twInfoTable * faultData = 0; char msg[140]; properties.FaultStatus = TRUE; sprintf(msg,"%s Temperature %2f exceeds threshold of %2f", thingName, properties.Temperature, properties.TemperatureLimit); faultData = twInfoTable_CreateFromString("message", msg, TRUE); twApi_FireEvent(TW_THING, thingName, "SteamSensorFault", faultData, -1, TRUE); twInfoTable_Delete(faultData); }   Invoke Services   In order to invoke a Service, you will use the twApi_InvokeService function. The full documentation for this function can be found in [C SDK HOME DIR]/src/api/twApi.h. Refer to the table below for additional information.   Parameter Type Description entityType Input The type of Entity that the service belongs to. Enumeration values can be found in twDefinitions.h. entityName Input The name of the Entity that the service belongs to. serviceName Input The name of the Service to execute. params Input A pointer to an Info Table containing the parameters to be passed into the Service. The calling function will retain ownership of this pointer and is responsible for cleaning up the memory after the call is complete. result Input/Output A pointer to a twInfoTable pointer. In a successful request, this parameter will end up with a valid pointer to a twInfoTable that is the result of the Service invocation. The caller is responsible for deleting the returned primitive using twInfoTable_Delete. It is possible for the returned pointer to be NULL if an error occurred or no data is returned. timeout Input The time (in milliseconds) to wait for a response from the server. A value of -1 uses the DEFAULT_MESSAGE_TIMEOUT as defined in twDefaultSettings.h. forceConnect Input A Boolean value. If TRUE and the API is in the disconnected state of the duty cycle, the API will force a reconnect to send the request.   See below for an example in which the Copy service from the FileTransferSubsystem is called:   twDataShape * ds = NULL; twInfoTable * it = NULL; twInfoTableRow * row = NULL; twInfoTable * transferInfo = NULL; int res = 0; const char * sourceRepo = "SimpleThing_1"; const char * sourcePath = "tw/hotfolder/"; const char * sourceFile = "source.txt"; const char * targetRepo = "SystemRepository"; const char * targetPath = "/"; const char * targetFile = "source.txt"; uint32_t timeout = 60; char asynch = TRUE; char * tid = 0; /* Create an infotable out of the parameters */ ds = twDataShape_Create(twDataShapeEntry_Create("sourceRepo", NULL, TW_STRING)); res = twDataShape_AddEntry(ds, twDataShapeEntry_Create("sourcePath", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("sourceFile", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("targetRepo", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("targetPath", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("targetFile", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("async", NULL, TW_BOOLEAN)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("timeout", NULL, TW_INTEGER)); it = twInfoTable_Create(ds); row = twInfoTableRow_Create(twPrimitive_CreateFromString(sourceRepo, TRUE)); res = twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(sourcePath, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(sourceFile, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(targetRepo, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(targetPath, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(targetFile, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromBoolean(asynch)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromInteger(timeout)); twInfoTable_AddRow(it,row); /* Make the service call */ res = twApi_InvokeService(TW_SUBSYSTEM, "FileTransferSubsystem", "Copy", it, &transferInfo, timeout ? (timeout * 2): -1, FALSE); twInfoTable_Delete(it); /* Grab the tid */ res = twInfoTable_GetString(transferInfo,"transferId",0, &tid);   Bind Event Handling You may want to track exactly when your edge Entities are successfully bound to or unbound from the server. The reason for this is that only bound items should be interacting with the ThingWorx Platform and the ThingWorx Platform will never send any requests targeted at an Entity that is not bound. A simple example that only logs the bound Thing can be seen below. After creating this function, it will need to be registered using the twApi_RegisterBindEventCallback function before the connection is made.   void BindEventHandler(char * entityName, char isBound, void * userdata) { if (isBound) TW_LOG(TW_FORCE,"BindEventHandler: Entity %s was Bound", entityName); else TW_LOG(TW_FORCE,"BindEventHandler: Entity %s was Unbound", entityName); } …. twApi_RegisterBindEventCallback(thingName, BindEventHandler, NULL);   OnAuthenticated Event Handling   You may also want to know exactly when your Edge device has successfully authenticated and made a connection to the ThingWorx platform. Like the bind Event handling, this function will need to be made and registered. To register this handler, use the   twApi_RegisterOnAuthenticated Callback function before the connection is made. This handler form can also be used to do a delay bind for all Things.   void AuthEventHandler(char * credType, char * credValue, void * userdata) { if (!credType || !credValue) return; TW_LOG(TW_FORCE,"AuthEventHandler: Authenticated using %s = %s. Userdata = 0x%x", credType, credValue, userdata); /* Could do a delayed bind here */ /* twApi_BindThing(thingName); */ } … twApi_RegisterOnAuthenticatedCallback(AuthEventHandler, NULL);     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); }   Click here to view Part 4 of this guide
View full tip
  Step 5: Properties   In the Delivery Truck application, there are three Delivery Truck Things. Each Thing has a number of Properties based on its location, speed, and its deliveries carried out. In this design, when a delivery is made or the truck is no longer moving, the Property values are updated.   The deliveryTruck.c helper C file is based on the DeliveryTruck Entities in the Composer. After calling the construct function, there are a number of steps necessary to get going. For the SimpleThing application, there are a number of methods for creating Properties, Events, Services, and Data Shapes for ease of use.   Properties can be created in the client or just registered and utilized. In the  SimpleThingClient  application, Properties are created. In the DeliveryTruckClient application, Properties are bound to their ThingWorx Platform counterpart. Two types of structures are used by the C SDK to define Properties when it is seen fit to do so and can be found in [C SDK HOME DIR]/src/api/twProperties.h:   Name Structure Description Property Definitions twPropertyDef Describes the basic information for the Properties that will be available to ThingWorx and can be added to a client application. Property Values twProperty Associates the Property name with a value, timestamp, and quality.   NOTE: The C SDK provides a number of Macros located in [C SDK HOME DIR]/src/api/twMacros.h. This guide will use these Macros while providing input on the use of pure function calls.   The Macro example below can be found in the main source file for the   SimpleThingClient   application and the accompanying helper file simple_thing.c.   TW_PROPERTY("TempProperty", "Description for TempProperty", TW_NUMBER); TW_ADD_BOOLEAN_ASPECT("TempProperty", TW_ASPECT_ISREADONLY,TRUE); TW_ADD_BOOLEAN_ASPECT("TempProperty", TW_ASPECT_ISLOGGED,TRUE); NOTE: The list of aspect configurations can be seen in [C SDK HOME DIR]/src/api/twConstants.h. Property values can be set with defaults using the aspects setting. Setting a default value in the client will affect the Property in the ThingWorx platform after binding. It will not set a local value in the client application.   For the DeliveryTruckClient, we registered, read, and update Properties without using the Property definitions. Which method of using Properties is based on the application being built.   NOTE: Updating Properties in the ThingWorx Platform while the application is running, will update the values in the client application. To update the values in the platform to match, end the Property read section of your property handler function with a function to set the platform value.   The createTruckThing function for the deliveryTruck.c source code takes a truck name as a parameter and is used to register the Properties, functions, and handlers for each truck.   The updateTruckThing function for the deliveryTruck.c source code takes a truck name as a parameter and is used to either initialize a struct for DeliveryTruck Properties, or simulate a truck stop Event, update Properties, then fire an Event for the ThingWorx platform.   Connecting properties to be used on the platform is as easy as registering the property and optionally adding aspects. The following shows the properties that correlate to those in the DeliveryTruck entities in the Composer. To do this within the code, you would use the  TW_PROPERTY macro as shown in the deliveryTruck.c. This macro must be proceeded by either TW_DECLARE_SHAPE, TW_DECLARE_TEMPLATE or TW_MAKE_THING because these macros declare variables used by the TW_PROPERTY that follow them.   //TW_PROPERTY(propertyName,description,type) TW_PROPERTY(PROPERTY_NAME_DRIVER, NO_DESCRIPTION, TW_STRING); TW_PROPERTY(PROPERTY_NAME_DELIVERIES_LEFT, NO_DESCRIPTION, TW_NUMBER); TW_PROPERTY(PROPERTY_NAME_TOTAL_DELIVERIES, NO_DESCRIPTION, TW_NUMBER); TW_PROPERTY(PROPERTY_NAME_DELIVERIES_MADE, NO_DESCRIPTION, TW_NUMBER); TW_PROPERTY(PROPERTY_NAME_LOCATION, NO_DESCRIPTION, TW_LOCATION); TW_PROPERTY(PROPERTY_NAME_SPEED, NO_DESCRIPTION, "TW_NUMBER);   Read Properties   Reading Properties from a ThingWorx platform Thing or the returned Properties of a Service can be done using the TW_GET_PROPERTY macro. Examples of its use can be seen in all of the provided applications. An example can be seen below:   int flow = TW_GET_PROPERTY(thingName, "TotalFlow").number; int pressue = TW_GET_PROPERTY(thingName, "Pressure").number; twLocation location = TW_GET_PROPERTY(thingName, "Location").location; int temperature = TW_GET_PROPERTY(thingName, "Temperature").number;   Write Properties   Writing Properties to a ThingWorx platform Thing from a variable storing is value uses a similarly named method. Using the TW_SET_PROPERTY macro will be able to send values to the platform. Examples of its use can be seen in all of the provided applications. An example is shown below:   TW_SET_PROPERTY(thingName, "TotalFlow", TW_MAKE_NUMBER(rand() / (RAND_MAX / 10.0))); TW_SET_PROPERTY(thingName, "Pressure", TW_MAKE_NUMBER(18 + rand() / (RAND_MAX / 5.0))); TW_SET_PROPERTY(thingName, "Location", TW_MAKE_LOC(gpsroute[location_step].latitude,gpsroute[location_step].longitude,gpsroute[location_step].elevation));   This macro utilizes the twApi_PushSubscribedProperties function call to pushe all property updates to the server. This can be seen in the updateTruckThing function in deliveryTruck.c.   Property Change Listeners   Using the Observer pattern, you can take advantage of the Property change listener functionality. With this pattern, you create functions that will be notified when a value of a Property has been changed (whether on the server or locally by your program when the TW_SET_PROPERTY macro is called).   Add a Property Change Listener   In order to add a Property change listener, call the twExt_AddPropertyChangeListener function using the:   Name of the Thing (entityName) Property this listener should watch Function that will be called when the property has changed void simplePropertyObserver(const char * entityName, const char * thingName,twPrimitive* newValue){ printf("My Value has changed\n"); } void test_simplePropertyChangeListener() { { TW_MAKE_THING("observedThing",TW_THING_TEMPLATE_GENERIC); TW_PROPERTY("TotalFlow", TW_NO_DESCRIPTION, TW_NUMBER); } twExt_AddPropertyChangeListener("observedThing",TW_OBSERVE_ALL_PROPERTIES,simplePropertyObserver); TW_SET_PROPERTY("observedThing","TotalFlow",TW_MAKE_NUMBER(50)); }   NOTE: Setting the propertyName parameter to NULL or TW_OBSERVE_ALL_PROPERTIES, the function specified by the propertyChangeListenerFunction parameter will be used for ALL properties.   Remove a Property Change Listener   In order to release the memory for your application when done with utilizing listeners for the Property, call the twExt_RemovePropertyChangeListener function.   void simplePropertyObserver(const char * entityName, const char * thingName,twPrimitive* newValue){ printf("My Value has changed\n"); } twExt_RemovePropertyChangeListener(simplePropertyObserver);   Click here to view Part 3 of this guide  
View full tip
  Use the C SDK to build an app that connects to ThingWorx with persistent bi-directional communication.     GUIDE CONCEPT   This project will introduce more complex aspects of the ThingWorx C SDK and help you to get started with development.   Following the steps in this this guide, you will be ready to develop your own IoT application with the ThingWorx C SDK.   We will teach you how to use the C programming language to connect and build IoT applications to be used with the ThingWorx Platform.   YOU'LL LEARN HOW TO   Establish and manage a secure connection with a ThingWorx server, including SSL negotiation and connection maintenance Enable easy programmatic interaction with the Properties, Services, and Events that are exposed by Entities running on a ThingWorx server Create applications that can be directly used with your device running the C programming language Basic concepts of the C Edge SDK How to use the C Edge API to build a real-world application How to utilize resources provided in the Edge SDK to help create your own application    Note: The estimated time to complete ALL 4 parts of this guide is 60 minutes.      Step 1: Completed Examples   Download the completed files for this tutorial: ThingWorx C Edge SDK Sample Files.zip.   This tutorial will guide you through working with the C SDK on differing levels. Utilize this file to see a finished example and return to it as a reference if you become stuck creating your own fully fleshed out application.   Keep in mind, this download uses the exact names for Entities used in this tutorial. If you would like to import this example and also create Entities on your own, change the names of the Entities you create.     Step 2: Environment Setup   In order to compile C code, you need a C compiler and the ThingWorx C Edge SDK. It will be helpful to have CMake installed on your system. CMake is a build tool that will generate make or project files for many different platforms and IDEs.   Operating System Notes Windows You will need a 3rd party compiler such as MinGW GCC, Cygwin GCC or you can follow these Microsoft instructions to download and use the Microsoft Visual C++ Build Tool. Mac Download the Apple Developer Tools. Linux/Ubuntu A compiler is included by default.   NOTE: You can use CMake, version 2.6.1 or later to build projects or make files, which then are used to build the applications that you develop with the C SDK.   Before you can begin developing with the ThingWorx C SDK, you need to generate an Application Key and modify the source code file. You can use the Create an Application Key guide as a reference.   Modify Source File   Extract the files from the C SDK samples zip file. At the top level of the extracted files, you will see a folder called examples. This directory provides examples of how to utilize the C SDK. Open a terminal, go to your workspace, and create a new directory. You can also just switch to the unzipped directory in your system. After you've created this directory in your workspace, copy the downloaded files and folders into your new directory. You can start creating your connection code or open the main.c source file in the examples\SteamSensor\src directory for an example.   Operating System Code Linux/Ubuntu gedit main.c OR vi main.c Mac open –e main.c Windows start main.c        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-37ddc6dd34618" NOTE: Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a User and place the user as a member of Admins.   Compile and Run Code   To test your connection, you will only need to update the main.c in the SteamSensor example folder. CMake can generate Visual Studio projects, make build files or even target IDEs such as Eclipse, or XCode. CMake generates a general description into a build for your specific toolchain or IDE.   Inside the specific example folder you would like to run, ie SteamSensor. Create a directory to build in, for this example call it bin. mkdir bin  cd bin      5. Run the CMake command listed below. This assumes CMake is already on your PATH. cmake ..      6. CMake has now produced a set of project files which should be compatible with your development environment.   Operating System Command Note Unix make A set of make files Windows msbuild tw-c-sdk.sln /t:build A visual studio solution   NOTE: CMake does its best to determine what version of Visual Studio you have but you may wish to specify which version to use if you have more than one installed on your computer. Below is an example of forcing CMake to use a specific version of Visual Studio: cmake -G "Visual Studio 15 2017" .. If your version of Visual Studio or other IDE is unknown, use cmake -G to see a list of supported IDEs.   You also have the alternative of opening the tw-c-sdk.sln from within Visual Studio and building in this IDE.   NOTE: By default, CMake will generate a build for the creation of a release binary. If you want to generate a debug build, use the command-> cmake -DBUILD_DEBUG=ON ..       7. Once your build completes you will find the build products in the CMake directory (see example below). From here, open the project in your IDE of choice.   NOTE: You should receive messages confirming successful binding, authentication, and connection after the main.c file edits have been made.   Operating System Files Description Unix ./bin/src/libtwCSdk_static.a  Static Library Unix ./bin/src/libtwCSdk.so  Shared Library Unix ./bin/examples/SteamSensor/SteamSensor   Sample Application Windows .\bin\src\<Debug/Release>\twCSdk_static.lib  Static Library Windows .\bin\src\<Debug/Release>\twCSdk.dll  Shared Library Windows .\bin\examples\<Debug/Release>\SteamSensor\SteamSensor.exe  Sample Application     Step 3: Run Sample Code   The C code in the sample download is configured to run and connect to the Entities provided in the ThingWorxEntitiesExport.xml file. Make note of the IP address of your ThingWorx Composer instance. The top level of the exported zip file will be referred to as [C SDK HOME DIR].   Navigate to the [C SDK HOME DIR]/examples/ExampleClient/src directory. Open the main.c source file.   Operating System Command Linux/Ubuntu gedit main.c OR vi main.c Mac open –e main.c Windows start main.c   Modify the Server Details section at the top with the IP address for your ThingWorx Platform instance and the Application Key you would like to use. Change the TW_HOST definition accordingly.   NOTE: By default, TW_APP_KEY has been set to the Application Key from the admin_key in the import step completed earlier. Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a user and place the user as a member of the Admins security group.   /* Server Details */ #define TW_HOST "127.0.0.1" #define TW_APP_KEY "ce22e9e4-2834-419c-9656-e98f9f844c784c"   If you are working on a port other than 80, you will need to update the conditional statement within the main.c source file. Search for and edit the first line within the main function. Based on your settings, set the int16_t port to the ThingWorx platform port. Click Save and close the file. Create a directory to build in, for this example call it bin.   Operating System Command Linux/Ubuntu mkdir bin Mac mkdir bin Windows mkdir bin   Change to the newly created bin directory.   Operating System Command Linux/Ubuntu cd bin Mac cd bin Windows cd bin   Run the CMake command using your specific IDE of choice.    NOTE: Include the two periods at the end of the code as shown below. Use cmake -G to see a list of supported IDEs.   cmake ..   Once your build completes, you will find the build products in the bin directory, and you can open the project in your IDE of choice. NOTE: You should receive messages confirming successful binding, authentication, and connection after building and running the application    10. You should be able to see a Thing in your ThingWorx Composer called SimpleThing_1 with updated last Connection 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
  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 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
  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-2cb4-4327-81ea-7e71e26 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-2cb4-4327-81ea-7e71e26bb   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-2cb4-4327-81ea-7e71e26bb645 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://iotboston.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
  Step 5: Add Property to Thing   Property values are associated with a specific Thing, and are used to store data that changes over time. Required Parameters   AppKey created by your ThingWorx server Name of the Thing to which the Property will be added Name for the new Property and data type of the Property's value   Request   Construct the URL. A new Property can be added to an existing Thing by making an HTTP POST to this endpoint. Substitute <name of Thing> with the actual name of a Thing that exists on the ThingWorx server that will have the Property added. <server_ip:port>/Thingworx/Things/<name of Thing>/Services/AddPropertyDefinition       2. Send request parameters. The name of the new Property to be added and type of the Property are sent in the body of the POST as a JSON object. For example, the JSON object below will create a new Property named SomeNumber using the ThingWorx base type NUMBER. Some other commonly used types are STRING, INTEGER, and BOOLEAN. { "name" : "SomeNumber", "type" : "NUMBER" }   NOTE: The full request must include a header with the appKey for your specific ThingWorx server.   Response   A successful call to the AddPropertyDefinitionservice does not return any content in the body of the response. Only an HTTP 200 is returned.   HTTPie example:   http -v -j http://52.201.57.6/Thingworx/Things/SomeTestThing/Services/AddPropertyDefinition appKey==64b879ae-2455-4d8d-b840-5f5541a799ae name=SomeNumber type=NUMBER   WARNING for other HTTP clients: Most HTTP clients do not set a Content-Type header by default, without this header set the server will return an error message. The POST request to the AddPropertyDefinition endpoint has a JSON body so the header must be set to match the format of the request body.   The Content-Type header does not appear in the sample HTTPie call because HTTPie sets the Accept and Content-type request headers to application/json by default. Below is an example cURL call that explicitly sets the Content-Type header to application/json.   curl -v -H "Content-Type: application/json" -X POST -d '{"name": "SomeNumber","type": "NUMBER"}' http://52.201.57.6/Thingworx/Things/SomeTestThing/Services/AddPropertyDefinition?appKey=d0a68eff-2cb4-4327-81ea-7e71e26b     Validate   View new Property on Server. The Property you just added is now available in the ThingWorx Composer. Before anything else can be done with your new Property through the REST API, the Thing must be restarted. To confirm your Property was added to your Thing, open Composer and click Things, select the name of the Thing you just created, then click Properties and Alerts. You will see the new Property listed. You may need to refresh to see the changes.             2. Execute RestartThing Service. Restart your Thing with the added Property by making a HTTP POST to the endpoint below. Substitute <name of Thing> with the actual name of the Thing you created. No body is required in the POST, however, the Content-Type header of a POST that executes a Service must always be set to application/json or text/xml even if the service does not take any parameters and no content is being sent. No body is returned upon success, only an HTTP 200 response code. <server_ip:port>/Thingworx/Things/<name of Thing>/Services/RestartThing   HTTPie example:   http -v -j POST http://52.201.57.6/Thingworx/Things/SomeTestThing/Services/RestartThing appKey==64b879ae-2455-4d8d-b840-5f5541a799ae      Step 6: Set Property Value   You can set the value of a specific Property with the REST API using the PUT verb. Required Parameters:   AppKey created by your Foundation server A Name of valid Thing and name of Property New Property value   Request   Construct the URL. A Property value can be set by making an HTTP PUT call to this endpoint: <server_ip:port>/Thingworx/Things/<name of Thing>/Properties/<name of Property> Substitute <name of Thing> with the actual name of a Thing that exists on the ThingWorx server and <name of Property> with the name of a Property that has been added to the Thing.       2. Send request parameters.   The name of the Property to be set is duplicated in the body of the PUT and is sent along with the value as a JSON object. The example below will set the Property SomeNumber to 34.4 { "SomeNumber" : 34.4 } NOTE: The full request must include authentication credentials for your specific ThingWorx server.   Response   A successful call to set a Property does not return any content in the body of the response. Only an HTTP 200 is returned.   HTTPie example   http -v -j PUT http://52.201.57.6/Thingworx/Things/SomeTestThing/Properties/SomeNumber appKey==64b879ae-2455-4d8d-b840-5f5541a799ae SomeNumber=34.4   WARNING for other HTTP clients: By default HTTPie sets the Accept and Content-type request headers to application/json. A PUT request to the Properties endpoint has a JSON body so the Content-Type header must be set to match the format of the request body.   Most HTTP clients do not set the correct header by default and it must be set explicitly. Below is an example cURL call that sets the Content-Type header to application/json   curl -v -H "Content-Type: application/json" -X PUT -d '{"SomeNumber":12.34}' http://52.201.57.6/Thingworx/Things/SomeTestThing/Properties/SomeNumber?appKey=d0a68eff-2cb4-4327-81ea-7e71e26b     Validate   To confirm your Property was changed for your Thing, go to Composer and click Things. Select the name of the Thing you just created, then click Properties and Alerts tab. Click on the circular arrow Refresh to see the updated Property value.       Step 7: Get Latest Property Value   You can retrieve Property values of a specific Thing with the REST API using the GET verb.   Required Parameters:   AppKey created by your ThingWorx server Name of Thing and name of Property   Request   Construct the URL. To get the current value for a property, make a GET request to this endpoint: <server_ip:port>/Thingworx/Things/<name of Thing>/Properties/<name of property> Substitute <name of thing> with the actual name of a Thing that exists on the ThingWorx server and <name of Property> with the name of a Property that has been added to the Thing.   NOTE: The full request will also need to include the hostname and authentication credentials for your specific ThingWorx server.         2. Send request parameters. Other than authentication, no other parameters are used in  this GET request.   Response   The content can be returned in four different formats by sending an Accept header with the request.   Desired Response Type Accept Header Values JSON application/json XML text/xml HTML text/html (or omit Accept Header) CSV text/csv   HTTPie example:   http -v -j http://52.201.57.6/Thingworx/Things/SomeTestThing/Properties/SomeNumber appKey==64b879ae-2455-4d8d-b840-5f5541a799ae     Click here to view Part 3 of this guide.
View full tip
  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
Key Functional Highlights Add connectivity to National Instruments TestStand Make it easier to edit the apps Easier to find mashups and things in Composer Support for Asset sub-types Open up the tag picker to allow adding any connection types through Composer General App Improvements Enhance tag picker to improve speed of configuration Make it easier to add additional properties to assets Make app configuration more intuitive by centralizing the configuration Controls Advisor Merge the Server and Connection status fields Asset Advisor Performance improvement when displaying pages Add support for CFS/ServiceMax integration Added trial support for Service     Compatibility ThingWorx 8.2.x KEPServerEX 6.2 and later KEPServerEX V6.1 and older as well as different OPC Servers (with Kepware OPC aggregator) National Instruments TestStand 2016 SP1 and later Support upgrade from 8.0.1 and later     Documentation What’s New in ThingWorx Manufacturing Apps ThingWorx Manufacturing Apps Setup and Configuration Guide What’s New in ThingWorx Service Apps ThingWorx Service Apps Setup and Configuration Guide ThingWorx Manufacturing and Service Apps Customization Guide     Download ThingWorx Manufacturing Apps Freemium portal ThingWorx Manufacturing and Service Apps Extensions
View full tip
Connectors allow clients to establish a connection to Tomcat via the HTTP / HTTPS protocol. Tomcat allows for configuring multiple connectors so that users or devices can either connect via HTTP or HTTPS.   Usually users like you and me access websites by just typing the URL in the browser's address bar, e.g. "www.google.com". By default browsers assume that the connection should be established with the HTTP protocol. For HTTPS connections, the protocol has to be specified explictily, e.g. "https://www.google.com"   However - Google automatically forwards HTTP connections automatically as a HTTPS connection, so that all connections are using certificates and are via a secure channel and you will end up on "https://www.google.com" anyway.   To configure ThingWorx to only allow secure connections there are two options...   1) Remove HTTP access   If HTTP access is removed, users can no longer connect to the 80 or 8080 port. ThingWorx will only be accessible on port 443 (or 8443).   If connecting to port 8080 clients will not be redirected. The redirectPort in the Connector is only forwarding requests internally in Tomcat, not switching protocols and ports and not requiring a certificate when being used. The redirected port does not reflect in the client's connection but only manages internal port-forwarding in Tomcat.   By removing the HTTP ports for access any connection on port 80 (or 8080) will end up in an error message that the client cannot connect on this port.   To remove the HTTP ports, edit the <Tomcat>\conf\server.xml and comment out sections like       <!-- commented out to disallow connections on port 80 <Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="443" /> -->     Save and restart Tomcat. If opening Tomcat (and ThingWorx) in a browser via http://myServer/ the connection will fail with a "This site can’t be reached", "ERR_CONNECTION_REFUSED" error.   2) Forcing insecure connections through secure ports   Alternatively, port 80 and 8080 can be kept open to still allow users and devices to connect. But instead of only internally forwarding the port, Tomcat can be setup to also forward the client to the new secure port. With this, users and devices can still use e.g. old bookmarks and do not have to explicitly set the HTTPS protocol in the address.   To configure this, edit the <Tomcat>\conf\web.xml and add the following section just before the closing </web-app> tag at the end of the file:     <security-constraint>        <web-resource-collection>              <web-resource-name>HTTPSOnly</web-resource-name>              <url-pattern>/*</url-pattern>        </web-resource-collection>        <user-data-constraint>              <transport-guarantee>CONFIDENTIAL</transport-guarantee>        </user-data-constraint> </security-constraint>     In <Tomcat>\conf\web.xml ensure that all HTTP Connectors (port 80 and 8080) have their redirect port set to the secure HTTPS Connector (usually port 443 or port 8443).   Save and restart Tomcat. If opening Tomcat (and ThingWorx) in a browser via http://myServer/ the connection will now be forwarded to the secure port. The browser will now show the connection as https://myServer/ instead and connections are secure and using certificates.   What next?   Configuring Tomcat to force insecure connection to actually secure HTTPS connection just requires a simple configuration change. If you want to read more about certificates, encryption and how to setup ThingWorx for HTTPS in the first place, be sure to also have a look at   Trust & Encryption - Theory Trust & Encryption - Hands On
View full tip
The Protocol Adapter Toolkit (PAT) is an SDK that allows developers to write a custom Connector that enables edge devices to connect to and communicate with the ThingWorx Platform.   In this blog, I will be dabbling with the MQTT Sample Project that uses the MQTT Channel introduced in PAT 1.1.2.   Preamble All the PAT sample projects are documented in detail in their respective README.md. This post is an illustrated Walk-thru for the MQTT Sample project, please review its README.md for in depth information. More reading in Protocol Adapter Toolkit (PAT) overview PAT 1.1.2 is supported with ThingWorx Platform 8.0 and 8.1 - not fully supported with 8.2 yet.   MQTT Connector features The MQTT Sample project provides a Codec implementation that service MQTT requests and a command line MQTT client to test the Connector. The sample MQTT Codec handles Edge initiated requests read a property from the ThingWorx Platform write a property to the ThingWorx Platform execute a service on the ThingWorx Platform send an event to the ThingWorx Platform (also uses a ServiceEntityNameMapper to map an edgeId to an entityName) All these actions require a security token that will be validated by a Platform service via a InvokeServiceAuthenticator.   This Codec also handles Platform initiated requests (egress message) write a property to the Edge device execute a service without response on the Edge device  Components and Terminology       Mqtt Messages originated from the Edge Device (inbound) are published to the sample MQTT topic Mqtt Messages originated from the Connector (outbound) are published to the mqtt/outbound MQTT topic   Codec A pluggable component that interprets Edge Messages and converts them to ThingWorx Platform Messages to enable interoperability between an Edge Device and the ThingWorx Platform. Connector A running instance of a Protocol Adapter created using the Protocol Adapter Toolkit. Edge Device The device that exists external to the Connector which may produce and/or consume Edge Messages. (mqtt) Edge Message A data structure used for communication defined by the Edge Protocol.  An Edge Message may include routing information for the Channel and a payload for Codec. Edge Messages originate from the Edge Device (inbound) as well as the Codec (outbound). (mqtt) Channel The specific mechanism used to transmit Edge Messages to and from Edge Devices. The Protocol Adapter Toolkit currently includes support for HTTP, WebSocket, MQTT, and custom Channels. A Channel takes the data off of the network and produces an Edge Message for consumption by the Codec and takes Edge Messages produced by the Codec and places the message payload data back onto the network. Platform Connection The connection layer between a Connector and ThingWorx core Platform Message The abstract representation of a message destined for and coming from the ThingWorx Platform (e.g. WriteProperty, InvokeService). Platform Messages are produced by the Codec for incoming messages and provided to the Codec for outgoing messages/responses.   Installation and Build  Protocol Adapter Toolkit installation The media is available from PTC Software Downloads : ThingWorx Connection Server > Release 8.2 > ThingWorx Protocol Adapter Toolkit Just unzip the media on your filesystem, there is no installer The MQTT Sample Project is available in <protocol-adapter-toolkit>\samples\mqtt Eclipse Project setup Prerequisite : Eclipse IDE (I'm using Neon.3 release) Eclipse Gradle extension - for example the Gradle IDE Pack available in the Eclipse Marketplace Import the MQTT Project : File > Import > Gradle (STS) > Gradle (STS) Project Browser to <protocol-adapter-toolkit>\samples\mqtt, then [Build Model] and select the mqtt project     Review the sample MQTT codec and test client Connector : mqtt > src/main/java > com.thingworx.connector.sdk.samples.codec.MqttSampleCodec decode : converts an MqttEdgeMessage to a PlatformRequest encode (3 flavors) : converts a PlatformMessage or an InfoTable or a Throwable to a MqttEdgeMessage Note that most of the conversion logic is common to all sample projects (websocket, rest, mqtt) and is done in an helper class : SampleProtocol The SampleProtocol sources are available in the <protocol-adapter-toolkit>\samples\connector-api-sample-protocol project - it can be imported in eclipse the same way as the mqtt. SampleTokenAuthenticator and SampleEntityNameMapper are also defined in the <protocol-adapter-toolkit>\samples\connector-api-sample-protocol project. Client : mqtt > src/client/java > com.thingworx.connector.sdk.samples.MqttClient Command Line MQTT client based on Eclipse Paho that allows to test edge initiated and platform initiated requests. Build the sample MQTT Connector and test client Select the mqtt project then RMB > Gradle (STS) > Task Quick Launcher > type Clean build +  [enter] This creates a distributable archive (zip+tar) in <protocol-adapter-toolkit>\samples\mqtt\build\distributions that packages the sample mqtt connector, some startup scripts, an xml with sample entities to import on the platform and a sample connector.conf. Note that I will test the connector and the client directly from Eclipse, and will not use this package. Runtime configuration and setup MQTT broker I'm just using a Mosquitto broker Docker image from Docker Hub​   docker run -d -p 1883:1883 --name mqtt ncarlier/mqtt  ThingWorx Platform appKey and ConnectionServicesExtension From the ThingWorx Composer : Create an Application Key for your Connector (remember to increase the expiration date - to make it simple I bind it to Administrator) Import the ConnectionServicesExtension-x.y.z.zip and pat-extension-x.y.z.zip extensions available in <protocol-adapter-toolkit>\requiredExtensions  Connector configuration Edit <protocol-adapter-toolkit>\samples\mqtt\src\main\dist\connector.conf Update the highlighted entries below to match your configuration :   include "application" cx-server {   connector {     active-channel = "mqtt"     bind-on-first-communication = true     channel.mqtt {       broker-urls = [ "tcp://localhost:1883" ]       // at least one subscription must be defined       subscriptions {        "sample": [ "com.thingworx.connector.sdk.samples.codec.MqttSampleCodec", 1 ]       }       outbound-codec-class = "com.thingworx.connector.sdk.samples.codec.MqttSampleCodec"     }   }   transport.websockets {     app-key = "00000000-0000-0000-0000-000000000000"     platforms = "wss://thingWorxServer:8443/Thingworx/WS"   }   // Health check service default port (9009) was in used on my machine. Added the following block to change it.   health-check {      port = 9010   } }  Start the Connector Run the Connector directly from Eclipse using the Gradle Task RMB > Run As ... > Gradle (STS) Build (Alternate technique)  Debug as Java Application from Eclipse Select the mqtt project, then Run > Debug Configurations .... Name : mqtt-connector Main class:  com.thingworx.connectionserver.ConnectionServer On the argument tab add a VM argument : -Dconfig.file=<protocol-adapter-toolkit>\samples\mqtt\src\main\dist\connector.conf Select [Debug]  Verify connection to the Platform From the ThingWorx Composer, Monitoring > Connection Servers Verify that a Connection Server with name protocol-adapter-cxserver-<uuid> is listed  Testing  Import the ThingWorx Platform sample Things From the ThingWorx Composer Import/Export > From File : <protocol-adapter-toolkit>\samples\mqtt\src\main\dist\SampleEntities.xml Verify that WeatherThing, EntityNameConverter and EdgeTokenAuthenticator have been imported. WeatherThing : RemoteThing that is used to test our Connector EdgeTokenAuthenticator : holds a sample service (ValidateToken) used to validate the security token provided by the Edge device EntityNameConverter : holds a sample service (GetEntityName) used to map an edgeId to an entityName  Start the test MQTT client I will run the test client directly from Eclipse Select the mqtt project, then Run > Run Configurations .... Name : mqtt-client Main class:  com.thingworx.connector.sdk.samples.MqttClient On the argument tab add a Program argument : tcp://<mqtt_broker_host>:1883 Select [Run] Type the client commands in the Eclipse Console  Test Edge initiated requests     Read a property from the ThingWorx Platform In the MQTT client console enter : readProperty WeatherThing temp   Sending message: {"propertyName":"temp","requestId":1,"authToken":"token1234","action":"readProperty","deviceId":"WeatherThing"} to topic: sample Received message: {"temp":56.3,"requestId":1} from topic: mqtt/outbound Notes : An authToken is sent with the request, it is validated by a platform service using the SampleTokenAuthenticator (this authenticator is common to all the PAT samples and is defined in <protocol-adapter-toolkit>\samples\connector-api-sample-protocol) EntityNameMapper is not used by readProperty (no special reason for that) The PlatformRequest message built by the codec is ReadPropertyMessage   Write a property to the ThingWorx Platform In the MQTT client console enter : writeProperty WeatherThing temp 20   Sending message: {"temp":"20","propertyName":"temp","requestId":2,"authToken":"token1234","action":"writeProperty","deviceId":"WeatherThing"} to topic: sample Notes : An authToken is sent with the request, it is validated by a platform service using the SampleTokenAuthenticator EntityNameMapper is not used by writeProperty The PlatformRequest message built by the codec is WritePropertyMessage No Edge message is sent back to the device   Send an event to the ThingWorx Platform   In the MQTT client console enter : fireEvent Weather WeatherEvent SomeDescription   Sending message: {"requestId":5,"authToken":"token1234","action":"fireEvent","eventName":"WeatherEvent","message":"Some description","deviceId":"Weather"} to topic: sample Notes : An authToken is sent with the request, it is validated by a platform service using the SampleTokenAuthenticator fireEvent uses a EntityNameMapper (SampleEntityNameMapper) to map the deviceId (Weather) to a Thing name (WeatherThing), the mapping is done by a platform service The PlatformRequest message built by the codec is FireEventMessage No Edge message is sent back to the device   Execute a service on the ThingWorx Platform ... can be tested with the GetAverageTemperature on WeatherThing ... Test Platform initiated requests     Write a property to the Edge device The MQTT Connector must be configured to bind the Thing with the Platform when the first message is received for the Thing. This was done by setting the bind-on-first-communication=true in connector.conf When a Thing is bound, the remote egress messages will be forwarded to the Connector The Edge initiated requests above should have done the binding, but if the Connector was restarted since, just bind again with : readProperty WeatherThing isConnected From the ThingWorx composer update the temp property value on WeatherThing to 30 An egress message is logged in the MQTT client console :   Received message: {"egressMessages":[{"propertyName":"temp","propertyValue":30,"type":"PROPERTY"}]} from topic: mqtt/outbound   Execute a service on the ThingWorx Platform ... can be tested with the SetNtpService on WeatherThing ...
View full tip
Protocol Adapter Toolkit (PAT) is an SDK that allows developers to write a custom Connector that enables edge devices (without native AlwaysOn support) to connect to and communicate with the ThingWorx Platform. A typical use case is edge communication using a protocol that can't be changed (e.g. MQTT). Prior to PAT, developers had to use the ThingWorx (Edge or Platform) SDKs, or the ThingWorx REST interface, to enable the edge devices to communicate with ThingWorx. Overview PAT provides three main components: the Channel, the Codec, and the ThingWorx Platform Connection. The Channel implements a network protocol to communicate directly with the Edge Device. Its responsibilities include reading data from an Edge Device, writing data to an Edge Device, and routing data to the correct Codec. You can implement your own custom channel or use one of the out of the box channels provided by PTC : WebSocket, HTTP (1.0.x) and MQTT (1.1.x). The Codec translates messages from your edge devices into messages that ThingWorx platform can process (property read/write,service call, events), and provides a means to take the results of those actions and turn them back into messages for the device.  You must implement the Codec. The Platform Connection layer sends and receives messages with the ThingWorx platform. Note : The PAT Connector capabilities depend on edge protocol and channel implementation. Installation The PAT installation media contains : README.md - start here SDK (Java API) and runtime libraries PAT skeleton project (Gradle) Sample codec implementations for the WebSocket, HTTP, and MQTT channels (Gradle) Sample Custom Channel implementation (basic TCP protocol adapter) (Gradle) Required extensions to be installed on the platform : ConnectionServicesExtension and pat-extension Reference Documents ThingWorx Protocol Adapter Toolkit Developers Guide 1.0.0 README.md in various levels of installation folders ThingWorx Connection Services and Compatibility Matrix 1.0.0 Related Knowledge Protocol Adapter Toolkit - MQTT Sample Project hands-on (1.1.x)
View full tip
Announcements