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

Community Tip - Did you get called away in the middle of writing a post? Don't worry you can find your unfinished post later in the Drafts section of your profile page. X

IoT Tips

Sort by:
Twilio extends the ThingWorx functionality to send SMS and voice messages in variety of languages. Starting from scratch I'll cover the steps required to setup the Twilio extension and the basic account registration (trial version) and setup at Twilio.com Twilio allows registering with the trial account, which comes with $15 as initial account balance, something which is quite useful for testing the initial setup and testing of Twilio extension in conjunction to ThingWorx. Prerequisite 1. Sign up, if not already done, with Twilio.com for free trail account 2. Configure the account to setup a verified phone number to receive text and voice messages, free trial account allows setting up 1 verified phone number that can receive text and voice messages Note: See What's the difference between a verified phone number and a Twilio phone number? 3. Choose and configure a Twilio phone number capable of sending text and voice messages, free trial account allows setting up of 1 Twilio number which will be used in the Extension configuration in ThingWorx for sending the messages 4. Download Twilio Extension from ThingWorx Marketplace Note that Twilio phone number should be enabled with the send SMS or send voice message capability, depending on what your use case is. Failing to do so will lead to error while testing the sendSMS or sendVOICE service (two default services provided with the Twilio Extension when imported in ThingWorx) Signing up and setting up Twilio account 1. Sign up on Twilio.com with your details and emailID. When registering for the first time you'll be prompted for your personal phone number as part of the security requirement. Also with free trial account this will be the only phone number where you'll be able to send SMS or Voice message via Twilio Extension in ThingWorx 2. Next would be to setup the Twilio number with voice and text messaging, navigate to https://www.twilio.com/console/phone-numbers/getting-started 3. Do ensure that you setup the voice or text capabilities for the new Twilio number, failing to do so will lead to error in sending message via Twilio Extension in ThingWorx 4. Different Twilio Number have different capabilities, it's quite possible that you don't find the number with required capabilities i.e. Voice, SMS - in that scenario simply search for different number, one that has the capabilities you are looking for 5. With trial account only 1 Twilio number is avilable for setup 6. While setting up the Twilio number you will be required to provide a valid local address of your country The cost of setting up the number and further sending the SMS will only be deducted from the $15 made available when you signed up for the first time. Navigate to your account details on Twilio.com to make note of the following information which will be used when configuring the Twilio Extension in ThingWorx: a. Account SID b. Authentication ID c. Your Verified Phone Number (will be used for receiving the messages) d. Twilio Phone number created with required capabilities, e.g. that number is capable of sending text message Here's how it shows up once you are successfully registered and logged on to the twilio.com/console To check your Twilio Phone Number and the Verified Phone Number navigate to twilio.com/phone-numbers As it can be seen in the above screenshot, the number I have bought from Twilio is capable of sending Voice and SMS. With this all's set  and ready to configure the Twilio Extension in ThingWorx, which is pretty straight forward. Setup Twilio Extension in ThingWorx 1. Let's setup the extension by navigating to the ThingWorx Composer > Import/Export > Extensions > Import > browse to the location where you saved the Twilio Extension from ThingWorx Marketplace and click Import 2. Once imported successfully refresh the composer and navigate to Modeling > Things , to create a new Thing implementing the Twilio Template (imported with the extension) like so, in screenshot below Thing is named DemoTwilioThing 3. Navigate to the the Configuration section of that Thing, to provide the information we noted above from Twilio account Note: this demo thing is setup to send the text SMS to my verified phone number only, therefore the CallerID in the configuration above is the Twilio number I created after signing up on Twilio with text message capability. 4. Save the created the Thing 5. Finally, we can test with the 1 of the 2 default services provided with the Twilio Template i.e. SendSMSMessage service 6. While testing the SendSMSMessage service use your verified phone number in To for receiving the message Troubleshooting some setup related issues I'll try to cover some of the generic errors that came up while doing this whole setup with Twilio Extension Error making outgoing SMS: 404 / TwilioResponse 20404 Reason If the Twilio number is not enabled with SMS sending capabilities you may run into such an error when testing the service. Here's the full error stack Unable to Invoke Service SendSMSMessage on DemoTwilioThing : Error making outgoing SMS: 404 <?xml version='1.0' encoding='UTF-8'?><TwilioResponse><RestException><Code>20404</Code><Message>The requested resource /2010-04-01/Accounts/<AccountSID>/SMS/Messages was not found</Message><MoreInfo>https://www.twilio.com/docs/errors/20404</MoreInfo><Status>404</Status></RestException></TwilioResponse> Resolution Navigate back to the Phone Number section on Twilio's website and as highlight in screenshot above check if the Twilio number is enabled with SMS capabilities. Error making outgoing SMS:400 / TwilioResponse 21608 Reason You may encounter following error when attempting to send SMS/Voice message, here's the full error detail Wrapped java.lang.Exception: Error making outgoing SMS: 400 <?xml version='1.0' encoding='UTF-8'?><TwilioResponse><RestException><Code>21608</Code><Message>The number <somePhoneNumber>is unverified. Trial accounts cannot send messages to unverified numbers; verify <somePhoneNumber>at twilio.com/user/account/phone-numbers/verified, or purchase a Twilio number to send messages to unverified numbers.</Message><MoreInfo>https://www.twilio.com/docs/errors/21608</MoreInfo><Status>400</Status></RestException></TwilioResponse> Cause: Error making outgoing SMS: 400 <?xml version='1.0' encoding='UTF-8'?><TwilioResponse><RestException><Code>21608</Code><Message>The number <somePhoneNUmber>is unverified. Trial accounts cannot send messages to unverified numbers; verify <somePhoneNumber> at twilio.com/user/account/phone-numbers/verified, or purchase a Twilio number to send messages to unverified numbers.</Message><MoreInfo>https://www.twilio.com/docs/errors/21608</MoreInfo><Status>400</Status></RestException></TwilioResponse> Resolution As the error points out clearly the number used in To section while testing the SendSMSMessage service didn't have verified number. With free trial account you can only use the registered verified phone number where SMS/Voice message can be sent. If you want to use different number an account upgrade is required. Error making outgoing SMS:400 / TwilioResponse 21606 Reason Following error is thrown while testing SendSMSMessage service with different Twilio number which is either not the same as the number you bought when setting up the trial account or it doesn have SMS sending capabiltiy. Here's the full error stack Wrapped java.lang.Exception: Error making outgoing SMS: 400 <?xml version='1.0' encoding='UTF-8'?><TwilioResponse><RestException><Code>21606</Code><Message>The From phone number <TwilioNumber>is not a valid, SMS-capable inbound phone number or short code for your account.</Message><MoreInfo>https://www.twilio.com/docs/errors/21606</MoreInfo><Status>400</Status></RestException></TwilioResponse> Cause: Error making outgoing SMS: 400 <?xml version='1.0' encoding='UTF-8'?><TwilioResponse><RestException><Code>21606</Code><Message>The From phone number <TwilioNumber> is not a valid, SMS-capable inbound phone number or short code for your account.</Message><MoreInfo>https://www.twilio.com/docs/errors/21606</MoreInfo><Status>400</Status></RestException></TwilioResponse> Resolution Check the configuration in the ThingWorx Composer for the Thing created out of Twilio Template whether or not the callerID is configured with correct Twilio account number
View full tip
Performance and memory issues in ThingWorx often appear at the Java Virtual Machine (JVM) level. We can frequently detect these issues by monitoring JVM garbage collection logs and thread dumps. In this first of a multi-part series, let's discuss how to analyze JVM garbage collection (GC) logs to detect memory issues in our application. What are GC logs? When enabled on the Apache server, the logs will show the memory usage over time and any memory allocation issues (See: How to enable GC logging in our KB for details on enabling this logging level).  Garbage Collection logs capture all memory cleanup operations performed by the JVM.  We can determine the proper memory configuration and whether we have memory issues by analyzing GC logs. Where do I find the GC logs? When configured as per our KB article, GC logs will be written to your Apache logs folder. Check both the gc.out and the gc.restart files for issues if present, especially if the server was restarted when experiencing problems. How do I read GC logs? There are a number of free tools for GC log analysis (e.g. http://gceasy.io, GCViewer). But GC logs can also be analyzed manually in a text editor for common issues. Reading GC files: Generally each memory cleanup operation is printed like this: Additional information on specific GC operations you might see are available from Oracle. A GC analysis tool will convert the text representation of the cleanups into a more easily readable graph: Three key scenarios indicating memory issues: Let's look at some common scenarios that might indicate a memory issue.  A case should be opened with Technical Support if any of the following are observed: Extremely long Full GC operations (30 seconds+) Full GCs occurring in a loop Memory leaks Full GCs: Full GCs are undesirable as they are a ‘stop-the-world’ operation. The longer the JVM pause, the more impact end users will see: All other active threads are stopped while the JVM attempts to make more memory available Full GC take considerable time (sometimes minutes) during which the application will appear unresponsive Example – This full GC takes 46 seconds during which time all other user activity would be stopped: 272646.952: [Full GC: 7683158K->4864182K(8482304K) 46.204661 secs] Full GC Loop: Full GCs occurring in quick succession are referred to as a Full GC loop If the JVM is unable to clean up any additional memory, the loop will potentially go on indefinitely ThingWorx will be unavailable to users while the loop continues Example – four consecutive garbage collections take nearly two minutes to resolve: 16121.092: [Full GC: 7341688K->4367406K(8482304K), 38.774491 secs] 16160.11: [Full GC: 4399944K->4350426K(8482304K), 24.273553 secs] 16184.461: [Full GC: 4350427K->4350426K(8482304K), 23.465647 secs] 16207.996: [Full GC: 4350431K->4350427K(8482304K), 21.933158 secs]      Example – the red triangles occurring at the end of the graph are a visual indication that we're in a full GC loop: Memory Leaks: Memory leaks occur in the application when an increasing number of objects are retained in memory and cannot be cleaned up, regardless of the type of garbage collection the JVM performs. When mapping the memory consumption over time, a memory leaks appears as ever-increasing memory usage that’s never reclaimed The server eventually runs out of memory, regardless of the upper bounds set           Example(memory is increasing steadily despite GCs until we'll eventually max out): What should we do if we see these issues occurring? Full GC loops and memory leaks require a heap dump to identify the root cause with high confidence The heap dump needs to be collected when the server is in a bad state Thread dumps should be collected at the same time A case should be opened with support to investigate available gc, stacktrace, or heap dump files
View full tip
As per ThingWorx Documentation: Updating Properties Automatically in a Mashup A mashup using the GetProperties service can be configured to use websockets and receive updates to properties automatically. When creating or editing a mashup, you can configure the GetProperties service so that the properties are automatically updated by selecting the Automatically update values when able checkbox in the service properties panel. So, the feature to update Properties Automatically in a Mashup is limited to GetProperties service only. Following are the steps to invoke our own custom Service automatically when a property change: 1. Find all the Properties in your Thing for which the DataChange should trigger the custom service. 2. In mashup; add value display widget (or some other widgets) for each property in Step1. 3. Bind the properties from GetProperties service to these widget. 4. Set visible property of these widgets to false so that they don't show up at the RunTime. 5. Now bind the ServiceInvokeCompleted event of GetProperties Service to your custom Service. 6. Save and view Mashup. Result: When any of the Property from Step1 is changed; Custom Service will be invoked in our Mashup.
View full tip
One of topics that are usually of interest when entering the ThingWorx world is integration with third-party systems. Disclaimer: the following guide is intended to be rather comprehensive and guide you in achieving the best integration with your desired system ( !=quick and dirty ). For example, from my experience, customers many times ask: -how can I connect to my hardware device -how can I connect to this device cloud so I can get data from it? -how can I connect to my ERP? With some luck, I hope that at the end of this article I will provide a generic workflow that will help you on achieving the best integration solution for your use-case. We need to write down some requirements (they are not in order; depending on the usecase might not be worth to be answered): 0. What is the usecase (detailed description) ?.      This is by far one of the most important aspects of any software development project.      Please document your usecase with all possible future uses.      For example:           - I want to send information from sensors to the ThingWorx Server, and I want to do TCP Tunnelling to the device and/or Remote Desktop. Or maybe only sending information from sensors and nothing else. Do I need in the future Software Updates or not?           - I want to read the Customer information from my CRM AND also update that information (read/write). 1. Write down system specification for the hardware or software system.           -Available RAM for user apps           -Available Disk Space for User Apps           -Does it have a TCP IP Stack?           -Operating System           -Installed runtimes (Java/.NET - which versions?) 2. Can I access the system or device directly from the ThingWorx Server?      This means answering the question: is my system directly accessible from my server? Or is there a firewall which stops incoming connections?      Another question to answer, is: can I modify my firewall to allow incoming connections? 3. What protocol is my device or system capable of supporting for data transfer?      Example: I have a device which is capable of outputting information through TCP only.                     I have a device who can only do HTTP callbacks to a HTTP server.                     I have Microsoft SQL, to which I can connect through ADO.NET or JDBC.                     I have a third party service billing provider who supports interfacing via HTTP Webservices (SOAP or REST).                     I have a device supporting CoAP.      Typically all third party software systems support communication via Webservices. 4. Can I configure and/or deploy new software to my device or system?      We need to have this question answered, because on some cases it might make more sense to write some logic on the system or device.      For example if I want to access data from an SQL server and my usecase might require some processing for which that SQL server is better suited to do, it might be much more efficient to have that logic stored as a Stored Procedure there and I just call it from ThingWorx.       Or in the case of Windchill, it might make more sense to write an InfoEngine task to do my functionality than writing that on the ThingWorx side.      Possible example answers:                     -My device is already deployed in the field and I can not modify the configuration at all.                     -My device is a new product, so I can put whatever software I want on it.                     -I only have read access to my software system, so I must do all processing externally. If you wrote down all of those it is time to determine what are the integration options for us. The typical workflow that I follow is the next one: I look for any Out-Of-The-Box supported protocol (determined at step 3) and then implement the needed functionality in the language that is best suited for my usecase (Javascript usually). The list of protocols that the platform supports is listed in different places: -PTC Help Center Link -ThingWorx Marketplace - https://marketplace.thingworx.com/items The key point is that the list is alive and updated by both our partners and us. Usually the preferred way to write logic is by using the Javascript services. It makes it incredibly fast to write down your business logic without having the need to recompile. The elements from the ThingWorx ecosystems that we can use are the following: -the ThingWorx server itself (it has built in support for calling external Webservices) -ThingWorx Extensions. They are Java written pieces of code that can help you achieve your usecase. To be used whenever your ThingWorx server OOTB functionality (or Marketplace Extensions) does not allow you to develop your usecase. There is no actual need to write an Extension if somebody else already developed that for you and published in the ThingWorx Marketplace https://marketplace.thingworx.com/items      A link for understanding Extension is the following: How to rapidly develop ThingWorx IIoT Extensions -ThingWorx Integration Connectors -ThingWorx Edge Micro Server: https://developer.thingworx.com/ems -ThingWorx Edge SDKs: https://developer.thingworx.com/sdks Examples: -I have an third party Server which allows me to send SMS and Voice messages through it via its Rest API.      Answer: best here is to use the OOTB Webservices support from ThingWorx, which exposes the HTTP verbs, like GET, POST, PUT, via the ContentLoaderFunctions -I have a device which has a TCP stack that is capable only to do HTTP calls.      Answer: I can point that device to do calls against the REST API of ThingWorx, in order to update data directly there. -I have a fleet of 300.000 devices which are sending their data to an MQTT server.      Answer: In this case I can use the MQTT Extension that is offered by ThingWorx -I have an external SQL server that does not accept inbound connections (behind a firewall) but I must get data from it. Network will however allow outbound connections      Answer: use the ADO.NET Edge Client that must be installed in a location accessible to that server. The ADO.NET Edge Client will connect to the Server and then to the ThingWorx platform allowing use of SQL statements directly from within the platform. -I have a device who only accepts TCP connections and I want to read data from it. It sends data only after receiving a command through TCP.      Answer: Use the TCP Extension available in the ThingWorx Marketplace. It is built specifically for this usecase -I have a device which has lots of RAM and Disk Space and I must send data from it, while allowing software updates in the future.      Answer: depending on your preferred coding language you can use either the ThingWorx Edge Microserver (for which you must write code in LUA) or write an implementation in one of the ThingWorx Edge SDKs. A key point here is to understand that the coding effort is identical in theory, and is only limited by the experience you have and the functionality that may be available easier in Java, vs LUA, vs C, vs. Net. I appreciate feedback to this article in the hope of being able to continuously improve it.
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
Hello, There have been some inquires about how can one use AngularJS for developing custom parts that can run in the ThingWorx environment. To address these inquires I have created a document that describes the process of integrating AngularJS with ThingWorx. The document attached comes with the source code for the examples presented throughout the document and an extension for AngularJS 1.5.8 and angular-material components. Feedback is appreciated. Thank you.
View full tip
This is part of the continuing series of Blog posts regarding Troubleshooting the Application, this article will discuss more advance issues that some clients and customer have encountered while building or using ThingWorx Analytics. Packer Script Error – Unable to Download CentOS Image As the application is developed and built inside a CentOS image, the ThingWorx Analytics Packer Script tool for Virtual Machine Appliance creation utilizes the CentOS mirror repository in the creation process. When the end user is attempting to build the Virtual Machine Appliance with the Packer Script media creation tool, part of the process is to download the CentOS 7 ISO image file as the basis for the operating system that the ThingWorx Analytics Server software will be installed to. If CentOS updates or changes their mirror links for the source file ISO, you may encounter the following error: ==> virtualbox-iso: Downloading or copying Guest additions virtualbox-iso: Downloading or copying: file:///C:/Program%20Files/Oracle/VirtualBox/VBoxGuestAdditions.iso ==> virtualbox-iso: Downloading or copying ISO virtualbox-iso: Downloading or copying: file:///local-file-repo/CentOS-7-x86_64-Minimal-1511.iso virtualbox-iso: Error downloading: open local-file-repo/CentOS-7-x86_64-Minimal-1511.iso: The system cannot find the path specified. virtualbox-iso: Downloading or copying: http://mirror.spro.net/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1511.iso virtualbox-iso: Error downloading: checksums didn't match expected: 88c0437f0a14c6e2c94426df9d43cd67 ==> virtualbox-iso: ISO download failed. Build 'virtualbox-iso' errored: ISO download failed. ==> Some builds didn't complete successfully and had errors: --> virtualbox-iso: ISO download failed. ==> Builds finished but no artifacts were created. Solution Method 1: Configuration File Replacement We have created a custom JSON configuration file that resolves the mirror issue for CentOS 7 v1611. You can download the JSON file here; you may have to right-click and “save link as” a JSON extension file. Also note, you will have to save/rename this JSON file as neuron-solo-variables.json. Using this file, navigate to your Packer Script builder directory, usually this is found in the following path: <PATH>\ThingWorx-Analytics-Server-Standalone\components\vm-builder\neuron-vm-builder Copy the new JSON file into this directory, and replace the current existing copy. You can now re-run the Packer Script for your desired Virtual Machine Appliance output. Method 2: Manual Configuration File Adjustment You will have to locate an active mirror for CentOS 7. A list of current active mirrors can be found here. When selecting a mirror, you will need to select the Minimal ISO install, as this is the base image that is used for the VM creation. Next, you will have to open the current neuron-solo-variables.json configuration file located in the <PATH>\ThingWorx-Analytics-Server-Standalone\components\vm-builder\neuron-vm-builder directory. You will have to replace the os_image_download_url value with an active Mirror URL from the list above. Next, for the os_iso_md5_checksum variable, you will need to replace the entry with the new SHA256 checksum from CentOS, which can be located here. Default Settings: New Settings: Save changes and close the neuron-solo-variables.json configuration file. CentOS has switched over from MD5 to SHA256 checksums. Even though in the following the variable name has “MD5” in the string, we will be modifying a second JSON configuration file to address this. In the same directory that we are currently working in, open the neuron-solo.json configuration file. You will need to modify the attribute iso_checksum_type to sha256 Default Settings: New Settings: Save changes and close the neuron-solo.json configuration file. You can now re-run the Packer Script for your desired Virtual Machine Appliance output.
View full tip
Integrating LDAP authentication into Thingworx is fairly simple. Since release 5.0 and later, the out-of-the-box (OOTB) Thingworx authenticators already include the necessary code to validate a user's credentials against an LDAP server. These authenticators look to see if an LDAP server is connected every time a user attempts a login, and then further check to see if this user exists in the LDAP server. If the username does exist in LDAP, then Thingworx will check if the password entered is a match to the password stored within LDAP. If the password entered does not match the password stored in LDAP, then Thingworx will next check if the password matches the one stored in Thingworx for that user. So in order for a user to login to Thingworx, they must have a user Thing created for them within Thingworx Composer (this can be done programmatically, see below), and a valid password which matches either an LDAP account password or the password as it is set for that user on the Thing in Thingworx Composer. The first thing a developer needs to do to integrate LDAP is configure their Thingworx instance so that it can find the LDAP server and access its contents. This is done by importing an XML file which will allow the developer to see a Thing that comes with the Thingworx platform (see attached file "directoryServices.xml"). The Thing that needs configuring is called ApacheDS3 and it is a DirectoryServices Thing. The largest task for a developer to do to integrate LDAP into Thingworx involves importing their LDAP users into Thingworx. Getting the LDAP usernames out of the LDAP server will vary depending on which distribution of LDAP is in use. However, once the developer acquires this information, using it to create users in Thingworx is simple. The developer will need to create a Thing Service which creates a dummy password and assigns the LDAP username in the parameters. Then they can pass the parameters into the CreateUser service of the “EntitiyServices” resource: var params = { password: "SOMETHING_COMPLICATED", //dummy password does not matter, but you don't want an accidental match, so make it something very complicated, and standard to your company's LDAP users name: ldap_username, //retrieve from LDAP description: "This user was created as part of LDAP import", //can be whatever you'd like tags: undefined }; Resources["EntityServices"].CreateUser(params); // no return Any users created in this way will be redirected to Squeal if there is no home mashup assigned, so you will have to add an additional bit of code which assigns the home mashups to users, looping through something like this: var params = {     name: "dashboard" //replace this with String name of dashboard (must exist) }; Users[username].SetHomeMashup(params); For full steps on integrating LDAP and Thingworx, including instructions on how to set up an ApacheDS test LDAP server, see the Thingworx support article titled “Integrate LDAP Authentication and Import LDAP User Directory into Thingworx” (reference document – CS221840).
View full tip
Troubleshooting platform issues is  generally done by using a layer approach, similar to a simplified OSI Model. From bottom to top, the following layers represent the areas to analyze during each step: 1. Physical (Server, power, wired connections): check the server status and condition, CPU and memory levels. 2. Software (Operating system, tomcat, java versions, compatibility, and configuration): refer to the compatibility matrix to ensure the requirements are met; verify Tomcat  java configuration. * Note: Tomcat manager, server status, conveniently provides this information in one place. 3. Network: ensure  proper connectivity, port availability, firewall  configuration, and additional security, if applicable. 4. Application. The main focus of this blog post will concentrate on the step 4. As the Thingworx application is driven by Tomcat, first available tools coming "out-of-the-box" is the built-in Tomcat manager app.  Clicking on the "Server Status" provides the information on the versions, memory usage, processes, times and thread counts. Keep in mind, the default Tomcat maximum thread number is 200. Some additional tools that could assist in troubleshooting java applications and gathering performance metrics are: Javamelody, new relic, profiler4j. These have to be obtained, installed, and configured separately. Javamelody: Free and lightweight monitoring tool which does not do any profiling, safe to use in production environments. It comes with a series of plug-ins including for Grails, Jenkins and Jira. New relic: Real-time Java application monitoring, features code deployment reports, transaction tracing across different tiers and the ability to create alerts. Subscription fee applies. Profiler4j: Profiler4J is a free open-source tool for profiling in Java. It is enabled by passing an argument at start-up with a path to the Profiler4J .jar file. It comes with several graphs and charts showing a call graph with method details, a call tree, a memory monitor, a class list and thread monitoring. From the application perspective, Thingworx composer provides a PlatformSubsystem and LoggingSubsystem: PlatformSubsystem contains such services as GetPerformanceMetrics, GetSummaryInformation, GetThingworxVersion, and more to provide fundamental information for any troubleshooting scenario. LoggingSubsystem contains the logs, log settings, and other monitoring values. List of recommended tools for troubleshooting all layers: Wireshark: monitors network traffic Jstack: monitors memory consumption of specific threads Dynatrace: system performance and web application performance jconsole: system or application performance ​​
View full tip
This blog is intended to help diagnose and fix the most common issues that may be encountered when working with ThingWatcher. It cannot be stressed strongly enough that you should be familiar with your data including the average time interval between data points, and the collection duration and certainty threshold you specified. Before you start troubleshooting ThingWatcher, check that result and training microservices is running. For testing result microservices open a web browser and paste result URL; http://<IP of microservices>:<Port of results microservices>/results/models (e.g., http://localhost:8096/results/models) For testing training microservices open a web browser and paste training URL; http://<IP of microservices>:<Port of training microservices>/training (e.g., http://localhost:8091/training) If you see either: {"values":[],"total":0,"next":null,"previous":null} or a list of training jobs in JSON format, this means the result and training microservice service is available. 1. Question. I haven't seen an anomaly but I believe that my 'property' is anomalous?         This can be caused by different reasons, here are the most common causes: The certainty is too high. If the certainty is too high ThingWatcher is conservative in its categorization of "true positives" and therefore may emit more "false negatives". Reducing the certainty will change this behavior but note that ThingWatcher may now categorize too many "false positives" as a result. In other words, ThingWatcher may detect the desired anomalies but also some non-anomalies. The 'property' is anomalous during training data collection. If ThingWatcher creates a predictive model from anomalous data, it may not be able to detect the desired anomalies during MONITORING because the data does not really appear to be anomalous. So ThingWatcher treats this pattern as 'normal'. Therefore, ensure that 'property' values are also non-anomalous during training. There are long time gaps during the monitoring state so ThingWatcher stays in Buffering and categorizes these data points as non-anomalous. 2. Question. ThingWatcher detects an anomaly but my 'property' is non-anomalous? The certainty might be too low. In this case, ThingWatcher reports anomalies when the incoming data pattern looks even slightly different from the expected data pattern. ThingWatcher might need more training data. If the 'property' data has a pattern that occurs over a long time span, ThingWatcher needs to collect multiple cycles of all these patterns in order to detect a true anomaly without emitting too many false positives. 3. Question. ThingWatcher is in FAILED State, why?     There are many possible reasons for a failed state, here are the most likely problems that can cause a failed state. ThingWatcher emits a FAILED ThingWatcher State because the training service has not been setup or is down. similarly, the result service is not available. NotemessageText=Unexpected exception. {Throwable=[ConnectException: Operation timed out}]]messageText=Unexpected exception. {Throwable=[ConnectException: Connection refused}]]. Note that ThingWatcher is still able to collect all training data and you will only begin to see these failed states after ThingWatcher tried to post the training request. ThingWatcher emits a FAILED ThingWatcher State because time gaps prevent the data collection for training.You will see this warning in the log messages : "A long time gap was detected in the data that is greater than the threshold of {n}". This means you have a long gap in the training data and ThingWatcher will recollect the data. If there are more than 3 recollections due to a long time gap, ThingWatcher transitions to a failed state and will not be able to recover. In this case you can either instruct ThingWatcher to retrain and try again or check the data source to make sure it does not have long gaps. 4. Question. Why does ThingWatcher remain in Buffering? There are many possible reasons for ThingWatcher to remain in Buffering, but the most likely issue is time gaps which cause ThingWatcher to remain stuck in Buffering. If the incoming data regularly contains long time gaps, you will notice that ThingWatcher keeps alternating between the monitoring and buffering states. You may need to provide better quality data i.e. more evenly spaced data. Source: Alex Meng, Specialist Software Engineer
View full tip
An introduction to installing the ThingWorx platform. Information on the environment, prerequisites, and configuration steps when installing ThingWorx. Includes walkthroughs of installing with H2 and PostgreSQL databases, an introduction and demonstration of the Linux installation script, solutions to common installation problems and more.     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
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
Please open your ApplicationLog located in ThingworxStorage/logs and inspect for errors. Something like the following might be observed: **********LICENSING ERROR ANALYSIS 2017-03-31 16:29:19.591+0300 [L: ERROR] [O: ] [I: ] [U: SuperUser] [S: ] [T: localhost-startStop-1] C:\WINDOWS\Sun\Java\bin is listed as a java.library.path but it does not exist 2017-04-12 13:51:53.515+0200 [L: ERROR] [O: c.t.s.s.l.LicensingSubsystem] [I: ] [U: SuperUser] [S: ] [T: localhost-startStop-1] Failed to load FlxCore library. Ensure it's in PATH (Windows) or LD_LIBRARY_PATH(other platforms) or set with the VM arg, -Djava.library.path. Error message : com.flexnet.licensing.DllEntryPoint.entry([B) Typically, if the license file has been downloaded and placed correcrtly, according to the 7.4 installation guide, the error in the log will specify where the file was found. If the license path was specified per the installation guide in the tomcat java path, you may try to clear it from the Tomcat java settings and keep these parameters: -Dserver -Dd64 -XX:+UseNUMA -XX:+UseConcMarkSweepGC -Dfile.encoding=UTF-8 And then set up the license path in the environment variable path: Go to explorer, right click on "my computer" -> Properties -> Advanced settings -> Environment variables -> edit "PATH", add ; and then path to your tomcat extensions folder, “ ;<path to extensions folder of tomcat> “ or, for example ";C:\ptc\Thingworx\webapps\Thingworx\WEB-INF\extensions"
View full tip
Usually we want to search out all User list in ThingWorx with Service GetEntityList   But it only shows limited information. In order to see more details like User Extension information etc., and in order to add more search conditions we could encapsulate it in a new created service. Below is an example code: input: emailAddress(String) output: INFOTABLE // Code start here // step 1 Get all user list var params = {            maxItems: undefined /* NUMBER */,           nameMask: undefined /* STRING */,           type: "User" /* STRING */,           tags: undefined /* TAGS */   };   var users = Resources["EntityServices"].GetEntityList(params);   // step 2 get all other properties for user list var params = {            infoTableName: "infotable" /* STRING */,            dataShapeName: "userPropertiesDS" /* DATASHAPENAME */   };   var infotable = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape(params);   for (var v=0;v<users.length;v++){       var row = new Object();       row.EmailAddress= Users[users .name].emailAddress;            row.name = users .name;       row.fullName = Users[users .name].fullName;       infotable.AddRow(row);   // ...... // Add any other user properties you want to display } // step 3 filter the user list with search conditions // You could add as many parameters as you like var query = {   "filters": {     "type": "AND",     "filters": [       {         "fieldName": "EmailAddress",         "type": "EQ",         "value": emailAddress       },       {         "fieldName": "name",         "type": "EQ",         "value": "user1"       }     ]   } }; var params = {          t: infotable /* INFOTABLE */,          query: query /* QUERY */   }; // result: INFOTABLE var result = Resources["InfoTableFunctions"].Query(params);     Besides, to create a query is also a one step operation in Thingworx , you do not need to create it manually:
View full tip
In the following scenario (for redhat in this case), running the dbsetup script results in the error: ./thingworxPostgresDBSetup.sh psql:./thingworx-database-setup.sql:1: ERROR:  syntax error at or near ":" LINE 1: CREATE TABLESPACE :"tablespace" OWNER :"username" location :... ^ psql:./thingworx-database-setup.sql:3: ERROR:  syntax error at or near ":" LINE 1: GRANT ALL PRIVILEGES ON TABLESPACE :"tablespace" to :"userna... ^ psql:./thingworx-database-setup.sql:5: ERROR:  syntax error at or near ":" LINE 1: GRANT CREATE ON TABLESPACE :"tablespace" to public; ^ psql:./thingworx-database-setup.sql:14: ERROR:  syntax error at or near ":" LINE 1: CREATE DATABASE :"database" WITH ^ psql:./thingworx-database-setup.sql:16: ERROR:  syntax error at or near ":" LINE 1: GRANT ALL PRIVILEGES ON DATABASE :"database" to :"username"; Given that the installed components match the requirements guide (tomcat 8, Postgresql 9.4.5+ for Thingworx 7.x), run the following command: Run this directly from bin directory of postgres deployment – psql -q -h localhost -U twadmin -p 5432 -v database=thingworx -v tablespace=thingworx -v tablespace_location=/app/navigate/ThingworxPostgresqlStorage -v username=twadmin That must get into command line interface. From there  run the following with full qualified path to the sql file on disk (replace FULLPATH with the path to sql file ) \i ./FULLPATH/thingworx-database-setup.sql If you are experiencing the above-mentioned syntax error, then likely the output will be: psql: FATAL:  database "twadmin" does not exist. Then from postgres bin directory, run the following: ./psql postgres \set Then the second command; \q psql -q -h localhost -U twadmin -p 5432 -v database=thingworx -v tablespace=thingworx -v tablespace_location=/app/navigate/ThingworxPostgresqlStorage -v username=twadmin \set   We see the following outputs: ./psql postgres Password: psql.bin (9.4.11) Type "help" for help. postgres=# \set AUTOCOMMIT = 'on' PROMPT1 = '%/%R%# ' PROMPT2 = '%/%R%# ' PROMPT3 = '>> ' VERBOSITY = 'default' VERSION = 'PostgreSQL 9.4.11 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-55), 64-bit' DBNAME = 'postgres' USER = 'postgres' PORT = '5432' ENCODING = 'UTF8' postgres=# \q -bash-4.1$ psql -q -h localhost -U twadmin -p 5432 -v database=thingworx -v tablespace=thingworx -v tablespace_location=/ThingworxPostgresqlStorage -v username=twadmin Password for user twadmin: twadmin=# \set AUTOCOMMIT = 'on' QUIET = 'on' PROMPT1 = '%/%R%# ' PROMPT2 = '%/%R%# ' PROMPT3 = '>> ' VERBOSITY = 'default' VERSION = 'PostgreSQL 8.4.20 on x86_64-redhat-linux-gnu, compiled by GCC gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17), 64-bit' database = 'thingworx' tablespace = 'thingworx' tablespace_location = '/ThingworxPostgresqlStorage' username = 'twadmin' DBNAME = 'twadmin' USER = 'twadmin' HOST = 'localhost' PORT = '5432' ENCODING = 'UTF8' Note, even though Postgresql 9.4.5 has been installed by the system administrator, there are still traces of Postgresql 8.4.20 present in the system that cause the syntax error issue (possibly as part of  the default OS packaging). Removing the 8.4.20 rpms will resolve the problem.
View full tip
1. Use Postman or any other software for Rest Api call to the ThingWorx. 2. Create a query in Postman with following parameters: Type: POST URL: https://<IP>:<PORT>/Thingworx/Users/<UserName>/Services/AssignNewPassword <IP>: IP of the server where ThingWorx is installed. <PORT>: Port on which ThingWorx is running (if required). <UserName>: User Name of the user whom Password is to be reset. Headers: appkey : Your Administrator App key or App key of user having Permission for AssignNewPassword Service for the user. Content-Type: application/json Body: {     "newPassword":"NewPasswordHere",     "newPasswordConfirm":"NewPasswordHere" } 3. Send the Query. 4. Login using new Password.
View full tip
Steps to to navigate to different mashups on double click of different google map markers in ThingWorx Create a DataShape with two fields Location MashupName Create a DataTable using the DataShape Add required Location data and corresponding MashupName to be opened in the DataTable Create a mashup Add GoogleMap and Navigate widget to the mashup Bind All Data from QueryDataTableEntries service of the DataTable in the mashup to the GoogleMap widget by dragging and dropping that item onto the GoogleMap and selecting the Data option In GoogleMap widget properties select LocationField as Location Bind MashupName from Selected Row(s) in QueryDataTableEntries service of the DataTable in the mashup to the Navigate widget by dragging and dropping that item onto the Mashup Link and selecting the MashupName option Bind the DoubleClick event of GoogleMap widget properties in the mashup to Navigate widget by dragging and dropping that item onto the Mashup Link and selecting the Navigate option Save and view mashup Copy of my article as blog post: https://support.ptc.com/appserver/cs/view/solution.jsp?n=CS249997&lang=en_US
View full tip
The ThingWorx Android SDK was designed to load without modification into Android Studio but due to recent changes in Android Studio, the Thingworx Always On Android SDK 1.0 needs to have minor modifications made to its build files before it will load or build. This changes will be made in the 1.1 release in July, 2016 but until then they will have to be updated after the user downloads the SDK. Android Studio changed the minimum required Android build tools for gradle. This also forces a new version of gradle to be required. The following changes must be made to each set of SDK project build files. The tw-android-sdk/gradle/wrapper/gradle-wrapper.properties file ( there is only one present in the entire sdk) must have this line changed from: distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip to: distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip In all build.gradle files change from: buildToolsVersion "19.1.0" to: buildToolsVersion “21.0.0” also in all build.gradle files change from: dependencies { classpath 'com.android.tools.build:gradle:1.3.0' } to: dependencies { classpath 'com.android.tools.build:gradle:2.1.0' } Now you should be able to import and build all examples again.
View full tip
The purpose of this post is to provide some ideas and help diagnosing issues in mashup. First, check if the problem occurs at mashup runtime or in design(edit) mode. Runtime: Is the issue visual or related to improper service execution? (e.g, "my data is displaying correctly but the styling or formatting is wrong" -- visual, "my data is displayed incorrectly but the styling and formatting is right" -- improper service execution) For visual/styling/formatting issues, return to the edit mode of mashup, and ensure the proper style definitions were set up. Ensure the logic behind the connections is correct. Check configuration of the widget(s) involved. Were there any changes made to the styles after the mashup was saved and run the first time? If so, try - clearing the browser cache;  -reconnecting the dependent entity with the style involved in the issue. If the problem persists, contact technical support to raise a cosmetic defect ticket. For improper service execution, return to the composer and use the "test" button on the service to execute and validate the output. If the outputs are incorrect, check the code inside of the service. If the outputs come out as expected, try reconnecting the service in the mashup design mode and clearing the browser cache. If the issue is related to the data from the user database not displaying  -- ensure the database connectivity and proper credentials. If the problem persists, reach out to the technical support to raise a defect.    2.   Design/edit mode: If the widgets are not displaying correctly or not appearing in the list: Check the extensions involved are appearing under the extension manager. Re-upload if needed and restart the composer. If the Google Maps widget is not showing in the mashup the first time of being used, allow up to 2 hrs to load and cache. Submit a ticket to technical support, including the screenshots of the issue. For other styling, formatting, or improper display issues at design time: document the observation and supply the screenshots to the technical support team for investigation. Note: See Tools and approaches used in troubleshooting Twx issues.
View full tip
Here are some tips on how to submit a ticket to the ThingWorx technical support team and what to expect. Providing a typical minimum information is always a good practice to lessen the questions and unnecessary back-and-forth communication prior to the actual investigation of the problem. Open a new ticket for each separate issue. We do track every technical issue that comes in. If the ticket is being submitted for troubleshooting: Please provide the versions of Thingworx, Tomcat, java; Operating System and specs. Attach the list of the extensions used. Include a detailed description of the problem; if applicable, include the screenshots. Evaluate the business impact caused by the issue. Optional: state the method of contact preference, whether it's a phone or email, and time if applicable. Expect a support engineer (SE) to establish the first contact via email, letting known of the case ownership, and further investigation. If the ticket is being submitted for enhancement request or improvement: Please provide a clear description of the feature, use case(s), expectations and any additional details that might play a role in prioritizing the request. Once the ticket has been created, it will be assigned to a support engineer (SE) who will then place a request (Jira) to R&D and provide a Jira # to the point of contact in the support ticket Enhancement requests and improvements are always considered; however, the delivery is not guaranteed. Once an SE provides the case contact with the Jira #, the support ticket will be closed, and the point of contact may reach out to the SE at any time to check on the status of the Jira. If the ticket is being submitted for a bug or a defect: Please provide the versions of Thingworx, Tomcat, java; Operating System and specs. Include a clear description of the problem, expected result, current result; a Evaluate the business impact. If reproducible, include the steps. Optional: include the entities and data (.xml, .json if applicable) to demonstrate the issue Once the ticket has been created, it will be assigned to a support engineer (SE) who will then place a request (Jira) to R&D and provide a Jira # to the point of contact in the support ticket (assuming no further information is required) The R&D will provide an estimate release after the issue is evaluated. Upon sending the ETA to the case contact, the SE will close the support ticket.
View full tip
Hello!   We will host a live Expert Session: "Top 5 items to check for Thingworx Performance Troubleshooting" on Sept 3rdh at 09:00 AM EST.   Please find below the description of the expert session as well as the link to register .   Expert Session: Top 5 items to check for Thingworx Performance Troubleshooting Date and Time: Thursday, Sept 3rd, 2020 09:00 am EST Duration: 1 hour Description: How to troubleshoot performance issues in a Thingworx Environment? Here we will cover the top 5 investigation steps that will help you understand the source of your environment issues and allow better communication with PTC Technical Support Registration: here   Existing Recorded sessions can be found on support portal using the keyword ‘Expert Sessions’   You can also suggest topics for upcoming sessions using this small form.
View full tip