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
Architecting Reason Code Trees in DPM Tori Firewind, IoT EDC   What are Machine Codes? Factory hardware devices communicate status changes to their human operators and other machines (IoT) via machine codes. The manufacturers often determine the machine codes for different types of factory hardware, so those are often pre-determined. However, how the reason trees map these machine codes to corresponding business logic in ThingWorx is entirely customizable. Knowing the best way to design your reason trees for this purpose can be challenging, so this guide is here to help with your conceptual knowledge. Using the UI to create, edit, and configure reason codes in technical detail can be found in the Help Center.    The Tree Trunk At the highest level of the reason tree, the trunk, there are really 3 categories: Availability (A), Performance or Productivity (P), and Quality (Q). These should look familiar; they are the three dimensions of OEE (Overall Equipment Effectiveness). Fg 1. Calculation of OEE Availability refers to long stops, events that stop planned production long enough that it makes sense to track a reason for being down (typically several minutes, but the threshold between a long stop and a short stop can vary depending on the ideal rate of production of materials).                  Availability = Run Time / Planned Production Time   Productivity/Performance really refers to short stops, things that cause the machine to run at less-than- optimal speeds. This can include stops caused by running out of materials for production, doing minor maintenance like switching out a single, easily-changed part, or even frequent breaks due to ill health of an operator. User error can be a cause as well, say if the machine needs a certain heat to produce parts, and the heat keeps fluctuating (requiring the machine to take the time to calibrate for this before starting on production) because operators are smoking out a back door or adjusting thermostat temperatures. Fg 2. Levels of Runnable Time   Operator influence often is a factor when it comes to the conditions that permit optimal performance from machinery, and every factory may face different challenges. Stops like these are not really outages; the amount of downtime isn’t enough to consider the production block entirely unproductive. Production was continuing and ongoing throughout most of the block despite the issues; the rate was just slower than ideal.                  Performance/Productivity = (Total Count / Run Time) / Ideal Run Rate   Quality refers mostly to the number of items that are considered scrap or rework, and it can be split into two categories: start up scrap (that which is expected because the machine is in the process of warming up or being fine-tuned by the operator) and production scrap (things which come out wrong and must be tossed or reworked because the conditions under which they were produced weren’t ideal; this is called first-pass yield only, meaning it's only a "good" product if it passes inspection the first time).                  Quality = Good Count / Total Count​   The Branches and the Leaves of the Tree The “leaves” are the reason codes which directly map to machine codes , and the “branches” are the method of categorization that connects them to the trunk. Both the leaves and the trees, the children and the parent nodes of the tree, are split into two states: planned versus unplanned downtime. Changeovers, maintenance, and even scrap, can be broken down into this dichotomy.   For scrap, there are startup rejects (planned, because the machines have ramp up periods) and production rejects (unplanned, because the conditions weren’t ideal). For maintenance there is planned and unplanned, small changes that occur on the fly that result in productivity loss, and maybe also reduce availability in the long run. Small, unplanned changes can occasionally shift into the availability loss category if a simple, quick repair winds up being complex and time-consuming. A good reason tree can differentiate easily between short and longer stops in order to respond to each in a deliberate way.   To start off in the process of architecting your reason tree, try writing the three categories on a board in a common room in an average factory (or several as a survey). Ask operators to stop in over the course of a few days and write various machine codes that they see often and find useful under one of these categories, or more than one if the machine code pops up under different circumstances and can mean different things. Have them write a 10 word justification, if the association isn’t obvious. Gather all of the “leaves” in this way, and then begin to associate them with the “trunk”, forming the “branches”.   An example tree can be seen in figure 3 here, with leaves like “Changeover” and “Maintenance” being semi-ambiguous; they could just as easily be seen as unplanned stops. Therefore, there may be multiple reason codes mapping up to the top of the tree in more than one branch, and these can have different categories, which controls how the business logic responds to the different codes. The Help Center has more details about how the events are mapped to types, and each type contains multiple categories, as configured by you when you set-up the DPM model. Fg 3: Different types of changeovers may have different codes, and can map up as either planned or unplanned, but all planned and unplanned stops (long stops) are under the Availability category of the trunk. Similarly, small stops can involve idling, like if there are not enough materials, reduced speed if the conditions are not ideal, or other small stops, usually caused by human error or unforeseeable circumstances. Quality loss then refers to the products which fail quality checks, either because the machine still has the wrong paint in the applicator and needs a few rounds to be ready for the next production item, or because the conditions are again, not ideal, and items wind up scrapped.   Example Reason Tree Fg 5 example tree with more specific tags (there may be dozens or hundreds in a full reason tree, though the fewer are needed to capture the events we care about, the better).   Theory of Constraints Fg 6 theory of constraint wheel: an industry process for gradual OEE improvement in factories that has been adapted into the PTC methodology as well. While architecting your reason tree, always remember the key purpose: gathering only as much data as necessary to analyze the efficiency of a factory and to identify the bottleneck, or the most limiting factor. The important point is to identify not just the bottleneck that seems the most troublesome, but the one that actually results in the greatest impact to OEE across the entire factory.   Without software like DPM, and a properly designed reason code tree, the process of improving a factory can be very challenging, involving a lot of guesswork, and sometimes solving one problem at the cost of another. The issue is that these machines produce a LOT of raw data, and humans are not the best tool available to gather and aggregate this data in a consumable way. A good reason tree ensures a smart application that can quickly prioritize the machine (bottleneck) that most impacts production, and not just the machine that functions in the least optimal way.   So, the theory of constraints is really a process for identifying small, incremental changes, which together can make a big difference, and fast, in factory OEE. The rate at which this cycle can be completed varies, however. The slower the process of identifying constraints and the less information that is gathered, the slower and less precise the first two steps of this process. Alternatively, in a traditional constraint identification process, too much information can be a problem as well, due to human limitation, as discussed above. So, DPM is a great benefit in this regard, because it aggregates the data into a consumable, comparable way every 5 minutes, freeing up your human analytics for problem solving and prioritization, and not data gathering and sorting.   Other Key Tips Also remember that a good tree treats the trunk like a whole unit, with each category occupying a percentage of the overall OEE. Afterall, look back up at the 3 dimensions of OEE in the equation above. For example, the more you see issues with availability, the less you will see issues with scrap, for the machine simply doesn’t have as much time to produce scrap if it is constantly down. The more you see issues with quality loss, the less you should see of productivity loss, because these are simply inversely proportional modes; to say it differently, if a machine is running quickly and seeing few minor maintenance stops, then it is likely to produce more scrap (as well as more good product as well).   Another thing to remember is that even DPM is limited in its capacity to interpret raw data. Even while many magnitudes more efficient than any human gathering and analysis could ever be, there is an upper limit to how much raw data DPM can ingest and analyze before the system gets very expensive. For this reason, you want to ensure your reason trees use only as many reason codes as are required to capture the OEE of a factory site. This will mean using different codes for different types of things, most likely, which is easy to do maintainably across many sites using thing shapes. Keeping things tightly defined and organized is the easiest way to ensure a clean, efficient system for gathering and storing data.   Also remember that data will not need to persist very long once DPM is fully operational and adopted by your factories. DPM ensures that the changes made to the production line to improve efficiency are the highest impact, and the least difficult to implement, meaning that there will be a very rapid return on investment, and a process to ensure future issues are identified and resolved quickly. Data from past issues in the factory won’t be as relevant, and historical data stores can be kept smaller than one might think. It is the power of ingesting data directly into the processing and aggregation process, the automatic reduction of data down into presentable, consumable webpages, that makes DPM and ThingWorx such a great factory solution for optimizing OEE.
View full tip
In this post I show how to use Federation in ThingWorx to execute services on a different ThingWorx platform instance. In the use case below I set up one ThingWorx instance in the Factory and another instance in the Cloud, whereby the latter is executing a service which is actually running on the former.   Please find the document in attachment.   HTH, Alessio Marchetti  
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
  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
    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
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
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
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
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
  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
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
    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
Build robust, secure, full-featured edge integrations and gateways for any platform using C, .NET, Java (supporting Android development).  Tutorials are available for the C and Java SDK's by clicking the relevant link below.     C SDK The C SDK is the basis for ThingWorx Edge SDKs and the Edge MicroServer (EMS). You can compile C SDK applications on any platform and even run it without an operating system. Using the C SDK for your application means least amount of RAM, processing power, and disk space, frequently requiring less than 200 kilobytes. The C SDK is also the only SDK that is distributed as source code.       Java SDK The Java SDK is especially useful if you are integrating with an application that uses a Java-based API. While applications based on the Java SDK tend to use more RAM, processing power, and disk space than a C SDK equivalent application, they typically take less time to develop. To use it, you will need a platform with a supported Java Virtual Machine. The Java SDK support Android development.       .NET SDK Use the Microsoft .NET SDK when integrating with a .net based application or if your team typically works with Microsoft technologies. It may only be used on Windows based machines.  
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
Underneath, video is about ThingWorx Analytics and walks through following functions: Upload a Dataset. Create a Training Model. Create a Scoring Job.
View full tip
This video begins Module 7: Predictive & Prescriptive Scoring of the ThingWorx Analytics Training videos. It describes how a trained machine learning model takes inputs and makes predictions of different kinds, depending on the use case. It shows how scoring works in production, taking inputs from various sources and producing a score to help users make informed decisions. It also covers the concept of field importance in an individual score.
View full tip
Announcements