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

ThingWorx Navigate is now Windchill Navigate Learn More

IoT & Connectivity Tips

Sort by:
Video Author:                     Christophe Morfin Original Post Date:            October 10, 2016 Applicable Releases:        ThingWorx Analytics 52.x and 7.4   Description: In this video we cover the process of installing ThingWorx Analytics Server 52.1.  It is suggested that you first review the first part on prerequisites.      
View full tip
The IoT Building Block Design Framework By Victoria Firewind and Ward Bowman, Sr. Director of the IoT EDC   Building Block Overview As detailed quite extensively on its own designated Help Center page, building blocks are the future of scalable and maintainable IoT architecture. They are a way to organize development and customization of ThingWorx solutions into modular, well-defined components or packages. Each building block serves a specific purpose and exists as independently as possible from other modules. Some blocks facilitate external data integration, some user interface features, and others the manipulation or management of different kinds of equipment. There are really no limits to how custom a ThingWorx solution can be, and customizations are often a major hurdle to a well-oiled dev ops pipeline. It’s therefore crucial for us all to use a standard framework, to ensure that each piece of customization is insular, easy-to-replace, and much more maintainable. This is the foundation of good IoT application design.   PTC’s Building Block Framework At PTC, building blocks are broken down in a couple different ways: categories and types. The category of a building block is primarily in reference to its visibility and availability for use by the greater ThingWorx community. We use our own framework here at PTC, so our solution offerings are based around solution-specific building blocks, things which we provide as complete, SaaS solutions. These solution-specific building blocks combine up into single solutions like DPM, offerings which require a license, but can then easily be deployed to a number of systems. PTC solutions provide many, complex, OOTB features, like the Production Dashboard of DPM, and the OperationKPI building block.   Anyone doing any sort of development with ThingWorx, however, does still have access to many other building blocks, included with the domain specific building block category. These are the pieces used to build the solution building blocks like DPM, and they can be used to build other more custom solutions as well. Take the OperationKPI block which can vary greatly from one customer to the next in how it is calculated or analyzed. The pieces used to build the version that ships with DPM are right there, for instance, Shift and ReasonCode. They are designed to have minimal dependencies themselves, meant to be used as dependencies by custom blocks which do custom versions of the module logic found within the PTC solution-specific blocks. Then there are the common blocks as well, and these are used even more widely for things like user management and database connectivity.   The type of the building block refers really to where that building block falls in the greater design. A UI building block consumes data and displays it, so that is the View of a classic MVC design pattern. However, sometimes user input is needed, so perhaps that UI building block will depend on another block. This other block could have a utility entity that fuels UI logic, and the benefit to having that be a separate block is then the ease with which it can be subbed out from one ThingWorx instance to the next.   Let’s say there are regional differences in how people make use of technologies. If the differences are largely driven by what data is available from physical devices at a particular site, then perhaps these differences require different services to process user input or queries on the same UI mashups used across every site. Well in this case, having the UI block stand alone is smart, because then the Model and Controller blocks can be abstracted out and instantiated differently at different sites.   The two types that largely define the Model and Controller of the classic MVC are called Abstract and Implementation building blocks, and the purposes are intertwined, but distinct: abstract building blocks expose the common API endpoints which allow for the implementation blocks to vary so readily. The implementation blocks are then those which actually alter the data model, which is what happens when the InitializeSolution method is called. In that service, they are given everything they need to generate their data tables and data constraints, so that they are ready to be used once the devices are connected.   Occasionally, UI differences will also be necessary when factories or regions have different ways of doing things. When this happens, even mashups can be abstracted using abstract building blocks. Modular mashups which can be combined into larger ones can be provided in an abstract building block, and these can be used to form custom mashups from common parts across many sites in different implementation blocks all based on the same abstract one.   The last type of building block is the standard building block, which is the most generic. This one is not intended to be overridden, often serving as the combination of other building blocks into final solutions. It is also the most basic combination of components necessary to adhere to the building block design framework and interface with the shared deployment infrastructure. The necessary components include a project entity, which contains all of the entities for the building block, an entry point, which contains the metadata (name, description, version, list of dependencies, etc.) and overrides the service for automatic model generation (DeployComponent), and the building block manager. The dashed arrows indicate an entity implements another, and the solid arrows, extension. The manager is the primary service layer for the building block, and it makes most of the implementation decisions. It also has all of the information required to configure menus and select which contained mashups to use when combining modular mashups into larger views. The manager really consists of 3 entities: a thing template with the properties and configuration tables, a thing which makes use of these, and a thing shape which defines all of the services (which can often be overridden) which the manager thing may make use of.   Most building blocks will also contain security entities which handle user permissions, like groups which can be updated with users. Anyone requiring access to the contents of a particular building block then simply needs to be added to the right groups later on. This as well as model logic entities like thing shapes can be used concurrently to use organizational security for visibility controls on individual equipment, allowing some users to see some machines and not others, and so on.   All of the Managers must be registered in the DefaultGlobalManagerConfiguration table on the PTC.BaseManager thing, or in the ManagerConfiguration table of any entity that implements the PTC.Base.ConfigManagement_TS thing shape. Naming conventions should also be kept standard across blocks, and details on those best practices can be found in the Build Block Help Center.   Extending the Data Model Using Building Blocks Customizing the data model using building blocks is pretty straight-forward, but there are some design considerations to be made. One way to customize the data model is to add custom properties to existing data model entities. For instance, let’s say you need an additional field to keep track of the location of a job order, and so you could add a City field to PTC.JobOrder.JobOrder_AP data shape. However, doing this also requires substantial modification to the PTC.JobOrder.Manager thing, if the new data shape field is meant to interface with the database.   So this method is not as straight-forward as it may seem, but it is the easiest solution in an “object-oriented” design pattern, one where the data varies very little from site to site, but the logic that handles that data does vary. In this design pattern, there will be a thing shape for each implementing building block that handles the same data shape the abstract building block uses, just in different ways. A common use case for why this may happen is if the UI components vary from site to site or region to region, and the logic that powers them must also vary, but the data source is relatively consistent.   Another way to extend the data model is to add custom data shapes and custom managers to go with them. This requires you to create a new custom building block, one which extends the base entry point as needed for the type of block. This method may seem more complicated than just extending a data shape, but it is also easier to do programmatically: all you have to do is create a bunch of entities (thing templates, thing shapes, etc.) which implement base entities. A fresh data shape can be created with complete deliberation for the use case, and then services which already exist can be overridden to handle the new data shape instead. It is a cleaner, more automation friendly approach.   However, the database will still need to be updated, and this time CRUD services are necessary as well, those for creating and managing instances of the data shape. So, this option is not really less effort in the short term. In the long-term, though, scripts that automate much of the process for building block generation can be used to quickly and easily allow for development of new modules in a more complex ThingWorx solution. The ideal is to use abstract blocks defined by the nature of the data shape which each of their implementing blocks will use to hook the view into the data model.   This “data-driven” design pattern is one which involves creating a brand-new block for each customization to the data model. The functionality of each of these blocks centers around what the data table and constraints must look like for that data store, and the logic to handle the different data types should vary within each implementation block, but override the common abstract block interface so that any data source can be plugged into the thing model, and ThingWorx will know what to do with it.   The requests can then contain whatever information they contain (like MQTT), and which logic is chosen to process that data will be selected based on what information is received by the ThingWorx solution for each message. Data shapes can be abstracted in this way, so that a single subscription need exist to the data shape used in the abstract building block, and its logic knows how to call whatever functions are necessary based on whatever data it receives. This allows for very maintainable API creation for both data ingestion and event processing.
View full tip
  Step 6: Building the Data Model   You can build your data model using different methods. You can build your data model where the Data Shapes match with your tables, but what you'll realize over time is that you will often need custom Data Shapes. When you query for data, you will often need data from differing tables to be in one result set. Because of this, I suggest against making your data model based on the tables. You can start the basis for your model with the tables in mind, but know that this won't be the basis for long.   Create Data Shapes   Let's start by setting up two queries and the Data Shapes to match. The first query will be to find the list of classes a student is assigned to and query will be completed here. The second query will be to find all student in an active class and we'll ask you to create it based on how we did the first one.   1. In the ThingWorx Composer, click the + New button in the top left.    2. In the dropdown list, click Data Shapes.   3. Name the Data Shape DataShape.StudentCourses   4. Add the set of fields below. You may notice, we included information from the Person table that we might already have. This is perfectly fine based on how much data you expect to come back. This will allow you to reuse this database for other purposes later where the person information might change. This can be very beneficial when you're calling a service with this Data Shape (or InfoTable based on this Data Shape). Allowing you to keep the input simple.    Name Base Type  Additional Info   id  STRING Primary Key   person_key  STRING  N/A  person_name_first  STRING  N/A  person_name_last  STRING  N/A  course_key  STRING  N/A  course_name  STRING  N/A  course_professor  STRING  N/A   Let's add in our database query and use our new Data Shape.    1. Open the DatabaseController.Facilities entity and go to the Services tab. If you have not done so as yet, add the configuration information to allow your queries to connect to a database. 2. Create a new service of type SQL (Query) called GetStudentEnrollment. 3. Click Save and Continue to save your changes.   4. Add a parameter to the service title email. It will have a String base type and be required. 5. Add the following query to the canvas.         SELECT person_key, person_name_first, person_name_last, course_key, course_name, course_professor FROM Person person INNER JOIN PersonCourses pc ON person.person_key = pc.person_key INNER JOIN Courses courses ON courses.course_key = pc.course_key WHERE person.person_email = [[email]]​           6. For the output of the service, InfoTable should be there by default. If not, switch the output to be an InfoTable. For the Data Shape, set it to the Data Shape we just created, DataShape.StudentCourses.   You now have a database where you can run your queries and use the responses to bind to Widgets in Mashups.    We have our database connection and a data model setup to handle our current queries. This might be where you begin to question if you would like to add Data Tables. This is more of a design choice. You might want to keep datasets in a Data Table for quick access or separation. Nevertheless, if you already have you database, you won't need many (if any) Data Tables.     Step 7: Next Steps   Congratulations! You've successfully completed the guide for Connecting to an External Database, and learned how to use the ThingWorx Platform to connect to database, query for data, and write new data.   The next guide in the Utilizing ThingWorx to Secure Your Aerospace and Defense Systems learning path is Low Level Device Connection.   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Design Your Data Model Build Configure Permissions   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum
View full tip
Euromap 63 Driver -Injection molding machines are generally unconnected -First out of the box connectivity in this market: was quickly followed by a Softing Euromap 63 driver -Provides personas across the enterprise visibility into IMM production -File based protocol -KEPServerEX access to a shared folder is required: read/write/edit/delete permissions are necessary can be a mapped drive -Timing is not well defined in specification: -File locking race conditions are possible -Driver designed to minimize issues -Manufacturers have implemented specification in different ways Testing has indicated significant variances Driver has relaxed parsing rules Allows for vendor inconsistency Fanuc Focas Ethernet Driver Fanuc Focas Ethernet: -Driver to connect to Fanuc CNC Controllers -Fanuc controls ~80% of the CNC market (Siemens, Mazak, Okuma, Haas and Hedenhain control remainder) -ThingWorx has connectivity to all except Heidenhain -Prior to 8.4, ThingWorx could access summary information: Machine status Alarm status -K737 Library support -K738 Library was recently discontinued With 8.4, ThingWorx has access to 100s of parameters - cnc_rdparam provides access to additional NC data such as: Axis position information Spindle speed Etc Parameter access is model specific -Users must read controller model manual to indentify which parameters are available -Addressing scheme is numeric cnc_rdparam.0 - cnc_rdparam.37267 SCM in C SDK Enables custom connectivity applications with SCM: -Content update -Configuration updates -Firmware upgrade Developers can now build SCM directly into their applications Security features built in: -Digital signing -Script whitelist .NET SDK and Reboot support coming soon   When EMS does not need to be installed for SCM, does this mean that any custom Agent can be developed now to push software updates remotely to the devices/machines? -It means that any application can be built using the C-SDK in order to push software updates   For more information: Reference documents can be found here 8.4 Release notes
View full tip
In this video we cover the installation of the platform analytics services which include: Descriptive services and property transform services.  
View full tip
I have implemented an Edge Nano Server that offers the following advantages: Easy to setup Not limited to HTML protocol.  For example, an edge device can be implemented that connects to devices via Bluetooth Code can be found here: GitHub - cschellberg/EdgeGateway Code contains EdgeNanoServer, docker installation scripts(for installing Thingworx Platform), and a test client done in python. Don Schellberg Consultant
View full tip
Now that ThingWorx 9.3 is live, let’s take a closer look at some of our new features we released for Composer and Mashup Builder.   Referenced By Find where entities, code references, and project dependencies are used in your existing projects using the new “Referenced by” report feature. This feature is not automatically enabled because it is intended to be used during development, since it can call upon all of the entities in your project and can impact your load times in production. That being said, this is your friendly reminder to turn off this feature during production.     How to enable: Go to the relationship subsystem and tick the check box to enable during development.   How it works: The “Referenced By” feature finds any entity that is referenced in your ThingWorx environment based on the supplied search characteristics. You can run this “Referenced By” report in the Composer or via a ThingWorx service “GetWhereUsed”.  When you use the “Referenced By” feature on an entity, you can find all of the references in the system for that entity in Mashup bindings, service script references, thing property bindings, and more.     Grid Widget The new grid widget component, which was available for preview in ThingWorx 9.2, is now complete, so it’s time to get your grid on! We have improved styling and performance capabilities with this new widget, including greater support for inline editing, autocreation of columns based on infotables, and adding new footer areas. You can also configure the grid using the property editor in Mashup Builder, where previously we had plain text entry.   Style Migration The new Style Migration is a game changer. It allows you to retain the same look and feel of your Mashups as you upgrade from previous versions of ThingWorx to the newest web components and features available in 9.3. Improved from our previous migrator, this allows you to move to the latest platform version and capabilities without having to re-implement or redesign your applications and widgets.     How it works: When you upgrade to the latest version of ThingWorx, you will see a pop-up window appear if you have any legacy widgets or layouts in your Mashup. The window will have the option for you to apply one of three style themes to your Mashup: PTC Convergence Theme (the new ThingWorx Default theme), Legacy Styles Theme (the old ThingWorx theme, from version 8.0 and earlier), or Custom Theme (choose from custom themes you defined using the Theme Editor and Style Theme that will appear when custom theme is selected in the pop-up). Depending on how you already styled or would like to style your Mashups, select an option and click migrate. This migrator maintains previous coloring, spacing, and other design properties better than previous migrators. You, of course, have the option to not upgrade your Mashup, but we recommend that you migrate, especially where we have new widgets available to replace legacy versions. If there are any issues with your migration, you can always click “Undo” in the toolbar.   Things to Consider: This migration will work best with ThingWorx default styling, out of the box styling, and Mashups with widgets that we now have replacements for (these are marked legacy in the builder). Always make sure you review your Mashups to make sure bindings and properties remained. Note that custom CSS will not be migrated, and custom widgets developed outside the standard platform installation will remain the same on the new Mashup.   Other Bonus Features That’s not all we rolled out in ThingWorx 9.3. You will also see Composer enhancements for test execution on ThingTemplates and dynamic use of Master Mashups to allow for swapping out Masters at run time based on predefined conditions based on your users. Plus, we now have truncation support for the breadcrumb component and tabs component, which utilizes an ellipsis pattern for long  text for a more user-friendly application.  With enhancements to our charts, you can now show/hide legends and format axis in new ways. We also support localization for our new web component widgets, .   How has your experience been building solutions with the latest updates to Composer and Mashup Builder? How can we continue to build upon these enhancements? Let us know what you think.   Stay connected, Rachel
View full tip
This video concludes Module 8: Time Series Modeling of the ThingWorx Analytics Training videos. 
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
When an Expression Rule of type MobileLocation calls a Groovy script, the script is provided with the implicit object mobileLocation.  This example shows how the mobileLocation object can be used. This Expression Rule calls the Groovy script 'getAddress' to retrieve the location and translate it into a street address: Type:  MobileLocation IF:      some condition e.g. true THEN:  SetDataItem("location", str(ExecuteCustomObject("getAddress"))) The 'getAddress' script uses the mobileLocation object to retrieve the asset's reported location, and then calls a REST service to translate a given latitude and longitude to a street address.  The street address is returned. import groovyx.net.http.RESTClient String rmdHostname =  "http://ws.geonames.org"; if (mobileLocation != null) { rmd = new RESTClient(rmdHostname); try {       def resp = rmd.get( path: 'findNearestAddress',                       query:[lat:mobileLocation.lat , lng:mobileLocation.lng] )        streetnum = resp.data.address.streetNumber.text()        street = resp.data.address.street.text()        town = resp.data.address.adminName2.text()        state = resp.data.address.adminCode1.text()        postalcode = resp.data.address.postalcode.text()            return streetnum + " " + street + " " +  town + " " + state + " " + postalcode } catch (groovyx.net.http.HttpResponseException e) {     e.printStackTrace();     } }
View full tip
This groovy script will return a list of users based off a given UserGroup and allows for filtering by username. import com.axeda.drm.sdk.Context import groovyx.net.http.HTTPBuilder import static groovyx.net.http.ContentType.* import static groovyx.net.http.Method.* import net.sf.json.JSONObject import groovy.json.* import com.axeda.drm.sdk.data.* import com.axeda.drm.sdk.device.* import com.axeda.drm.sdk.user.UserFinder import com.axeda.drm.sdk.user.User import com.axeda.drm.sdk.user.UserGroupFinder //-------------------------------------------------------------------------------------------------------------------- // Example of getting Users from a User Group and filtering by username // //-------------------------------------------------------------------------------------------------------------------- def response = [:] def result = [] try {     final def CONTEXT = Context.create(parameters.username)       UserFinder uFinder = new UserFinder(CONTEXT)     UserGroupFinder ugFinder = new UserGroupFinder(CONTEXT)     List userGroups = getUserGroupsList(ugFinder, "*Demo*")     List SmithsInDemoGroup = userGroups.collect{ usergroup ->         usergroup.getUsers().findResults{ user ->             if (user.username =~ /Smith/){                                      user                                      }                      }     }.flatten()     SmithsInDemoGroup.each{ u ->         result << u.fullName     }   response = [     result: [             items: result     ]   ] } catch (Exception e) {     def m = ""     e.message.each { ex -> m += ex }     response = [                 faultcode: 'Groovy Exception',                 faultstring: m             ]; } return ['Content-Type': 'application/json', 'Content': JSONObject.fromObject(response).toString(2)];   def getUserGroupsList(UserGroupFinder ugFinder, String name){     ugFinder.setName(StringQuery.like(name))     def userGroup = ugFinder.findOne()     List userGroups = new ArrayList();     userGroups.add(userGroup);     return userGroups }
View full tip
Hiya,   I recently prepared a short demo which shows how to onboard and use Azure IoT devices in ThingWorx and added some usability tips and tricks to help others who might struggle with some of the things that I did.     The good news... I recorded and posted it to YouTube here.   •Connect Azure IoT Hub with ThingWorx (to be updated soon for 9.0 release) •Using the Azure IoT Dev Kit with ThingWorx •Getting the Azure IoT Hub Connector Up and Running (V3/8.5)   Enjoy, and don't hesitate to comment with your own tips and feedback.   Cheers,   Greg
View full tip
  Utilize the C SDK to build an app that creates a secure connection to ThingWorx with low level device access.   Guide Concept   This project will cover using the ThingWorx C SDK to develop applications for the purpose of secure and low level development.   Following the steps in this this guide, you will be ready to develop your own IoT application with the ThingWorx C SDK.   We will teach you how to use the C programming language to connect and build IoT applications to be used with the ThingWorx Platform.       You'll learn how to   Establish and manage a secure connection with a ThingWorx server, including SSL negotiation and connection maintenance. Enable easy programmatic interaction with the Properties, Services, and Events that are exposed by Entities running on a ThingWorx server. Basic concepts of the C Edge SDK How to create an application that can communicate with other devices   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL parts of this guide is 60 minutes       Step 1: Completed Examples   Download the completed files attached to this tutorial: C_SDK.zip.   This tutorial will guide you through working with the C SDK on differing levels. Utilize this file to see a finished example and return to it as a reference if you become stuck creating your own fully flushed out application. With the C SDK, you can connect to whatever device you have at a level most programming languages wouldn't be able to. Now think of your secure system, your fighter jet, or even you communication devices. All these systems and levels need to have a way to secure transfer data and the C SDK is how we do it.   Keep in mind, this download uses the exact names for entities used in this tutorial. If you would like to import this example and also create entities on your own, change the names of the entities you create.     Step 2: Environment Setup   In order to compile C code, download the attached C compiler: C-SDK-2-2-12-1052.zip.    Operating System          Notes Windows You will need a 3rd party compiler such as MinGW GCC, Cygwin GCC or you can follow these Microsoft instructions to download and use the Microsoft Visual C++ Build Tool. Mac Download the Apple Developer Tools. Linux/Ubuntu A compiler is included by default.   NOTE: You can use CMake, version 2.6.1 or later to build projects or make files, which then are used to build the applications that you develop with the C SDK. Before you can begin developing with the ThingWorx C SDK, you need to generate an Application Key and modify the source code file. You can use the Create an Application Key as a reference.   Modify Source File   Extract the files from the C SDK samples zip file. At the top level of the extracted files, you will see a folder called examples, which provides examples of how to utilize the C SDK. Open a terminal, go to your workspace, and create a new project. After you've created this project in your workspace, import the entire C SDK downloaded from the PTC Support site for ease of use (mainly the src folder and the CMakeList.txt file). You can start creating your connection code or open the main.c source file in the examples\SteamSensor\src directory for an example.    Operating System        Code Linux/Ubuntu gedit main.c OR vi main.c Mac open –e main.c Windows start main.c   5. Modify the Server Details section at the top with the IP address for your ThingWorx Platform instance and the application key you would like to use. Change the TW_HOST definition accordingly. Change the TW_PORT definition accordingly. Change the TW_APP_KEY definition to the keyId value saved from the last step. /* Server Details */ #define TW_HOST "https://pp-XXXXXXXXX.devportal.ptc.i" #define TW_PORT 80 #define TW_APP_KEY "e1d78abf-cfd2-47a6-92b7-37dc6dd34618" NOTE: Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a user and place the user as a member of Admins.   Compile and Run Code   To test your connection, you will only need to update the main.c in the SteamSensor example folder.   CMake can generate visual studio projects, make build files or even target IDEs such as Eclipse, or XCode. CMake generates a general description into a build for your specific toolchain or IDE.   If you have not downloaded and installed CMake, do it now at the CMake website. NOTE: CMake comes as a command line and a GUI application. The steps in this guide use the command line version only. Inside the specific example folder you would like to run, ie SteamSensor. Create a directory to build in, for this example call it cmake. mkdir cmake cd cmake 4. Run the CMake command listed below. This assumes CMake is already on your PATH. cmake -G "Visual Studio 15 2012" .. 5. CMake has now produced a set of project files which should be compatible with your development environment.  Operating System    Command                                        Notes Unix command-> make A set of make files Windows **msbuild tw-c-sdk.sln /t:build** A visual studio solution NOTE: CMake does its best to determine what version of Visual Studio you have but you may wish to specify which version to use if you have more than one installed on your computer. Below is an example of forcing CMake to use a specific version of Visual Studio: cmake -G "Visual Studio 15 2017" .. If your version of Visual Studio or other IDE is unknown, use cmake -G to see a list of supported IDEs.   You also have the alternative of opening the tw-c-sdk.sln from within Visual Studio and building in this IDE.   NOTE: By default, CMake will generate a build for the creation of a release binary. If you want to generate a debug build, use the command-> cmake -DBUILD_DEBUG=ON.   6. Once your build completes you will find the build products in the cmake directory. From here, open the project in your IDE of choice. NOTE: You should receive messages confirming successful binding, authentication, and connection after the main.c file edits have been made.       Step 3: Run Sample Code   The C code in the sample download is configured to run and connect to the Entities provided in the ThingWorxEntitiesExport.xml file. Make note of the IP address of your ThingWorx Composer instance. The top level of the exported zip file will be referred to as [C SDK HOME DIR]. Navigate to the [C SDK HOME DIR]/examples/ExampleClient/src directory. Open the main.c source file.  Operating System      Command Linux/Ubuntu gedit main.c OR vi main.c Mac open –e main.c Windows start main.c   3. Modify the Server Details section at the top with the IP address for your ThingWorx Platform instance and the Application Key you would like to use. Change the TW_HOST definition accordingly. NOTE: By default, TW_APP_KEY has been set to the Application Key from the admin_key in the import step completed earlier. Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a user and place the user as a member of the Admins security group. /* Server Details */ #define TW_HOST "127.0.0.1" #define TW_APP_KEY "ce22e9e4-2834-419c-9656-e98f9f844c784c"   4. If you are working on a port other than 80, you will need to update the conditional statement within the main.c source file. Search for and edit the first line within the main function. Based on your settings, set the int16_t port to the ThingWorx platform port. 5. Click Save and close the file. 6. Create a directory to build in, for this example call it bin.  Operating System            Command Linux/Ubuntu mkdir bin Mac mkdir bin Windows mkdir bin   7. Change to the newly created bin directory.  Operating System              Command Linux/Ubuntu cd bin Mac cd bin Windows cd bin   8. Run the CMake command using your specific IDE of choice. NOTE: Include the two periods at the end of the code as shown below. Use cmake -G to see a list of supported IDEs. cmake ..   9. Once your build completes, you will find the build products in the bin directory, and you can open the project in your IDE of choice. NOTE: You should receive messages confirming successful binding, authentication, and connection after building and running the application. 10. You should be able to see a Thing in your ThingWorx Composer called SimpleThing_1 with updated lastConnection and isConnected properties. SimpleThing_1 is bound for the duration of the application run time.   The below instructions will help to verify the connection.   Click Monitoring. Click Remote Things from the list to see the connection status. You will now be able to see and select the Entity within the list.       Step 4: ExampleClient Connection   The C code provided in the main.c source file is preconfigured to initialize the ThingWorx C Edge SDK API with a connection to the ThingWorx platform and register handlers. In order to set up the connection, a number of parameters must be defined. This can be seen in the code below.   #define TW_HOST "127.0.0.1" #define TW_APP_KEY "ce22e9e4-2834-419c-9656-ef9f844c784c #if defined NO_TLS #define TW_PORT = 80; #else #define TW_PORT = 443; #endif   The first step of connecting to the platform: Establish Physical Websocket, we call the twApi_Initialize function with the information needed to point to the websocket of the ThingWorx Composer. This function:   Registers messaging handlers Allocates space for the API structures Creates a secure websocket err = twApi_Initialize(hostname, port, TW_URI, appKey, NULL, MESSAGE_CHUNK_SIZE, MESSAGE_CHUNK_SIZE, TRUE); if (TW_OK != err) { TW_LOG(TW_ERROR, "Error initializing the API"); exit(err); }   If you are not using SSL/TLS, use the following line to test against a server with a self-signed certificate: twApi_SetSelfSignedOk();   In order to disable HTTPS support and use HTTP only, call the twApi_DisableEncryption function. This is needed when using ports such as 80 or 8080. A call can be seen below:   twApi_DisableEncryption();   The following event handlers are all optional. The twApi_RegisterBindEventCallback function registers a function that will be called on the event of a Thing being bound or unbound to the ThingWorx platform. The twApi_RegisterOnAuthenticatedCallback function registered a function that will be called on the event the SDK has been authenticated by the ThingWorx Platform. The twApi_RegisterSynchronizeStateEventCallback function registers a function that will be called after binding and used to notify your application about fields that have been bound to the Thingworx Platform.   twApi_RegisterOnAuthenticatedCallback(authEventHandler, TW_NO_USER_DATA); twApi_RegisterBindEventCallback(NULL, bindEventHandler, TW_NO_USER_DATA); twApi_RegisterSynchronizeStateEventCallback(NULL, synchronizeStateHandler, TW_NO_USER_DATA);   NOTE: Binding a Thing within the ThingWorx platform is not mandatory, but there are a number of advantages, including updating Properties while offline.    You can then start the client, which will establish the AlwaysOn protocol with the ThingWorx Composer. This protocol provides bi-directional communication between the ThingWorx Composer and the running client application. To start this connection, use the line below:   err = twApi_Connect(CONNECT_TIMEOUT, RETRY_COUNT); if(TW_OK != err){ exit(-1); }   Click here to view Part 2 of this guide.      
View full tip
Push update what is it? It is a mechanism that GetProperties supports so that the Server can push a value to a client mashup. This will allow you to see values update in your mashup real time without needing the refresh widget. Another great way to use the push updates is to propagate events that tie to specific content fetches. Let's say your mashup has three areas: KPIs, Alerts, Live values. Using some logic server side you can set up a 'tracker' Thing with properties that indicate that one of those areas has updated data. Bring these notifications as property values into the mashup using GetProperties and as the Server pushes updates to the mashup runtime, you can map it to a Validator or Expression widget (set to autoevaluate) which in turn can now run the necessary Service to fetch the updated information for the specific area.
View full tip
Here is a sample to run ConvertJSON just for test 1. Create a DataShape 2. There are 4 input for service ConvertJSON fieldMap (The structure of infotable in the json row) json (json content)   { "rows":[         {             "email":"example1@ptc.com"         },         {             "name":"Lily",             "email":"example2@ptc.com"         }     ] } rowPath (json rows that indicate table information) rows dataShape (infotable dataShape) UserEmail
View full tip
This video continues Module 8: Time Series Modeling of the ThingWorx Analytics Training videos. It continues to show how ThingWorx Analytics automatically transforms time series datasets into ones that are ready for machine learning. It also describes the concept of virtual sensors. It finishes by describing the time series dataset that will be used in the following modules.
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
Aron Semle, Manufacturing Apps Solution Manager discusses and demonstrates new capabilities in the ThingWorx Manufacturing Apps 8.1 release.
View full tip
  When it’s time to make pizza, most of us head to the fridge for our bag of dough; we don’t head for the flour and yeast to start from scratch. So, why would your ThingWorx apps be any different? Start with pre-built solutions like Asset Advisor to rapidly create health monitoring apps and dramatically reduce your development time.   We previously introduced Asset Advisor on Episode 04 of “ThingWorx on Air.” Today, we dive deeper into Asset Advisor with Greg Huet, Asset Advisor’s technical product manager (aka product owner). Listen to Ep. 06: Rapidly Build IIoT Apps for Service & Monitoring with Asset Advisor to hear Greg share our strategy of studying existing use cases and finding similarities that we can pre-build into solutions so that you don’t have to build them from scratch. Hear how you can use Asset Advisor out-of-the-box with tweaks for your company’s configurations or as an accelerated starting point where you can add as much customization as your use case desires—it’s like building a custom pizza, but starting with pre-made dough, rather than yeast and flour.   Greg also mentions the ThingWorx Application Development Guide. Be sure to check out my previous post, where Ward, one of the document creators, shares four of his top tips from the guide.   Now, sit back, relax and go enjoy some pizza while you listen to Episode 06.   As always, stay connected! Kaya
View full tip
This video begins Module 6: Predictive Models & Model Validation of the ThingWorx Analytics Training videos. It gives examples of different types of goal variables. It also discusses data considerations in predictive modeling, It begins describing the machine learning algorithms used by ThingWorx Analytics to build predictive models. 
View full tip
User Load Testing in ThingWorx Java Client Tutorial Written by Tori Firewind, IoT EDC   Introduction As stated in previous posts, user load testing is a critical component of ensuring a ThingWorx solution is Enterprise-ready. Even a sturdy new feature that seems to function well in development can run into issues once larger loads are thrown into the mix. That's why no piece of code should be considered production-ready until it has undergone not just unit and integration testing (detailed in our Comprehensive DevOps Guide), but also load testing that ensures a positive user experience and an adequately sized server to facilitate the user load.    The EDC has spent quite a few posts detailing the process of setting up an accurate, real-world testing suite using JMeter for ThingWorx. In this piece, we detail an alternative approach that makes use of the Java Spring Boot Framework to call rest requests against the ThingWorx server and simulate the user load. This Java Client tutorial produces a very immature user load client, one which would still take a lot of development to function as flexibly as the JMeter tutorial counterpart. For Java developers, however, this is still a very attractive approach; it allows for more custom, robust testing suites that come only as an investment made in a solid testing tool.   For someone experienced in Java, the risk is smaller of overlooking some aspect of simulation that JMeter may have handled automatically. For example, JMeter automatically creates more than one HTTP session, and it's much easier to implement randomized user logins instead of one account. The Java Client could do it with some extra work (not demonstrated here), but it uses just the Administrator login by default for a quick and dirty sort of load test, one focused less on the customer experience and more on server and database performance under the strain of the user requests (the method used in our sizing guidance, for instance, to see if a server is sized correctly).   The amount of time required to develop a Java Client isn't so bad for a Java developer, and when compared with learning the JMeter Framework, might be a better investment. A tool like this can handle a greater number of threads on a single testing VM; JMeter caps out around 250 threads per client on an 8Gb VM (under ideal conditions), while a Java Client can have thousands of threads easily. Likewise, a Java Client has less memory overhead than JMeter, less concern for garbage collection, and less likelihood that influence from heap memory management will affect the test results.   However, remember that everything in a Java Client has to be built from scratch and maintained over time. That means that beyond the basic tutorial here, there needs to be some kind of metrics gathering and analysis tool implemented (JMeter has built-in reporting tools), the calls need to be randomized, and not called at set intervals like they are here (which is not a very accurate representation of user load compared to a real-world scenario), and the number of users accessing the system at once should probably vary over time (to resemble peak usage hours). JMeter has a recording tool to ensure all the necessary REST requests to simulate a mashup load are made, so great care has to be taken to ensure all of the necessary REST calls for a mashup are made by the Java Client if a true simulation is called for by that approach.    Java Client Tutorial   Conclusion Neither a Java Client nor a JMeter testing suite is inherently better than the other, and both have their place within PTC's various testing processes. The best test of all is to stand up any sort of user load testing client, either of these approaches, at the same time as the UAT or QA user experience testing. QA testers who load and click about on mashups in true, user fashion can then see most accurately how the mashups will perform and what the users will experience in the Enterprise-ready, production application once the changes go out.
View full tip
Announcements