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:
This post is part of the series Forced Root Cause Monitoring via Mashups and Modal Popups To not feel lost or out of context, it's recommended to read the main post first. Create Entities AlertStateDefinition Create a new StateDefinition called "rcp_AlertStateDefinition" In the State Information tab, select Apply State: Numeric from the list on the right hand side Create a new State: Less than or equal to "1" Display Name: "Something good" Style: a new custom style with text color #f5b83d (orange) Create a new State: Less than or equal to "2" Display Name: "Something bad" Style: a new custom style with text color #f55c3d (red) Create a new State: Less than or equal to "3" Display Name: "Something ugly" Style: a new custom style with text color #ad1f1f (red) with a Font Bold Edit the "Default" State Set the Style: a new custom style with text color #36ad1f (green) We will not use this style, but in case we need a default configuration it will blend into the color schema Save the StateDefinition ValueStream Create a new ValueStream called "rcp_ValueStream" (choose a default ValueStream, not a RemoteValueStream) Save the ValueStream AlertThing Create a new Thing called "rcp_AlertThing" Based on a Generic Thing Base Thing Template Using the rcp_ValueStream Value Stream In the Properties and Alerts tab create the following Properties Name: "trigger" Base Type: BOOLEAN With a Default Value of "false" Check the "Persistent" checkbox Name: "selectedReason" BaseType: NUMBER Check the "Persistent" checkbox Check the "Logged" checkbox Advanced Settings: Data Change Type: ALWAYS In the Services tab create a new Service Name: "clearTrigger" No Inputs and no Outputs Service code me.trigger = false; When this service is executed, it will set the trigger Property to false Click Done to complete the Service creation Save the Thing
View full tip
This blog addresses a few points that are related to scoring with ThingWorx Analytics. It, particularly, brings a clearer understanding of the concepts behind the values of the scores that are generated when performing a scoring job.   Scoring Outputs:   It is important to note that when training an analytics model, the method is to create a generalizable model from a relatively small training dataset.   By its nature, we expect the training process to see a limited subset and not an exhaustive list of all possible values for many constraints, especially for time and practicality.   As such, these generalized models will be expected to handle unseen data in the form of new combinations or values outside of previously observed ranges (more on this below).   One common way to see scores that exceed the observed ranges in training, under the assumption that the goals are continuous, is to use prescriptive scoring.   Prescriptive scoring attempts to find optimal values for a lever, meaning tunable, features in order to maximize or minimize score values. See the prescriptive scoring documentation and functionality for more information.   min/max constraints: these are constraints that are placed upon the inputs for training and expected inputs for scoring.   •          For training: If theses ranges were provided as part of the upload process, then training will raise exceptions regarding invalid data. However, if the ranges are not provided - they will be inferred from the data and, as such, training will not see values outside of observed ranges.   •          For scoring: Validation of the ranges will only be performed on the inputs - not the outputs. It is very important to note that the handling of these "constraints" is dependent upon the data type.   For categorical (e.g. colors) and ordinal data (e.g. shirt sizes), the constraints are strict and data that was not observed in training will raise exceptions during scoring.   However, for continuous values (e.g. temperature ranges) these constraints are more informational in nature. For predictive scoring, our code will accept records with values outside of those ranges.   The rule of thumb is that values slightly outside these ranges are acceptable and that as the values stray farther from the ranges, the accuracy of the model degrades very quickly.   For prescriptive scoring, these constraints are used to determine the acceptable ranges of values to try when determining the optimal values. Values outside of these constraints will NOT be tried.
View full tip
In this video we are walking through the installation steps of ThingWorx Analytics Server 8.1. This cover the Native Linux installation though the steps will be similar for a docker installation on Windows or Linux.   Updated Link for access to this video:  Installing ThingWorx Analytics Server 8.1 - Native Linux
View full tip
Hello ThingWorx community!   I’d like to invite you to join me and our ThingWorx experts for an exclusive webinar on October 30 at 11:00 AM (EDT) to explore the transformative potential of Agentic AI within the ThingWorx Industrial IoT and AI platform. In this session, you’ll gain insights into ThingWorx’s AI strategy, focused on delivering actionable intelligence and accelerating digital transformation across the product lifecycle. You’ll also see in action: Hands-on demos integrating Large Language Models (LLMs) with ThingWorx 10.X How to enable agentic automation using Model Context Protocol (MCP) Ways to enhance industrial apps with real-time decisions, natural language, and computer vision AI So, register here:   [Webinar]: ThingWorx Innovation With Industrial IoT and AI    Also, here is a personal video invitation message to you all!      Post webinar, please provide your feedback and comments below!    We look forward to having you join us!     Cheers, Ayush Tiwari Director Product Management  
View full tip
One of the killer features of the Axeda Platform is the Axeda Console, a browser-based online portal where developers and business users alike can browse information in an out-of-the-box graphical user interface.  The Axeda Console is functional, re-brandable and extensible, and can easily form the foundation for a customized connected product experience. Let's take a tour of the Axeda Console and explore what it means to have a full-featured connected app right at the start of your development. What this tutorial covers This tutorial discusses the landscape of the online browser-based suite of tools accessible to Axeda customers.  It does not do a deep dive into each of the available applications, but rather serves as an introduction to the user interface. Sections of the Axeda Applications Console that are discussed: Landing Page (Home) User Preferences Asset Dashboard Axeda Help Note: This article features screenshots from Axeda 6.5 which is the current release as of July 1, 2013.  In prior versions the Axeda Applications Console has also been referred to as ServiceLink.  Stay tuned for Axeda 6.6! What can I do from here? From the landing page for the Axeda Console, you can access recent assets in your right sidebar or search for assets in the left sidebar.  Each of the links in the main Welcome text corresponds to a main tab. Troubleshoot, Monitor, and Service Assets - (Service tab) An Overview of the status of assets, filterable by a search on fields such as serial number, model, organization, etc. Access and Control Remote Assets - (Access tab) If you are familiar with Windows Remote Desktop, this will seem familiar.  This allows you to log into and control an asset as if you were typing from a physical keyboard directly into it without having to be on the same network or in the same location.  This is particularly useful when the asset is behind a firewall or other controlled network. Install and Deploy Software Updates - (Software tab) This tool provides the ability to create, view, configure, delete and deploy software packages (like a file that contains an update) to assets. View Usage Data and Asset Charts - (Usage tab) You can use the Axeda Usage application to track and analyze asset usage. Add New Assets, Organizations and Models - (Configuration tab) Find tools here for creating, updating and deleting domain objects. Administrator Users, Groups and Assets - (Administration tab) Manage users, groups, auditing, and system-setup tasks The remaining tabs that are not linked from the Home page are either custom tabs or less frequently used tabs (depending on use case). The custom tabs are examples of custom applications that are not distributed out of the box with an Axeda instance. Wireless - (custom tab) an integration with the Jasper API that allows the user to monitor SIMs activated in their assets Maintenance - track information about the operation of machines against service cycles Case - manage the resolutions of asset issues Report - (requires an additional license) provides a suite of standard reports, custom reports may also be added Dashboard - allows you to create a landing page that displays information that is interesting to you Simulator - (custom tab) an app that allows you to set data items, alarms, mobile locations, and geofences on an asset For more details on Custom Tabs and the Extended UI, please take a look at [Extending the UI - Custom Tabs and Modules]. (Coming soon) User Preferences Each user in an Axeda instance has a certain set of privileges and visibility, which determine what actions she can take and what information she can see.  A user also has control over certain aspects of her own use of the Axeda Console, which are configurable from the yellow Preferences link, located in the top right corner of the page. This opens up the User Preferences page. The User Preferences link allows you to set defaults for your user only.  From here you can change the following settings: User Attributes (email and password) Locale - Change the locale which also sets the display language Time Zone - Change the time zone as displayed in the Applications Console (note that this does NOT affect individual asset time zone.  Asset time zone is reported by the agent) Notification Styles - Specify which contact methods are appropriate for you and for what severity of triggered alert Default Application - Set which tab should open up when you log into the Axeda Console Items Per Page (Long Table) - For longer listings of items, how many rows should be displayed Items Per Page (Short Table) - For shorter listings of items, how many rows should be displayed Asset Dashboard As the asset is the center of the Axeda universe, so the Asset Dashboard could be considered the central feature of the Axeda Console.  You can open up the dashboard for any particular asset by clicking it in the Service tab or in the Recent Assets shortcuts. You can also add modules within the Asset Dashboard that are either a custom application or the output of an Extended UI Module type custom object.  From the Asset Dashboard you have an at-a-glance view of this asset's current data, alarms, uploaded files, and location to name a few. The Asset Dashboard is built for viewing information about the asset.  To perform create/read/update/delete functions on the asset, you will need to search using the Configuration tool instead. To view a list of models or any domain object available for configuration, click the drop down arrow next to the View sub-tab and select the object name. Once you have the list of models displayed, click the Preferences link on the model to access a Model Preferences Dashboard that allows you to configure the model image, the modules displayed, and other features of the Asset Dashboard. Axeda Help As part of learning more about the Axeda Console, make use of the documentation available to you by clicking the Help link in the top right corner of the page. This will open a pop-up which contains information about the page you have open.  It allows you to do a deep dive into any aspect of the Axeda Console, and includes search and a browsable index on Axeda topics. Make sure to research topics in the Help section while troubleshooting your assets and applications.
View full tip
    Step 7: Widget Lifecycle at Runtime   When a Widget is first created, the runtime will obtain any declared Properties by calling the runtimeProperties() function.   The property values that were saved in the Mashup definition will be loaded into your object without your code being called in any way. After the Widget is loaded but before it’s displayed on the screen, the runtime will call renderHtml() for you to return the HTML for your object. The runtime will render that HTML into the appropriate place in the DOM. Immediately after that HTML is added to the DOM, you will be called with afterRender(). This is the time to do the various jQuery bindings (if you need any). It is only at this point that you can reference the actual DOM elements, and you should only do this using code such as:   // note that this is a jQuery object var widgetElement = this.domElement;   This is important because the runtime actually changes your DOM element ID (domElementId) and you should never rely on any ID other than the ID returned from this.   If you have defined an event that can be bound, whenever that event occurs, you should call the following:   var widgetElement = this.domElement; // change ‘Clicked’ to be whatever your event name is that // you defined in your runtimeProperties that people bind to widgetElement.triggerHandler('Clicked'); 4. If you have any properties bound as data targets, you will be called with updateProperty(). You are expected to update the DOM directly if the changed property affects the DOM - this is likely, otherwise why would the data be bound. 5. If you have properties that are defined as data sources and they are bound, you can be called with getProperty_{propertyName}() …. If you don’t define this function, the runtime will simply get the value from the property bag.     Step 8: Runtime APIs available to Widgets   The following APIs can be accessed by a Widget in the context of the runtime:   this.jqElementId - This is the DOM element ID of your object after renderHtml(). this.jqElement - This is the jquery element. this.getProperty(name) - Accessor. this.setProperty(name,value) - Modifier. this.updateSelection(propertyName, selectedRowIndices) - Call this anytime your Widget changes selected rows on data that is bound to a certain propertyName. For example, in a callback for an event like onSelectStateChanged(), you would call this API and the system will update any other Widgets relying on selected rows.   Step 9: Runtime Callbacks   The following functions on the widget are called by the runtime.   runtimeProperties() - [optional] Returns a JSON structure defining the properties of this widget. Optional properties are:   isContainer - true or false (default to false); Controls whether an instance of this widget can be a container for other widget instances. needsDataLoadingAndError - true or false (defaults to false) - Set to true if you want your widget to display the standard 25% opacity when no data has been received and to turn red when there is an error retrieving data. borderWidth - If your widget provides a border, set this to the width of the border. This helps ensure pixel-perfect WYSIWG between builder and runtime. supportsAutoResize- If your widget supports auto-resize, set this to true. propertyAttributes – If you have STRING properties that are localizable, list them here. For example, if TooltipLabel1 is localizable:   this.runtimeProperties = function () { return { 'needsDataLoadingAndError': true, 'propertyAttributes': { 'TooltipLabel1': {'isLocalizable': true} } } };   renderHtml() [required] - Returns HTML fragment that runtime will place on the screen; the widget’s content container (e.g. div) must have a ‘widget- content’ class specified. After this container element is appended to the DOM, it becomes accessible via jqElement and its DOM element ID will be available in jqElementId. afterRender() [optional] - Called after the widget HTML fragment is inserted into the DOM. Use this domElementId to find the DOM element ID. Use this jqElement to use the jQuery reference to this DOM element. beforeDestroy() [optional but highly recommended] - This is called anytime the widget is unloaded. This is where to:   unbind any bindings clear any data set with .data() destroy any third-party libraries or plugins, call their destructors, etc. free any memory you allocated or are holding onto in closures by setting the variables to null There is no need to destroy the DOM elements inside the widget, they will be destroyed for you by the runtime. resize(width,height) [optional – Only useful if you declare supportsAutoResize: true] - This is called anytime the widget is resized. Some widgets don’t need to handle this, for example, if the widget’s elements and CSS auto-scale. But others (most widgets) need to actually do something to accommodate the widget changing size. handleSelectionUpdate(propertyName, selectedRows, selectedRowIndices) - Called whenever selectedRows has been modified by the data source you’re bound to on that PropertyName. selectedRows is an array of the actual data and selectedRowIndices is an array of the indices of the selected rows. Note: To get the full selectedRows event functionality without having to bind a list or grid widget, this function must be defined.   serviceInvoked(serviceName)- serviceInvoked() - Called whenever a service you defined is triggered. updateProperty(updatePropertyInfo) - updatePropertyInfo An object with the following JSON structure:   { DataShape: metadata for the rows returned ActualDataRows: actual Data Rows SourceProperty: SourceProperty TargetProperty: TargetProperty RawSinglePropertyValue: value of SourceProperty in the first row of ActualDataRows SinglePropertyValue: value of SourceProperty in the first row of ActualDataRows converted to the defined baseType of the target property [not implemented yet], SelectedRowIndices: an array of selected row indices IsBoundToSelectedRows: a Boolean letting you know if this is bound to SelectedRows }   For each data binding, the widget’s updateProperty() will be called every time the source data is changed. You need to check updatePropertyInfo. TargetProperty to determine what aspect of the widget needs to be updated. An example from thingworx.widget.image.js:   this.updateProperty = function (updatePropertyInfo) { // get the img inside our widget in the DOM var widgetElement = this.jqElement.find('img'); // if we're bound to a field in selected rows // and there are no selected rows, we'd overwrite the // default value if we didn't check here if (updatePropertyInfo.RawSinglePropertyValue !== undefined) { // see which TargetProperty is updated if (updatePropertyInfo.TargetProperty === 'sourceurl') { // SourceUrl updated - update the <img src=this.setProperty('sourceurl', updatePropertyInfo.SinglePropertyValue); widgetElement.attr("src", updatePropertyInfo.SinglePropertyValue); } else if (updatePropertyInfo.TargetProperty === 'alternatetext') { // AlternateText updated - update the <img alt= this.setProperty('alternatetext', updatePropertyInfo.SinglePropertyValue); widgetElement.attr("alt", updatePropertyInfo.SinglePropertyValue); } } };   NOTE: In the code above, we set a local copy of the property in our widget object, so if that property is bound as a data source for a parameter to a service call (or any other binding) - the runtime system can simply get the property from the property bag. Alternately, we could supply a custom getProperty_ {propertyName} method and store the value some other way.   getProperty_{propertyName}() - Anytime that the runtime needs a property value, it checks to see if the widget implements a function that overrides and gets the value of that property. This is used when the runtime is pulling data from the widget to populate parameters for a service call.     Click here to view Part 4 of this guide.
View full tip
  Hi everyone,   If you’ve been curious about Solution Central, our new cloud tool for application management and deployment, and wondered how it can help your existing apps, then get ready because we have a feature for you! Our initial release of Solution Central focused on deploying apps built on 8.5 or later. Today, whether big or small, round or square, red or blue, built by PTC or by you, all apps can be deployed using Solution Central. Using Operator Advisor 8.4? We got you covered. Using an old extension? No worries. Using an app built on 7.2? Not a problem. Solution Central can deploy all apps.   This ability to deploy any app, regardless of which version it was created on, is just one of the many improvements we’re releasing to help you accelerate your deployment. You can take advantage of this latest capability in ThingWorx 8.5.3 and Solution Central 1.0.3. Try it out today!   We’re not stopping there, though.   We have a lot that we’re working on and wanted to share a quick glimpse of what you can expect in the very near future: ability to manage solution lifecycle through deletion of solutions and their versions ability to secure and manage connected environments through improved activation and deactivation services advanced administrative capability to withdraw and re-initiate deployment requests   The above functionality, along with additional enhancements, are targeted for TW8.5.5 and SC1.1.0 in early April.   These improvements will help to maximize the time savings and overall value you derive from Solution Central’s unique deployment services.   As always, stay connected, Kaya
View full tip
This post is part of the series Forced Root Cause Monitoring via Mashups and Modal Popups To not feel lost or out of context, it's recommended to read the main post first. Required Entities In this simplified example we'll just use a Thing to set a status triggering the popup. This Thing will have two properties and one service: Properties trigger (Boolean) - to indicate if an error status is present or not, if so - trigger the popup selectedReason (Number) - to indicate the selected reason / root cause chosen in the modal popup Service clearTrigger - to reset the trigger to "false" once a reason has been selected The selectedReason will be logged into a ValueStream. In addition to the Thing and the ValueStream we will need a StateDefinition to pre-define potential root causes to be displayed in the popup. We will use three states to be used in a traffic-light fashion to indicate the severity of the issue in a custom color schema. To display the monitoring Mashup and the popup we will need two Mashups.
View full tip
Thundering Herd Scenarios in ThingWorx Written by Jim Klink, Edited by Tori Firewind   Introduction The thundering herd topic is quite vast, but it can be broken down into two main categories: the “data flood” and the “reconnect storm”. One category involves what happens to the business login (the “data flood” scenario) and affects both Factory and Connected Products use cases. The other category involves bringing many, many devices back online in a short time (the “reconnect storm” scenario), which largely influences Connected Products scenarios.   Citation: https://gfp.sd.gov/buffalo-roundup/ Think of Connected Products as a thundering stampede of many small buffalo, which then makes a Factory thundering herd scenario a stampede of a couple massive brontosaurus, much fewer in number, but still with lots of persisted data to send back in. This article focuses in on how to manage the “reconnect storm” scenario, by delaying the return of individual buffalo to reduce the intensity of the stampede. Find here the necessary insights on how to configure your ThingWorx edge applications to minimize the effect of a server down scenario.    The C-SDK will be used for examples, but the general principles will apply to any of the ThingWorx edge options (EMS, .Net SDK, Java SDK).  This article also references the ExampleAgent application which is built using the C-SDK. The ExampleAgent is available for download as an attachment to this post.  It offers an easily configurable edge solution for Windows and Linux that can be used for the following purposes: Foundation for rapid development of a robust custom edge application based on the ThingWorx C-SDK for use by customers and partners. Full featured, well documented, ‘C’ source code example of developing an application using the ThingWorx C-SDK. A “local” issue is one which affects a single agent, a loss of connectivity due to hardware malfunction or local network issues. Local issues are quite common in the IoT world, and recovery usually isn’t too much of a challenge. A “global” issue occurs when many agents disconnect simultaneously, usually because there is an issue with the ThingWorx server itself (though the Load Balancer, Connection Server, or web hosting software could also be the source). Perhaps it is a scheduled software update, perhaps it is unexpected downtime due to issues, but either way, it’s important to consider how the fleet of agents will respond if ThingWorx suddenly becomes unavailable.   There are two broad issues to consider in a situation like this. One is maintaining the agent’s data so that it can be sent when the connection becomes available again. This can be done in the C-SDK using an offline file storage system, which includes properties, events, and services. Offline storage is configured in the twConfig.h file in the C SDK.  The second issue the number of Agents seeking to reconnect to the server in a short period of time when the server is available.    Of course, if revenue is based on uptime, perhaps persisting data is less critical and can be lost, making things simple. However, in most cases, this data will need to be stored on the edge device until reconnect. Then, once the server comes back up, suddenly all of this data comes streaming in from all of the many edge devices simultaneously.   This flood of both data and reconnection of a multitude of agents can create what is called a “thundering herd” scenario, in which ThingWorx can become backlogged with data processing requests, data can be lost if the queues are overwhelmed, or worst-case, the Foundation server can become unresponsive once again. This is when outages become costly and drag on longer than necessary. Several factors can lead to a thundering herd scenario, including the number of agents in the fleet, the amount of stored data per agent, the amount of data ordinarily sent by these devices, which is sent side-by-side with the stored data upon reconnection, and how much processing occurs once all of this data is received on the Foundation server.   The easiest way to mitigate a potential thundering herd scenario, and this is considered a ThingWorx best practice as well, is to randomize the reconnection of devices. Each agent can be configured to delay itself by a random amount of time before attempting to reconnect after a loss of connectivity. This random delay then distributes the number of assets connecting at a time over a longer period, thus minimizing the impact of the reconnections on ThingWorx. There are several configuration settings that help in this regard.   Configuring the Herd (C-SDK) The C-SDK is great at managing agent connectivity, having a lot of options for fine-tuning the connections. The web-socket connection is managed by the SDK layer of the edge device (which also manages the retry process). To review the source code for how connections are made, see the C-SDK file found here: src\api\twApi.c, specifically the function called twApi_Connect().   The ExampleAgent uses custom configuration files to manage this process from the application layer, a more robust and complete solution. Detailed here are the configuration options in the ExampleAgent attached to this post, most of which can be found in its ws_connection.json configuration file: connect_timeout is used throughout the C-SDK as the time to wait for a web-socket connection to be established (i.e. the ‘timeout’ value). This is the maximum delay for the socket to be established or to send and receive data. If it is established sooner, then a success code is returned. If a connection is not established in the configured timeout period, then an error is returned. Setting this value to 10 seconds is reasonable, for reference. connect_retries is the number of times the SDK will attempt to establish a connection before the twApi_Connect() function returns an error. Setting this to -1 will trigger the SDK to stay in the loop infinitely until a connection is established. connect_retry_interval is the delay between connection retries. max_connect_delay is used as a delay before even entering the loop, that which uses the connect_retries and connect_retry_interval parameters to establish the connection. The SDK function twAddConnectionDelay() is called, which delays by a random amount of time between 0 seconds and the value given by this parameter. This random delay is only used once per call to twApi_Connect().  This is therefore the parameter most critical to preventing thundering herd scenarios (as discussed above). Configuring the SDK agents to reconnect in this way is critical, but there are also some drawbacks, namely that while the twApi_Connect() function is running, there is no clean way of shutting the agent down. Likewise, the agent only does ONE randomized delay per call of the twApi_Connect() function, meaning that if reconnection cannot occur immediately, it’s still possible for many agents to try to reconnect at once. Consider this when determining what values to assign to these parameters.   ExampleAgent Design The ExampleAgent provided here is a fully implemented, configurable application, like the EMS in terms of functionality, but containing only simulated data. The data capture component is missing here and has to be custom developed. Attached alongside this source code is extensive documentation that explains how to get the application set up and configured. This isn’t meant to be used directly in a production environment.   Please note that the ExampleAgent is provided as-is; it is not an officially released product by PTC.   This disclaimer includes the ExampleAgent source code, build process, documentation, deliverables as well as any ExampleAgent modifications to the official releases of the C-SDK or the SCM extension product. Full and sole responsibility for the use, deployment, reliability, and accuracy of any ExampleAgent related code, documentation, etc. falls to the user, and any use of the ExampleAgent is an implicit agreement with this disclaimer.   The ExampleAgent was developed by PTC sales and services to help in the Edge application development process.  For assistance, support, or additional development, an authorized statement of work is needed.  Please Note:  PTC support is not aware of the existence of the ExampleAgent and cannot provide assistance.    Because of the small downside to configuring the twApi_Connect() function directly as discussed above, there is alternative approach given here as well. The ExampleAgent module ConnectionMgr.c controls the calling of the twApi_Connect() on a dedicated connection thread. The ConnectionMgrThreadFunction() contains the source code necessary to understanding this process.   The ConnectionMgr.c workflow and source code visualization via Microsoft Visual Studio are in the diagrams below. The ExampleAgent defines its own randomized delay to mitigate the thundering herd scenario while still deploying an edge system that responds to shut down requests cleanly. In this case, the randomized delay is configured by the parameter reconnect_random_delay_seconds in the agent_config.json file. Since the ConnectionMgrThreadFunction() controls the calling of twApi_Connect(), the ConnectionMgrThreadFunction() will delay the randomized value EVERY time before calling this reconnect function. A separate thread is created to call the reconnect function so that there are still resources available for data processing and to check for shutdown signals and other conditions.   Recommended Values These recommendations are based around managing the reconnection process from the application layer. These may be different if the C-SDK is configured directly, but creating application layer management is recommended and provided in the ExampleAgent attached. The ExampleAgent is configured by default to simplify the SDK layer’s involvement.   These configuration options tell the SDK layer to try to connect just once, after just 1 second: There is no official recommendation for the above values due to the fact that every use case is different and will require different fine tuning to work well.   Then this setting here handles the retry process from within the application layer of the ExampleAgent: Conclusion To reduce the chances of a thundering herd scenario, configure the fleet to reconnect after differing random delays. The larger the random delay times, the longer it takes for the fleet to come back online and fleet data to be received. While more complex ThingWorx deployment architectures (such as container-based deployments like Kubernetes or Thingworx High Availability (HA) clusters) can also help to address the increased peak load during a thundering herd event, randomized reconnect delays can still be an effective tool.        
View full tip
    Step 4: Create and Implement State Definitions   A state definition is a collection of style definitions, along with rules for when to apply each style definition. The rule plus the style definition is a state.   In the HelloWorldPlayground Mashup, if the Gauge Widget goes to 10 and the Increment the Count button is clicked once again, the Gauge starts back at 0. This value change is displayed in the Line Chart when it is refreshed. Nevertheless, it would be helpful to have a way to show a user that they’re encroaching 10 and will have to restart, such as the Gauge changing colors in the section. This and many other uses is where State Definitions become useful and go hand and hand with Style Definitions.     Create Style Definition to Represent State Change   First, let’s create Style Definitions to represent the changes in the count. The default Style Definition for a Gauge is the DefaultGaugeFaceStyle Style Definition. We can simply duplicate and update the new Style Definition for our own purposes.   Filter and click the checkbox next to the DefaultGaugeFaceStyle Style Definition. Click Duplicate.   Name the Style Definition UpdatedGaugeFaceStyle. Click Style Information.   Set the Display String property as AlarmingCount. Change the Background Color to light red (color code #D60000 is used in this example).   Change the Secondary Background Color to a darker red (color code #960A0A is used in this example). The inside line of the Gauge Widget is very thin. As an additional exercise, update the Line Thickness property and/or Line Color to see the effect.     Configure State Definition   Now let’s create a State Definition that will use both the default Gauge Style Definition and the one we just created.   In the ThingWorx Composer, click the + New at the top of the screen.   Select State Definitions in the dropdown.   Set the Project (ie, PTCDefaultProject). Name the State Definition GaugeCount. Click States Information.   Set the Apply States dropdown to Numeric.   Set the following values for the default state: Property Value Operator Less than (<) Value 10 Display Name Under 10 Style DefaultGaugeFaceStyle 8. Click the Add State button to create the other states to match the below image:   9. Click Save.   You’ve now created a State Definition. If the value is below 10, the default Gauge format will be applied. Once the value reaches 10, notice the state-based changes you defined are displayed in the appearance of the Gauge.     Implement State Definition in Mashup   Update HelloWorldPlayground Mashup to incorporate the State-based formatting.   Select the Gauge Widget in the Workspace pane and click the ValueFormatter property.   Select the State-based Formatting radio button. Choose Count_Property for the Dependent Field drop-down and select the GaugeCount State Definition that we just created.   Click Done and Save the Mashup. Click View Mashup. If you used the color schemes mentioned, your new HelloWorldPlayground Mashup should look like this.   Click the Increment the Count button to see the state changes. The Gauge now displays a visual indication for when the count is approaching 10.     Enhance State Definition   To further enhance the user experience, you could add another color that warns the user in advance before the threshold is reached. For this example, we will update our State Definition and create a Style Definition that uses the color yellow.   Duplicate the UpdatedGaugeFaceStyle Style Definition.   Name the Style Definition UpdatedGaugeFaceStyle2. Click Style Information.   Set the Display String property to AlarmingYellowCount. Set the Background Color property to yellow (color code #F9EF6B is used in this example).    Set the Secondary Background Color property to a darker yellow (color code #D2CD0E is used in this example). Open the States Information tab of the GaugeCount State Definition. Update the State Definition to fit the image below and utilize the Style Definition we just created: Click Save and View Mashup to see the updated runtime appearance of the application.       Step 5: Implementing Event-Based State Changes   The State and Style Definition you just implemented enables the Gauge to show users when the data property value is approaching the defined threshold. To increase the effectiveness of your application, you can define Event Handling processes that alert the user. In this section we will explain two ways to handle the Event when the count is nearing the threshold value. One, with a Service that gets called whenever the Button Widget is clicked, and the other by using Expression Widgets.   Using a Service to Handle Events In this part of the exercise, we will configure the Mashup so that once the Count hits 9, we will display a more drastically changed Gauge.   Adding Data Service   The below sections are based on the HelloWorldPlayground Mashup.   Select the Gauge Widget in the Workspace pane. Click the Copy button in the toolbar.   Select the Container in the Workspace pane. Click the Paste button in the toolbar. If you Gauge Widgets will not go on top of one another, set the Z-index value of the new Gauge to a smaller number and set the Container Layout Position to static.   Click the green Add Service button in the Data tab next to Things_Hello_World_Thing1 to add two services from you Things_Hello_World_Thing1 Entity. NOTE: You just copied and pasted a Widget inside of a Mashup. While the Mashup retains the same property configurations and style definitions, the pasted Gauge will not have the same connections as the original Widget. You still need to define the inputs/outputs. For this new Gauge, we will only need to connect to the GetPropertyValues service. 6. Add the UnderWarningValue and WarningValueReached Services with the Execute on Load checked for both. 7. Click Done.   Binding Data and Event   With the original Gauge selected, scroll to the Visible property value. Drag and drop the UnderWarningValue service result to the Visible property.   With the new Gauge selected, scroll to the Visible property value. Drag and drop the WarningValueReached service result to the Visible property.   Select the Button Widget in the Workspace pane. Drag and drop the Clicked Event to the UnderWarningValue and WarningValueReached services.   This will ensure the other Services are run whenever the Increment the Count button is clicked.   The UnderWarningValue service will return true if the Count property is under 9. The WarningValueReached service will return true if the Count property is equal to or above 9. The result sent to the original Gauge controls whether the Gauge is visible to users or not.   You could choose to implement a pop-up, alert, or another visual indicator to the UI that would inform your application users. 7. Select the new Gauge in the Mashup or Explorer pane. 8. Clear the GaugeFaceStyle Style Definition and replace it with the DefaultChartStyle11.   9. Click Save and View Mashup to see the changes. Using Expression Widgets to Handle Events   Expression Widgets are a great asset to handle information being passed around inside of a Mashup and also events occurring within a Mashup. In this scenario, we will use the Count property value to create changes in the UI.   Setup Expression Widget   In the Functions Tab in the bottom right. Add a new function.   Set the Function Type to Expression and name it HighCount.   Click Next Click Add Parameter and add a Count (Number) parameter. Set the Expression property to output = Count >= 9;.   Check the Auto Evaluate and Fire on First Value checkboxes. Click Done.     Bind and Evaluate Event   In the Functions Tab in the bottom right, click the bind button of our new Function.   Click the dropdown by the Count input parameter. Click Add Source.   Select Data, then the Count_Property from the GetPropertyValues service.   Redo the past steps for a second Function. Name this function GaugeVisibility with a parameter of type Boolean with the name Visibility. Update the second Expression Widget’s Expression property to output = Visibility != true;. Ensure the checkboxes are checked and bind to the output of our last Function.   Connect the output of this Function to the second Gauge. Click Save and View Mashup.   NOTE: Move the Gauges from on top of one another if necessary to set values and parameters. The first Expression will show the newest Gauge Widget when Count hits 9. The other Expression Widget will show the original Gauge based on the evaluation of the first Expression Widget results.   Click the Increment the Count button to see how the display changes in the Mashup at runtime.   Step 6: Next Steps   The next guide in the Customize UI and Display Options to Deploy Applications learning path is Object-Oriented UI Design Tips.    Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Style & Themes Help Center  
View full tip
With the release of ThingWorx 8.2.1 , we now have the possibility to auto provision the user attributes along with the user on its first login in ThingWorx via Active Directory Authentication. In the previous releases this was not available and after the initial user provisioning, users had to fill in rest of the user attribute details e.g. zipCode, City, Title, MobilePhone , etc. However with ThingWorx 8.2.1 and later we have following new attributes for configuration when the Active Directory entity is created in ThingWorx, namely   activeDirectoryAttributeName userExtensionPropertyName userExtensionDefaultValue activeDirectoryAttributeName : Represents the attribute within AD for an user   userExtensionPropertyName : This represents the attribute available for the user, as defined in the UserExtensions ThingShape   userExtensionDefaultValue : Default value that will be assigned in case the attribute value in AD for a particular user is empty/null   XML representation for these new tags     <ConfigurationTable description="User Extension Property Mapping Configuration Table" isMultiRow="true" name="UserExtensionPropertyMapping" ordinal="6"> <DataShape> <FieldDefinitions> <FieldDefinition aspect.friendlyName="Active Directory Attribute Name" baseType="STRING" description="Active Directory Attribute Name" name="activeDirectoryAttributeName" ordinal="0"/> <FieldDefinition aspect.friendlyName="Provisioned User's User Extension Property Default Value" baseType="STRING" description="Provisioned User's User Extension Property Default Value" name="userExtensionDefaultValue" ordinal="2"/> <FieldDefinition aspect.friendlyName="Provisioned User's User Extension Property Name" aspect.isPrimaryKey="true" baseType="STRING" description="Provisioned User's User Extension Property Name" name="userExtensionPropertyName" ordinal="1"/> </FieldDefinitions> </DataShape> <Rows> <Row> <activeDirectoryAttributeName> <![CDATA[userPrincipalName]]> </activeDirectoryAttributeName> <userExtensionDefaultValue> <![CDATA[blah]]> </userExtensionDefaultValue> <userExtensionPropertyName> <![CDATA[emailAddress]]> </userExtensionPropertyName> </Row> <Row> <activeDirectoryAttributeName> <![CDATA[streetAddress]]> </activeDirectoryAttributeName> <userExtensionDefaultValue> <![CDATA[SomeDefaultValue]]> </userExtensionDefaultValue> <userExtensionPropertyName> <![CDATA[mailingAddress]]> </userExtensionPropertyName> </Row> <Row> <activeDirectoryAttributeName/> <userExtensionDefaultValue> <![CDATA[DefaultValue]]> </userExtensionDefaultValue> <userExtensionPropertyName> <![CDATA[title]]> </userExtensionPropertyName> </Row> <Row> <activeDirectoryAttributeName> <![CDATA[DefaultDemoTitle]> </activeDirectoryAttributeName> <userExtensionDefaultValue/> <userExtensionPropertyName/> </Row> <Row> <activeDirectoryAttributeName/> <![CDATA[pincode]> <userExtensionDefaultValue/> <userExtensionPropertyName> <![CDATA[zipCode]]> </userExtensionPropertyName> </Row> </Rows> </ConfigurationTable   Note: This is not a complete XML file for creating the Active Directory entity in ThingWorx, rather only a part of the XML for basic initial XML configuration refer to the Managing Users in Active Directory section in Security > Directory Service Authentication in ThingWorx Help Center   With the above configuration once the Active Directory entity is successfully created under the ThingWorx Composer > Security > Directory Services, navigate to it and scroll down to the section named User Extension Property Mapping Configuration Table   Configuration for Directory Service Extending on basic structure Once the Active Directory entity is successfully created and connected to the target Active Directory, all the users that now gets provisioned from Active Directory within ThingWorx will get their attributes filled up automatically, given that the mapping is correct and the value actually exists in Active Directory for those mapped attributes, something like this     PS: Attributes not mapped will be left blank in the user's user extension properties   Auto populating of entities will also happen even after the user has been created on first login. Meaning if there are further AD attributes which are mapped with the user's user extension properties, value for them will also be pulled on next login done by the user there is no need for ThingWorx restart here.   As shown in the screenshot above for section User Extension Property Mapping Configuration Table, these values can be added or deleted.   Pitfalls to avoid It may happen that despite the mapping values may not auto populate, for such scenarios ensure that:   AD attribute used in the section Active Directory Attribute Name must match exactly the way it is in the AD, e.g. zipCode mentioned in the section Active Directory Attribute Name may be called as Zip Code in the AD attribute. This may likely lead to error <attribute_name> attribute not found in ApplicationLog.log Empty/invalid values in AD's user attributes will not populate the User's user extension properties Attribute names used in the column Provisioned User's User Extension Property Name also need to exactly match the way they are defined in the UserExtensions ThingShape, failing to do so will likely lead to error  Property name: {} not found in UserExtensions properties in ApplicationLog.log To void using incorrect attribute name copy out the exact property names from UserExtensions ThingShape UserExtensions ThingShape can be located in ThingWorx Composer > Modeling > Thing Shapes ; click on the UserExtensions > Properties to view all available properties UserExtensions ThingShape can also be edited to add more properties to it, which can later be used for mapping it with the AD attributes   Additional read: An enhancement jira has been filed to allow users to have a drop down menu for column Provisioned User's User Extension Property Name, for quick and accurate selection, see Some User Extension Property Mapping fails with warning "Property name: not found in UserExtensions properties" in ThingWorx
View full tip
The ThingWorx Manufacturing Apps 8.0.1 are tested and supported for use with ThingWorx 8.0.1. The ThingWorx Manufacturing Apps 8.1.0 are tested and supported for use with ThingWorx 8.1.0.
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
    Use Analytics Manager to automatically perform engine analytical calculations.   Guide Concept   This guide will use ThingWorx Analytics Manager to compare external-data from an Edge MicroServer (EMS) "Engine Simulator" to a previously-built analytical model.   Following the steps in this guide, you will learn how to deploy the model which you created in the earlier Builder guide.   We will teach you how to utilize this deployed model to investigate whether or not live data indicates a potential engine failure.   You'll learn how to   Deploy and execute computational models Define and trigger Analysis Events Map incoming data to the Model Map analytic outputs to applications   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 60 minutes       Step 1: Scenario   In this guide, we're continuing the same MotorCo scenario, where an engine can fail catastrophically in a low-grease condition.   In previous guides, you've gathered and exported engine vibration-data from an Edge MicroServer (EMS) and used it to build an engine analytics model.   The goal of this guide is to now operationalize that previously-created model to analyze individual, external readings to see if the "low grease" condition is currently happening.     Analytical model creation can be extremely helpful for the automotive segment in particular. For instance, each car that comes off the factory line could have an EMS constantly sending data from which an analytical model could automatically detect engine trouble.   This could enable your company to offer an engine monitoring subscription service to your customers.   This guide will show you how to put an analytic model of your engine into service to actively monitor performance.       Step 2: Configure Provider   In ThingWorx terminology, an Analysis Provider is a mathematical analysis engine.   Analytics Manager can use a variety of Providers, such as Excel, Mathcad, or even Analytics Server pre-built ones.   In this guide, we use the built-in AnalyticsServerConnector, a Provider that has been specifically created to work seamlessly in Manager and to use Builder Models.   From the ThingWorx Composer Analytics tab, click Analytics Manager > Analysis Providers > New....   In the Provider Name field, type Vibration_Provider. In the Connector field, search for and select TW.AnalysisServices.AnalyticsServer.AnalyticsServerConnector.   Leave the rest of the options at default and click Save.     Step 3: Publish Analysis Model   Once you have configured an Analysis Provider, you can publish Models from Analytics Builder to Analytics Manager. On the ThingWorx Composer Analytics tab, click Analytics Builder > Models.   Select vibration_model_s1_only and click Publish.   On the Publish Model? pop-up, click Yes. A new browser tab will open with the Analytics Manager's Analysis Models menu. Close that new browser tab, and instead click Analysis Models in the ThingWorx Composer Analytics navigation. This is the same interface as the auto-opened tab which you closed.   Click the model to select it. At the top, click Enable. Note the pop-up indicating that the Enable was successful.       Step 4: Modify EdgeThing   In previous guides in this Vehicle Predictive Pre-Failure Detection Learning Path, you have created various Entities, including Things such as EdgeThing.   In order to automate the process of pushing data from EdgeThing to Analytics Manager, we need to add a few more Properties to EdgeThing.   These Properties are simple STRING variables, and we'll also set Default Values for them to configure parameters of Analytics Manager.   The first is causalTechnique, which tells Analytics Manager which criteria to use when measuring the impact of a feature on a range of goal values.   The second is goalField, which is simply the data field for which Analytics Manager should try to identify the correlation. In this case, it'll be our primary issue, i.e. low_grease.   It is not mandatory that these suggested Property names match, but they are the names used within ThingWorx Analytics. You could use any Property name you wanted, as you'll be mapping from a particular Property to the functionality within Analytics in a later step.   Return to EdgeThing > Properties and Alerts.   Click + Add.   In the Name field, type causalTechnique. Check Has Default Value. In the text field under "Has Default Value", type FULL_RANGE. Note that you MUST type FULL_RANGE, including capitalization, as that is a command within Analytics Server.   Click the "Check with a +" icon for Done and Add. In the Name field, type goalField. Check Has Default Value. In the text field under "Has Default Value", type low_grease. Note that you MUST type low_grease, including being all lower-case, as that is the exact name of the Analytics Server goal.   Click the "Check" icon for Done. Click Save.   Results Storage   We also need a place in which to store the results that Analytics Manager returns. We'll utilize a few additional Properties for that as well.   On the EdgeThing > Properties and Alerts tab, click + Add. In the Name field, type Result_low_grease. Check the Base Type to BOOLEAN. Check Persistent.   Click the "Check with a +" icon for Done and Add. In the Name field, type Result_low_grease_mo. Change the Base Type to NUMBER. Check Persistent.   Click the "Check" icon for Done. Click Save.       Step 5: Create Event   Events are automatic analysis jobs which are submitted based on a pre-defined condition. In this step, we'll configure an Analysis Event, which will execute automatically whenever there is a data-change in our simulated engine.   On the ThingWorx Composer Analytics tab, click Analytics Manager > Analysis Events.   Click New.... If not already selected, change Source Type (Required) to Thing.   In Source, search for and select EdgeThing. In Event, select DataChange. In Property, select s1_fb1. If there are multiple s1_fb1 Properties, select the first one, as the second one is the s1_fb1 entry in the Info Table Property. In Provider Name, select Vibration_Provider. In Model Name, select the published Model.   Click Save.       Click here to view Part 2 of this guide.  
View full tip
Complete information about installing and using the Axeda Machine Streams Data Relay Project is available here. This page provides the files for Axeda Machine Streams Data Relay Project: For Linux users ready to run (bin) files: download the machine-streams-data-relay-1.0.3-bin.tar_.gz archive full Maven project files: download the machine-streams-data-relay-1.0.3-project.tar_.gz archive For Windows users ready to run (bin) files: download the machine-streams-data-relay-1.0.3-bin.zip archive full Maven project files: download the machine-streams-data-relay-1.0.3-project.zip archive From the links below, select the project you want to use.
View full tip
  Hello, ThingWorx Users!   As promised, we are back with Episode 02 of ThingWorx on Air. Listen to our PM Milan share the secrets of Operator Advisor and how we built the solution with an eye for IIoT developers.   Learn how Operator Advisor provides you with pre-built snippets of code for widgets, services, etc. targeted specifically for shop floor operators. No more starting from scratch!   Reach out if you have any questions or topic requests!   Stay connected, Kaya   P.S. Keep your ears peeled for the “Wowza Widget of the Week!”
View full tip
    Step 3: Test Connectivity    Before you can begin developing with the ThingWorx Java SDK, you will need to generate an Application Key and add it to the source code provided.   Generate Application Key On the Home screen of Composer click + New the top left.     In the dropdown list, click Application Key.   Give your Application Key a name (i.e., MyAppKey) and set the Project (ie, PTCDefaultProject). Assign the application key to a User.   Click Save. After saving, a Key ID is generated and appears above the Expiration Date. This is the secret key that you will use to make secure connections. If you have not updated the Expiration Date field, the default will be one day. This is an example of the Application Key ID that you will use for a successfull connection.   NOTE: Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a User and place the user as a member of Admins.   Modify Source File   At the top level, locate the SimpleClient Java source file in a package under the src folder. Open the SimpleClient.java source file and update the URI with the IP address of your ThingWorx instance. For example: config.setUri("ws://127.0.0.1:80/Thingworx/WS");   In the SimpleClient.java source file, update the Application Key with the Application Key you stored from the last section. For example: config.setSecurityClaims(new SamplePasswordCallback(cmd.getOptionValue("b3d06be7-c9e1-4a9c-b967-28cd4c49fa80"))); //SET YOUR APPLICATION KEY HERE     Compile and Run Code   Right-click the SimpleClient.java file. Scroll to Run As then select Java Application.   The output in the Eclipse console will confirm connection and authentication to the ThingWorx platform.     Step 4: Run Sample Applications   The Java code provided in the download is pre-configured to run and connect to the Entities in the ThingWorxEntitiesExport.xml file. Keep track of the IP address of the ThingWorx Composer you are using. Many of the utilized libraries are based on the use of Java 1.8. Use other versions at your own risk.   Within your Eclipse ThingWorx Development project, navigate to the com.thingworx.sdk.examples package and open ExampleClient.java.   The URI structure is as follows: ws://host_name:port_number/Thingworx/WS. Update the host_name and port_number to the host and port of your ThingWorx server. Navigate to the following line and update the IP and port if necessary: config.setUri("ws:// 127.0.0.1:80/Thingworx/WS"); TIP: To enable secure https connection, change “ws” to “wss” and port number to 443. (default port for https is 443). Navigate to the following line in ExampleClient.java and update the value of appKey to the keyId in the “admin_key” Application Key in the ThingWorx Composer. If this connect fails, attempt to use the "admin_key" Application Key in the ThingWorx Composer. Using the default admin's key is not recommended. For future development, create users and add them to be a member of the group of Administrators: config.setSecurityClaims(new SamplePasswordCallback(cmd.getOptionValue("b3d06be7-c9e1-4a9c-b967-28cd4c49fa80"))); //SET YOUR APPLICATION KEY HERE Right-click ExampleClient.java, scroll to Run As, and select Java Application. You should be able to see a new Thing in your Composer called SimpleThing_2.   To check the connected Entities, go to the Monitoring screen.   Click Monitoring. Click Remote Things from the list to see the connection status.   You will now be able to see and select the Entity within the list. NOTE: SimpleThing_1 and SimpleThing_2 will also have an update to the lastConnection property. While SimpleThing_1 is unbound, SimpleThing_2 is bound for the duration of the application run time.     Step 5: Example Client Connection   The Java code provided in the ExampleClient.java file initiates a number of actions from establishing a connection to defining Services and Properties.   Configuration   In the first step of connecting to the platform (Establish Physical Websocket), we create a ClientConfigurator instance to hold the location (URI) needed to point to the websocket of the ThingWorx Composer. It is also used to:   Configure the ThingWorx URI of the server Set the Application Key used for authentication Set the connection reconnection interval Ignore ssl errors ClientConfigurator config = new ClientConfigurator(); config.setUri("ws://127.0.0.1:80/Thingworx/WS");   Authentication   In the second step of connecting to the platform (Authenticate), we provide this ClientConfigurator instance an Application Key that belongs to the default_user that was imported to the ThingWorx Composer. The Application Key must match the keyId value for the User you would want to have the specific control and permissions.   **WARNING: It is not best practice to utilize the Administrator’s Application Keys in Edge development. For the reason that Application Keys in java source code are vulnerable to de-compilation and storing them in a configuration file is dangerous, the best practice is to create new Users, and give them any permission deemed necessary.   config.setSecurityClaims(new SamplePasswordCallback(cmd.getOptionValue("b3d06be7-c9e1-4a9c-b967-28cd4c49fa80"))); //SET YOUR APPLICATION KEY HERE   NOTE: If you are not using SSL/TLS, use this code to test against a server using a self-signed certificate: config.ignoreSSLErrors(true);   Create Client Communication   To create a client with the above configuration, create an instance of ExampleClient and pass the configurator created in the step above. ExampleClient is a class that extends ConnectedThingClient. The ConnectedThingClient facilitates communication to the ThingWorx server as well as manages any contained VirtualThing. ExampleClient.java is an example of this and creates the instance on the line: ExampleClient client = new ExampleClient(config); Create and Bind Thing Before starting the client, it is best to bind all VirtualThings that will be bound in order to decrease the necessary request messages. Binding Things before starting the client creates one bind request message to go to the ThingWorx server with all of the Things included. Starting the client then binding Things creates a bind request for each Thing that is being bound. // Create a new VirtualThing. The name parameter should correspond with the // name of a RemoteThing on the Platform. In this example, the SimpleThing_1 is used. VirtualThing thing = new VirtualThing(ThingName, "A basic virtual thing", client); // Bind the VirtualThing to the client. This will tell the Platform that // the RemoteThing 'SimpleThing_1' is now connected and that it is ready to // receive requests. client.bindThing(thing);   Start Connection   You can now start the client, which will establish the AlwaysOn protocol with the ThingWorx Composer. This protocol provides bi-directional communication between the ThingWorx Composer and the running client application.   // Start the client. The client will connect to the server and authenticate // using the ApplicationKey specified above. client.start();       Click here to view Part 3 of this guide.    
View full tip
  Discover how ThingWorx Functions can be implemented in a compelling Mashup design.   Guide Concept   This project will introduce how to create complex user interfaces that are built by using simple Mashup functions.   Following the steps in this guide, you will build a web application with multiple layers. We will teach you how to create a professional user interface that effectively conveys information to users.     You'll learn how to   Navigate to other UIs Create expressions and validations Create event routers and data handling Create confirmation modals/pop-ups Create status messages   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL parts of this guide is 60 minutes     Step 1: What Are Functions   In the Mashup Builder, we utilize Functions to create added capabilities in our Mashups. Whether we are navigating to another Mashup or triggering events based on some action. Functions are your best friends when creating more advanced Mashups.   Function  Description   Auto Refresh  Refreshes data automatically for widgets in a mashup.  Confirmation  Displays a confirmation dialog box.  Events Router  Routes multiple input sources to one output of the same type.  Expression  Evaluates JavaScript expressions.  Logout  Ends the current user session and redirects to a mashup or a Web page.  Navigation  Navigates from one mashup to another.  Status Message  Displays information, error, or warning messages in a mashup.  Validator  Validates data from input parameters by using JavaScript expressions.   In the next sections, we will cover some of these Functions and showcase how to add them to your Mashups.     Step 2: Create an Expression   Let's start things off by creating a simple Expression Function. This Expression will show or hide a label based on whether a checkbox is checked or not. This simple expression can be expanded to your use case.   It is VERY important to note that in an Expression Function (and also found in Services and Validation Functions) the output of the Function will be the result variable. Let's create our Mashup, then go over what is involved in an Expression.   In the ThingWorx Composer, click the + New at the top of the screen.   Select Mashup in the dropdown.   Select the Responsive layout then hit OK.   Set the Name to  MyFunctionsMashup. For the Project, click the + button and select PTCDefaultProject.    Under Project, click the blue Set as project context option. This will stop us from having to set the Project on every Thing we create. It should now match the following.    Click Save. Click on the Design tab at the top.   This Mashup will be where we create the Majority of our Functions and capabilities. Let's start adding to our Mashup.   Click the Layout tab. Scroll down and set the Orientation to Horizontal.   Click on the Widgets tab. Type in the Filter text box for Checkbox.   Drag and drop a Checkbox Widget to the Mashup Canvas. This Checkbox will dictate whether what we show for the coming Labels and Textbox. Type in the Filter text box for Button. This Button will dictate the event that triggers our Functions. Drag and drop a Button Widget to the Mashup Canvas.   Type in the Filter text box for Label. Drag and drop TWO (2) Label Widgets to the Mashup Canvas. We will only show one Label at a time and I'll show you how.   Type in the Filter text box for Text Field. Drag and drop a Text Field Widget to the Mashup Canvas.     We have the Widgets we need to show our Expression example. Let's start with connecting the Widgets to Functions.   Click the + button in the Functions section in the bottom right.    In the New Function popup, select Expression. Set the Name of the new Expression to isCheckboxChecked.   Click Next. In the new screen, click Add Parameter. Set the Name to this new parameter as checked. Set the Base Type as BOOLEAN.   Switch the Data Change Type to ALWAYS. Switch Output Base Type to BOOLEAN.   Add the following code to the Expression area.  if(checked) { result = true; } else { result = false; }   11. Click Done.   You've now created your first expression. This expression is an example of how easy it can be done. Let's add three three additional Expressions to have some fun.   Repeat steps 1-11 in the last section for TWO (2) new Expressions. Name these Expressions setFirstLabelVisbility and setSecondLabelVisbility. You should now have three total. Repeat steps 1-8 in the last section for ONE (1) new Expression. Name this Expression setTextFieldText. We should have a Parameter called checked. Click Add Parameter again to add a Parameter named input. This fourth Expression should match the following thus far:     Switch Output Base Type to STRING. Add the following code to the Expression area:  if(checked) {     if(input && input.indexOf("YES") >= 0) {     result = input + ", YES";     } else {         result = "YES";     } } else {     result = "NO";     }   6. Click Done.   This expression will see whether or not the Checkbox is checked, then output a string of YES or a simple NO. Let's setup our connections between Widgets and Expressions.   Ensure Expressions are visible and match the following.   Click on the Checkbox in the Mashup Canvas. Click the dropdown that appears.   Drag and drop the State Property to the checked Parameter of all FOUR (4) of the Expressions.   Your bindings should match the following after you're done with setting all four.   Expand the setFirstLabelVisibility Expression (if not already expanded).   Drag the Output to the first Label and select Visible   Expand the setSecondLabelVisibility Expression (if not already expanded).   Drag the Output to the second Label and select Visible.   Our labels are configured. Now let's setup our Text Field Widget.    Expand the setTextFieldText Expression (if not already expanded). Drag the Output to the Text Field and select Text.   Select the Button Widget in the Mashup Canvas.  Click the dropdown for the Button Widget. Drag and drop the Clicked Event to all FOUR (4) of the Expressions.   Your Button Widget should look like the following:   Select the Text Field Widget in the Mashup Canvas Click the dropdown for the Text Field Widget. Drag and drop the Text Property to the input Parameter of the setTextFieldText Expression. Click Save. Click View Mashup. Play around and see all the work you've done. You may notice that both Label Widgets show or hide at the same time. To split when they will show or hide, update the code for one of the Label visibility Expressions to the following:    if(checked) {     result = false; } else {     result = true;     }   Click here to view Part 2 of this guide.
View full tip
Video Author:                     Christophe Morfin Original Post Date:            October 2, 2017 Applicable Releases:        ThingWorx Analytics 8.1   Description:​ In this video we will walk thru a few steps to ensure the installation process was successful.    
View full tip
    Learn how ThingWorx can be deployed in a clustered environment   Guide Concept   Web applications have increased reliability and performance by using a "pool" of independent servers called a cluster. It is important to understand what benefits the different methods of clustering provide, and what the different methods can mean for your system.   ThingWorx Foundation can be deployed in either an Active-Active clustered architecture or a standard single-server deployment. This guide describes the benefits of an Active-Active clustered architecture over other clustering methods and provides a system administrator with resources to navigate the different architecture options.     You'll learn how to   Overview of different server clustering techniques Pros and cons of the different clustering configurations that can be used with ThingWorx Where to find detailed information about ThingWorx server clustering   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes       Step 1: Clustering Overview   Clustering is the most common technique used by web applications to achieve high availability. By provisioning redundant software and hardware, clustering software can automatically handle failures and immediately make the application available on the standby system without requiring administrative intervention.   Depending on the business requirements for High Availability, clusters can be configured in any of the following configurations:    Cluster Configuration           Description                                                                                       Recovery Time Cold Standby Software is installed and configured on a back-up server when the primary system fails. Hours Active-Passive A second server is provisioned with a duplicate of all software components and is started in case of failure of the primary server. Minutes Hot Standby Duplicate software is installed and running on both primary and secondary servers. The secondary server does not process any data when the primary server is functional. Seconds Active-Active Both the primary and one or more secondary servers are active and processing data in parallel. Data is continuously replicated across all running servers. Instantaneous   Cold Standby   ThingWorx installed in a default single-server configuration is not inherently a cold standby system. Periodic system backups can be used to bring the system back online in the event of system failure.   Note: A cold standby configuration does not constitute high availability   Active-Passive   High availability can be achieved with an Active-Passive configuration.     One “active” ThingWorx server performs all processing and maintains the live connections to other systems such as databases and connected assets. Meanwhile, in parallel, there is a second “passive” ThingWorx server that is a mirror image and regularly updated with data but does not maintain active connections to any of the other systems.   If the “active” ThingWorx server fails, the “passive” ThingWorx server is made the primary server, but this can take a few minutes to establish connections to the other systems.   Active-Active   ThingWorx uses Active-Active architecture for achieving high availability.   Active-Active configuration differs from Active-Passive in that all the ThingWorx servers in the cluster are “active.” Not only is data mirrored across all ThingWorx servers, but also all servers maintain live connections with the other systems. This way, if any of the ThingWorx servers fail, the other ThingWorx servers take over instantaneously with no recovery time.   Because all ThingWorx servers are active and processing data in parallel, the cluster can handle higher loads than the single running server in an Active-Passive configuration. An Active-Active deployment leverages the investment made in multiple servers by providing not only greater reliabilility, but also giving the ability to handle demand spikes. When server utilizations exceed 50%, customers can easily scale their deployment by adding more ThingWorx servers to the cluster - horizontally scaling. This also avoids the limitations of vertically scaling - provisioning a single server with more and more CPU cores and RAM.   Benefits of Active-Active Clustering   Higher Availability You can avoid single points of failure and configure the ThingWorx Foundation platform in an Active-Active cluster mode to achieve the highest availability for your IIoT systems and applications. Increased Scalability You can horizontally scale from one to many ThingWorx servers to easily manage large amounts of your IIoT data at scale more smoothly than ever before.     Step 2: ThingWorx Active-Active Architecture   An Active-Active Cluster configuration introduce two software components and two components that are optional in a standard ThingWorx architecture are now required.   The reference architecture diagram below shows ThingWorx deployed with multiple ThingWorx Foundation servers configured in an Active-Active Cluster deployment.   Note: This is an example of a possible ThingWorx deployment. The business requirements of an application will determine the specific configuration in an Active-Active clustered environment.   Load balancer was optional in a single-server deployment, is now a requirement. ThingWorx Connection Server is also now required. Apache ZooKeeper is used to coordinate multiple running servers. Apache Ignite is used to share current state between servers.  Component       Description                                                                                          Provider Load Balancer Distributes network traffic to servers ready to accept it. In Active-Active Cluster configuration, the load balancer is used to direct WebSocket based traffic to the ThingWorx Connection Services while user requests (http/https) traffic is directly distributed to the ThingWorx Foundation servers. Example load balancers: HA Proxy Azure Application Gateway AWS ALB See the ThingWorx High Availability Documentation for details. ThingWorx Connection Server Handles AlwaysOn connections with devices and multiplexes all messages over one connection to ThingWorx Foundation Servers. In an Active-Active configuration, it handles all WebSocket based traffic to and from the ThingWorx Foundation Server. PTC Apache ZooKeeper A centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. It is a coordination service for distributed application that enables synchronization across a cluster. Apache Software Foundation Apache Ignite Used by ThingWorx Foundation Servers to share state. It may be embedded with each ThingWorx instance or can be run as a standalone cluster for larger scale. Apache Software Foundation Data and Model Provider Provides persistent storage of application data. All ThingWorx 9 supported database options: PostgreSQL Microsoft SQL Server Microsoft Azure SQL InfluxDB (only available as a data provider)         Step 3: Next Steps   Congratulations! You've successfully completed the Active-Active Clustering with ThingWorx guide.   At this point, you can make an educated decision regarding which clustering architecture is best suited for your ThingWorx application. Whether you already use ThingWorx or pursuing ThingWorx, its important to understand how Active-Active clustering is achieved and whether it is right for your system.   Learn More   We recommend the following resources to continue your learning experience:       Capability Guide Manage ThingWorx Application Development Reference Build Get Started with ThingWorx for IoT Experience Create Your Application UI   Additional Resources   To learn more about Active-Active Clustering and general ThingWorx deployment guidelines, there are ample resources available through our Help Center and PTC Community:   Resource Link Community Developer Community Forum Support ThingWorx Platform Sizing Guide Support ThingWorx Deployment Architecture Guide Support ThingWorx High Availability Documentation
View full tip
Neural Net is a learning algorithm that is inspired by how the human brain works. For example, imagine you love chocolate cake so much that, you joyfully exercise a bit more during the week just to enjoy that delicious chocolate cake without feeling guilty. But if the weather is terrible there is no way you go exercise, and then you can’t eat the delicious chocolate cake. Although, if your beautiful girlfriend / boyfriend exercise with you, then you ignore the weather and joyfully exercise and then you can enjoy that delicious chocolate cake without feeling guilty. The brain’s nervous system passes information using a synapse structure which allows neurons to pass information to other neurons and finally make a decision. This structure of passing information and decision making is the construction behind neural net algorithm. The data structure provides weights on the edges for the nodes/synapses in a directed graph. For example, our chocolate cake decision making could be translated into: w1=6 Whether or not your girlfriend or boyfriend exercise together with you w2=3 Enjoying delicious chocolate cake w3=2 Weather The high weights for example indicates the condition to have a high influence on your output decision making, while lower weight is not that influential. The illustration below is an example of neural net with 5 different input of information: The edges/arrows represent weights each input/node have a weight associated with it. These weights are applied when training neural net. Three of the inputs could represent 1= Delicious chocolate cake, 2= The weather, 3= Your girlfriend or boyfriend, and the last two inputs could be other information. The output is the condition of the decision determined by the hidden layer. ThingWorx Analytics Server applies neural net with full interconnection layer, which means each value from the input layer is duplicated and sent to each node in the hidden layer, just like in following illustration.
View full tip
Announcements