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:                     Asia Garrouj Original Post Date:            June 13, 2017 Applicable Releases:        ThingWorx Analytics 8.0   Description: This video is the second of a 3 part series walking you through how to setup ThingWatcher for Anomaly Detection. In this second video you will learn how to use the "Discover UI" from the NextGen Composer to bind simulated data coming thru KEPServer for Anomaly Detection.    
View full tip
Developing with Axeda Artisan (for Axeda Platform, v6.8 and later) Axeda Artisan is a development tool based on the Apache Maven build system. Artisan includes authoring, management, and deployment mechanisms that define and manage the development of Axeda Platform extension points, allowing you to flexibly install, update, and uninstall many types of objects on the Axeda Platform. The Components of Artisan The Artisan framework is comprised of several components: The Axeda Platform Each instance of the Axeda Platform contains libraries and sample Artisan Projects (archetypes) that are downloaded by developers to author and deploy their own Artisan Projects. The Artisan Project An Artisan Project is a collection of content and configuration files that are used to define a set of objects that will be installed on the Axeda Platform. The Artisan Installer The Artisan Installer is a flexible, configurable application that uses the Apache Maven build life-cycle to upload the contents of an Artisan Project to the Axeda Platform. Axeda Platform APIs The Artisan Installer interacts with the Axeda Platform and uses Axeda APIs to install, upgrade, or uninstall ArtisanProjects. How You Work With Artisan The goal of using Artisan is to develop an Artisan Project that will become an object or application that runs on the Axeda Platform. There are several phases involved in creating an Artisan Project: Preparing Your Development Environment – When first working with Artisan, you need to prepare your development environment by installing or configuring Java, Apache Maven, and any other required development tools. Creating an Artisan Project – Artisan uses archetypes as the basis for Artisan Projects. Archetypes are used to generate an Artisan Project that contains the correct type of development framework, which you then modify to create your own Artisan Project: The Hello World archetype provides a sample project you can use to create common objects on the Axeda Platform. The Machine Streams archetype provides a sample project you can use to configure machine streams for your Axeda Platform. Installing an Artisan Project on the Axeda Platform – The Artisan Installer packages the contents of the Artisan Project, and deploys them on the Axeda Platform. Testing the Artisan Project – Once installed, you can test your Artisan Project to verify its functionality and identify any issues that need to be addressed. It is common for an Artisan Project to be installed on the Axeda Platform several times as issues are identified and corrected during development. Creating a Stand-alone Installer – Once ready for deployment to production, the Artisan Installer is used to create a stand-alone installer for distributing the project contents to other instances of the Axeda Platform. Where to Go from Here To begin working with the Artisan framework to create your own projects, refer to the following: Artisan Landing Page – A page hosted on the Axeda Platform that introduces Artisan and serves as a starting point for creating an Artisan Project. The Artisan Landing Page can be found at the following location: http://instance_name:port/artisan                     Where instance_name:port/ is the ip address and port of an instance of the Axeda Platform. Axeda® Artisan Developer’s Guide – A reference that introduces Artisan, describes how to prepare your development environment, and provides detailed technical information concerning creating an Artisan Project and configuring the Artisan Installer. The Axeda® Artisan Developer’s Guide is available with all Axeda product documentation from the PTC Support site, http://support.ptc.com/
View full tip
Build an Equipment Dashboard Guide Part 1   Overview   This project will introduce you to the principles of ThingWorx Foundation by creating an eqipment dashboard. Following the steps in this guide, you will create the building blocks of your first IoT application, including Things and Streams. We introduce the basics for creating an IoT application. NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL 2 parts of this guide is 30 minutes.    Step 1: Learning Path Overview   This guide explains the steps to create an Industrial Eqipment Dashboard, and is part of the Connect and Monitor Industrial Plant Equipment Learning Path. You can use this guide independently from the full Learning Path. If you want to learn the basics of creating an eqipment dashboard with ThingWorx, this guide will be useful to you.When used as part of the Industrial Plant Learning Path, you should already have ThingWorx Kepware Server installed, and it should be sending data to ThingWorx Foundation. You also need to have previously created the Thing Shape and Thing Template used for this dashboard. We hope you enjoy this Learning Path.   Step 2: Create Thing   A Thing is used to digitally represent a specific component of your application in ThingWorx. In Java programming terms, a Thing is similar to an instance of a class. In this step, you will create a Thing that represents an individual Pump using the Thing Template we created in the previous guide. Using a Thing Template allows you to increase development velocity by creating multiple Things without re-entering the same information each time. In ThingWorx Foundation, navigate to Browse > Modeling > Things. Click + New. In the Name field, type MyPump. NOTE: This name, with matching capitalization, is required for the data display created in a later step.       4. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject.       5. In the Base Thing Template field, search for and select the previously-created PumpTemplate.       6. At the top, click Save.          Manage Property Bindings At the top, click Properties and Alerts. At the top, click Manage Bindings. In the top-left Local > Search Things field, search for and select IndConn_Tag1. Drag-and-drop Simulation_Examples_Functions_Random3's + symbol onto the watts Property on the right. At the bottom-right of the pop-up, click Done. Note how the Tag from ThingWorx Kepware Server is now bound to the the watts Property. Click Save. Click Refresh repeatedly to confirm the watts Property value is changing.     Step 3: Store Data in Value Stream   Now that you have created the MyPump Thing to model your application in ThingWorx, you need a storage Entity to record changing Property values. This step shows how to save time-series data in a Value Stream already created in a previous guide. To learn more, refer to the Methods for Data Storage guide. Navigate to Browse > Modeling > Thing Templates. Click the previously-created PumpTemplate Thing Template to open it. Confirm you are on the General Information tab. If necessary, click Edit to allow changes. In the Value Stream field, search for and select IndConn_ValueStream. Click Save.   Step 4: Create Application UI   ThingWorx Foundation is used to create customized web applications that can display and interact with data from multiple sources. These web applications are called Mashups and are created using the Mashup Builder. The Mashup Builder is where you create your web application by dragging and dropping Widgets such as Grids, Charts, Maps, and Buttons onto a Canvas. All of the user interface elements in your application are Widgets. We will build a web application with three Widgets: Image showing a picture of the pump Value Display showing the pump serial number Line Chart showing the value of watts Property trend over time.   Create New Mashup   Navigate to Browse > Visualization > Mashups.   Click + New.   Keep the defaults and click OK.   In the Name field, type pump-dashboard. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. Click Save.   At the top, click Design.   Define Mashup Areas   At the top-left, ensure the Layout tab is selected. Click Add Bottom to split your UI into two halves.   Click the newly-created bottom-half to select it. Click Add Left.   Click the bottom-left container to select it. In the top-left Layout section, scroll down and select Fixed Size.   Type 200 in the Width text box that appeared, then press your keyboard’s Tab key to record your entry.   Add Widgets   In the top-left, click the Widgets tab.   In the Filter field, type image.   Drag-and-drop an Image Widget onto the lower-left area of the central Canvas. This Widget will show an image of the pump in use. 4. In a similar manner to what was just done with the Image Widget, drag-and-drop a Value Display Widget onto the top area. 5. Likewise, drag-and-drop a Line Chart Widget onto the lower-right area.   6. Click Save.          Click here to view Part 2 of this guide. 
View full tip
In this particular scenario, the server is experiencing a severe performance drop.The first step to check first is the overall state of the server -- CPU consumption, memory, disk I/O. Not seeing anything unusual there, the second step is to check the Thingworx condition through the status tool available with the Tomcat manager. Per the observation: Despite 12 GB of memory being allocated, only 1 GB is in use. Large number of threads currently running on the server is experiencing long run times (up to 35 minutes) Checking Tomcat configuration didn't show any errors or potential causes of the problem, thus moving onto the second bullet, the threads need to be analyzed. That thread has been running 200,936 milliseconds -- more than 3 minutes for an operation that should take less than a second. Also, it's noted that there were 93 busy threads running concurrently. Causes: Concurrency on writing session variable values to the server. The threads are kept alive and blocking the system. Tracing the issue back to the piece of code in the service recently included in the application, the problem has been solved by adding an IF condition in order to perform Session variable values update only when needed. In result, the update only happens once a shift. Conclusion: Using Tomcat to view mashup generated threads helped identify the service involved in the root cause. Modification required to resolve was a small code change to reduce the frequency of the session variable update.
View full tip
    Learn how to connect, query, insert, and handle data from an external database.   GUIDE CONCEPT   This project will introduce how to utilize and incorporate an external database with the ThingWorx Platform.   Following the steps in this guide, you will connect the ThingWorx Platform to a database, insert data, execute stored procedures, and query data.      YOU'LL LEARN HOW TO   Connect ThingWorx to external databases Query databases and and handling results Insert data and running stored procedures   NOTE: The estimated time to complete this guide is 60 minutes.     Step 1: Completed Example   Download the attached DatabaseApplication.zip and import it into ThingWorx Composer. This download will provide examples that can be used as a reference or as a final copy as you walk through this guide.   In this tutorial, you will learn how to query data and write data to live external databases. The zip file provided contains the following files and entities as a completed version of the scenario to be covered. Import the .twx files into ThingWorx in any order. Run the SQL Server table scripts in a database you have setup followed by the stored procedures.      Name                                                 Description                                                                      Type SQLServerDatabaseController A connected entity for use with an SQL Server database ThingWorx Entity OracleDatabaseController A connected entity for use with an Oracle database ThingWorx Entity AddStudentToCourse.sql Stored procedure to add students to a course in a SQL Server database Database Stored Procedure GetStudentInCourse.sql Stored procedure to information about students in a course in SQL Server database Database Stored Procedure Course.sql SQL Server table representing Courses Database Stored Procedure Person.sql SQL Server table representing Students Database Stored Procedure PersonCourses.sql SQL Server table representing the connection between Students and Courses Database Stored Procedure     This guide will use connections to a SQL Server database, however you can use ANY database that can be used with the Java programming language. Based on the database you will be using, please perform the installation process for that database and create a user with READ, WRITE, and EXECUTE permissions. Ensure the password is set for this user and keep in mind that a UI for the database connection is not needed, but it can make things a bit simpler.      Database Download                       Installation Documentation           Jar File Download SQL Server Download SQL Server Installation SQL Server Jar File Oracle Download Oracle Installation Oracle Jar File     Please follow the below steps to enable a connection between ThingWorx and your database of choice: Ensure the user you created has read, write, and execute permissions. If you would rather split roles, you can create multiple users to handle each aspect. The execute permission for stored procedures is not necessary. Download the database driver/.jar file and move it to the lib directory of the Tomcat installation (ie, /lib). Restart the Tomcat server to load the JDBC driver to make it available for the ThingWorx web application.   Step 2: Connect to External Database   ThingWorx is based on java programming language and can make connections to any database that supports a java-based connection. All that is needed is to add the .jar file for the database to the lib folder of Tomcat folder and setup the connection in the ThingWorx Platform. Follow the below steps to get started creating the connection.   Create Connection   To create a connection and begin working with an external database, you will need to create a database Thing and set up the connection string and credentials. (To see the final version of this entity, you can look at SQLServerDatabaseController.)   In ThingWorx Composer, click the + New at the top of the screen.   Select Thing in the dropdown.   Name the Thing DatabaseController and select Database as the base type. Set the Project field (ie, PTCDefaultProject).   Click Save and go to the Configurations tab. In this tab, you will enter the class name of your driver, the connection string for that database connection, and the credentials to access the database. Keep in mind, the JDBC Driver Class Name, JDBC Connection String, and the connectionValidationString values are all database type specific. For example, to connect to a SQL Server database, the below configuration can be used.      Title                                              Description                    Example JDBC Driver Class Name The specific class name of the driver being used for the connection. net.sourceforge.jtds.jdbc.Driver (SQL Server) or oracle.jdbc.driver.OracleDriver (Oracle) JDBC Connection String The connection string to locate the database by host/port/database name. jdbc:jtds:sqlserver://server:port/databaseName (SQL Server) or jdbc:oracle:thin:@hostname:port:databaseName (Oracle) connectionValidationString A simple query that should always work in a database. SELECT GetDate() (SQL Server) or SELECT SYSDATE FROM DUAL (Oracle) After entering credentials, click Save. Go the Properties and Alerts tab. You'll see properties showing the connection validation similar to the image below. If you don't have a connection as yet, work on your configuration information and validate the credentials being used. If you're still having troubles after that, see the examples section below or use the next section for help to try a query of the database.   Help and Troubleshooting For help finding the correct configuration for you, check out these JDBC Configuration Examples or try out this Connection String Reference for help with your connection string.   You've just created your first database connected Thing! Now jump to the next section and let's begin to query the database for information. Step 3: Query Data from External Database Now that you're connected to the database, you can begin querying the database for information and the flow of data. The queries and data shown below are based on the table scripts provided in the download. Examples of how the ThingWorx entity should look can be seen in the SQLServerDatabaseController and OracleDatabaseController entities. Running a Query As you may have noticed by working in ThingWorx and developing applications, an InfoTable is often used to work with large sets of data. An InfoTable is also how data is returned from a database query. If you're expecting only 1 value in the result set, the data will be held in the first index of the InfoTable. If you're expecting rows of data coming back, expect there to be rows of information inside of the InfoTable. Follow the steps below to set up a helper service to perform queries for the database. While other services might generate the query to be used, this helper service will be a shared execution service. In the DatabaseController entity, go to the Services tab. Create a new service of type SQL (Query) called RunDatabaseQuery.   3. Set the Output as InfoTable, but do not set the DataShape for the InfoTable. 4. Add the following parameter:  Name            Base Type   Required query String True 5. Add the following code to the new service: <<query>> 6. Click Save and Continue. Your service signature should look like the below example.   You now have a service that can run queries to the database. This is also a simple method to test/troubleshoot the database connection or a quick query. Run your service with a simple query. You might notice that no matter the fields in the result set, the InfoTable will match it based on field type and field name. There are two ways you can go from here. You can either query the database using services that call this service, or you can create more SQL command services that query the database directly. Let's go over each method next, starting with a service to call our helper. In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service JavaScriptQuery_PersonsTable. Set the Output as InfoTable, but do not set the DataShape for the InfoTable. Add the following code to your new service: try { var query = "SELECT * FROM Persons"; logger.debug("DatabaseController.JavaScriptQuery_PersonsTable(): Query - " + query); var result = me.RunDatabaseQuery({query:query}); } catch(error) { logger.error("DatabaseController.JavaScriptQuery_PersonsTable(): Error - " + error.message); }   5. Click Save and Continue. Any parameter, especially those that were entered by users, that is being passed into an SQL Statement using the Database Connectors should be fully validated and sanitized before executing the statement! Failure to do so could result in the service becoming an SQL Injection vector. This is a simple way to query the database since much of your development inside of ThingWorx was already based in JavaScript. Now, let's utilize the second method to create a query directly to the database. You can use open and close brackets to create parameters for your query. You can also use <> as a method to mark a value that will need to be replaced. As you build your query, use [[Parameter Name]] for parameters/variables substitution and <> for string substitution. In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service SQLQuery_GetPersonByEmail. Ensure the Output is InfoTable. Add the following code to your new service: SELECT * FROM Persons WHERE person_email = [[email]]; 5. Add the following parameter:  Name          Base Type    Required email String True 6. Click Save and Continue. An example of using the string replacement is as follows:         DELETE FROM <> WHERE (FieldName = '[[MatchName]]'); DELETE FROM << TableName >> WHERE ( FieldName = [[MatchNumber]]);             Click here to view Part 2 of this guide.
View full tip
Procedure on how to configure Single Sign On (SSO) with Thingworx and Windchill, where users will be able to access Thingworx/Navigate with their  Windchill credentials. This video consist of demo and architecture of how SSO works.     For full-sized viewing, click on the YouTube link in the player controls.   Visit the Online Success Guide to access our Expert Session videos at any time as well as additional information about ThingWorx training and services.
View full tip
Warning This post is quite long, has various chapters and you might get bored reading it. If you just want a summary read the "Use case" and "Conclusion" chapter - and maybe the "Required Logic" chapter, because I made a cool graph for it. The rest is all about implementation... Introduction I recently had the opportunity to deliver a ThingWorx training for Saint Gobain. One of the use cases for their ThingWorx application is monitoring machine errors and outages on the production line. If an outage or error status is triggered, the machine operator will see a popup on the monitoring screen where he is forced to select a root cause. This root cause will then be persisted in ThingWorx for more data transformation, analytics and reporting - like cost analysis or optimization opportunities. During the training we were also discussing on how such a forced root cause monitoring can be implemented via Mashups and the usage of modal popups. I've compiled the details into this post as it might also interest other developers. The ThingWorx Entities I'm using in this example can be downloaded from here Note: I'm using the word "Alert" here - but not in the context of a ThingWorx Property Alert... just beware to not be confused due to the wording. Use Case One of the requirements for Saint Gobain's IoT Solution was an interactive alert monitoring directly in the factory on the production machines. Let's say the machine has stopped, the root cause should be recorded. For this an interactive popup will be displayed on the machine's monitoring display and an employee has to choose the root cause from a pre-defined list. This could be planned outages, e.g. for maintenance or unplanned outages, e.g. material jam. The root cause will then be recorded and a history of outage causes can be stored in a ThingWorx value stream. This can then be later analyzed with e.g. ThingWorx Analytics capabilities to understand and optimize the machine's production capabilities and efficiency. As the root cause must be entered, the popup will be forced to be displayed when a certain condition / criteria is met - and it will only disappar when a root cause is chosen. The user should not be able to interact with any other elements of the Mashup and not be able to just close the popup. The popup will close itself and reset the initial condition once the root cause has been identified and chosen. Requirements Required Entities Required Logic Note: Just to make it easier to manage and export Entities, I will add all of the created elements in a new Project called RootCausePopups. All of the elements will have a "rcp_" added in front of their name - just to make it easier for me to find and identify them. Implementation Before we start - set a Project Context Create Entities Create a Popup Mashup Create the Main Mashup Testing the Mashups Conclusion Certain conditions (like the state of a checkbox) can be used to trigger modal popups. A modal popup forces a user interaction and the interaction will not offer any other option until a choice is made. With these parameters it's easy to have mandatory reaction from users when it's important to capture data which rely on the analysis of an engineer or a user - e.g. reasons for machine outages. Using this technique there's not much training required for staff, other than pushing a button with an option of their choice - this saves quite some time in capturing data in any other way (e.g. updating Excel files or manual pen-and-paper techniques). As this data is now part of the ThingWorx instance it can be used for further transformation, analysis or just for monitoring purposes There's of course more possibilities when it comes to states and formatting which would exhaust the context of this post - but feel free to explore... In the example we wouldn't need the textbox, but it's there to demonstrate if the correct values are persisted or not In the example we could of course also set the visibility of the checkbox to false, so that we would only see the popup and the Grid holding historic information We could also create different StateDefinitions to color-format / text-format the input differently from the output in the Grid If you found this interesting (and actually made it to the end of this post) - feel free to play with this concept a bit more... The dependencies might seem a bit difficult, but it should be easy to implement and to adjust to your own ideas and requirements.
View full tip
This Guide contains all the Linux commands that you may have to use for ThingWorx Analytics Installation or day to day use. Command/Category Description Network/port ip a List the ips of all of the network interfaces ssh How to jump from one machine to another ping Send packets to a remote machine.  useful for testing connectivity netstat –anp Check active port cat < /dev/tcp/localhost/8080 Test connection to a port Replace localhost with desired hostname or ip, replace 8080 with desired port number (/dev/tcp/host/port) exit Exit my current sign in.  this lets one disconnect from remove ssh sessions or if one has changed one's user e.g. switched to root scp Retrieve something via ssh Resource Usage free -m Check memory -m is for output in Mb Mpstat -P ALL CPU usage top Process usage jvmtop Collect cpu usage of jvm and its thread https://github.com/patric-r/jvmtop (requires jdk to be installed) File Interaction cp / mv Copy and move respectively. mv just deletes the source file.  Usage: cp /source/location/file /output/location/file cat Mostly used to just print the contents of a file to the command line.  can also print multiple files at once:  cat /var/log/gridworker/warning.log /var/log/gridworker/error.log vim / vi A command line text editor. Not the most user friendly (none of them are) but really useful. Here's a cheat sheet for the commands https://www.fprintf.net/vimCheatSheet.html rm Remove files chmod Change the access permissions of files chown Change the user or group ownership of files grep A text based filtering.  Useful for making a larger list smaller and more targeted.  Almost always used after a pipe (see pipe below) less Generally used to view the contents of a file with more friendly scrolling locate Find a file by name Directory ls What’s in the directory.  Will do the current directory but you can also pass the directory e.g. ls /var/log/tomcat. Black writing is files Blue writing is directories Red writing is compressed file pwd Tell me which directory I'm currently in cd Change directory.  provide the directory to change to or just use cd to return to the user's home directory clear Clears the screen Terminal clears all provided commands mkdir Creates Directories Running Processes ps Query what services are running. usually use ps -aux to get a full, sorted list.  using grep with this is helpful systemctl The correct way to interact with services that are running Package installation yum install <packageName> Install a package. More useful commands: https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s1-yum-useful-commands.html yum list installed List installed packages yum list <package> List available packages yum --showduplicates list java-1.7.0-openjdk-devel Use --showduplicates to see all versions Can use * for package name: *openjdk* rpm -ql <packagename> Find where package are installed Note: works if package installed with yum Yumdownloader --urls <packageName> Find URL where a package is downloaded from. Note: need to install yum-utils package Repoquery --requires <packageName> Find dependencies of a package Note: need to install yum-utils package repoquery --qf=%{name} -g --list --grouppkgs=all [groups] | xargs repotrack -a x86_64 -p /repos/Packages Download a package with all its dependencies. Need to install yum-utils package From  <http://unix.stackexchange.com/questions/50642/download-all-dependencies-with-yumdownloader-even-if-already-installed> Other Commands curl http://localhost:8080/1.0/about/versioninfo Send REST call via command line Use -X POST (default GET) for a POST (see man page - https://curl.haxx.se/docs/manual.html for example) See also http://www.codingpedia.org/ama/how-to-test-a-rest-api-from-command-line-with-curl/ Find / -type f -exec grep -I mystring {} \; Search string in files Sudo -u user command Execute a command as different user The below helpers are not commands themselves, but can be used in conjunction with the above commands. Helper Description 'pipe' The | character.  lets one chain commands.  e.g. ps -aux | grep java ./ The shorthand way to refer to this directory explicitly ../ The shorthand way to refer to the parent directory 'tab completion' Pressing tab will let linux guess what command/option best fits what's currently written.  very useful for navigating directories and long-named files (NOTE: not necessarily tab based upon one's keyboard layout/language) 'ctrl-r' Look up the mostly likely command that matches what one typing.  so if one earlier used ps -aux | grep java | less and the hit ctrl-r and typed -aux it would likely pull that command or at least the most recent one that matches
View full tip
Hello Developer Community, We are pleased to announce pre-release availability of the ThingWorx Edge SDK for Android! The Android SDK beta is built off the Java SDK code base, but replaces the Netty websocket client with Autobahn for compatibility with Android OS.  Those familiar with the Java SDK API will feel very much at home in the Android SDK.  We recommend beginning with the included sample application.  Please watch this thread for upcoming beta releases.  b4 adds file transfers between the ThingWorx platform and Android devices and an example application. We welcome your questions and comments in the thread below!  Happy coding! Regards, ThingWorx Edge Products Team
View full tip
All of the entities and data in storage entities(Stream, ValueStream, DataTable, Wiki, Blog) are kept in Persistence Provider, to enhance the storage volume of Thingworx, it is advised to use bigger Persistence Provider (PostgreSQL or Cassandra rather than Neo4j and H2), move and keep certain part of data in external database or set up a second Persistence Provider Data Storage entities (Stream, ValueStream, DataTable) and Collaboration entities (Wiki, Blog) can be assigned to the new Persistence Provider to keep the Business Data The original Persistence Provider (upon installation) will be freed from large data input and respond faster, and only holds the Model Data (entity information) Small Persistence Provider like H2 or Neo4j, which does not require extra steps to setup in the Thingworx installation process, cannot set up a second Persistence Provider (they don't have .bat files to configure the database) Here is an example for setting up a second PostgreSQL (may also applicable for Cassandra) Install a new PostgreSQL in the server Should give different folder names for the files, or two PostgreSQL will affect each other PostgreSQL 9.5 could work with Thingworx 7.2.x, but cannot be used with 7.3 and above. Version 9.5 is not officially supported or advised by now, and the user should take their own risk if doing so. The new PostgreSQL will have a new port number (e.g. first port is 5432, the new port is 5433) Open PostgreSQL using pgAdmin 3 Create a new user role: a. Right click PostgreSQL9.4 (localhost:5433). b. Select NewObject>New Login Role. On the Properties tab, in the Role name field, enter the user role name. c. On the Definition tab, in the Password field, enter a unique password (you will be prompted to enter it twice). Add the new <postgres-installation>/bin folder to system path variable Edit the thingworxPostgresDBSetup.bat and thingworxPostgresSchemaSetup.bat from the Thingworx software download package, and change the port property to 5433 Execute the two scripts, and new database and tablesapce will be created platform-settings.json file does not need extra configuration Restart the Tomcat server, a new folder will be created under ThingworxPostgresqlStorage folder Go to Thingworx composer, create a new Persistence Provider in the Home list Give it a new name, and select Persistence Provider Package(only one choice) After selection, a Configuration field will show up in the ENTITY INFORMATION field ( such field will not appear in Neo4j based Thingworx) Open Configuration and change the JDBC URL to jdbc:postgresql://localhost:5433/thingworx, update Password, click Save The new Persistence Provider can be used in data storage entities now The new Persistence Provider can also be set as default provider
View full tip
Introduction In the dynamic landscape of IoT and industrial applications, development teams often face challenges such as limited visibility into application behavior, fragmented tooling, and time-consuming troubleshooting processes. To address these pain points, PTC has launched a DevOps initiative aimed at strengthening the ThingWorx low-code platform. This initiative delivers key enhancements in debugging, source control, monitoring, alerting, logging, and AI-driven development support. As ThingWorx continues to evolve, our commitment remains centered on improving the day-to-day experience for both developers and administrators. We've been listening closely to your feedback—this new project reflects our response, focusing on smoother DevOps integration and empowering users with deeper control and visibility into their applications. While many enterprises already rely on IT-recommended tools to manage the application lifecycle and Day-2 operations, PTC is committed to complementing these investments by delivering additional capabilities and guidance tailored to the ThingWorx platform. Key features of the new devOps project initiative include real-time debugging and version control, the ability to roll back to previous versions, hot-fix deployments, and distributed team development through seamless integration with repositories like GitHub. Furthermore, streamlined application packaging and deployment significantly simplify the management of ThingWorx-based applications. These enhancements go beyond routine updates and reflect a meaningful evolution in how teams develop, troubleshoot, and optimize IoT applications in production environments.  Debugging : Preview in ThingWorx 10.0   The first major feature introduced under DevOps is the debugging capability, currently available in a private preview (alpha version). Debugging has long been a challenge in ThingWorx applications, where troubleshooting JavaScript code within the platform was often cumbersome and time-consuming. With the new JavaScript Debugger, developers can now debug their scripts directly within ThingWorx Composer, reducing the time spent identifying and fixing issues. This feature brings real-time issue resolution, allowing developers to pinpoint errors efficiently without needing external tools.   Security and seamless integration into the existing ThingWorx environment were critical design considerations for this feature. The debugging actions are logged securely for audit and compliance, ensuring that sensitive information remains protected. Furthermore, support for major browsers such as Chrome, Firefox, Edge, and Safari enhances the accessibility of this feature across different development environments. The debugging capability is expected to significantly improve developer productivity by offering better visibility into JavaScript execution and real-time error tracking, reducing the trial-and-error approach that developers previously relied upon. Here is a brief video offering a preview of upcoming features included in the ThingWorx 10.0 release, with general availability planned for the 10.1 release later this year.   Debugger Capability (Preview) Logging and Monitoring : Continuous improvement   In addition to the new debugging capabilities, we’ve delivered several enhancements focused on monitoring and alerting—specifically designed to support the needs of IT administrators responsible for maintaining the uptime and reliability of ThingWorx environments in the last major release. The integration of OpenTelemetry has transformed logging and performance monitoring, allowing better observability of system operations. This enhancement enables third-party integrations with monitoring tools such as Sumo Logic, Datadog, and Splunk, providing developers and administrators with deeper insights into system performance. These improvements have made ThingWorx more resilient and responsive, allowing teams to proactively detect and address issues before they impact operations. Mashup Builder : Continuous improvement   We have been continuously enhancing Mashup development capabilities, starting with the introduction of Read-Only Mashups in ThingWorx 9.6 and extending through to the latest improvements in recent releases. Also, a new Export Function replaces the legacy Data Export Widget, offering a more secure and efficient data export process. Binding Verification & Debugging introduces a powerful capability to detect and resolve broken bindings after mashup migrations, reducing errors and improving reliability. Improved UI Management features, such as widget highlighting and container zooming, make mashup creation and debugging more intuitive. Additionally, developers can now customize Tab Titles & Favicons, enabling better branding and a more polished user experience for ThingWorx applications. Mash up improvements in ThingWorx 9.7 The Road Ahead: AI-Powered Development and Version Control   The next phase of the DevOps initiative is set to deliver major advancements in source control and AI-driven development. One key enhancement is the addition of IDE-like features for source code management, enabling developers to better track, iterate, and roll back changes. Planned integrations with GitHub and other repositories will support seamless collaboration in distributed teams.   We welcome your feedback as you explore the new Debugger Feature Preview included in the ThingWorx 10.0 release. In parallel, we are actively working with customers and partners to enhance key capabilities such as source code version control and application lifecycle management within the ThingWorx platform. If you're interested in contributing to the future of low-code development, we encourage you to share your thoughts in the comments below—our team will be in touch to connect.   Vineet Khokhar Principal Product Manager, IoT Security Stay tuned for more updates as we approach the release of ThingWorx 10.0, and as always, in case of issues, feel free to reach out to <support.ptc.com>  
View full tip
  Step 3: Create a Base Mashup   Now that you have some data, you need to create and configure a Mashup to display the data.   Using Mashup Parameters, the Collection Widget will replicate the base Mashup multiple times, correlating to each row of data in the Info Table Property.   On the ThingWorx Composer Browse tab, click Visualization > Mashups, + New                2. Keep the default ofResponsive(without selecting any Templates), and click OK          3. In the Name field, enter cwht_base_mashup.      4. If Project is not already set, search for and select PTCDefaultProject.      5. Click Save.     Add Widgets to Design   At the top, click Design. TIP: You can click the left arrow on the divider between the Browse left-navigation and the Mashup Builder to minimize the navigation and provide more room for the Mashup Builder itself.                  2.  On the Layout tab at the top-left, select Positioning > Static. You generally want the base Mashup to be "Static" so that you know the size of the cells which  the Collection Widget will replicate.                3. From the top-left Widgets tab, drag-and-drop a Gauge Widget onto the central Canvas area.             4. Drag-and-drop an LED Display Widget onto the central Canvas area.               5. Drag-and-drop a Text Field Widget onto the central Canvas area       Reduce the Mashup Size   At the top-left on the Explorer tab, select the Container.                2. In the central Canvas area, click-and-drag the far-right side of the container to reduce its horizontal size               3. Click-and-drag the bottom of the container to reduce its vertical size     Create Mashup Parameters   On the top-left Explorer tab, select the Mashup itself. A drop-down menu indicator will appear in the top-left of the Mashup.                 2. Click the top-left drop-down menu to reveal the Mashup options               3. Select Configure Mashup Parameters to open the Configure Mashup pop-up menu                4. Click Add Parameter three times              5. For the Name fields, enter first_number, second_number, and third_number.         6. Change the Base Type to NUMBER for all three Parameters           7. Click Done to close the Configure Mashup pop-up menu   Bind Mashup Parameters to Widgets   Click the Mashup's drop-down menu in the top-left to expose the options again. There are now additional options for first_number, second_number, and third_number.              2. Drag-and-drop first_number onto the Gauge Widget               3. Select Data on the Select Binding Target pop-up menu of the Gauge Widget.         4. Drag-and-drop second_number onto the LED Display Widget. You may have to first reselect the Mashup itself to reveal the Mashup's drop-down menu to access the second_number Mashup Parameter. Remember that you can easily select the Mashup itself through the Explorer tab.                                    5. Select Data on the Select Binding Target pop-up menu of the LED Display Widget.         6. Drag-and-drop third_number onto the Text Field Widget.         7. Select Text on the Select Binding Target pop-up menu of the Text Field Widget.         8. At the top, click Save. You can expand the Connections window at the bottom and select the Mashup itself to confirm that all three Mashup Parameters have been correctly bound to each Widget.          9. Click the Right Arrow on the far-left of the Mashup Builder to re-expand the Browse navigation menu.         Click here to view Part 3 of this Guide.
View full tip
Merging InfoTables can seem to be an overwhelming task in ThingWorx. What even IS an InfoTable?? The short answer is that an InfoTable is a specifically structured JSON object. Merging InfoTables is therefore as easy as incrementing through each, adding the columns of each to another table, and then populating the new table with data. For InfoTables with the same DataShapes, the built in "Union" service can be used. Find this snippet under the InfoTableResources section. There is also a snippet for incrementing through DataShape fields if the DataShape is known. For InfoTables which don't have the same DataShapes or for which the DataShape is not known, things get a bit trickier. Thankfully, some new KCS documentation provides example code to step you through merging any number of tables together. I hope this documentation is helpful!
View full tip
Presentation by Michael Anderson highlighting new capabilities and features in the ThingWorx Manufacturing and Service Apps 8.2
View full tip
Do you trust me? if (true) { why } else      { !why } Communication between client and server can be encrypted or not. Communication between client and server can be between trusted parties or not. Both statements are independant of each other. There's no need to trust a server - but still traffic can be encrypted. There's no need to encrypt traffic - but still a server can be trusted. For secure and safe communication in an IoT environment encryption as well as trust should be an integral part of exchanging data. ​ Trust Certificates and Chains of Trust Trust establishes the identity of the parties involved, e.g. is server I'm contacting really the server it pretends to be? This can be ensured with server certificates. On the other hand, client certificates ensure that the client is actual the client it pretends to be. This can be used as an authentication approach and if the identity of the server as well as the client is confirmed, this is also known as mutual authentication. Trust is usually invoked through certificates. Certificates have a subject, usually the servername that the certificate belongs to. This can also be a wildcard subject like *.myserver.com which will be valid for all subdomains of myserver.com. A certificate can be digitally signed to ensure its identity. Usually a Certificate Authority (CA) signs the certificate. This CA can in turn be signed by another CA and so an, creating a whole chain of CAs. This chain is commonly known as the Chain of Trust or the certification path. If a certificate is not signed by a CA it's called a "self-signed certificate". These are mostly used for test scenarios, but should never be used in real production environments. Certificates can also expire by using dates like "Valid From" and "Valid To" to determine if a certificate is valid or not. In case a certificate or CA is expired, all following certificates in the Chain of Trust will no longer be considered as valid. For "commercial" certificates, certificates that are signed by an official CA like Google, Let's Encrypt or VeriSign, a Certificate Signing Request (CSR) is used. For this a key-pair is generated and the CSR is signed with the private key. The CSR contains the public key and is sent to and finally signed by the CA itself, returning the public certificate e.g. signed by VeriSign. This mechanism allows to generate certificates by preparing the main information and just having the CA sign it as a trusted authority. Key-pair All certificates consist of a key-pair - a private key and a public key. The private key is indeed very private to the server and MUST NOT be shared with anyone else. The public key is indeed very public and can be shared with anyone. The key-pair consists of mainly two very large prime numbers and some mathematical magic allows for a mathematical one-way function ​with a trap door. This function allows to en-crypt any message with the public key and to de-crypt this message with the private key. So by giving out the public key to anyone, anyone can en-crypt a message to the server but only the server alone can de-crypt it with its private key. Therefore it's important that the private key is not shared with anyone, otherwise messages can be de-crypted by anyone possessing the private key and secure communication can be compromised. This method is called public-key encryption, or asymmetric encryption (as the key for en- and de-crypting are different). For more information, check out https://en.wikipedia.org/wiki/Public-key_cryptography This key-pair is not related to any encryption while sending data between client and server. Encryption on a transport level is accomplished by using different, random keys. It's just used to generate a unique certificate with a unique fingerprint as a public certificate. The private key part is amongst other things used for signing other certificates in the Chain of Trust. Tomcat needs access to the private key of the server specific certificate, to actually verify that the certificate is authentic. However, certificates can also be used for e.g. emails where the private key is in fact used to en- or decrypt the mail on a content level! ThingWorx ThingWorx is mainly configured for server side trust. In this case all connecting clients can ensure that the identity of the ThingWorx server is a trusted one - and not a fake server or an untrusted source. Certificates and trust are usually triggered when a secure connection is established, via TLS / SSL - e.g. by calling https://<myserver.com>:443/Thingworx The default port for a HTTPS (HTTP Secure / over TLS) connection is 443. For "normal" HTTP configuration, certificates are not required. Keystore To establish trust, any client needs to know the public certificate of the ThingWorx server. This is usually stored in a keystore. In ThingWorx, Tomcat needs to be configured with the location and the password of the keystore containing the certificate. For each web-request Tomcat will then present the server certificate to the client. The client can then verify through its own keystore if the certificate is trusted or not. When operating in browsers, this is done via e.g. the Windows-Keystore. For devices a custom, e.g. a Java-Keystore is required. The keystore must contain the whole Chain of Trust as well as the server specific certificate and its key. If the Chain of Trust is not stored completely in the keystore, or the key is missing / not accessible, the certificate validation process will already fail on server side. Certificates in Windows The default Windows-Keystore is actually pre-filled with lots of Root-Certificates, which start the Chain of Trust - such as Google, VeriSign or Microsoft. Trust needs to start somewhere… If the browser can trace the CAs of certificate back to a trusted Root CA, it's indicated by a green lock and the server will be trusted. If the Root CA cannot be found, it's indicated by a red lock (not a purse) - meaning that the server is not trusted. The server can still be contacted anyway, by manually acknowleding the risks (like identity theft or credit card scams). As an example, here's the certificate for Wikipedia and its Chain of Trust, starting with the GlobalSign Root CA: Trustworthy? In the end, certificates only clarify the identity of a server. If it is trusted or not, is completely up to the user / device. This trustful relationship all comes down to the client keystore / truststore. While the presenting server holds its certificate in the keystore, the verifying client holds the trusted certificates in the truststore. Any certificate in the truststore will ensure the correct server identity. Any unknown certificate will trigger a "Are you sure?" question in the browser. And as devices usually cannot respond to such a question, communication with an untrusted server can be forbidden by default. There are also products, like PTC Navigate which will require a client certificate to not only ensure server identity, but also ensure that also specific clients are able to connect to the server. Encryption No matter if a server is trusted or not, as soon as HTTPS is used as a protocol, communication will be encrypted. The certificate plays a role, but no matter if it's in the client's truststore, TSL forces encryption. Client Hello Usually the client contacts the server and sends a Client Hello. With this it also sends a list of available cipher suites, the intended receiver (server name) and a list of available Signature Hash Algorithms to be used. Cipher suites are used to determine which algorithms are used to establish a connection. The Signature Hash Algorithms define the Hash function, like SHA256 and the key / signature, like RSA. In my environment usually the Elliptic Curve Diffie-Hellman key exchange is used to transfer public keys between server and client. During the Client Hello information about the elliptic curves are also transferred. For more information on these topics, see https://en.wikipedia.org/wiki/SHA-2 https://en.wikipedia.org/wiki/RSA_(cryptosystem) https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange https://www.youtube.com/watch?v=YEBfamv-_do (Diffie-Hellman explained) https://en.wikipedia.org/wiki/Elliptic_curve_cryptography Server Hello After receiving the Client Hello, the server sends back the Server Hello. This consists of multiple handshakes. In this phase, the server sends the preferred cipher suite (intersection of client and server suites) including the Signature Hash Algorithm to be used. In the same step the server is sending off the certificate to the client for identity validation. For establishing trust and validating the certificate, the server needs to know the private key for the server specific certificate. The server also announces in the server key exchange what public key it's using for encryption to the client. This key is not related to the certificate, but a random number from a newly generated key-pair. Keys are exchanged between server and client and vice versa via the Diffie-Hellman key exchange. Client Response The client now sends in the client key exchange what public key it's using for encryption to the server. This is also a random key transmitted via the Diffie-Hellman key exchange. Initiating Communication After announcing the public keys, both server and client will now communicate encrypted by using their custom key-pairs for asymmetric encryption of the payloads. This can also include an additional change of the cipher specification. As the public keys have been exchanged via the Diffie-Hellman key exchange, server and client are now bi-directionally communicating using each other's public key to en-crypt a message and each's own private key to de-crypt the message again. For more information, also see https://tools.ietf.org/html/rfc5246 Trust & Encryption - Hands On Do you trust me now? if (true) { why } else      { !why } To see how this all works in a ThingWorx enviroment, and how easy it actually set up what has been discussed above, see also Trust &amp; Encryption - Hands On
View full tip
Why we need improve ThingWorx Query Performance? ThingWorx is good at injesting data from systems and devices and persisting data in Value Stream. When users build mashups/services which pull anything more than small amounts of data back, or have many users making queries at the same time, they encounter slow performance and/or server failure. Let's take a typical example which may happen among many of our end users: User A is currently gathering data from their edge devices and placing them in a Value Stream. About 80 properties are sharing the same Value Stream and they are estimating roughly 10 million rows a month of data into the platform. Their application requires querying large sections of this data and displaying aggregate info to certain mashups. A ton of work has been done to optimize these queries to make them as efficient as possible. However, querying with results larger than a few thousand rows causes RAM usage to spike so high, that the JVM runs out of heap space and brings down the server. What we have done to improve Query Performance in ThingWorx 8.2? 1. Improvements to the implementation of QueryPropertyHistory and QueryNamedPropertyHistory services:      1) These two query services are optimized by:          (1) Before ThingWorx 8.2, we query property history from database for each properties(imagine 80 properties in our example in the beginning), and then combine the            dataset(80 datasets in our example!) and display them in one table.          (2) In ThingWorx 8.2, we have replaced the "query for each property" with "single query for all properties"      2) Moved most of the query work to database level which is formally done post processing after grabing all the dataset from database including:          (1) Moved Combiner logic to database          (2) Moved Filter functionality in database Note: This improvement is only implemented on MS SQL and PostgreSQL, other persistence providers are not considered in this version, and this may be the plan for future release. 2. Improved string handling for the Query<Basetype>PropertyHistory services Memory reduction for these services are implemented by storing only one copy of each distinct string How much memory reduction could the Query Service Improvement bring QueryPropertyHistory and QueryNamedPropertyHistory Services From our internal test scenario we have seen approximately a 20% reduction in Thingworx platform memory utilization for these services with no Filter applied. Filtering may reduce memory an additional amount. Besides, a approximately 10% execution time saved as a result of this new improvement! Query<Basetype>PropertyHistory services Memory reduction is highly dependent on the stored data. From our internal test scenario, this improvement is providing up to 10% memory reduction on the platform. Note: This improvement is only implemented on MS SQL and PostgreSQL, so the memory reduction is not applied to other persistence providers. Best practice to call Query Services to improve Performance Although there are some Query service improvements in 8.2, still by following some rules or choosing a suitable service would bring extra performance improvement according to different use scenarios. From this point of view, this secion applies to all ThingWorx versions not specially for 8.2. 1. Limit the number of calls to the Query services from a given mashup/app       By repeatedly calling QueryPropertyHistory to display data may cause severe performance problems. Try to clean up unnecessary service calls in mashup and there should be a significant       improvement to the system.       Note: That was without any of the above improvements. 2. Use Query<BASETYPE>PropertyHistory service as much as possible     Unless customer needs to create a normalized dataset for multiple properties, try using QueryIntegerPropertyHistory, QueryStringPropertyHistory, etc. as they return smaller datasets and do not     use the combiner to normalize the data across a large number of properties. 3. Use QueryNamedPropertyHistory as much as possible     Similarly, QueryNamedPropertyHistory can provide a smaller dataset if you don’t need the values from all the properties on the Thing. So for example if a Thing has 10 logged properties but     you only need 3 returned; using QueryNamedPropertyHistory and identifying the three properties specifically needed will return a significantly reduced data set. 4. Use a Query to narrow down the dataset Where/when it makes sense, use a Query to narrow down the dataset; similarly to option 3, the returned dataset will be smaller. Note: this will have limited use scenario though. What needs to be done for end user when upgrading or utilize the service in ThingWorx 8.2 All the changes are transparent to the user! We improved the underlying implementation of the existing services so users won’t need to do anything after upgrade to see the improvements. There are no changes to the databases or schema.  
View full tip
Hello, Since there have been discussions regarding SNMP capabilities when using the ThingWorx platform, I have made a guide on how you can manage SNMP content with the help of an EMS. Library used: SNMP4J - http://www.snmp4j.org/ Purpose: trapping SNMP events from an edge network, through a JAVA SDK EdgeMicroServer implementation then forwarding the trap information to the ThingWorx server. Background: There are devices, like network elements (routers, switches) that raise SNMP traps in external networks. Usually there are third party systems that collect this information, and then you can query them, but if you want to catch directly the trap, you can use this starter-kit implementation. Attached to this blog post you can find an archive containing the source code files and the entities that you will need for running the example, and a document with information on how to setup and run and the thought process behind the project. Regards, Andrei Valeanu
View full tip
ThingWorx's JDBC extensions - Relational Database Management System and the JDBC Extensions allow ThingWorx to connect to variety of different databases. With that comes a natural question how and what sort of SQL statements could be executed via these extensions? Note: ​​Importing the JDBC extensions i.e. the RDBMS and JDBC Extensions, creates a Database Template for that particular database. If you are working with RDBMS extension then Template of corresponding Database will be created with similar name e.g. importing the RDBMS Extension for Oracle 12 will create Template named OracleDBServer12. While importing the JDBC driver using the JDBC extension will create Template name based on the JDBC driver used or a custom name could be given. Following examples and SQL statements are adhering to Oracle's SQL*Plus standard, however these can be easily adapted to the type of RDBMS you intend to work with. Topics How to create SQL Service in ThingWorx entity Types of SQL Statements Examples on SQL Service usage and some extended use cases / examples How to create SQL Service in ThingWorx Navigate to the Thing implementing the Database Template, e.g. OracleDBServer12         2. Click on the Services section under the Entity Information and click on Add My Service         3. A new service creation section will come up, change the Service type of JavaScript (this is default selection) to either SQL (Query) or SQL (Command) depending on the type of SQL you are to create under this particular service                       4. Here's quick example on creating SQL (Query) service which takes name as input for a select *  sql … Statement, i.e. it returns complete set of rows and columns from any given table on which the user has the access to perform Select                   Note: BaseType defaults to Infotable when creating SQL (Query) service and the returned number of rows are restricted to 500. Therefore, if table contains rows more than 500, ensure to change the Max Rows parameters         5. Example on creating SQL (Command) service that delete all the rows from the database table               Note: The Base Type defaults to Number when using SQL (Command)     Additional information:     When creating a SQL service, apart from providing changing the Service Info and  Inputs /Outputs, 3rd section Tables/Columns allows users to explore the Tables and their respective columns as part of that particular user's schema - meaning the objects on which the user has select rights in his schema in the database.     Types of SQLs This is not an exhaustive list, rather contains most commonly used types of SQL statements     1. Data Definition Language (DDL)           a. Create, Alter and drop schema objects           b. Grant and Revoke privileges and roles     2. Data Manipulation Language (DML)           a. Insert           b. Delete           c. Select Examples for SQL Service usage and some extended use cases / examples     1. Data Definition Language (DDL)           a. Create statement                       b. Alter statements                         c. Drop statement                         d. Flashback statements (Oracle specific)                         e. Grant statement                     f. Rename statement                 2. Data Manipulation Language (DML)           a. Insert statement                     b. Delete statement                     c. Select statements           Use cases - Case 1 : Backing up DataTable DataTable objects in ThingWorx are for quick lookup of data and they are most performant till ~100K rows. Exceeding rows over 100K in a DataTable makes it highly susceptible to performance issues in terms of querying or writing to it. Unless, there's sharding​ on the persistence provider or multiple persistence providers used - JDBC connectivity to external data stores like RDBMS systems could help in keeping up with growing number of rows in DataTables. RDBMS tables are more than capable of storing very large amount of rows without being taxed over the performance. JDBC extension could be used to do just that in a use case requiring backing up DataTable or any Data Storage objects from ThingWorx for that matter. Here's one quick example using one of the Insert SQL service shown above to back up the entire DataTable to the Oracle's DB table. Following ThingWorx JavaScript service wraps the InsertIntoBULKDATAINSERTDT SQL service: // result: INTEGER // getting total row count in the DataTable var totalCount = Things["BulkInsertDT"].GetDataTableEntryCount(); var params = { maxItems: totalCount /* NUMBER */ }; // result: INFOTABLE // DataTable service to fetch all the rows from it var allData = Things["BulkInsertDT"].GetDataTableEntries(params); // looping over the result fetched above to get all the rows for insertion     for (var i = 0; i<totalCount; i++) {         var result = allData.getRow(i); // mapping the data for insert     var params = {         LongCol3: result.LongCol3 /* LONG */,         numcol1: result.NumCol1 /* NUMBER */,         StringCol2: result.StringCol2 /* STRING */,         IntCol4: result.IntCol4 /* INTEGER */     }; try { // result: NUMBER // calling the SQL Service InsertIntoBULKDATAINSERTDT created under a DB Thing called OracleDBThingNew     var result = Things["OracleDBThingNew"].InsertIntoBULKDATAINSERTDT(params); } catch (err) {      Logger.info ("Failed to insert the values" + err) }     }
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
I always find it difficult to remember which version of software is supported with which version of ThingWorx, so I created a table for my reference. I hope this is also helpful to other people.     Oracle JDK Tomcat Database Options Memo PostgreSQL Neo4J H2 Microsoft SQLServer SAP HANA DetaStax Enterprise Edition ThingWorx 6.5 1.8.0(64-bit) 8.0.23(64-bit) 9.4.4 embedded N/A N/A N/A N/A IE 10 ThingWorx 6.6 1.8.0(64-bit) 8.0.23(64-bit) 9.4.4 embedded N/A N/A N/A N/A   ThingWorx 7.0 1.8.0(64-bit) 8.0.23(64-bit) 9.4.? embedded N/A N/A N/A N/A   ThingWorx 7.1 1.8.0_92-b14(64-bit) 8.0.33(64-bit) 9.4.5 embedded N/A N/A N/A 4.6.3   ThingWorx 7.2 1.8.0_92-b14(64-bit) 8.0.33(64-bit) 9.4.5 embedded embedded N/A N/A 4.6.3 IE 11 and later ThingWorx 7.3 1.8.0_92-b14(64-bit) 8.0.38(64-bit) 9.4.5 embedded embedded N/A SPS 11, 12 4.6.3, 5   ThingWorx 7.4 1.8.0_92-b14(64-bit) 8.0.38(64-bit) 9.4.5 embedded embedded 2014 and later SPS 11, 12 4.6.3, 5   ThingWorx 8.0 1.8.0_92-b14(64-bit) 8.0.44(64-bit), 8.5.13(64-bit) 9.4.5 embedded embedded 2014 and later SPS 11, 12 4.6.3, 5   ThingWorx 8.1 1.8.0_92-b14(64-bit) 8.0.44(64-bit), 8.5.13(64-bit) 9.4.5 embedded embedded 2014 and later SPS 11, 12 4.6.3, 5   ThingWorx 8.2 1.8.0_92-b14(64-bit) 8.0.47(64-bit), 8.5.23(64-bit) 9.4.5 embedded embedded 2014 and later SPS 11, 12 4.6.3, 5   ThingWorx 8.3                  
View full tip
Contents: Introduction Prerequisites Installing Java Installing PostgreSQL Running the Installer Post Installation Steps Troubleshooting tips   Introduction:   Starting with ThingWorx 8.4, PTC released a new way to install a fresh ThingWorx environment.  This installer takes care of all the permissions, database scripts, credential encryption, and tomcat options that previously needed to be done manually.  More information on the installer can be found in the ThingWorx Help Center   NOTE: This is different than the Docker installer we have available in earlier releases.   As of right now, the installation guide has very basic instructions for the installer.  The purpose of this post is to show you from start to finish what the process looks like.  For this example, I chose to deploy PostgreSQL 10 on the local system to keep things simple.   Prerequisites:   Download the latest Java 8 SE JDK RPM for RHEL Get your database ready: If you're accessing a remote PostgreSQL instance, make sure PSQL is installed and working on your ThingWorx Server Download the appropriate installer from support.ptc.com Ensure the RHEL user that will be executing the installer has SUDO privileges   NOTE: There are pieces of the manual installation guide that I had to reference in order to get JAVA and PostgreSQL properly configured.   Installing Java:   Per Page 83, I downloaded the latest Linux x64 RPM for Java 8 SE JDK (201) and followed steps 2-8 to configure Java. For step 5, I needed to use the -f parameter listed in the guide under NOTE Step 7 make sure you don't accidentally select OpenJDK if it was preinstalled   Installing PostgreSQL:   I'm following along with the Version 10 download instructions found on https://www.postgresql.org/download/linux/redhat/ NOTE: this needs root access, so run all the commands with SUDO Install the client packages Postgresql10 I will Install the optional server packages postgresql10-server since this is a local PostgreSQL instance Complete step 7 to enable automatic start.  We need to set the postgres password so our ThingWorx installer is able to create our thingworx user and the database.  This can be done with the following command: NOTE: Since this is the master user for your database, it is highly recommended to use a password that has a combination of case, numbers, letters, and symbols Sudo passwd postgres Although, this may be redundant, I also run the following command to update the password used in PostgreSQL : sudo -u postgres psql -c "ALTER ROLE postgres WITH password '<password from above>'" Navigate to /var/lib/pgsql/10/data and open pg_hba.conf for editing Review page 91 of the Installation guide to determine which setting best applies to your business needs In the same directory open postgresql.conf Scroll down to "listen_addresses" line and un-comment it.  This would  be the place to make changes if you expect remote connections to access the database.  If it is local, then the default of localhost is fine Restart PostgreSQL to apply these changes: Sudo service postgresql-10 restart   Running the Installer:   Everything should be in place now to run our installer.  Extract the ThingWorxFoundationPostgres-1.2.0-SNAPSHOT.run file to the ~ (home) directory Execute the .run file: NOTE: If it doesn't let you execute the file, it may not have extracted as an executable.  Run the below command to make it executable then try again: Chmod -x ThingWorxFoundationPostgres-1.2.0-SNAPSHOT.run Sudo ./ThingWorxFoundationPostgres-1.2.0-SNAPSHOT.run   At this point you'll be going through text to setup your installation settings.  I'll briefly list out the order you'll see them below: Terms and conditions and whether you agree Where you want ThingWorx deployed (/opt by default) NOTE: this folder will contain ThingworxStorage/ ThingworxPlatform/ tomcat/ etc… Installation Configuration user (twxfoundation by default).  This step creates a user in RHEL that will have ownership of Tomcat, various ThingWorx directory's, etc ThingWorx Administrator Password.  Used to login to ThingWorx Composer. WRITE THIS DOWN SOMEWHERE!  You cannot retrieve this password, and most likely will require you to do a fresh installation if you forget it Tomcat Port http (8080) Tomcat SSL port (8443) Use SSL For simplicity, I chose not to use it for this exercise PostgreSQL information Host Name : mine is local, so localhost Port (5432) Administrator Username (Administrator) : use postgres here, since that's the DB user password we updated above Admin password : use the postgres password ThingWorx Database login username (twadmin).  This user will be created in PostgreSQL and be tied to our ThingWorx database ThingWorx database login password: NOTE There's no place to re-enter your password, so make sure you write this down.   Unexpected issue:   For this particular install, I kept running into a failure saying "Warning: Failed to validate the PostgreSQL connection.  Check the information you entered".  I opened another putty connection and, as root, navigated to /var/lib/pgsql/10/data/log and opened the postgresql log to find the following:   2019-02-28 17:10:30.678 UTC [93377] LOG:  could not connect to Ident server at address "::1", port 113: Connection refused 2019-02-28 17:10:30.678 UTC [93377] FATAL:  Ident authentication failed for user "postgres" 2019-02-28 17:10:30.678 UTC [93377] DETAIL:  Connection matched pg_hba.conf line 84: "host    all             all             ::1/128                 ident"     The solution for me was to go into the pg_hba.conf and change the IPv6 local connections from ident to md5.  Again, make sure you are reading through the PostgreSQL documentation and adjusting these properties in a way that meets both your security and business needs.   Once the change was made, I restarted postgresql, and switched back over to my Putty instance that had the installer going.     A summary pops up for a few items, and then it asks if you're ready to continue NOTE: The progress bar goes to 100% pretty quickly, and doesn't appear to move.  Just let it sit for a few minutes while it finishes up Copy the Thingworx Device ID for future reference To check if ThingWorx is running, run 'sudo service Thingworx-Foundation status' in your command line If it is active (running) try to access it with a remote browser: More information around the command Firewalld can be found here  http://<thingworxurl>:<tomcatport>/Thingworx NOTE: If it just hangs, check your firewall to make sure the port is open for external communication   Post Installation Steps:   Licensing: Navigate to /opt/ThingWorxPostgres-1.2.0-SNAPSHOT/licensingconfigurator and run the twx-licensing-configurator.run as SUDO Choose whether or not you want PTC to store your credentials and download the license for you, or if you want to manually download the license yourself from http://support.ptc.com -> Manage Licenses (bottom right) For this example, I manually downloaded the license Move the license file over to the ThingWorx Server Since you're running the licensingconfigurator as SUDO, don't put this file into your user's home directory.  Instead, put it into /tmp NOTE: Change the downloaded filename to license_capability_response.bin.  Otherwise the file will not be recognized Then it will ask for your ThingWorx Administrator password This appears to be used for verification after the license is in place, and it sees if it can successfully log into your system Once it has completed, and assuming it says "Setup has finished configuration licensing for ThingWorx", open up a web browser and login as Administrator -> Monitor -> Subsystems -> Licensing Subsystem and verify that your licensing information looks correct on the system   Extensions: Extra security has been added as of 8.4 around importing Extensions.  More details can be found in the Help Center In short, adding extensions is disabled by default, and you need to add some lines into your /ThingworxPlatform/platform-settings.json under the "PlatformSettingsConfig" section. For example, here is what I added:    "PlatformSettingsConfig": {                 "BasicSettings": {                         "BackupStorage": "/opt/ThingWorxPostgres-1.2.0-SNAPSHOT/ThingworxBackupStorage",                         "DatabaseLogRetentionPolicy": 7,                         "EnableBackup": true,                         "EnableHA": false,                         "EnableSystemLogging": true,                         "HTTPRequestHeaderMaxLength": 2000,                         "HTTPRequestParameterMaxLength": 2000,                         "InternalAesCryptographicKeyLength": 128,                         "Storage": "/opt/ThingWorxPostgres-1.2.0-SNAPSHOT/ThingworxStorage"                 },                 "ExtensionPackageImportPolicy": {                        "importEnabled": true,                        "allowJarResources": true,                        "allowJavascriptResources": false,                        "allowCSSResources": false,                        "allowJSONResources": false,                        "allowWebAppResources": false,                        "allowEntities": true,                        "allowExtensibleEntities": false       }           }   Make sure you set the appropriate items above to true based on what your extensions require   Troubleshooting:   If things backfire, depending on where you are in the setup process, the following logs should be looked at for clues on the failure:   Installation: /tmp/bitrock_installer.logs I believe the installation directory (default /opt/ThingWorxPostgres-1.2.0-SNAPSHOT) will contain a log file if the installer fails /opt/ThingWorxPostgres-1.2.0-SNAPSHOT/ThingworxStorage/logs/ (need root access) /opt/ThingWorxPostgres-1.2.0-SNAPSHOT/tomcat/apache-tomcat-<version>/logs PostgreSQL (requires root): /var/lib/pgsql/10/data/log LicensingConfigurator : /opt/ThingWorxPostgres-1.2.0-SNAPSHOT/licensingconfigurator
View full tip
Announcements