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

Community Tip - Need help navigating or using the PTC Community? Contact the community team. X

IoT Tips

Sort by:
    Modernize your Mashups with CSS to enhance the presentation of your application.   GUIDE CONCEPT   This project will introduce using CSS to create a customized, consistent look and feel for your IoT application.   Following the steps in this guide, you will create a custom CSS class definitions and bind these classes to Mashup features.   We will teach you how to present a professional-looking user interface and ensure consistency of style treatments within your application by implementing Cascading Style Sheets (CSS) in Mashups.     You'll learn how to   Create custom CSS classes using the integrated CSS editor Bind CSS classes to a Mashup and to individual Widgets Use Media queries to dynamically apply styling     Step 1: Custom CSS Benefits   You now have more flexibility to customize your application’s UI and improve the user experience using industry-standard web techniques. You can implement CSS in ThingWorx to control the visualization of your Mashup.   Feature                   Benefit Text Treatments Optimize text with shadow, color, font, and border Responsive UI Customize layout based on user actions and the data being displayed Media Queries Accommodate many screen sizes with flexboxes and other standard containers Animations Implement standard CSS key frames Customizations Modify application appearance without changing source Mashup Linting Expedite development with code auto-completion and design-time syntax warnings       Step 2: Access Sample Files   We created sample entities you can use to complete the steps in this guide. Download the attached Mashups_CustomCssTutorialMashup.xml From the Home page of Composer, click the Import/Export icon, then choose Import   Keep the default options and click Browse. Locate and select the CustomCssTutorialMashup.xml file you downloaded and extracted, click Open then Import.   Click Close after the Import successful message is displayed. Click the Browse tab in the left navigation panel, then click Mashups.                     6. Select the CustomCssTutorialMashup.                 7. Click View Mashup to view the Mashup.     NOTE: This is a simple Mashup designed to demonstrate how the UI changes when CSS is applied.       Step 3: Create CSS Rule Block   In this step, you will use the built-in editor to create a custom CSS class that will be used in the next step to modify the appearance of three buttons grouped by the Fieldset Widget.   Open the CustomCssTutorialMashup in Edit and Design view.     Click Custom CSS.     Copy the CSS class below and paste it into the Custom CSS editor: .myMashupClass .widget-fieldset .widget-ptcsbutton { box-shadow: 5px 5px 5px #888888; } NOTE: This class will create a shadow around all of the buttons that are in a Fieldset container  only after it is bound to a Mashup,   4. Click Save.     Tips   Press Ctrl -> Space to use the Auto-complete feature and see code snippets, which can expedite your development time.     The Linting feature will warn you if there are errors in your code, so you can fix them at design time.       Step 4: Apply Custom Class to Mashup   In this step we will demonstrate how to modify the look and feel of a Mashup without changing the Mashup itself. The myMashupClass we just created chains two selectors: the widget-fieldset and the widget-button. Only Widgets that are in both selector categories will be modified.   Click Design and select the Explorer tab, then select the top-level Mashup.     In the property panel in the lower left, locate the CustomClass property and type myMashupClass as the value. Press Tab to save the value change.     WARNING: You must press Tab after every property change in order for the new value to be saved.   4. Click Save then View Mashup to see that the buttons in the Field Set have shadow borders.       Step 5: Apply Custom Class to Widget   In addition to the Mashup level, you can apply style treatments directly to a Widget in your Mashup. In ThingWorx, the following Widgets have a CustomClass property you can modify:     For this example, we will make the text on one of the buttons all caps.   In the CustomCssTutorialMashup, click Custom CSS. Add the following css code: .myButtonClass .widget-ptcsbutton { text-transform: uppercase; }     Return to the Design view, and In the Explorer tab, click the button-3.     In the Property panel, enter myMashupClass to the CustomClass field, then press tab     Save then View Mashup the Mashup to see that the button text is now all caps.       Step 6: Bind Custom Class   The UI of a Mashup can be dynamically updated at runtime by binding the value of the CustomClass property to a dynamic data source such as: Services Mashup parameters Widgets (expression widgets for example)   In this portion of the guide, we will demonstrate modifying a Mashup in response to user actions:   Return to the Design view for the CustomCssTutorialMashup. In the Mashup Builder, click the Functions tab in the lower right, then expand Event Routers and expand eventsrouter-6     Click Output property and drag it onto the bottom button of the group of three buttons.     Select the CustomClass property from the pop-up to bind it to Button-4   In Mashup Builder click Custom CSS tab. Add the following css code: .myBoundButtonClass1 .widget-ptcsbutton { text-transform: lowercase; } .myBoundButtonClass2 .widget-ptcsbutton { text-transform: uppercase; }           7. Click Save and then View Mashup.           8. Click on each of the Apply buttons to see the results of a CSS class applied to in response to user actions.     Step 7: Use Media Queries   You can use Media queries to apply styling based on the characteristics of the device being used to access the application. For this example, we will use a CSS Class to hide three elements when the browser’s width is less than 600 pixels wide.   1. Open the CustomCssTutorialMashup in Edit and Design view, then click Custom CSS.     2. Copy the CSS class below and use the Custom CSS editor to add it to the top of the existing  CSS, then click Save. @media screen and (max-width: 1000px) { #root_ptcslabel-10-bounding-box { visibility: hidden; } #root_ptcstextfield-7-bounding-box{ visibility: hidden; } #root_ptcstextfield-12-bounding-box { visibility: hidden; } }   NOTE: The ID selector in your CSS must add root_ to the beginning, and -bounding-box to the end of the element’s ID shown in Mashup Builder.   3. Click View Mashup, then click and drag the edge of the browser window to reduce the width below 600 pixels.     NOTE: The three Widgets selected in the media class added in the last step will disappear as soon as the browser is less than 600 pixels wide.       Click here to view Part 2 of this guide.
View full tip
  Step 8: Troubleshooting   Issue                                       Resolution CSS does not seem to be applied to the Mashup. Verify your CSS is included in the runtime TWX CSS. Clear Browser cache if your CSS is not merged to the combined TWX CSS. (under debug mode: Hold refresh button->Clear Cache). TWX fails to import the extension. If the extension is already installed, but you made recent changes, you need to bump the Version number in the metadata.xml. Recent CSS changes are ignored. Clear browser cache if your CSS file has changed recently.     Step 9: Next Steps   Congratulations! You've successfully completed the Add Style to Your UI with CSS guide, and learned how to:   Create custom CSS classes using the integrated CSS editor Bind CSS classes to a Mashup and to individual Widgets Use Media queries to dynamically apply styling   Learn More   We recommend the following resources to continue your learning experience:    Capability     Guide Build Application Development Tips & Tricks Experience ThingWorx Application Development Reference   Additional Resources   If you have questions, issues, or need additional information, refer to:  Resource       Link Community Developer Community Forum Support Help Center
View full tip
Design and Implement Data Models to Enable Predictive Analytics Learning Path   Design and implement your data model, create logic, and operationalize an analytics model.   NOTE: Complete the following guides in sequential order. The estimated time to complete this learning path is 390 minutes.    Data Model Introduction  Design Your Data Model Part 1 Part 2 Part 3  Data Model Implementation Part 1 Part 2 Part 3  Create Custom Business Logic  Implement Services, Events, and Subscriptions Part 1 Part 2  Build a Predictive Analytics Model  Part 1 Part 2 Operationalize an Analytics Model  Part 1 Part 2  
View full tip
    Guide Concept   This project will introduce how to get your application ready for usage by actual users or ready to collect data.   Following the steps in this guide, you will be ready to present your finished application to users so they can benefit from its functionality. Deploying your application provides the ability for users to access it from anywhere, anytime and enables your edge devices to communicate with your application 24/7.   We will teach you how to deploy your ThingWorx IoT application to be ready for whatever experience you've molded it to be.     You'll learn how to   Create login screens, users and user groups Define security permissions Deploy application Identify and troubleshoot issues   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes     Step 1: Completed Example   Download the CompletedApplication.xml attached to this guide.  Within the downloaded file, you will find Entities referenced in this lesson, including a finished application that will be used for the deployment exercise. Import and utilize this file to see a finished example and return to it as a reference if you become stuck during this guide and need some extra help or clarification.   Keep in mind, this download uses the exact names for entities used in this tutorial. If you would like to import this example and also create entities on your own, change the names of the entities you create.       Step 2: Define Organization   In order to control access to your application, you first need to create an Organization. Think of the organization entity as your company or department. Once you define the organization, you will create Users and User Groups.   Organizations are hierarchical structures that allow you to assign visibility to entities in the ThingWorx Model. You can add users and group to each level within this structure.   Organizational Structure   This is the organization defined within the sample application download for this guide.  Entity Name                Entity Type      Description Constructors Organization High level of an organization. UpperManagement User Group Executives in the organization. HR User Group HR department in the organization. Management User Group First and second tier management in the company. Laborers User Group Skilled trade workers in the organization. ConstructorsGroup User Group Security group for all employees in the company. j.general User HR Department Employee a.jones User Skilled Laborer j.lewis User Manager i.jorden User CEO default_user User User used in trial version for all company roles.      Create Organization   Follow the steps below to create an Organization and make it login ready. Once your Organization is saved, you are provided with a login screen. Customize the login page to your liking with the General Information tab of the Organization after creating it.   In the ThingWorx Composer, click the + New at the top of the screen.     Select Organization in the dropdown.     Name your Organization Constructors. Set the Project field (ie, PTCDefaultProject) and click Save     Click Edit and select the Organization tab to see the hierarchy. With the top organization selected, in the Members search bar, search for the user you have created yourself and add them. Keep track of the user you added, they will be needed to log into the application later in this guide.            View Organization   From the Home page of Composer, filter for and select the Constructors Organization. The General Information tab shows the configurations for the login screen and resetting passwords. For more information on password resets, see the Password Reset Help Page. The Login Image is where you would put your logo or an image you would want users to see when they are logging into your application. The Home Mashup is the page you would like users to go to after they have passed the login prompt. The Login Style and Login Button Style are Style Definition properties. NOTE: If you keep these fields blank, the default configurations will be applied. You can create your own Style Definitions by following steps in our Styles and States Guide.   Create Organizational Units   Let's create the structors for our Organization. With the Constructors Organization open, follow the directions below:   Click the green + button under the structure you would like to expand. Name your Organization unit UpperManagement In the Members search bar, search for the user or user group you created and add it.     Click Save. Repeat the steps to create the full hierarchy of the organization and its members.     Setup Entity Visibility   Visibility is a simple form of access control. If an entity is visible to members of an organizational unit, then its members have access to the entity.   Select the Permissions tab of any Thing you created in Composer.     Filter and select Constructors in the Search Organizations field. Click Save.         Step 3: Security and Permissions   By Default, new Users have no permission configurations. Permissions can be defined for any Entity created on the ThingWorx platform. All Entities have permission control for both design time and run time.   Design time is the period in which changes can be made to the Entity in Composer. Run time is the period in which the application is running and calls are made.   Permissions should be set for each and every Entity within the application in order to keep it secure and maintain access to services.   Select the Permissions tab of any Thing you created in Composer (ie, ConstructorsBlog).   Select the Design Time or Run Time tab.   After selecting one, filter and select a User or UserGroup to set their permissions. Set the Allow, Deny or Inheritence markers to set permissions respectively.   The Inherit category allows a user to inherit permissions from the user group it belongs to.       Step 4: Deploy Application   ThingWorx Composer is set up to allow deployment in very simple steps. An application can run locally on a computer or remotely on a server as long as an Apache Tomcat server is installed on the same machine. Simply copy the URL that is generated when you click View Mashup within Composer. That is the URL to share with users so they can access your application.     If you plan to use a Login Screen, use the View Mashup URL generated from the Login Mashup you create. To view the login page of your application, type the following URL: [server]/Thingworx/FormLogin/ (ie, localhost/Thingworx/FormLogin/Constructors).   The login page for the sample application can be found at: [server]/Thingworx/FormLogin/Constructors.     To log in using this screen, type in the username and password of a user that is in the organization.   To use one of the example Users, set their password in the Composer and test it within the login prompt. Based on the permissions you set, users will have a different view of the application when they log in.         Step 5: Logging and Troubleshooting   There are two mechanisms that enable you a view into your application and what is happening behind-the-scenes, through the ThingWorx Composer Monitoring and the ThingWorx filesystem.   ThingWorx Composer Monitoring   ThingWorx provides pages to see all logs and communications between your ThingWorx instance, your applications, and edge devices using the Monitoring drop-down in the top navigation toolbar of your Composer. To see this page click Monitoring on the left menu, then select the option you would like to see.      Resource                  Usage Application Log This page will show you the log for your application and information on the processing running. Communication Log This page is used to show communication between your ThingWorx instance and outside sources. Configuration Log This page provides information into what is happening behind the scenes for your ThingWorx Composer and how it has been configured. Security Log This page highlights any information around access to the application, composer, or any security updates Script Log Logging information you have set for scripts running in your ThingWorx instance. Error Log Details for errors within your ThingWorx instance. Remote Things This page provides the list of Entities that are able to connect to edge devices, connected to your application, and even Entities that are currently disconnected.   ThingWorx File System   Log files for ThingWorx and your application can be found in the [Root]\ThingworxStorage\logs directory. The ROOT DIRECTORY is the folder in which ThingWorx has been running (ie, C:\ThingworxStorage\logs for Windows or /ThingworxStorage/logs for Mac or Linux).   Each log file corresponds to some of the content you can see in the Monitoring dropdown in the ThingWorx Composer.       Step 6: Next Steps   Congratulations you have completed the Deploy an Application How-To, and learned how to:   Create login screens, users and user groups Define security permissions Deploy application Identify and troubleshoot issues   The next guide in the Customize UI and Display Options to Deploy Applications learning path is How to Display Data in Charts.    Additional Resources   We recommend the following resources to continue your learning experience:    Capability    Guide Build Implement Services, Events, and Subscriptions Secure Configure Permissions     If you have questions, issues, or need additional information, refer to:    Resource       Link Community Developer Community Forum Support Help Center  
View full tip
  Implement reusable Mashup Templates and Shapes in your IoT application.     Guide Concept   This guide will introduce you to creating your own advanced responsive ThingWorx user interface templace. You’ll learn some best practices and tips for creating a UI for your IoT application. With Mashup templates, you’re able to quickly and easily build pages that will look alike and have some of the same functionality already programmed.   Following the steps in this guide, you will create reusable content and develop scalable user interfaces.   We will teach you how to make UI development easier and more efficient for all of your IoT application needs.     You'll learn how to   Utilize ThingWorx using best practices for UI design Create Entities to make development faster and scalable    NOTE: The estimated time to complete this guide is 30 minutes     Step 1: Completed Example Files   Download and import GiftedReusability.xml attached to this case. Within the file you imported, you will find Entities referenced in this lesson, including a finished application. Import and utilize this file to see a finished example and return to it as a reference if you become stuck during this guide and need some extra help or clarification. Keep in mind, this download uses the exact names for entities used in this tutorial. If you would like to import this example and also create entities on your own, change the names of the entities you create.     Step 2: Create Reusable Mashup   A reusable Mashup can be embedded in another Mashup in order to enable common components. Follow the steps below to create a reusable Mashup.   In the ThingWorx Composer, click the + New at the top of the screen.   Select Mashup Template in the dropdown.   Select Responsive for the layout option. Click Ok.   Enter a name for the Mashup Template, such as MashupTemplateExample. Set the Project field (ie, PTCDefaultProject). Click Save then click Design to get to the Mashup canvas.   You've now created a Mashup template that can be utilized to create other Mashups faster and easier. After saving, you will have the regular Mashup design window as shown below.     Play around and have some fun with this new Mashup. With the Workspace view in the Default option, you can see how simple it is to add sections and layout configurations within the page. You can also see that there is functionality for adding Widgets and data to the template. Let's add containers.   Let's add some containers to our UI. This will allow for easier grouping of UI components or to allow users an easy comparison of charts and graphs.   Select the Main layout and click Add Left. Do this a second time. Select the left most container and select Add Bottom. Select the right most container and select Add Top. Select the top section that was just added and click Add Right.   You should have something like the image above. Now that you have formulated these sections, you can use the standard methods to add Widgets, styles, and data. In the Nested Container section, you can decide on how these containers should be sized as your add new sections to your page.   If you make any changes to this Mashup Template, you are then able to create new Mashups based off of this Mashup after select Responsive as the layout option. We will be making some of these changes in the next steps.       Step 3: Configure Mashup   There are two Thing Templates provided. AirHandler is a top level template with several direct implementations (FanA, FanB, FanC, etc.). There is also a HeatHandler Thing Template. This template inherits from the AirHandler Thing Template and has 2 direct implementations.   The AirHandlerTemplate Mashup can be used with either direct AirHandler implementations, or indirect implementations such as implementations of the HeatHandler Thing Template. This Mashup can also be reused further with implementations of another Thing Template.   Open the AirHandlerTemplate Mashup, which contains the layout that will be used in this example. Drag and drop a Property Display Widget onto the left column in the layout on the canvas.   Drag and drop an Image Widget onto the bottom right space of the canvas.   Drag and drop a Checkbox Widget onto the top part space of the of the canvas.   Click the + button in the Data panel.   Check the Dynamic checkbox. Select the AirHandler in the Select Entity text box. Filter for and find the GetPropertyValues service, then click the arrow.   Check the Execute on Load checkbox. Click Done.   You've just created a Mashup Template that will utilize the AirHandler entity for data and property values. This will allow you to continuously create new Mashups with a head start. In the next steps, we will connect the data values of the AirHandler template to the Widgets in the screen.         Step 4: Define Entity Parameter   Mashups come with a parameter named Entity. This parameter is a BaseType of ThingName and often used in dynamic Mashups as an input to Services or outlets of information. In our example, the Entity parameter is used to tell the Mashup which implementation of the AirHandler we should present.   With the updated AirHandlerTemplate Mashup still open, follow the directions below:   Select the Mashup in the Explorer pane. Select the Settings icon in the Widget properties panel.   The Configure Mashup Parameters pop-up will appead. Add a parameter named Entity with a Base Type of Thing Name. Select Done.   In the Mashup Property panel, drag the Entity parameter to the EntityName field of the DynamicThingTemplates_AirHandler data source.   Select All Data from the GetPropertyValues Service and drag it to the Property Display Widget. When prompted, select Data from the Select Binding Target pop-up.   Expand the All Data section of the GetPropertyValues service. Drag the FanStatus field to the Checkbox Widget. When prompted, select State from the Select Binding Target pop-up.   Drag the HandlerImage field from AllData section to the Image Widget. When prompted, select SourceURL.    With the Mashup selected in the Workspace pane. Drag the EntityChanged event from the Widget Properties panel to drop GetPropertyValues service. This ensures that the GetPropertyValues service will be called at runtime when the Mashup shows a new Entity.    Click Save.   NOTE: You can configure the Property Display Widget to display only certain properties. To do this, select the Property Display Widget in the Workspace pane, click the dropdown arrow and select Configure Widget. Uncheck the fields you do not want to see (for example, name, description, tags, and HandlerImage) and click Done.   You have just created a reusable Mashup to display information based on the particular incoming AirHandler. At this point, clicking View Mashup will not display any data. Proceed through the remainder of this exercise to connect it as a Contained Mashup.       Step 5: Use Mashup Template as Component   This HandlerExample Mashup is not a Mashup Template. It will be used later to contain a Mashup Template. It already contains the layout that will be used in the example.   Adding Service   The below steps are based on the HandlerExample Mashup. This completed version can be found in the provided download.   Create a new Mashup named Handler and add a column. Drag and drop a List Widget onto the left column of the Mashup layout.    Drag and drop a Contained Mashup Widget onto the right column of the Mashup layout. In the Name property for the Contained Mashup Widget, filter and select the AirHandlerTemplate Mashup.    Click the + button in the Data pane. Select AirHandler in the Select Entity search box. Filter for and find the GetImplementingThings service, then click the blue arrow.   Check the Execute on Load checkbox. Click Done.   Configuring Data Input   Select All Data from the GetImplementingThings service and drag it to the List Widget. When prompted, select Data.    Expand the Selected Row(s) section of the GetImplementingThings service. Drag the name field to the Contained Mashup Widget. When prompted, select Name.    Select the List Widget in the Workspace pane. In the Properties section, set the DisplayField and ValueField properties to name.    With the List Widget still selected, check the AutoSelectFirstRow property. Click Save, then View Mashup.    You will see Fans and Heaters in the list because they are both implementations for the AirHandler template. The Mashup can be used for both scenarios and will show the property fields for both. The AirHandlerTemplate can be used with other templates because it is only a Mashup Template.   Based on the properties of the other Thing Templates used with this particular template, determines whether an image will be shown in the right layout.   The FinishedExample Mashup is a finished example of this exercise.       Step 6: Next Steps   Congratulations on completing the guide!   The next guide in the Customize UI and Display Options to Deploy Applications learning path is Deploy an Application.    If you have questions, issues, or need additional information, refer to:    Resource       Link Build Application Development Tips & Tricks Community Developer Community Forum Support Help Center  
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
    Use Thing Shapes to create groups of related Properties   Guide Concept   Save time and effort by modeling a solution in ThingWorx using Thing Shapes to group Properties. A logical group of Properties can be applied to Things and Thing Templates.     You'll learn how to   Create a Thing Shape Add Properties to a Thing Shape   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes       Step 1: Create Thing Shape   In this section you will create a Thing Shape for sensor properties of a MXChip development board.   Thing Shapes are components that contain Properties and Services. In Java programming terms, they are similar to an interface.   Start on the Browse folder icon of ThingWorx Composer. Under the Modeling section of the left-hand navigation panel hover over Thing Shapes, then click the + button.   Type ThermostatShape in the Name field.   If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. Click Save.     Step 2: Add Properties to Thing Shape   Click Properties and Alerts tab at the top of your Thing Shape.   Click + Add. Enter the Property name in the Name field as shown in the table below. Name Base     Type           Persistent?       Logged? humidity NUMBER   X messageId STRING X   temperature NUMBER   X Select the appropriate Base Type from the drop-down menu.   Check Persistent and/or Logged according to the table. NOTE: When Persistent is selected, the property value will be retained during a system restart. Properties that are not persisted will be reset to the default during a system restart. When Logged is selected, every property value change will be automatically logged to a specified Value Stream. Click Check +. TIP: When adding multiple properties at once, click Done and Add after each, once you've entered a Name, selected a Base Type and any other criteria. If adding a single property, click Done. Repeat steps 4 through 6 for each of the properties in the rows of the table. Click the done Check. You'll see that these Properties have been created for the ThermostatShape.   Click Save.     Step 3: Next Steps   Congratulations! You've successfully completed the Create A Thing Shape, and learned how to: Create a new Thing Shape Add Properties to the Thing Shape   This is the last guide in the Azure MXChip Development Kit Learning Path.  If you wish to return to the Learning Path, click the link.   Learn More   The following resources continue your learning experience:  Resource       Link Build Data Model Introduction Experience 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 Thing Shape Support Help Center      
View full tip
  Maintain cookies and security information by implementing session parameters in your application.   Guide Concept   This project will introduce creating and accessing session data from a User logged into your application. Session data is global session-specific parameters that can be used on the Client and Server side.   Following the steps in this guide, you will be able to access the logged in User's information and their set values.   We will teach you how to access session data, that can later be used to provide Users with unique experiences and a more robust application.   You'll learn how to   Create Session Data Access Stored Session Data   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes     Step 1: Completed Example   Download the completed files for this tutorial:  Sessions.xml.   The Sessions.xml file contains a completed example of session parameters. Utilize this file to see a finished example and return to it as a reference if you become stuck during this guide. Keep in mind, this download uses the exact names for entities used in this tutorial. If you would like to import this example and also create entities on your own, change the names of the entities you create.     In the bottom-left of Composer, click Import/Export.     Click IMPORT.     In the Import pop-up, keep the default values and click Browse. Navigate to the Sessions.xml file you downloaded. Select it and click Open. Click Import in the Import pop-up. Click Close to close the pop-up.       Step 2: Create Session Parameters  Click the Browse folder on the left-hand side. Under System, select Subsystems.     Filter for UserManagementSubsystem and open it in Edit mode.     Select Services. Filter for the AddSessionShape Service.     Click the Play button to open the Execute window. Enter UserLogin (the provided ThingShape) as the name input field. Click Execute.     Click Done.   You've just created your first Session Parameter. These values are used for content held in a cookie for a website or information that might be static for the User or session.   Best Practice: For information that will be static for the entire application and not based on the session, use a database option or a stored value in a Thing.       Step 3: Access Session Parameters   Click the Browse folder on the left-hand side. Under System, select Resources.   Filter for CurrentSessionInfo and open it.   Select Services. Filter for the GetGlobalSessionValues Service.   Click the Play button to open the Execute window. Click Execute. You will notice the result is a list of the properties in the UserLogin ThingShape. Your result might differ from mine.   Click Done.   NOTE: There is a difference between Session parameters and Mashup parameters. Mashups can have input values that will be used for services or content of that Mashup ONLY. Session parameters are based on the user using the application in a session. This data will be accessible throughout the application and last until they have completed their usage. This guide shows how to create Session parameters that are considered global session parameters.     Step 4: Next Steps   Congratulations! You've successfully completed the Create Session Parameters guide, and learned how to: Access a logged-in user's information and their set values Use session data to provide users with unique experiences and a more robust application   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Create Custom Business Logic Build Data Model Introduction   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource  Link Community Developer Community Forum Support Session Parameter Help Center  
View full tip
Create Industrial Equipment Model Guide   Overview   This project introduces how to model industrial equipment in ThingWorx Foundation. NOTE: This guide’s content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes.    Step 1: Learning Path Overview   This guide explains the steps to get started modeling industrial equipment in ThingWorx Foundation and is part of the Connect and Monitor Industrial Plant Equipment Learning Path. You can use this guide independent from the full Learning Path. Other guides are available for more complete Data Model Introduction. When using this guide as part of the Industrial Plant Learning Path, you should already have ThingWorx Kepware Server installed and sending data to ThingWorx Foundation. In the next guide in the Learning Path, we'll use Foundation's Mashup Builder to construct a GUI that displays information and from ThingWorx Kepware Server. We hope you enjoy this Learning Path.   Step 2: Create Thing Shape   Thing Shapes are components that contain Properties and Services. In Java programming terms, they are similar to an interface. In this section, you will build Thing Shapes for an electric motor. Motor Start on the Browse folder icon tab of ThingWorx Composer. Under the Modeling section of the left-hand navigation panel, hover over Thing Shapes, then click the + button. Type MotorShape in the Name field. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. Click Save.   Add Properties   Click the Properties and Alerts tab at the top of your Thing Shape.   Click + Add. Enter the Property name from the first row of the table below into the Name field of the Thing Shape. Name Base Type Persistent? Logged? serialNumber String X   currentPower Number   X 4. Select the appropriate Base Type from the drop-down menu. 5. Check Persistent and/or Logged according to the table. NOTE: When Persistent is selected, the Property value will be retained when a Thing is saved. Properties that are not persisted will be reset to the default after every Save of the parent Thing. When Logged is selected, every Property value change will be automatically logged to a specified Value Stream. 6. Click ✓+ button. TIP: When adding multiple Properties at once, click Done and Add after each, once you've entered a Name, selected a Base Type and any other criteria. If adding a single Property, click Done. 7. Repeat steps 2 through 5 for the other Properties in the the table. 8. Click the done ✓ Button. You'll see that these Properties have been created for the Motor Thing Shape. 9. Click Save.   Step 3: Create Thing Template   You can create reusable building blocks called Thing Templates in ThingWorx to maintain scalability and flexibility of your application development. With Thing Templates, you define a set of similar objects by specifying the Properties (characteristics) and Services (behaviors) that are common for all the objects. In Java programming terms, a Thing Template is like an abstract class and can be created by extending other Thing Templates. Once a Thing Template is defined and saved in ThingWorx Foundation Server, you can replicate multiple Things to model a complete set without duplicating effort. In this step, you will create a Thing Template that defines Properties for a pump. This pump Template could be used to create multiple Things that each represent a specific pump used in an industrial facility. Start on the Browse folder icon tab on the far left of ThingWorx Composer. Under the Modeling section of the left-hand navigation panel, hover over Thing Templates and click the + button. Type PumpTemplate in the Name field. NOTE: Thing Template names are case-sensitive.       4. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject.       5. In the Base Thing Template box, click + to choose GenericThing as the Template.              6. In the Implemented Shapes field, click the + to select the MotorShape Thing Shape.              7. Click Save.   Add Properties   In this step, you will specify the Properties that represent the characteristics of a Pump. Some Properties like the location may never change (static), while other Properties like power and temperature information may change every few seconds (dynamic). Select the Properties and Alerts tab under Thing Template: PumpTemplate.   Click the Edit button if the Template is not already open for editing, then click + Add next to My Properties. Enter the Property name in the Name field copied from a row of the table below. Name Base Type Persistent Logged PlantID STRING x   plant_lat_long LOCATION x   watts NUMBER x x 4. Select the Base Type of the Property from the drop down menu. 5. Check the appropriate Persistent and Logged check box. NOTE: When Persistent is selected, the Property value will be retained when the parent Thing is saved. Properties that are not persisted will be reset to the default during a system restart and whenever the Thing is saved. When Logged is selected, every Property value change will be automatically logged to a specified Value Stream. 6. Click the ✓+ button. TIP: When adding multiple Properties at once, click Check+ after each, once you've entered a Name, selected a Base Type and any other criteria. If adding a single Property, click Check button. 7. Repeat steps 3 through 6 for each of the Properties in the rows of the table. 8. After entering the final Property, click the ✓ button. 9. Click Save. You should see the following Properties in your Composer.   In the next guide of this Learning Path, we will create a single Thing based on this Template to represent a specific Pump.     Step 4: Next Steps   Congratulations! You've successfully completed the Create Industrial Equipment Model tutorial, and learned how to: Use Composer to create Thing Shapes and Thing Templates Create Model Tags to keep entities organized   The next guide in the Connect and Monitor Industrial Plant Equipment learning path is Build an Equipment Dashboard.    
View full tip
Those who have been working with ThingWorx for many years will have noticed the work done around ingress stress testing and performance optimization.  Adding InfluxDB as a time-series data persistence provider really helped level up these capabilities while simultaneously decreasing the overall resources required by the infrastructure.  However with this ease comes a hidden challenge: query and data processing performance to work it into something useful.   Often It's Too Much Data In general most customers that I work with want to collect far too much data -- without knowing what it will be used for, or what processing will be required in order to make it usable and useful.  This is a trap in general with how many people envision IoT projects, being told by infrastructure providers that cloud storage and compute resources are abundant and cheap and that they should get as much data as possible.  This buildup of data means that more effort needs to be spent working it into something useful (data engineering/feature extraction) and addressing common data issues (quality, gaps, precision, etc.).  This might be fine for mature companies with large data analytics teams; however this is a makeup that I've only seen in the largest of our customers.  Some advice - figure out what you need and how you'll use it, and then collect that.  Work on extracting value today rather than hoping that extra data collected  now will provide some insights years from now.   Example - Problem Statement You got your Thing Model designed, and edge devices connected.  Now you've got data flowing in and being stored every 5 seconds in InfluxDB.  Great progress!  Now on to building the applications which cover the various use cases. The raw data is most likely going to need to be processed and potentially even significantly transformed into other information in order to make it useful.  Turning a "powered on and running" BOOLEAN to an "hour meter" INTEGER is a simple example.  Then you may need to provide a report showing equipment run time hours by day over a month.  The maintenance team may also have asked to look for usage patterns which lead to breakdowns, requiring extracting other data points from the initial one like number of daily starts, average daily run time, average time between restarts. The problem here is that unless you have prepared these new data points and stored them as well (say in a Stream), you are going to have to build these data sets on the fly, and that can be time and resource intensive and not give you the response time expected.  As you can imagine, repeatedly querying and processing large volumes of unchanging raw data is going to have resource and time implications - so this is why data collection and data use need to be thought about separately.   Data Engineering In the above examples, the key is actually creating new data points which are calculated progressively throughout normal operation.  This not only makes the information that you want available when you need it - in the right format - but it also significantly reduces resource requirements by constantly reprocessing raw data.  It also helps managing data purging, because as you create and store usable insights, you can eventually just archive away your old raw data streams.   Direct Database Queries vs. Thingworx Data Services Despite the above being a rule of thumb, sometimes a simple well structured database query can get you exactly what you need and do so quite quickly.  This is especially true for InfluxDB when working with extremely large time-series datasets.  The challenge here is that ThingWorx persistence providers abstract away the complexity of writing ones own database queries, so we can't easily get at the databases raw power and are forced to query back more data than needed and work it into a usable format in memory (which is not fast).   Leveraging the InfluxDB API using the ContentLoader Technique As InfluxDBs API is 100% REST, we can access it using in-built ThingWorx Content Loader services.  Check out this demonstration and explanation video where I talk about how to interact directly with InfluxDB in order to crush massive time-series data and get back much more usable and manageable data sets.  It is important to note here that you should use a read-only database user here, as you should never modify the ThingWorx databases to avoid untested scenarios which may lead to data corruption.   Optimizing ThingWorx query performance with the InfluxDB REST API - YouTube InfluxToolBox ThingWorx demo project (by T. Wobben)      
View full tip
Recently I have been accompanying an integration partner and end customer around an issue experienced with ThingWorx resource exhaustion.  Early on it seemed like this was an issue with the ThingWorx Azure IoT Hub Connector as it would freeze up and become unresponsive.  Following a root cause analysis it became clear that it was actually caused by a lack of a number of standard cloud design patterns, which if used would have automatically adapted operation of the overall solution to be far more resilient as well as resource optimized.   The way that the logic was structured, it prioritized job execution on entities with the oldest last success time and would continue to retry these executions (IoT Direct Methods) every few seconds until successful.  There were a number of problems here, but I'll unpack a few in order to tie the problem to the solution via design patterns.   1) No exception handling When the direct method execution failed/timed out or the system reported being unable to execute the remote service, this response was not used to adapt the solutions behavior. 2) No backoff retry mechanism As exceptions were not caught, an adaptive retry mechanism with incremental or exponential backoff could not be leveraged to limit the impact of the build up of the failing retries. 3) No exception tracking Tracking that exceptions were occurring and counting them would allow powering an exponential backoff retry algorithm (with jitter), a Cancel or Circuit Breaker pattern (stop doing something which is just broken), as well as provided alerting to address specific areas of the distributed solution experiencing issues. 4) Conflicting priorities It was interesting to see the manifestation of the conflicting interests of wanting to ensure checks and balances (had all needed data) and system resiliency.  Retries and resource usage built up exponentially due to the transient error instead of backing them off.  Trying so hard to get the needed data from failing sensors meant that operational sensors were deprioritized and their data was not received either - spreading the localized issue to the whole system.   Around the time that I shared my recommendations and some examples of how to make the solution more resilient, one of my technical colleagues at Microsoft shared some extremely interesting and relevant design patterns documented by Microsoft as a part of the "Microsoft Azure Well-Architected Framework".  This framework with included Design Patterns for specific cloud application goals allows applying well-known industry standard approaches to dealing with the challenges of large scale distributed enterprise systems (reliability, performance, cost optimization).   She later then shared this blog post describing exactly the exponential backoff retry with jitter pattern which we had together recommended to the systems integrator.   What's interesting for us ThingWorx people is that this framework from Microsoft is about well-architected cloud solutions and does not specifically reference the Azure stack, and as such many of these approaches and design practices can be employed in your ThingWorx applications.  What are you waiting for?  Go check them out!
View full tip
We will host a live Expert Session: "Thingworx Mashup 101 - Do's and Don'ts" on February 24th, 13h30 EST.   Please find below the description of the expert session and the registration link.   Expert Session: Thingworx Mashup 101 - Do's and Don'ts Date and Time: February 24th, 13h30 EST Duration: 1 hour Host: Aanjan Ravi - Technical Product Manager Registration Here: https://www.ptc.com/en/events/thingworx-mashup-101   Description: This session covers the most common and useful tips about how to correctly use Mashup builder, Widgets and Layouts – and what to avoid -  to create applications with good principles of UI/UX and easier to maintain.   Existing Recorded sessions can be found on support portal using the keyword ‘Expert Sessions’. You can also suggest topics for upcoming sessions using this small form.   Here are some recorded sessions that might be of your interest. You can find recordings for the full library of webinars using the keyword ‘Expert Sessions’ in PTC support portal search Thingworx Active Active Clustering This session will cover the main aspects of the High Availability Clustering feature launched with the ThingWorx 9.0 release.   Recoding Link Upgrade to Thingworx 9 – How to Plan / Evaluate Impacts This session highlights the key points you should evaluate to properly plan your upgrade to Thingworx 9. Recording Link Top 5 items to check for Thingworx Performance Troubleshooting How to troubleshoot performance issues in a Thingworx Environment? Here we cover the top 5 investigation steps that will help you understand the source of your environment issues and allow better communication with PTC Technical Support     Recording Link
View full tip
We will host a live Expert Session: "Thingworx Mashup 101 - Do's and Don'ts" on February 24th, 13h30 EST.   Please find below the description of the expert session and the registration link.   Expert Session: Thingworx Mashup 101 - Do's and Don'ts Date and Time: February 24th, 13h30 EST Duration: 1 hour Host: Aanjan Ravi - Technical Product Manager Registration Here: https://www.ptc.com/en/events/thingworx-mashup-101   Description: This session covers the most common and useful tips about how to correctly use Mashup builder, Widgets and Layouts – and what to avoid -  to create applications with good principles of UI/UX and easier to maintain.   Existing Recorded sessions can be found on support portal using the keyword ‘Expert Sessions’. You can also suggest topics for upcoming sessions using this small form.   Here are some recorded sessions that might be of your interest. You can find recordings for the full library of webinars using the keyword ‘Expert Sessions’ in PTC support portal search Thingworx Active Active Clustering This session will cover the main aspects of the High Availability Clustering feature launched with the ThingWorx 9.0 release.   Recoding Link Upgrade to Thingworx 9 – How to Plan / Evaluate Impacts This session highlights the key points you should evaluate to properly plan your upgrade to Thingworx 9. Recording Link Top 5 items to check for Thingworx Performance Troubleshooting How to troubleshoot performance issues in a Thingworx Environment? Here we cover the top 5 investigation steps that will help you understand the source of your environment issues and allow better communication with PTC Technical Support     Recording Link
View full tip
We will host a live Expert Session: "Thingworx Navigate 3D Viewer" on October 9th at 11:00 AM EST.   Please find below the description of the expert session and the registration link .   Expert Session: Thingworx Navigate 3D Viewer Date and Time: Friday, October 9th, 2020 11:00 am EST Duration: 1 hour Host: Robbie Morrison, Product Management Senior Manager   Description: Following the series of new capabilities released with Navigate 9.0, this session will focus in the details of Navigate 3D Viewer leverage this to your use cases   Register here   Existing Recorded sessions can be found on support portal using the keyword ‘Expert Sessions’.   You can also suggest topics for upcoming sessions using this small form.   Here are some recorded sessions that might be of your interest. You can find recordings for the full library of webinars using the keyword ‘Expert Sessions’ in PTC support portal search   Navigate 9.0 – What’s New? This session is the intro of a series that will cover new capabilities of the recent Navigate 9 release and the value that each can bring to your implementation. Then we will have further sessions covering the details of some of them   Recoding Link Top 5 items to check for Thingworx Performance Troubleshooting How to troubleshoot performance issues in a Thingworx Environment? Here we cover the top 5 investigation steps that will help you understand the source of your environment issues and allow better communication with PTC Technical Support     Recording Link Thingworx 9.0 Component Based App Development Following the series of new capabilities released with Navigate 9.0, this session will focus in the details of Navigate Component Based app development and how to leverage this to your use cases Recording Link
View full tip
We will host a live Expert Session: Thingworx Navigate Component Based App Development on Wednesday 09/30, 08:00 AM Eastern Daylight Time   Please find below the description of the expert session as well as the link to register .   Expert Session: Thingworx Navigate Component Based App Development Date and Time: Wednesday 09/30, 08:00 AM Eastern Daylight Time Duration: 1 hour Host: Pratibha Bhatnagar Description: Following the series of new capabilities released with Navigate 9.0, this session will focus in the details of Navigate Component Based app development and how to leverage this to your use cases.   Existing Recorded sessions can be found on support portal using the keyword ‘Expert Sessions’   You can also suggest topics for upcoming sessions using this small form
View full tip
Applicable Releases: ThingWorx Platform 7.0 to 8.4   Description:   A practical example of how to build a data model in ThingWorx following a pre-defined design Following topics are covered: Review existing Design Plan Build all required entities in ThingWorx Composer Test the model and review scalability and reusability         The session was recorded using the old ThingWorx Composer, but the concepts are still applicable Related Success Service - Principles of Thingworx Modeling Related Service - Design your Thingworx Model
View full tip
Hi Community,   Although we have reference architectures and integration paths for connecting devices to ThingWorx through Azure IoT; no one has ever written anything about doing the same from one ThingWorx to another.  I thought I’d change that and put some ideas out there around how one might go about doing this.  Although this is not officially supported or recommended by PTC; I have consulted with a number of leading SMEs on the subject, which have participated in forming the basis of my thinking outlined here.   Components Required (in order of communication path): On-premise ThingWorx Platform Protocol Adapter Toolkit* (CXS) - MQTT Azure IoT Edge Azure IoT Hub ThingWorx Azure IoT Hub Connector (CXS) Azure Cloud-hosted ThingWorx Platform   PAT (2) with codec to encode MQTT messages publishes to on-premise IoT Edge MQTT endpoint which handles store-and-forward of messages to IoT Hub.  An Azure IoT device would exist for each Thing you wish to represent on the ThingWorx servers.  The Azure IoT Hub Connector would pick-up the incoming messages and pass them on to the cloud ThingWorx which would decode the MQTT payload and map to Thing property updates.   The only part that I presently don’t like about this approach is that you’ll need to decode the MQTT messages on the ThingWorx platform in the cloud when they are received from the IoT Hub, and this mechanism will need to also need to handle encoding and publishing back to the IoT Hub if C2D (Cloud-to-Device) messages are to be implemented (aka bi-directional).  This is required as ThingWorx only supports AlwaysOn as an application level protocol so some form of mapping needs to be done.   * Another approach would be to replace the PAT with a custom agent which implements both the ThingWorx Edge SDK and the Azure IoT device SDK   Regards,   Greg Eva
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
Reminder (and for some, announcement!) that the new ThingWorx 8 sizing guide is available here  https://www.ptc.com/en/support/refdoc/ThingWorx_Platform/8.0/ThingWorx_Platform_8_x_Sizing_Guide
View full tip
This is a lessons learned write up that I proposed to present at Liveworx but it didn't make the cut, but I did want to share it with all the developer folks. Please note that this is before we added Influx and Micro Services, which help improve the landscape. Oh and it's long 🙂 ------------------------------------------ This is written as of Thingworx 8.2   Different ways to scale Data and Processing with Thingworx Two main issues are targeted Data Storage Platform processing Data Storage in Thingworx Background Issues around storage is that due to the limited indexing in the Persistence Provider with then the actual values according to the datashape being in a JSON Blob So when you look in the Persistence Provider you’ll see Source sourceType Location entityID Datetime Tags ValueJSONBlob   The first six carry an index, the JSON Blob which holds the values according to the datashape is not, that can read something like {value1:firstvalue,value2:secondvalue,value3:[ …. ]} etc. This means that any queries beyond the standard keys – date/time, entityID (name of Stream or DataTable), source, sourcetype, tags, location become very inefficient because it will query the records and then apply the datashape query server side. Potentially this can cause you to pull way more records over from Persistence Provider to Platform than intended. Ie: a Query on Temperature in my data, that should return 25 records for a given month, will perhaps first return 250K records and then filter own to 25. The second issue with storage is that all Streams are stored in one table in the Persistence Provider using entityID as an additional key to figure out which stream the record is for. This means that your record count per table goes up much faster than you’d expect. Ie: If I have defined 5 ValueStreams for 5 different asset types, ultimately all that data is still in one table in the Persistence Provder. So if each has 250K records, a query against the valuestream will then in actuality be a query against 1.25 million records. I think both of these issues are well known and documented? By now and Dev is working on it. Solution approaches So if you are expecting to store a lot of records what can you do? Archive The easiest solution is to keep a limited set and archive off the rest of the data, preferably into a client’s datalake that is not part of the persistence provider, remember archiving from one stream to another stream is not a solution! Unless … you use Multiple Persistence Providers Multiple Persistence Providers Thingworx does support multiple persistence providers for storing data. So you can spin up extra schemas (potentially even in the same DataBase Server) to be the store for additional Persistence Providers which then are mapped to a specific Stream/ValueStream/DataTable/Blog/Wiki. You still have to deal with the query challenge, but you now have less records per data store to query through. Direct queries in the Persistence Provider If you have full access to your persistence provider (NOTE: PTC Cloud Services does NOT provide this right now). You can create an additional JDBC connection to the Persistence Provider and query the stream directly, this allows you to query on the indexed records with in addition a text search through the JSON Blob all server side. With this approach a query that took several minutes at times Platform side using QueryStreamEntries took only a few seconds. Biggest savings was the fact that you didn’t have to transfer so many records back to the Platform server. Additional Schemas You can create your own schema (either within the persistence provider DB – again not supported by PTC Cloud Services) in a Database Server of your choice and connect to it with JDBC/REST. (NOTE: I believe PTC Cloud Service may/might offer a standalone server with actual root access) This does mean you have to create your own Getter/Setter services to retrieve and store information, plus you’ll need some event to store (like DataChange). This approach right now is probably a common if not best practice recommendation if historical information is required for the solution and the record count looks to go over 1 million records and can’t just be queried based on timestamp. Thingworx Event Processing Background Thingworx will consistently deal with many Things that have many Properties, and often times there will be Alerts/Rules that need to run based on value changes. When you are using straight up Alerts based on a limit value, this isn’t such a challenge, but what if you need to add some latch/lock/debounce logic or need to check against historical values or check multiple conditions? How can you design something that can handle evaluating these complex rules, holds some historical or derived values and avoid race conditions and be responsive? Potential Problems Race conditions Multiple Events may need to update the same Permanent or Temporary store for the determination of a condition. Duplicates If you don’t have some ‘central’ tracker, you may possibly trigger the same rule multiple times. Slow response You are potentially triggering thousands or more events at the same time, depending on how you’ve set up your logic, your response could become so slow that the next event will be firing before finish and you’ll overload the system. System queue overrun If your events trigger faster than you can handle the events, you will slowly build up and finally overrun the event queue. System Thread count overrun Based on the number of cores in your system, you can overrun the number of threads that can be handled. Connection Pool overrun Each read/write to a stream/datatable but also Property Persist is a usage of the connection pool to your persistence provider. If you fire a lot at once, you can stack up requests and cause deadlocks System out of memory Potentially in handling the events you are depending on in memory information, if that is something that grows over time, you could hit an ‘Out of Memory’ issue. Solution Approaches Batch processing Especially with Agents/Sources that write a set of property updates, you potentially trigger multiple threads that all may need the same source information or update the same target information. If you are able to process this as a batch, you can take all values in account and only process this as a single event and have just a single read from source or single write to target. This will be difficult to achieve when using something like Kepserver, unless it is transferring as something non-standard like MQTT. But if you can have the data come in as a single REST POST this approach becomes possible. In Memory vs. Table/Stream Storage To speed up response time, you can put necessary information into Memory vs. in a DataTable or Stream. For example, if you need the most current received record together with some historical values, you could: Use a Stream but carry the current value because the stream updates async. (ie adding the current value to the stream doesn’t guarantee that when you read from the stream it has already been committed) Use a DataTable because they are synchronous but it can make the execution slow, especially if you are reaching 100K records or more Use an InfoTable or JSON Property, now this information is in memory and runs the fastest and is synchronous. Note that in some speed testing JSON object was faster than InfoTable and way faster than DataTable. One challenge is that you would have to do a full overwrite if you need to persist this information. Doing a full write does open up the danger of a race condition, if this information is being updated by multiple threads at the same time. If it is ok to keep the information in memory than an InfoTable is nice because you can just add/delete rows in memory. I sadly haven’t figured out yet how to directly do this to a JSON object property :(. It is important to consider disaster recovery scenarios if you are only using this in memory Centralized Processing vs. Distributed Processing Think about how you can possibly execute some logic within the context of the Entity itself (logic within the ThingShape/ThingTemplate) vs. having it fire into a centralized Service (sync or async) on a separate Entity. Scheduler or Timer As much as Schedulers and Timers are often the culprit of too many threads at the same time, a well setup piece of logic that is triggered by a Scheduler or Timer can be the solution to avoid race conditions If you are working with multiple timers, you may want to consider multiple schedulers which will trigger at a specific time, which means you can eliminate concurrence (several timers firing at the same time) Think about staggering execution if necessary, by using the hated, looked down upon … but oft necessary … pause() function !!!! Synchronous vs. Asynchronous Asynchronous execution can give great savings on the processing speed of a thread, since it will kick off the asynch parts and continue on. The terrible draw back, you can’t tell when it is finished nor what the resulting output is. As you mix and match synch/asynch vs processing speed, you may need to consider other ways to pick up when an asynch process finishes, some Property elsewhere that will trigger into a DataChange for example. Interesting examples Batch Process With one client there was a batch process that would post several hundred results at once that all had to be evaluated. The evaluation also relied on historical information. So with some logic these properties were processed as a batch, related to each other and also compared to information held in memory besides historically storing the information that came in. This utilized several in memory objects and ultimately also an eval() statement to have the greatest flexibility and performance. Mix and Match With another client, they had a requirement to have logic to do latch/lock and escalation. This means that some information needs to be persisted, however because all the several hundred properties per asset are coming in through Kepware once a second, it also had to be very fast. The approach here was to have the DataChange place information into an in memory infotable that then was picked up by a separate latch/lock/escalation timer to move it over to the persistent side. This allowed for the instantaneous processing of DataChange and Alerts, but also a more persistent processing of latch/lock/escalation logic. In Conclusion Remember that PTC created its software for specific purposes. I don’t think there ever will be a perfect magical platform that will do everything we need and want. Thingworx started out on a specific path which was very high speed data ingest and event platform with agnostic all around connectivity, that provided a very nice holistic modeling approach and a simple way to build UI/UX. Our use cases will sometimes go right past everything and at times to the final frontier aka the bleeding edge and few are a carbon copy of another. This means we need to be innovative and creative. Hopefully all of you can use the expert knowledge you have about our products to create those, but then also be proactive and please share with everyone else!  
View full tip
Objective Use Influx as a database to store data coming from Kepware ThingWorx Industrial Connectivity server   Prerequisite Configure ThingWorx connection to Kepware’s KEPServerEX  and bind tags that exist in KEPServerEX to things in the ThingWorx model as referenced in Industrial Connections Example   Configuration Steps 1. Create database in Influx for ThingWorx: Connect:    influx -precision rfc3339 > SHOW DATABASES > CREATE DATABASE thingworx   2. Create Influx Persistence Provider     and configure   3. In the Industrial Thing where the Remote Properties are bounded define Value Stream     and make sure to have Persistence Provider set to Influx and is set to Active     4. In the Value Stream Properties and Alerts define the mappings using Manage Bindings to specify what properties are to be stored in this value stream     5. Save it and test it to make sure properties are stored in Influx: > use thingworx > show measurements   name   ----   Channel1.Device1 > show field keys on thingworx from "Channel1.Device1" > select Channel1_Device1_Tag2 from "Channel1.Device1"   name: Channel1.Device1   fieldKey fieldType   -------- ---------   Channel1_Device1_Tag10 integer   Channel1_Device1_Tag11 integer   Channel1_Device1_Tag12 integer   Channel1_Device1_Tag13 integer   Channel1_Device1_Tag14 integer   Channel1_Device1_Tag15 integer   Channel1_Device1_Tag16 integer   Channel1_Device1_Tag17 integer   Channel1_Device1_Tag18 integer   Channel1_Device1_Tag19 integer   Channel1_Device1_Tag2 integer   Channel1_Device1_Tag20 integer   Channel1_Device1_Tag21 integer   Channel1_Device1_Tag3 integer   Channel1_Device1_Tag4 integer   Channel1_Device1_Tag5 integer   Channel1_Device1_Tag6 integer   Channel1_Device1_Tag7 integer   Channel1_Device1_Tag8 integer   Channel1_Device1_Tag9 integer   shows data stored in Channel1_Device1_Tag2: >select Channel1_Device1_Tag2 from "Channel1.Device1"   2019-02-20T16:26:13.699Z 8043   2019-02-20T16:26:14.715Z 8044   2019-02-20T16:26:15.728Z 8045   2019-02-20T16:26:16.728Z 8046   2019-02-20T16:26:17.727Z 8047   2019-02-20T16:26:18.725Z 8048   2019-02-20T16:26:19.724Z 8049   2019-02-20T16:26:20.722Z 8050   2019-02-20T16:26:21.723Z 8051   2019-02-20T16:26:22.722Z 8052
View full tip