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

Community Tip - Stay updated on what is happening on the PTC Community by subscribing to PTC Community Announcements. X

IoT Tips

Sort by:
Data Model Implementation Guide Part 1   Overview   This project will introduce you to methods for creating the data model that you have designed and are ready to implement. Following the steps in this guide, you will implement the Data Model you've already designed. After having insight into your desired Data Model, this guide will provide instructions and examples on how to build out your application using the ThingWorx platform. We will teach you how to utilize the ThingWorx platform to implement your fully functional IoT application. NOTE: This guide’s content aligns with ThingWorx 9.3. The estimated time to complete ALL 3 parts of this guide is 60 minutes. All content is relevant but there are additional tools and design patterns you should be aware. Please go to this link for more details.     Step 1: Completed Example   Download the completed files for this tutorial:  DataModelEntities.xml. The DataModelEntities.xml file provided to you contains a completed example of the completed data model implementation. 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: Data Model Scenario   This guide will implement the scenario shown in the Data Model Design guide. Let's revisit our Smart Factory example scenario. Name Description Operations User to keep the line running and make sure that it’s producing quality products Maintenance User to keep machines up and running so that the operator can crank out products Management User in charge of dispatching production orders and making sure the quotas are being met Conveyor Belts Thing on factory line to pass items along to the next stage Pneumatic Gate Thing on factory line Robotic Arm Thing on factory line Quality Check Camera Final Thing on factory line to ensure quality In order to add this to our solution, we will want to build a "connector" between ThingWorx and the existing system. These connectors will be Things as well. Internal system connection Thing for Production Order System Internal system connection Thing for Maintenance Request System Operator   Required Functionality Description 1 File Maintenance Request 2 Get quality data from assets on their line 3 Get performance data for the whole line 4 Get a prioritized list of production orders for their line 5 Create Maintenance Requests   Required Information Description 1 Individual asset performance metrics 2 Full line performance metrics 3 Product quality readings   Maintenance   Required Functionality Description 1 Get granular data values from all assets 2 Get a list of maintenance requests 3 Update maintenance requests 4 Set triggers for automatic maintenance request generation 5 Automatically create maintenance requests when triggers have been activated   Required Information Description 1 Granular details for each asset: In order to better understand healthy asset behavior 2 Current alert status for each asset: to know if there is something going wrong with an asset 3 When the last maintenance was performed on an asset 4 When the next maintenance is scheduled for an asset 5 Maintenance request info: Creation date, due date, progress notes   Management   Required Functionality Description 1 Create production orders 2 Update production orders 3 Cancel Production orders 4 Access line productivity data 5 Elevate maintenance request priority   Required Information Description 1 Production line productivity levels (OEE) 2 List of open Maintenance requests   Overlapping Matrix   This matrix represents all of the overlapping Components that are shared by multiple types of Things in our system:   Unique Matrix   This matrix represents the unique Components to each type of Thing:     Step 3: LineAsset Thing Template   After prioritizing and grouping common functionality and information, we came up with the list below for the first Thing Template to create, LineAsset with five Properties, one Event, and one Subscription. The breakdown for the LineAsset Thing Template is as follows:   Follow the below instruction to create this Entity and get the implementation phase of your development cycle going.   Line Asset Properties   Let's build out our Properties. In the ThingWorx Composer, click the + New at the top of the screen. Select Thing Template in the dropdown.        3. In the name field, enter LineAsset and set the Project (ie, PTCDefaultProject). 4. For the Base Thing Template field, select GenericThing.     5. Click Save.  6. Switch to the Properties and Alerts tab.  7. Click the plus button to add a new Property.   The Properties for the LineAsset Thing Template are as follows: Name Base Type Aspects Data Change Type State String Persistent and Logged ALWAYS SerialNumber String Persistent, Read Only, and Logged NEVER LastMaintenance DATETIME Persistent and Logged VALUE NextMaintenance DATETIME Persistent and Logged VALUE PowerConsumption NUMBER, Min Value: 0 Persistent and Logged ALWAYS Follow the next steps for all the properties shown in our template property table. Click Add. Enter the name of the property (ie, State). Select the Base Type of the proprty from the dropdown. Check the checkboxes for the property Aspects. Select the Data Change Type from the dropdown.   Click Done when finished creating the property. Your properties should match the below configurations.     Line Asset Event   Switch to the Events tab. Click Add. Enter the name of the Event (ie, Error). Select AlertStatus as the Data Shape. This DataShape will allow us to provide simple information including an alert type, the property name, and a status message.   Click Done. Your Event should match the below configurations.          Line Asset Subscription   Switch to the Subscriptions tab. Click Add. Check the Enabled checkbox. Switch to the Inputs tab. Select the name of the Event (ie, Error). Click Done. Your Subscription should match the below configurations.             Challenge Yourself   We have left the Subscription code empty. Think of a way to handle Error Events coming from your line asset and implement it in this section.   Click here to view Part 2 of this guide. 
View full tip
In this post, I show how you can downsample time-series data on server side using the LTTB algorithm. The export comes with a service to setup sample data and a mashup which shows the data with weak to strong downsampling.   Motivation: Users displaying time series data on mashups and dashboards (usually by a service using a QueryPropertyHistory-flavor in the background) might request large amounts of data by selecting large date ranges to be visualized, or data being recorded in high resolution. The newer chart widgets in Thingworx can work much better with a higher number of data points to display. Some also provide their own downsampling so only the „necessary“ points are drawn (e.g. no need to paint beyond the screen‘s resolution). See discussion here. However, as this is done in the widgets, this means the data reduction happens on client site, so data is sent over the network only to be discarded. It would be beneficial to reduce the number of points delivered to the client beforehand. This would also improve the behavior of older widgets which don’t have support for downsampling. Many methods for downsampling are available. One option is partitioning the data and averaging out each partition, as described here. A disadvantage is that this creates and displays points which are not in the original data. This approach here uses Largest-Triangle-Three-Buckets (LTTB) for two reasons: resulting data points exist in the original data set and the algorithm preserves the shape of the original curve very well, i.e. outliers are displayed and not averaged out. It also seems computationally not too hard on the server. Setting it up: Import Entities from LTTB_Entities.xml Navigate to thing LTTB.TestThing in project LTTB, run service downsampleSetup to setup some sample data Open mashup LTTB.Sampling_MU: Initially, there are 8000 rows sent back. The chart widget decides how many of them are displayed. You can see the rowcount in the debug info. Using the button bar, you determine to how many points the result will be downsampled and sent to the client. Notice how the curve get rougher, but the shape is preserved. How it works: The potentially large result of QueryPropertyHistory is downsampled by running it through LTTB. The resulting Infotable is sent to the widget (see service LTTB.TestThing.getData). LTTB implementation itself is in service downsampleTimeseries     Debug mode allows you to see how much data is sent over the network, and how much the number decreases proportionally with the downsampling.   LTTB.TestThing.getData;   The export and the widget is done with TWX  9 but it's only the widget that really needs TWX 9. I guess the code would need some more error-checking for robustness, but it's a good starting point.  
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
Data Model Implementation Guide Part 3   Step 7: Unique Components Thing Templates   All of the shared component groups have been created. The next stage is creating the unique component group of ThingTemplates. Each of the below sections will cover one ThingTemplate, how the final property configuration should look, and any other aspects that should be added. The breakdown for the unique component group ThingTemplates is as follows:   Robotic Arm Properties   The properties for the RoboticArm ThingTemplate are as follows: Name Base Type Aspects Data Change Type TimeSincePickup NUMBER, Min Value: 0 Persistent and Logged ALWAYS Axis1 String Persistent and Logged VALUE Axis2 String Persistent and Logged VALUE Axis3 String Persistent and Logged VALUE ClampPressure NUMBER, Min Value: 0 Persistent and Logged ALWAYS ClampStatus String Persistent and Logged ALWAYS   Your properties should match the below configurations.   Pneumatic Gate Properties   The properties for the PneumaticGate ThingTemplate are as follows: Name Base Type Aspects Data Change Type GateStatus String Persistent and Logged ALWAYS   Your properties should match the below configurations.   Conveyor Belt Properties   The properties for the ConveyorBelt ThingTemplate are as follows: Name Base Type Aspects Data Change Type BeltSpeed INTEGER, Min Value: 0 Persistent and Logged ALWAYS BeltTemp INTEGER, Min Value: 0 Persistent and Logged ALWAYS BeltRPM INTEGER, Min Value: 0 Persistent and Logged ALWAYS   Your properties should match the below configurations.   Quality Control Camera   Properties   The properties for the QualityControlCamera ThingTemplate are as follows: Name Base Type Aspects Data Change Type QualityReading INTEGER, Min Value: 0 Persistent and Logged ALWAYS QualitySettings String Persistent and Logged ALWAYS CurrentImage IMAGE Persistent and Logged ALWAYS   Your properties should match the below configurations.   Event   Create a new Event named BadQuality. Select AlertStatus as the Data Shape. Your Event should match the below configurations:     Step 8: Data Tables and Data Shapes   For the Data Model we created, an individual DataTable would be best utilized for each products, production orders, and maintenance requests. Utilizing DataTables will allow us to store and track all of these items within our application. In order to have DataTables, we will need DataShapes to create the schema that each DataTable will follow. This database creation aspect can be considered a part of the Data Model design or a part of the Database Design. Nevertheless, the question of whether to create DataTables is based on the question of needed real time information or needed static information. Products, production orders, and maintenance requests can be considered static data. Tracking the location of a moving truck can be considered a need for real time data. This scenario calls for using DataTables, but a real time application will often have places where Streams and ValueStreams are utilized (DataShapes will also be needed for Streams and ValueStreams). NOTE: The DataShapes (schemas) shown below are for a simplified example. There are different ways you can create your database setup based on your own needs and wants. DataTable Name DataShape Purpose MaintenanceRequestDataTable MaintenanceRequest Store information about all maintenanced requests created ProductDataTable ProductDataShape Store information about the product line ProductionOrderDataTable ProductionOrderDataShape Store all information about production orders that have been placed   Maintenance Requests DataShape   The maintenance requests DataShape needs to be trackable (unique) and contain helpful information to complete the request. The DataShape fields are as follows: Name Base Type Additional Info Primary Key ID String NONE YES Title String NONE NO Request String NONE NO CompletionDate DATETIME NONE NO   Unless you’ve decided to change things around, your DataShape fields should match the below configurations.   Products DataShape   The product DataShape needs to be trackable (unique) and contain information about the product. The DataShape fields are as follows: Name Base Type Additional Info Primary Key ProductId String NONE YES Product String NONE NO Description String NONE NO Cost NUMBER Minimum: 0 NO   Unless you’ve decided to change things around, your DataShape fields should match the below configurations.   Production Order DataShape   The production order DataShape needs to be trackable (unique), contain information that would allow the operator and manager to know where it is in production, and information to help make decisions. The DataShape fields are as follows: Name Base Type Additional Info Primary Key OrderId String NONE YES Product InfoTable: DataShape: ProductDataShape NONE NO ProductionStage String NONE NO OrderDate DATETIME NONE NO DueDate DATETIME NONE NO   Unless you’ve decided to change things around, your DataShape fields should match the below configurations.     Step 9: SystemConnections Implementation   We have created the ThingTemplates and ThingShapes that will be utilized within our Data Model for creating instances (Things). Before we finish the build out of our Data Model, let's create the Services that will be necessary for the MaintenanceSystem and ProductionOrderSystem Things.    This guide will not cover the JavaScript and business logic aspect of creating an application. When complete with the below sections, see the Summary page for how to create that level of definition.       Maintenance System   This is the system managed by the maintenance user and geared towards their needs.   Properties   The properties for the MaintenanceSystem Thing are as follows:     Name Base Type Aspects Data Change Type  MaintEngineerCredentials  PASSWORD  Persistent  VALUE    Your properties should match the below configurations.         Services    The Services for the MaintenanceSystem Thing are as follows:    Service Name  Parameters  Output Base Type Purpose   GetAllMaintenanceRequests  NONE  InfoTable: MaintenanceRequest  Get all of the maintenance requests filed for the maintenance user.  GetFilteredMaintenanceRequests  String: TitleFilter  InfoTable: MaintenanceRequest  Get a filtered version of all maintenance requests filed for the maintenance user.  UpdateMaintenanceRequests  String: RequestTitle  NOTHING  Update a maintenance request already in the system.    Use the same method for creating Services that were provided in earlier sections. Your Services list should match the below configurations.     Production Order System   This is the system utilized by the operator and product manager users and geared towards their needs.   Services   The Services for the ProductionOrderSystem Thing are as follows:      Service Name  Parameters Output Base Type   AssignProductionOrders String: Operator, String: ProductOrder  NOTHING   CreateProductionOrders  String: OrderNumber, String: Product, DATETIME: DueDate  NOTHING  DeleteProductionOrders  String: ProductOrder  NOTHING  GetFilteredProductionOrders  String: ProductOrder  InfoTable: ProductionOrder  GetProductionLineList  NONE  InfoTable: ProductDataShape  GetUnfilteredProductionOrders  NONE  InfoTable: ProductionOrder  MarkSelfOperator  NONE  BOOLEAN  UpdateProductionOrdersOP  String: ProductOrder, String: UpdatedInformation  NOTHING  UpdateProductionOrdersPM  String: ProductOrder, String: UpdatedInformation  NOTHING   Use the same method for creating Services that were provided in earlier sections. Your Services list should match the below configurations.       Challenge Yourself     Complete the implementation of the Data Model shown below by creating the Thing instances of the ThingTemplates we have created. When finish, add more to the Data Model. Some ideas are below.         Ideas for what can be added to this Data Model: #  Idea  1 Add users and permissions   2  Add Mashups to view maintenance requests, products, and production orders  3  Add business logic to the Data Model   Step 10: Next Steps     Congratulations! You've successfully completed the Data Model Implementation Guide. This guide has given you the basic tools to: Create Things, Thing Templates, and Thing Shapes Add Events and Subscriptions   The next guide in the Design and Implement Data Models to Enable Predictive Analytics learning path is Create Custom Business Logic.  
View full tip
  Design Your Data Model Guide Part 3   Step 7: Prioritize     The first step in the design process is to use the Thing-Component Matrix to identify and prioritize groups of Components that are shared across multiple Things. These groups will be prioritized by number of shared Components, from highest to lowest, enabling is to break out the most commonly used groups of Components and package them into reusable pieces. Let’s examine our example Thing-Component Matrix to identify and prioritize groups. In the table below, we have done this and recognized that there are FOUR groups.   NOTE: Each item in our unique Thing-Component Matrix would also count as a group on its own. This can be dealt with almost separately from our process, though, because there is no overlap between different Things. The "Templates for Unique Components" and "Adding Components Directly to Things" sections in the Iterate step of this guide covers these "one-offs."     Step 8: Largest Group     The base building block we use most often is the Thing Template. To start the design process, the first step is to create a Thing Template for the largest Component group. Applying this to our Smart Factory scenario, we'll take the largest group ("Group 1") and turn it  into a Thing Template using the Entity Relationship Diagram schematic.   Since every item on our production line shares these Components, we will name this Thing Template Line Asset. Now, let's build this using our Entity Relationship Diagram.   The result is a ThingWorx Thing Template with five Properties, one Event, and one Subscription.     Step 9: Iterate     Once an initial base template has been created for the largest group, the rest of the groups can be added by selecting the appropriate entity type (Thing Template, Thing Shape, or directly-instantiated Thing). The following Entity Decision Flowchart explains which entity type is used in which scenario:   Now that we have established our "Line Asset" Thing Template for our largest group, the next step is to iterate through each of our remaining groups. Following the flowchart, we will identify what entity type it should be and add it to our design.   Group 2 - "System Connector"   The second group represents connectors into both of our internal business systems. We will call them System Connectors.   If we look at Group 2 versus our "Largest Group" Thing Template, we can see that there is no overlap between their Components. This represents the third branch of the Entity Decision Flowchart, which means we want to create a new Thing Template.   Following this rule, here is the resulting template:   Group 3 - "Hazardous Asset"   The third group represents line assets that require emergency shutdown capabilities because under certain conditions, the machinery can become dangerous. We will call these Hazardous Assets.   If we look at our two previous Thing Templates, we can see that there is full overlap of these Components with our previous largest group, the "Line Asset" Thing Template. This represents the fourth branch of the Entity Decision Flowchart, which means we want to create a CHILD Thing Template.   Following this rule, here is the resulting Thing Template:   Group 4 - "Inventory Manager"   The fourth group represents line assets that keep track of inventory count, to ensure the number of assembled-products is equal to the number of checked-products for quality.   If we look at our existing Thing Templates, we can see that there is some overlap of the Components in our "Hazardous Asset" and "Line Asset" Thing Templates. This represents the second branch of the Entity Decision Flowchart, which means we want to create a Thing Shape.   Following this rule, here is the resulting Thing Shape:   Templates for Unique Components   Now that we have handled all our shared component groups, we also want to look at the unique component groups. Since we have already established that each group in our Unique Thing-Component Matrix does not share its Components with other Things, we can create Child Thing Templates for these line assets.   NOTE: Refer to the finished design at the bottom to reference all of the inherited Thing Templates and Thing Shapes for these Child Thing Templates.   Adding Components Directly to Things   In many cases, we will have Components that only exist for a single Thing. This frequently occurs when there will be only one of something in a system. In our case, we will only need one "System Connector" for each of the Maintenance System and the Production Order System.   Instantiate Your Things   At this point, the Data Model is fully built. All we need to do now is instantiate the actual Things which represent our real-world machines and digital-connections.     Step 10: Validate     The final step of the model breakdown design process is validation through instantiation. This is the process by which we take our designed Thing Templates / Thing Shapes / Things and actually create them on the ThingWorx platform to ensure they meet all of our requirements. This is done by tracing back through the chain of inheritance for all the Things in the data model to ensure they contain all of the required Components from the Thing-Component Matrix. Once we have verified that each Thing contains all of its requirements, the data model is complete.   Using this technique on each of your Things, you can explicitly prove that all of the requirements have been met.   Step 11: Next Steps   Congratulations! You've successfully completed the Design Your Data Model Guide covering the first three steps of the proposed data model design strategy for ThingWorx. This guide has given you the basic tools to: Create user stories Identify endpoints in your system Break down your data model using an Entity Relationship Diagram Decide when to use Thing Templates vs. Thing Shapes vs. directly-instantiated Things     The next guide in the Design and Implement Data Models to Enable Predictive Analytics learning path is Data Model Implementation.
View full tip
  ThingWorx Dev Portal users,    As you may have heard in prior communication, the ThingWorx Dev Portal  Developer Portal | Developer Portal : ThingWorx is being retired.         All ThingWorx Dev Portal content will remain accessible until September 28, 2022. Your favorite and the most useful ThingWorx Dev Portal content will be copied into the PTC Community  in our IoT Tips board.  The Community Team is in the process of making changes to all our “Community Tips” boards.        Subscribe and watch for an official announcement on our Community Announcements board about the change. The Community Tips Board changes go into effect on September 1st.  You can preview the ThingWorx Developer Portal content being migrated here.   Please let us know if you have any questions. 
View full tip
Getting Started on the ThingWorx Platform Learning Path   Learn hands-on how ThingWorx simplifies the end-to-end process of implementing IoT solutions.   NOTE: Complete the following guides in sequential order. The estimated time to complete this learning path is 210 minutes.   Get Started with ThingWorx for IoT   Part 1 Part 2 Part 3 Part 4 Part 5 Data Model Introduction Configure Permissions Part 1 Part 2 Build a Predictive Analytics Model  Part 1 Part 2
View full tip
Basic Mashup Widgets Guide Part 1    Overview   This project will introduce how to use some basic Widgets in a Mashup. Following the steps in this guide, you will create a Mashup that reacts to user input using a Button, Toggle Button, and Slider Widget. We will also teach you how to display data to users with the Grid Advanced, Gauge, and Property Display widgets. NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL 3 parts of this guide is 60 minutes.    Step 1: Create Mashup   Build Mashup Click the Browse folder icon on the top left of ThingWorx Composer. Select Mashups in the left-hand navigation, then click + New to create a new Mashup.        3. For Mashup Type select Responsive. NOTE: A Responsive Mashup scales with a browser’s screen size. In the steps below we will create 5 containers, one for each widget, to organize how the widgets are presented.          4. Click OK. 5. Enter a name for your Mashup. 6. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. 7. Click Save. 8. Select the Design tab to display Mashup Builder. 9. Select the Layout tab in the upper panel of the left dock. 10. Click Add Bottom to split the Mashup canvas into two halves. 11. Click inside the bottom container to selected it, then click Add Left. 12. Click inside the bottom-right container to select it, then click Add Right. 13. Click inside the top container to select it, then click Add Right again. You should now have 5 containers in two rows, ready to have widgets added.   Step 2: Button   A button allows users to trigger an action, or stop and start long-running processes. Select the Widgets tab in the uppper panel of the left dock, then enter button inside the Filter field in the top-left. Drag-and-drop the Button widget onto the upper left container.        3. Click the drop-down arrow on the left side of the Button widget. 4. Click and drag the Clicked service shown in the drop-down onto a free area of the Mashup canvas.         5. When the Select Service pop-up appears, Click the ResetInputsToDefaultValues service that is provided by the Container. 6. Click Save. 7. Click View Mashup then click Show/Hide Debug Info. 8. Click the Trace tab and click Start Trace. 9. Click the button you created in your Mashup then click Stop Trace to see the log of the Clicked event triggering the ResetInputsToDefaultValues service.   Many properties are available that give control over how a Button widget will be displayed. Many properties can be changed both statically when designing the Mashup, and dynamically in response to changes in property values.   Bindable Name Type Default Direction Description ContextId String None Input/Output User-definable value that can be used by downstream triggered widgets Disabled Boolean False Input Widget is not usable and is displayed greyed-out if set to true Label String Button Input The text that appears on the button ToolTipField String None Input Text shown when user hovers over widget Visible Boolean True Input Widget is visible if set to true CustomClass String None Input/Output User-definable CSS class applied to top di of the button   Static Name Type Default Direction DisplayName String auto-generated Descriptor used for referring to widget in Composer and Mashup Builder Description String None Description used for widget in user-facing interactions TabSequence Number 0 Tab sequence index Height Number Autosize Height of button Width Number Autosize Width of button Z-index Number 10 Controls widget placement on top or below other widgets   Widget Events Name Description Clicked Fired when user clicks button   Click here to view Part 2 of this guide. 
View full tip
  Basic Mashup Widgets Guide Part 2    Step 3: Slider   A Slider allows your application users to interactively select a numeric value. When the user changes the position of the slider bar, an event is fired and the value property is changed. On the New Mashup tab, enter slider inside the Filter field in the top left. Drag-and-drop the Slider widget onto the top-right Container of your Mashup. 3. In the lower panel of the left dock, scroll to the Maximum property and change the value to 1000. 4. Change the Value property to 500 set the default position of the slider.   Add Value Display To demonstrate the Slider functionality we will add a Value Display Widget within the same Container of your Mashup as the Slider and bind the slider widget output to the input of the Value Display.         1. In the Filter field where you entered slider, enter value.        2. Drag-and-drop a Value Display widget onto the same upper-right Container as the Slider widget. 3. Click the drop-down arrow on the left side of the Slider widget. 4. Click and drag the Value property listed in the Slider drop-down onto the Value Display widget. 5. Click the Data property that is available from the Select Binding Target pop-up. 6. Click Save to save your Mashup. 7. Click View Mashup then adjust the slider to see the changing value shown in the Value Display widget.             Many properties are available that give control over how a Slider widget will be displayed. Properties can be changed both statically when designing the Mashup, and dynamically in response to changes in property values.   Bindable Name Type Default Direction Description Value Number 0 Input/Output Value defined by position of Slider that can be used by downstream widgets or services Minimum Number 0 Input/Output Value for left-most position of Slider, bottom-most position of Vertical Slider Maximum Number 100 Input/Output Value for right-most position of slider, top-most position of Vertical Slider HandleSize Number 34 Input Size in pixels of the slider handle Visible Boolean True Input Widget is visible if set to true StepSize Number 1 Input Smallest change in value when slider is moved   Static Name Type Default Direction DisplayName String None Name used for widget in user-facing interactions Description String None Description used for widget in user-facing interactions HandleIcon None/Circle/Split Circle Slider handle style SliderBar Thick/Thin Thick Slider bar style SteppingMode Boolean False When True, moves the slider by Step amount toward the click on the Slider bar TrackingMode Boolean False When True, the slider generates events as it changes value. Use with caution, this mode generates many events rapidly. DisplayMinMaxLabels Boolean True When enabled, displays the minimum and maximum values of the slider DisplayValueLabel Boolean True When enabled, displays the value of the slider   Widget Events Name Description ValueChanged Fired when Slider Value changes   Widget Services Name Description Increment Increase value of Slider by Step amount Decrement Decrease value of Slider by Step amount     Step 4: Toggle Button   A Toggle Button widget is used when a Mashup user may select only one choice from two options. On the Widgets tab in the top-left, enter button in the Filter field. Drag-and-drop the Toggle Button widget onto the lower left container of the mashup.   Scroll to the State property in the lower panel of the left dock where Toggle Button widget properties are shown. Click the check box to set the default state to true.   Add Value Display To demonstrate the toggle Button, we will add a Value Display Widget to the same Mashup container and bind the toggle Button State property to be shown by the Value Display. Drag-and-drop a Value Display Widget onto the same lower left container of the Mashup where the Toggle Button was placed. Click the drop-down arrow on the left side of the Toggle Button Widget. Click and drag the State property listed in the drop-down onto the Value Display Widget and a Select Binding Target pop-up will appear.  Click the Data property that is available from the Value Display Widget. Click Save to save your Mashup so it can be tested. Click View Mashup then click the Toggle Button to see the value of the button shown in the Value Display Widget.   Other properties are available to provide control over how a Toggle Button Widget will be displayed. Properties can be changed both statically when designing the Mashup, and dynamically in response to changes in property values.   Bindable Name Type Default Direction Description State boolean false Input/Output Value of toggle, can be used by downstream Widgets or Services Label String None Input Text that is displayed next to toggle button Visible Boolean True Input Widget is visible if set to true   Static Name Type Default Description DisplayName String auto-generated Name used to identify Widget in Mashup Builder Description String None Description used for Widget in user-facing interactions Height number autosize Sets the height of the widget in pixels LabelAlignment Left/Right Left Where label is shown relative to toggle button   Widget Events Name Description StateChanged Fired when user clicks the button   Click here to view Part 3 of this guide.
View full tip
Data Model Introduction    Overview   This project will introduce the ThingWorx Foundation Data Model. Following the steps in this guide, you will consider data interactions based on user needs and requirements, as well as application modularity, reusability, and future updates. We will teach you how to think about a properly constructed foundation that will allow your application to be scalable, flexible, and more secure. NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes.    Step 1: Benefits   A Data Model creates a uniform representation of all items that interact with one another. There are multiple benefits to such an approach, and the ability to break up items and reuse components is considered a best practice. ThingWorx has adopted this model at a high level to represent individual components of an IoT solution. Feature Benefit Flexibility Once a model has been created, it is simple to update, modify, or remove components without needing to rework the system or retest existing components. Scalability It’s easy to clone and modify devices that are either identical or similar when changing from a Proof of Concept or Pilot Program to a Scaled Business Model. Interoperability Seamlessly plug into other applications. Collaboration A Data Model allows pre-defined links between components, meaning that various parts can be defined when designing the model so that multiple people can work on those individual parts without compromising the interoperability of the components. Seamless platform A Data Model allows for seamless integration with other systems. A properly-formed model will make it easier to create high-value IoT capabilities such as analytics, augmented/virtual reality, industrial connectivity, etc.   Step 2: Entities   Entities   Building an IoT solution in Foundation begins with defining your Data Model, the collection of Entities that represent your connected devices, business processes, and your application. Entities are the highest-level objects created and maintained in Foundation, as explained below.     Thing Shape   Thing Shapes provide a set of characteristics represented as Properties, Services, Events, and Subscriptions that are shared across a group of physical assets. A Thing Shape is best used for composition to describe relationships between objects in your model. They promote reuse of contained Properties and business logic that can be inherited by one or more Thing Templates. In Foundation, the model allows a Thing Template to implement one or more Thing Shapes, which is similar to a class definition in C++ that has multiple inheritance. When you make a change to the Thing Shape, the change is propagated to the Thing Templates and Things that implement that Thing Shape; so, maintaining the model is quick and easy.   Thing Template   Thing Templates provide base functionality with Properties, Services, Events, and Subscriptions that Thing instances use in their execution. Every Thing is created from a Thing Template. A Thing Template can extend another Thing Template. When you release a new version of a product, you simply add the additional characteristics of the version without having to redefine the entire model. This model configuration provides multiple levels of generalization of an asset. A Thing Template can derive one or more additional characteristics by implementing Thing Shapes. When you make a change to the Thing Template, the change is propagated to the Things that implement that Thing Template; so again, maintaining the model is quick and easy. A Thing Template can be used to classify the kind of a Thing or asset class or as a specific product model with unique capabilities. If you have two product models and their interaction with the solution is the same (same Properties, Services, and Events), you could model them as one Thing Template. Classifying Thing Templates is useful for aggregating Things into collections, which are useful in Mashups. You may want separate Thing Templates for indexing, searching, and future evolutions of the products   Thing   Things are representations of physical devices, assets, products, systems, people, or processes that have Properties and business logic. All Things are based on Thing Templates (inheritance) and can implement one or more Thing Shapes (composition). A Thing can have its own Properties, Services, Events, and Subscriptions and can inherit other Properties, Services, Events, and Subscriptions from its Thing Template and Thing Shape(s). How you model the interconnected Things, Thing Templates, and Thing Shapes is key to making your solution easy to develop and maintain in the future as the physical assets change. End users will interface with Things for information in applications and for reading/writing data.   Best Practice: Create a Thing Template to describe a Thing, then create an instance of that Thing Template as a Thing. This practice leverages inheritance in your model and reduces the amount of time you spend maintaining and updating your model.   Step 3: Inheritance Model   Defining Things, Thing Templates, and Thing Shapes in your Data Model allows your application to handle both simple and complex scenarios. Entity Function Thing Shapes Assemble individual components. Thing Templates Combine those components into fully functional objects. Thing Unique representation of a set of identical components defined by the Thing Template.       In this example, there is a Parent/Child model between two related Thing Templates. NOTE: Things and Thing Templates may only inherit ONE Thing Template. Both Things and Thing Templates may inherit any number of Thing Shapes. Thing Templates employ a linear-relationship, while Thing Shapes employ a modular-relationship. Any Thing or Thing Template may have any number of sub-components (i.e. Thing Shapes), but each Thing or Thing Template is just one description of one object as a whole. How you decide to compartmentalize your Data Model into Thing Shapes and Thing Templates to create the actual Things that you’ll be using is a custom design that will be specific to each implementation.   Step 4: Scenario   The ThingWorx Data Model provides a way for you to describe your connected devices and match the complexity of a real-world scenario. Things, Thing Templates, and Thing Shapes are building blocks that define your data model.     You can define the components of Things, Thing Templates, and Thing Shapes, including Properties, Services, Events, and Subscriptions. Component Definition Properties Each Property has a name, description, and a data type (Base Type). Depending on the base type, additional fields may be enabled. A simple scalar type, like a number or string, adds basic fields like default value. More complex base types have more options. Properties can be static (i.e. Model Number) or dynamic (i.e. Temperature). Services A Service is a method/function defined by a block of code that performs logic specifying actions a Thing can take. There are several implementation methods, or handlers (for example: Script, SQLQuery, and SQL command), for services depending on the template you use. The specific implementation of a user-defined Service is done via a server-side script. The Service can then be invoked through a URL, a REST client capable application, or by another Service in ThingWorx. When you create a new service, you can define input properties and an output. You can define individual runtime permissions for each Service. Events Events are triggers that define changes of state (example: device is on, temperature is above/below threshold) of an asset or system and often require an action to correct or respond to a change. Business logic and actions in a ThingWorx application are driven by Events. Subscriptions Action associated with an Event, primary method to set up intelligence in ThingWorx model which enable you to optimize/automate. Subscriptions use Javascript code to define what you want your application to do when the Event occurs.   NOTE: Anything inherited by a Thing Template or Thing will inherit the associated Components.     This diagram shows what a specific Inheritance Model might look like for a connected Tractor. There is one master Template at the top. In this case, it’s a collection of similar types of tractors. The parent Template inherits a few Shapes - an Engine and a Deck that have been used in previous designs. Importing them as Shapes allows us to reuse previous design work and expedite the development process. One of the child Templates incorporates another Shape, this time in the form of a GPS tracking device. Then, at the bottom, there are the specific tractors with individual serial numbers that will report their connected data back to an IoT Application.   Step 5: Next Steps   Congratulations! You've successfully completed the Data Model Introduction, and learned about: The function of a data model for your IoT application Data model components, including Thing, Thing, Shape and Thing Template How ThingWorx components correspond to connected devices Please comment on this post so we can improve this guide in future ThingWorx version iterations.   This guide is part of 2 learning paths: The next guide in the Getting Started on the ThingWorx Platform learning path is Configure Permissions.  The next guide in the Design and Implement Data Models to Enable Predictive Analytics learning path is Design Your Data Model.      
View full tip
Design Your Data Model Guide Part 1   Overview   This project will introduce the process of taking your IoT solution from concept to design. Following the steps in this guide, you will create a solution that doesn’t need to be constantly revamped, by creating a comprehensive Data Model before starting to build and test your solution. We will teach you how to utilize a few proposed best practices for designing the ThingWorx Data Model and provide some prescriptive methods to help you generate a high-quality framework that meets your business needs. NOTE: This guide’s content aligns with ThingWorx 9.3. The estimated time to complete ALL 3 parts of this guide is 60 minutes. All content is relevant but there are additional tools and design patterns you should be aware of. Please go to this link for more details.    Step 1: Data Model Methodology   We will start by outlining the overall process for the proposed Data Model Methodology.       Step Description 1 User Stories Identify who will use the application and what information they need. By approaching the design from a User perspective, you should be able to identify what elements are necessary for your system. 2 Data Sources Identify the real-world objects or systems which you are trying to model. To create a solid design, you need to identify what the “things” are in your system and what data or functionality they expose. 3 Model Breakdown Compose a representative model of modular components to enable uniformity and reuse of functionality wherever possible. Break down user requirements and data, identifying how the system will be modeled in Foundation. 4 Data Strategy Identify the sources of data, then evaluate how many different types of data you will have, what they are, and how your data should be stored. From that, you may determine the data types and data storage requirements. 5 Business Logic Strategy Examine the functional needs, and map them to your design for proper business logic implementation. Determine the business logic as a strategic flow of data, and make sure everything in your design fits together in logical chunks. 6 User Access Strategy Identify each user's access and permission levels for your application. Before you start building anything, it is important to understand the strategy behind user access. Who can see or do what? And why? NOTE: Due to the length of this subject, the ThingWorx Data Model Methodology has been divided into multiple parts. This guide focuses on the first three steps = User Stories, Data Sources, and Model Breakdown. Guides covering the last three steps are linked in the final Next Steps page.    Step 2: User Stories     With a user-based approach to design, you identify requirements for users at the outset of the process. This increases the likelihood of user satisfaction with the result. Utilizing this methodology, you consider each type of user that will be accessing your application and determine their requirements according to each of the following two categories: Category Requirement Details Functionality Determine what the user needs to do. This will define what kind of Services and Subscriptions will need to be in the system and which data elements and Properties must be gathered from the connected Things. Information What information do they need? Examine the functional requirements of the user to identify which pieces of information the users need to know in order to accomplish their responsibilities.   Factory Example   Let’s revisit our Smart Factory example scenario. The first step of the User Story phase of the design process is to identify the potential users of your system. In this example scenario, we have defined three different types of users for our solution: Maintenance Operations Management Each of these users will have a different role in the system. Therefore, they will have different functional and informational needs.   Maintenance   It is the maintenance engineer’s job to keep machines up and running so that the operator can assemble and deliver products. To do this well, they need access to granular data for the machine’s operating status to better understand healthy operation and identify causes of failure. They also need to integrate their maintenance request management system to consolidate their efforts and to create triggers for automatic maintenance requests generated by the connected machines. Required Functionality Get granular data values from all assets Get a list of maintenance requests Update maintenance requests Set triggers for automatic maintenance request generation Automatically create maintenance requests when triggers have been activated Required Information Granular details for each asset to better understand healthy asset behavior Current alert status for each asset When the last maintenance was performed on an asset When the next maintenance is scheduled for an asset Maintenance request for information, including creation date, due date, progress notes   Operations   The operator’s job is to keep the line running and make sure that it’s producing quality products. To do this, operators must keep track of how well their line is running (both in terms of speed and quality). They also need to be able to file maintenance requests when they have issues with the assets on their line. Required Functionality File maintenance request Get quality data from assets on their line Get performance data for the whole line Get a prioritized list of production orders for their line Create maintenance requests Required Information Individual asset performance metrics Full line performance metrics Product quality readings   Management   The production manager oversees the dispatch of production orders and ensures quotas are being met. Managers care about the productivity of all lines and the status of maintenance requests. Required Functional Create production orders Update production orders Cancel production orders Access line productivity data Elevate maintenance request priority Required Information Production line productivity levels (OEE) List of open maintenance requests   Step 3: Data Sources – Thing List     Thing List   Once you have identified the users' requirements, you'll need to determine what parts of your system must be connected. These will be the Things in your solution. Keep in mind that a Thing can represent many different types of connected endpoints. Here are some examples of possible Things in your system: Devices deployed in the field with direct connectivity or gateway-connectivity to Foundation Devices deployed in the field through third-party device clouds Remote databases Connections to external business systems (e.g., Salesforce.com, Weather.com, etc.)   Factory Example   In our Smart Factory example, we have already identified the users of the system and listed requirements for each of those users. The next step is to identify the Things in our solution. In our example, we are running a factory floor with multiple identical production lines. Each of these lines has multiple different devices associated with it. Let’s consider each of those items to be a connected Thing. Things in each line: Conveyor belt x 2 Pneumatic gate Robotic Arm Quality Check Camera Let's also assume we already have both a Maintenance Request System and a Production Order System that are in use today. To add this to our solution, we want to build a connector between Foundation and the existing system. These connectors will be Things as well. Internal system connection Thing for Production Order System Internal system connection Thing for Maintenance Request System NOTE: It is entirely possible to have scenarios in which you want to examine more granular-level details of your assets. For example, the arm and the hand of the assembly robot could be represented separately. There are endless possibilities, but for simplicity's sake, we will keep the list shorter and more high-level. Keep in mind that you can be as detailed as needed for this and future iterations of your solution. However, being too granular could potentially create unnecessary complexity and data overload.    Click here to view Part 2 of this guide.
View full tip
Design Your Data Model Guide Part 2   Step 4: Data Sources – Component Breakout   Component Breakout     Once you have a full list of Things in your system (as well as requirements for each user), the next step is to identify the information needed from each Thing (based on the user's requirements). This involves evaluating the available data and functionality for each Thing. You then align the data and functionality with the user's requirements to determine exactly what you need, while eliminating that which you do not. This is important, as there can be cost and security benefits to only collecting data you need, and leaving what you don't. NOTE: Remember from the Data Model Introduction that a Thing's Components include Properties, Services, Events, and Subscriptions.   Factory Example   Using the Smart Factory example, let’s go through the different Things and break down each Thing's components that are needed for each of our users.   Conveyor Belts   The conveyor belt is simple in operation but could potentially have a lot of available data. Maintenance Engineer - needs to know granular data for the belt and if it has any alerts emergency shutdown (service) machine state (on/off) (property) serial number (property) last maintenance date (property) next scheduled maintenance date(property) power consumption (property) belt speed (property) belt motor temp (property) belt motor rpm (property) error notification (event) auto-generated maintenance requests (subscription) Operator - needs to know if the belt is working as intended belt speed (property) alert status (event) Production Manager - wants access to the data the Operator can see but otherwise has no new requirements   Robotic Arm   The robotic arm has 3 axes of rotation as well as a clamp hand. Maintenance Engineer - needs to know granular data for the arm and if it has any alerts time since last pickup (property): how long it has been since the last part was picked up by this hand? product count (property): how many products the hand has completed emergency shutdown (service) machine state (on/off) (property) serial number (property) last maintenance date (property) next scheduled maintenance date (property) power consumption (property) arm rotation axis 1 (property) arm rotation axis 2 (property) arm rotation axis 3 (property) clamp pressure (property) clamp status (open/closed) (property) error notification (event) 15.auto-generated maintenance requests (subscription) Operator - needs to know if the robotic arm is working as intended clamp status (open/closed) (property) error notification (event) product count (property): How many products has the hand completed? Production Manager - wants access to the data the Operator can see but otherwise has no new requirements   Pneumatic Gate   The pneumatic gate has two states, open and closed. Maintenance Engineer - needs to know granular data for the gate and if it has any alerts emergency shutdown (service) machine state (on/off) (property) serial number (property) last maintenance date (property) next scheduled maintenance date (property) power consumption (property) gate status (open/closed) (property) error notification (event) auto-generated maintenance requests (subscription) Operator - needs to know if the pneumatic gate is working as intended. gate status (open/closed) (property) error notification (event) The Production Manager wants access to the data the Operator can see but otherwise has no new requirements   Quality Control Camera   The QC camera uses visual checks to make sure a product has been constructed properly. Maintenance Engineer - needs to know granular data for the camera and if it has any alerts machine state (property): on/off serial number (property) last maintenance date (property) next scheduled maintenance date (property) power consumption (property) current product quality reading (property) images being read (property) settings for production quality assessment (property) error notification (event) auto-generated maintenance requests (subscription) product count (property): how many products the camera has seen Operator - needs to keep track of the quality check results and if there are any problems with the camera setup settings for production quality assessment (property) error notification (event) bad quality flag (event) product count (property): how many products the camera has seen Production Manager - wants access to the data the Operator can see but otherwise has no new requirements   Maintenance Request System Connector   Determining the data needed from the Maintenance Request System is more complex than from the physical components, as it will be much more actively used by all of our users. It is important to note that the required functionality already exists in our system as is, but it needs bridges created to connect it to a centralized system. Maintenance Engineer - needs to receive and update maintenance requests maintenance engineer credentials (property): authentication with the maintenance system endpoint configuration for connecting to the system (property) get unfiltered list of maintenance requests (service) update description of maintenance request (service) close maintenance request (service) Operator - needs to create and track maintenance requests operator credentials (property): authentication with the maintenance system endpoint configuration for connecting to the system (property) create maintenance request (service) get filtered list of maintenance requests for this operator (service) Production Manager - needs to monitor the entire system - both the creation and tracking of maintenance requests; needs to prioritize maintenance requests to keep operations flowing smoothly production manager credentials (property): authentication with the maintenance system endpoint configuration for connecting to the system (property) create maintenance request (service) get unfiltered list of maintenance requests (service) update priority of maintenance request (service)   Production Order System Connector   Working with the Production Order System is also more complex than the physical components of the lines, as it will be more actively used by two of the three users. It is important to note that the required functionality already exists in our existing production order system as is, but it needs bridges created to connect to a centralized system. Maintenance Engineer - will not need to know anything about production orders, as it is outside the scope of their job needs Operator - needs to know which production orders have been set up for the line, and needs to mark orders as started or completed operator credentials (property): authentication with the production order system endpoint configuration for connecting to the system (property) mark themselves as working a specific production line (service) get a list of filtered production orders for their line (service) update production orders as started/completed (service) Production Manager - needs to view the status of all production orders and who is working on which line production manager credentials (property): authentication with the production order system endpoint configuration for connecting to the system (property) get a list of production lines with who is working them (service) get the list of production orders with filtering options (service) create new production orders (service) update existing production orders for quantity, and priority (service) assign a production order to a production line (service) delete production orders (service)   Step 5: Data Sources – Thing-Component Matrix     Now that you have identified the Components necessary to build your solution (as well as the Things involved in enabling said Components), you are almost ready to create your Data Model design. Before moving onto the design, however, it is very helpful to get a good picture of how these Components interact with different parts of your solution. To do that, we recommend using a Thing-Component Matrix. A Thing-Component Matrix is a grid in which you will list Things in rows and Components in columns. This allows you to identify where there are overlaps between Components. From there, you can break those Components down into reusable Groups. Really, all you're doing in this step is taking the list of individual Things and their corresponding Components and organizing them. Instead of thinking of each item's individually-required functionality, you are now thinking of how those Components might interact and/or be reused across multiple Things.   Sample Thing-Component Matrix   As a generic example, look at the chart presented here.   You have a series of Things down the rows, while there are a series of Components (i.e. Properties, Services, Events, and Subscriptions) in the columns. This allows you to logically visually identify how some of those Components are common across multiple Things (which is very important in determining our recommendations for when to use Thing Templates vs. Thing Shapes vs. directly-instantiated Things). If we were to apply this idea to our Smart Factory example, we would create two sections of our Thing-Component Matrix, i.e. the Overlapping versus Unique Components. NOTE: It is not necessary to divide your Thing Component Matrix between Overlapping vs Unique if you don't wish to do so. It is done here largely for the sake of readability.   Overlapping Matrix   This matrix represents all the overlapping Components that are shared by multiple types of Things in our system:   Unique Matrix   This matrix represents the Components unique to each type of Thing:     Step 6: Model Breakdown         Breaking down your use case into a Data Model is the most important part of the design process for ThingWorx. It creates the basis for which every other aspect of your solution is overlaid. To do it effectively, we will use a multi-step approach. This will allow us to identify parts we can group and separate, leading to a more modular design.   Entity Relationship Diagram   To standardize the represention of Data Models, it is important to have a unified view of what a representation might look like. For this example, we have developed an Entity Relationship Diagram schematic used for Data Model representation. We will use this representation to examine how to build a Data Model.   Breakdown Process   ThingWorx recommends following an orderly system when building the specifics of your Data Model. You've examined your users and their needs. You've determined the real-world objects and systems you want to model. You've broken down those real-world items by their Component functionality. Now, you will follow these steps to build a specific Data Model for your application. Step Description 1 Prioritize the Groups of Components from your Thing-Component Matrix by each Group's Component quantity. 2 Create a base Thing Template for the largest group. 3 Iterate over each Group deciding which entity type to create. 4 Validate the design through instantiation. In the next several pages, we'll examine each of these steps in-depth.   Click here to view Part 3 of this guide.   
View full tip
Data Model Implementation Guide Part 2   Step 4: SystemConnector Thing Template   After grouping our second set of common functionality and information, we came up with the list below for the second Thing Template to create, SystemConnector with 3 Properties. The breakdown for the SystemConnector Thing Template is as follows:   Follow the below instruction to create this Entity and get the implementation phase of your development cycle going.   System Connector Properties   Let's jump right in. In the ThingWorx Composer, click the + New at the top of the screen.        2. Select Thing Template in the dropdown. 3. In the name field, enter SystemConnector and select a Project (ie, PTCDefaultProject). 4. For the Base Thing Template field, select GenericThing. 5. Click Save. 6. Switch to the Properties and Alerts tab. 7. Click the plus button to add a new Property.   The Properties for the SystemConnector Thing Template are as follows: Name Base Type Aspects Data Change Type EndPointConfig String Persistent and Logged VALUE OperatorCredentials PASSWORD Persistent VALUE ProdManagerCredentials PASSWORD Persistent VALUE Follow the next steps for all the Properties shown in our template property table. Click Add. Enter the name of the property (ie, EndPointConfig). Select the Base Type of the proprty from the dropdown. Check the checkboxes for the property Aspects. Select the Data Change Type from the dropdown.   Click Done when finished creating the property. Your Properties should match the below configurations.            Step 5: HazardousAsset Thing Template     After another round of prioritizing and grouping common functionality and information, we came up with the third Thing Template to create, HazardousAsset. It is a child of the LineAsset Thing Template with one added Service. The breakdown for the HazardousAsset Thing Template is as follows:   Hazardous Asset Service   In the ThingWorx Composer, click the + New at the top of the screen. 2. Select Thing Template in the dropdown. 3. For the Base Thing Template field, select LineAsset and select a Project (PTCDefaultProject). 4. In the name field, enter HazardousAsset. 5.  Click Save then edit to store all changes now. 6.  Switch to the Services tab. 7.  Click Add. 8.  Enter EmergencyShutdown as the name of the service. 9. Switch to the Me/Entities tab. 10. Expand Properties. 11. Click the arrow next to the State property. 12. Modify the generated code to match the following:       me.State = "Danger!! Emergency Shutdown";       Your first Service is complete! 13. Click Done. 14. Click Save to save your changes. Your Service should match the below configurations.     Step 6: InventoryManager Thing Shape   This time around, we will create our first ThingShape, InventoryManager with 1 Property. The breakdown for the InventoryManager Thing Shape is as follows:   Follow the below instruction to create this Entity and get the implementation phase of your development cycle going. System Connector Properties The properties for the InventoryManager Thing Shape are as follows: Name Base Type Aspects Data Change Type ProductCount INTEGER Min Value:0 Persistent and Logged ALWAYS In the ThingWorx Composer, click the + New at the top of the screen. Select Thing Shape in the dropdown. In the name field, enter InventoryManager and select a Project (ie, PTCDefaultProject).       4. Click Save then Edit to store all changes now.         5. Switch to the Properties tab.        6. Click Add.       7. Enter ProductCount as the name of the property.       8. Select the Base Type of the proprty from the dropdown (ie, INTEGER).       9. Check the checkboxes for the property Aspects.      10. Select the Data Change Type from the dropdown.            11. Click Done when finished creating the property. Your Properties should match the below configurations.   Add Thing Shape to Template   We can see that there is some overlap in the components of our HazardousAsset and LineAsset ThingTemplates. In particular, both want information about the product count. Because HazardousAsset inherits from LineAsset, would only need to change LineAsset. Follow the steps below to perform this change: Open the LineAsset Thing Template. In the Implemented Shapes field, enter and select InventoryManager. Save changes.         Click here to view Part 3 of this guide.   
View full tip
  How to Display Data in Charts Guide Part 2   Step 4: Create Thing   In order for the Mashup to pull data into the display, you first need to create an Entity. In this example, we utilize a Thing with an Info Table Property, as well as a Time Series Property. We’ll use the DataShape we created in the last step to format the Info Table Property. Then, we'll assign the Info Table Property some default values to display in our non-time-series charts.We will change the values of the Time Series Property (which will record them to the Value Stream) for display in our time-series charts.   Info Table Property   From the Browse tab of ThingWorx Composer, click Modeling > Things, + New.   In the Name field, enter DDCThing. If Project is not set, search for and select PTCDefaultProject. In the Base Thing Template field, search for and select GenericThing. In the Value Stream field, search for and select DDCValueStream.   At the top, click Properties and Alerts.   Click + Add. In the Name field, enter InfoTableProperty. Select INFOTABLE from the Base Type drop-down. In the Data Shape field, search for and select DDCDataShape. Check the Persistent checkbox.   First Default Value   Check the box for Has Default Value. A new DDCDataShape button will appear under Has Default Value. 2. Click the new DDCDataShape button under Has Default Value. 3. Click + Add. 4. Enter the following values for each field: Field Value PrimaryKey 1 Label A - 25% Value 25 XAxis 1 Data 5 ASensor 5 BSensor 3 CSensor 1 XValue 1 YValue 5 BubbleValue 7     3. At the bottom-right of the pop-up, click the green Add button to apply the first Default Values.   Second Default Value   Click + Add. Enter the following values for each field: Field Value PrimaryKey 2 Label B - 35% Value 35 XAxis 2 Data 10 ASensor 10 BSensor 6 CSensor 2 XValue 2 YValue 10 BubbleValue 9   3. At the bottom-right of the pop-up, click the green Add button to apply the second Default Values.   Third Default Value   Click + Add. Enter the following values for each field: Field Value PrimaryKey 3 Label C - 40% Value 40 XAxis 3 Data 20 ASensor 15 BSensor 9 CSensor 3 XValue 3 YValue 20 BubbleValue 14     3. At the bottom-right of the pop-up, click the green Add button to apply the third Default Values. 4. At the bottom-right of the pop-up, click the green Save button to close the pop-up.   Time Series Property   At the top-right, click the "Check with a +" button for Done and Add. In the Name field, enter TimeSeriesProperty. Change the Base Type to NUMBER. Check the Persistent checkbox. Checking this box causes the last Value entered into the Property to persist through reboots of the system. Check the Logged box. Checking this box causes all changes to the Property to be logged if you have a Value Stream defined to record the changes. 6. At the top-right, click the "Check" button for Done.   7. At the top, click Save.   If the DDCThing's TimeSeriesProperty changes from this point onward, it will now be recorded in the DDCValueStream. Normally, any changes would come from an Edge IoT sensor of some type, but for the purposes of this guide, we will manually change the value repeatedly to simulate these types of changes.   Set 5   Under TimeSeriesProperty's Value column, click the "pencil" button for Set value of property.   In the slide-out at the top-right, enter 5.   At the top-right, click the "Check" button for Done.   Set 10   Under TimeSeriesProperty's Value column, click the "pencil" button for Set value of property. In the slide-out at the top-right, enter 10.   At the top-right, click the "Check" button for Done.   Set 15   Under TimeSeriesProperty's Value column, click the "pencil" button for Set value of property. In the slide-out at the top-right, enter 15.   At the top-right, click the "Check" button for Done. Set 20   Under TimeSeriesProperty's Value column, click the "pencil" button for Set value of property. In the slide-out at the top-right, enter 20.   At the top-right, click the "Check" button for Done. Set 25   Under TimeSeriesProperty's Value column, click the "pencil" button for Set value of property. In the slide-out at the top-right, enter 25.   At the top-right, click the "Check" button for Done. At the top, click Save.   Step 5: Create Mashup   Before we can bind the data to the various Chart Widgets, we first have to create a Mashup and add the charts to it. From the Browse tab of ThingWorx Composer, click Visualization > Mashups, + New.   Keep the default of Responsive, and click OK.   In the Name field, enter DDCMashup.   If Project is not set, search for and select PTCDefaultProject. At the top, click Save.   At the top, click Design.   Divide the Mashup   On the top-left under the Layout section, click two times on Add Left.   With the left-third selected in the central Canvas window, click Add Bottom.   With the middle-third selected in the central Canvas window, click Add Bottom. With the right-third selected in the central Canvas window, click Add Bottom.   At the top, click Save. Add the Charts   At the top-left, click on the Widgets tab.   Search for pie inside the Filter Widgets field in the top-left. Drag-and-drop a Pie Chart Widget onto the top-left section of the Canvas.   In the top-left, change Category to Legacy, and search for label chart inside the Filter Widgets field in the top-left. Drag-and-drop a Label Chart Widget onto the top-middle section of the Canvas. Note that, even the Label Chart is a Legacy Widget, it will still work. 6. Change Category back to Standard, and search for proportional inside the Filter Widgets field in the top-left. 7. Drag-and-drop a Proportional Chart Widget onto the top-right section of the Canvas. 8. Search for bubble inside the Filter Widgets field in the top-left. 9. Drag-and-drop a Bubble Chart Widget onto the bottom-left section of the Canvas. 10. Search for line inside the Filter Widgets field in the top-left. 11. Drag-and-drop a Line Chart Widget onto the bottom-middle section of the Canvas.   12. Search for event inside the Filter Widgets field in the top-left. 13. Drag-and-drop a Event Chart Widget onto the bottom-right section of the Canvas.   14. Click Save.   Click here to view Part 3 of this guide.   
View full tip
Get Started with ThingWorx for IoT Guide Part 1   Overview   This project will introduce you to the principles of ThingWorx Foundation by creating a working web application. Following the steps in this guide, you will create the building blocks of your first application for the Internet of Things (IoT). You will use ThingWorx Composer to create Thing Templates, which are then used to create Things that model the application domain. A simulator is imported to generate time-series data that is saved to a Value Stream. After modeling the application in ThingWorx Composer, you'll use Mashup Builder to create the web application Graphical User Interface (GUI). No coding is required in modeling the application, or in composing the web GUI that displays dynamically-generated data. NOTE: This guide’s content aligns with ThingWorx 9.3. The estimated time to complete ALL 5 parts of this guide is 30 minutes.      Step 1: Data Model   Model-based design with reusable building blocks makes your applications scalable and flexible. A ThingWorx application is built from Things, each based on a Thing Template that defines the common Properties (characteristics) and Services (behaviors) for a set of entities. Once a Thing Template is created, you can easily instantiate multiple Things without duplicating effort. In this tutorial, we will develop an application for a house including a thermostat, an electrical meter, and a sensor data simulator. We will demonstrate how to capture, store, and visualize data using the ThingWorx Foundation Server.   You will create Thing Shapes that model both a thermostat and an electric meter. You will then create a Thing Template that represents a house based on these shapes and other Properties.   Step 2: Create Thing Shapes 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 meter and a thermostat. Meter 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 MeterShape in the Name field. NOTE: Thing Shape names are case sensitive   If Project is not already set, choose PTCDefaultProject. Click Save. Add Properties Click Properties and Alerts tab at the top of your 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? meterID STRING X   currentPower NUMBER   X costPerKWh NUMBER X X currentCost NUMBER     Select the Base Type from the drop-down menu that is listed in the table next to the Property name.   Check Persistent and/or Logged if there is an X in the table row of the Property. NOTE: When Persistent is selected, the property value will be retained when a Thing is restarted. Properties that are not persisted will be reset to the default during a restart. When Logged is selected, every property value change will be automatically logged to a specified Value Stream. 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. Repeat steps 2 through 6 for each of the properties in the rows of the table. Click the done ✓ Button. You'll see that these Properties have been created for the Meter Thing Shape.   Click Save. Thermostat This time we will use a shortcut to create a Thing Shape. In the top, left of the screen you will find +, click the new entity icon, then select Thing Shape from the list.   TIP: This is a shortcut you can use to create anything you can access from the Home tab in Composer. Type ThermostatShape in the Name field. If Project is not already set, choose PTCDefaultProject. Select the Properties and Alerts tab at the top. Click + Add and create the following properties following the same steps as before: Name Base Type Persistent? Logged? thermostatID STRING X   temperature NUMBER X X setTemperature NUMBER X X message STRING   X Click Save. You'll see that these Properties have been created for the Thermostat Thing Shape.       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 building. This building Template could be used to create multiple Things that each represent a specific home, business, or other building structure. 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 BuildingTemplate in the Name field. NOTE: Thing Template names are case sensitive If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. In the Base Thing Template box, click + to choose GenericThing as the Template.   In the Implemented Shapes field, click the + to select the MeterShape Thing Shape.   Click Save. Add Properties In this step, you will specify the Properties that represent the characteristics of a building. Some Properties like the building 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: BuildingTemplate.   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, Select the Base Type of the property from the drop down menu. Check Persistent and/or Logged if there is an X in the table row of the Property. 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 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. Repeat steps 3 through 6 for each of the properties in the rows of the table. Name Base Type Persistent Logged buildingID STRING x   building_lat_long LOCATION x   watts NUMBER x x After entering the final property, click the ✓ button. Click Save. You should see the following properties in your Composer.   In the next part of this introductory exercise, we will create a single Thing based on this Template to represent a house.
View full tip
Create Your Application Guide UI Part 1    Overview   This project will introduce the ThingWorx Mashup Builder. Following the steps in this guide, you will learn how to use this tool to create a Graphical User Interface (GUI) for your IoT Application. We will teach you how to rapidly create and update a Mashup, which is a custom visualization built to display data from devices according to your application's business and technical requirements. NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL 5 parts of this guide is 30 minutes.    Step 1: Create New Mashup   The Mashup Builder is a drag-and-drop environment with a What You See Is What You Get (WYSIWYG) interface. With the Mashup Builder you can quickly and easily create a visualization of your IoT data. In this step, we'll explain various options to customize your application GUI. Click Browse > VISUALIZATION > Mashups.   Click + New. You are now on the New Mashup pop-up window.           Layout Options When creating your UI, you must choose whether you want a Responsive, Static, or Responsive (Advanced) Mashup, depending on the resolutions of the displays you want your application users to utilize when running your application. Mashup Layout Description When to Use Responsive Expands to the resolution of the display in an even more dynamic manner than the Responsive (Legacy) option. Previously-labeled as Responsive (Advanced), this is now the default option with modifications to the Mashup Builder interface versus previous versions. For instance, divisions such as a header or footer are available with the Template options at the bottom of the pop-up. Static (Legacy) Sized to the dimensions that you define. Static Mashups are appropriate when your users have a standard device on which they’ll be utilizing your application, such as a smartphone or tablet. When displayed in a lower resolution you will see scroll bars, in a higher resolution there will be unused space around the Mashup. Responsive (Legacy) Expands to the resolution of the display without leaving any unused space around the Mashup. Responsive Mashups should be utilized when you anticipate that users will interface with your application through various-sized screens. Responsive Mashups should always be tested at various resolutions to ensure optimum display of your IoT data.   Keep the default of Responsive (with NO Responsive Templates chosen), and click OK in the pop-up window. In the Name field, enter appui_mashup.   If the Project is not already set, search for and select PTCDefaultProject.  At the top, click Save.   At the top, click Design. This is the Mashup Builder user interface we will use for the remainder of this guide.              6. On the left, click the "left arrow" Collapse icon to cause the Composer Navigation to slide-out, revealing more room for the Mashup Builder interface.         Step 2: Mashup Builder Sections Now that you've launched the Mashup Builder, you'll need an understanding of the layout and configuration options.     NOTE: Section 1 in the top-left has a drop-down arrow you can click to reveal additional sections if your screen resolution is too small to show all of Widgets, Layout, and Explorer. There is also the Mashups tab in Section 1, but it is not covered in this guide.   Mashup Builder Section Description 1a Widgets Widgets provides a list of every graphical element within the platform. There are a wide variety of selections, from grids to graphs to text boxes to buttons. There is also a Filter Widgets field where you can enter the name of a particular Widget to sort the list. 1b Layout Layout is used to divide your Mashup into logical sub-sections. 1c Explorer Explorer allows you to reach any individual element of a Mashup. This can be helpful when multiple Widgets are overload on top of each other in the central Canvas window, making it difficult to click on them individually. 2 Canvas This is an area into which you can drag-and-drop Widgets to your desired location to build your application UI. You can also drag-and-drop data onto the Widgets in the Canvas. 3a Data Data is fundamental to any Mashup that wants to display ThingWorx IoT data, as it allows you to bind backend-data to particular Widgets. 3b Session Session provides access to Session Parameters, which are similar to global variables that may be used across multiple Mashups, such as cookies or security information for a logged-in User. 3c User User provides access to the User Extensions. User Extensions are the Properties of the logged-in User and can be used on the Client side and/or the Server side. 4a Properties Properties displays the Properties for the selected Mashup or Widget. These Properties allow you to perform a variety of modifications to Widgets, such as setting its exact position. 4b Style Properties Style Properties are a sub-set of Properties dealing with items such as changing color. 5a Bindings As data connections are made to various Widgets, the Bindings window will show these links in an easy-to-understand 'arrow' format. For instance, if a button press causes a Thing’s Service to be called, then you’ll see a connection from the Button Widget’s *Clicked* Event over to the Thing’s Service. 5b Reminders Reminders points out issues with your Mashup, such as unbound but required Properties, which often must be fixed before the Mashup can be saved. 6a Data Properties Data Properties displays properties of the selected data element. This can be helpful, for instance, when you want something to be triggered only when something else has completed. In that scenario, you’d look for the ServiceInvokeCompleted Event in this bottom-right area. 6b Functions Functions provides the ability to write custom business logic within the Mashup itself.   Step 3: Introducing Widgets   The primary way in which you'll create the GUI for your IoT application is with Widgets. Widgets are self-contained graphical elements that you can drag-and-drop onto the central Canvas area. Once placed on the Canvas, you can: Modify Widget layout Resize Widgets Bind Data to Widgets Combining several Widgets together will allow you to quickly and easily create a functional GUI for your IoT application. Widget Name Widget Example Picture Description Button   The Button Widget triggers an Event when it is clicked. Typically, this Event will be used to trigger a Service to either push or pull data from the platform’s backend. Checkbox   The Checkbox Widget provides a simple box which can be either set or not-set. You primarily use a Checkbox when you’re setting or displaying Boolean data. Gauge   The Gauge Widget provides a more “graphically interesting” way to display a numerical value. You can set the minimum and maximum values which a Gauge displays, or style a Gauge so that different areas are different colors. Label   The Label Widget displays a non-user-interactable string within your Mashup. You can use this to create headings or descriptions for parts of your Mashup. Text Field   The Text Field Widget is a small, one-line area into which you can either accept an input string from the User or display a string from the platform’s backend. Combining a few of the basic Widgets described above allows you to create a Mashup for your IoT application. However, without data being supplied to these Widgets from the platform's backend, they're just pretty graphics. In the next section, we will introduce a few of the Mashup Services that enable bidirectional data flow between your GUI and device data.   Click here to view Part 2 of this guide.     
View full tip
  Create Your Application Guide UI Part 4    Step 6: Apply Services   You now have an idea of what your Mashup will look like, but without Data Services, it won't accomplish anything productive. In the following steps you'll apply Mashup Data Services to the Widgets.   Add Data Services   Click the + button in the top-right in the Data tab.   In the Entity Filter field, search for and select MBQSThing. In the Select Services field, search for and select GetPropertyValues. Check the Execute on Load checkbox for GetPropertyValues. In the Services Filter field, search for and select SetProperties. In this case, you WILL NOT check the box for Mashup Loaded? because we do not want to call this Service upon initial Mashup load. 6. Click Done. Both the GetPropertyValues and SetProperties Services now appears under the Data tab as well. 7. Click Save.   GetPropertyValues   GetPropertyValues has brought all the values of our Thing's Properties into the Mashup. Now let's tie these values to the Widgets. Expand All Data under the GetPropertyValues Service on the right under the Data tab.   Drag-and-drop Gears_Count onto the textfield-gears-count Widget.   On the Select Binding Target pop-up, click Text.   Repeat Steps 2 and 3, binding Pistons_Count to textfield-pistons-count and Wheels_Count to textfield-wheels-count. Drag-and-drop Gears_Count_Manually_Set onto the checkbox-gears-manual Widget.   On the Select Binding Target pop-up, click State.   Repeat Steps 5 and 6, binding Pistons_Count_Manually_Set to checkbox-pistons-manual and Wheels_Count_Manually_Set to checkbox-wheels-manual. Click Save.   SetProperties   We want to tie the Widgets to the SetProperties Service to manually set the inventory counts in case something has gone wrong with our IoT sensors in the warehouse. On the right under the Data tab, minimize the GetPropertyValues Service and expand the SetProperties Service.        2. Click the textfield-gears-count Widget to select it. 3. Click the top-left drop-down of the TextBox to expand the options. 4. Drag-and-drop Text onto SetProperties > Gears_Count. 5. Repeat Steps 2 through 4, binding Text from textfield-pistons-count onto Pistons_Count and textfield-wheels-count onto Wheels_Count. 6. Click the checkbox-gears-manual Widget to select it. 7. Click the top-left drop-down of the Checkbox to expand the options. 8. Drag-and-drop State onto Gears_Count_Manually_Set. 9. Repeat Steps 6 through 8, binding State from both checkbox-pistons-manual to Pistons_Count_Manually_Set and checkbox-wheels-manual to Wheels_Count_Manually_Set. 10. Click the button-manual-set Widget to select it. 11. Click the top-left drop-down of the Button to expand the options. 12. Drag-and-drop the Clicked Event onto SetProperties under the Data tab. NOTE: The previous steps in this section where we bound Widgets to Properties simply defined what-goes-where in terms of storing the values into the ThingWorx Foundation backend.To actually push those values, the SetProperties Service itself must be called. 13. With the SetProperties Service selected, drag-and-drop SetProperties' ServiceInvokeCompleted Event (in the bottom-right Data Properties section) onto the GetPropertyValues Service (in the top-right Data tab). If you don't see ServiceInvokeCompleted, ensure that you have the Data Properties tab selected. This will cause the GUI to update once the new values have been saved to the platform’s backend. 14. Click Save.   Manual Data Retrieval   We want to tie a Button to GetPropertyValues to update the GUI with the backend's ever-changing inventory counts without requiring a page reload. Click button-manual-retrieve to select it. Click the top-left drop-down of this Button Widget to expand the options. Drag-and-drop the Clicked Event onto the GetPropertyValues Service. This will create another way to update the part counts in the GUI, other than reloading the page. 4. Click Save.   Click here to view Part 5 of this guide. 
View full tip
Using the Solution Central API Pitfalls to Avoid by Victoria Firewind, IoT EDC   Introduction The Solution Central API provides a new process for publishing ThingWorx solutions that are developed or modified outside of the ThingWorx Platform. For those building extensions, using third party libraries, or who just are more comfortable developing in an IDE external to ThingWorx, the SC API makes it simple to still utilize Solution Central for all solution management and deployment needs, according to ThingWorx dev ops best practices. This article hones in one some pitfalls that may arise while setting up the infrastructure to use the SC API and assumes that there is already AD integration and an oauth token fetcher application configured for these requests.   CURL One of the easiest ways to interface with the SC API is via cURL. In this way, publishing solutions to Solution Central really involves a series of cURL requests which can be scripted and automated as part of a mature dev ops process. In previous posts, the process of acquiring an oauth token is demonstrated. This oauth token is good for a few moments, for any number of requests, so the easiest thing to do is to request a token once before each step of the process.   1. GET info about a solution (shown) or all solutions (by leaving off everything after "solutions" in the URL)     $RESULT=$(curl -s -o test.zip --location --request GET "https://<your_sc_url>/sc/api/solutions/org.ptc:somethingoriginal12345:1.0.0/files/SampleTwxExtension.zip" ` --header "Authorization: Bearer $ACCESS_TOKEN" ` --header 'Content-Type: application/json' ` )     Shown here in the URL, is the GAV ID (Group:Artifact_ID:Version). This is shown throughout the Swagger UI (found under Help within your Solution Central portal) as {ID}, and it includes the colons. To query for solutions, see the different parameter options available in the Swagger UI found under Help in the SC Portal (cURL syntax for providing such parameters is shown in the next example).   Potential Pitfall: if your solution is not published yet, then you can get the information about it, where it exists in the SC repo, and what files it contains, but none of the files will be downloadable until it is published. Any attempt to retrieve unpublished files will result in a 404.   2. Create a new solution using POST     $RESULT=$(curl -s --location --request POST "https://<your_sc_url>/sc/api/solutions" ` --header "Authorization: Bearer $ACCESS_TOKEN" ` --header 'Content-Type: application/json' ` -d '"{\"groupId\": \"org.ptc\", \"artifactId\": \"somethingelseoriginal12345\", \"version\": \"1.0.0\", \"displayName\": \"SampleExtProject\", \"packageType\": \"thingworx-extension\", \"packageMetadata\": {}, \"targetPlatform\": \"ThingWorx\", \"targetPlatformMinVersion\": \"9.3.1\", \"description\": \"\", \"createdBy\": \"vfirewind\"}"' )     It will depend on your Powershell or Bash settings whether or not the escape characters are needed for the double quotes, and exact syntax may vary. If you get a 201 response, this was successful.   Potential Pitfalls: the group ID and artifact ID syntax are very particular, and despite other sources, the artifact ID often cannot contain capital letters. The artifact ID has to be unique to previously published solutions, unless those solutions are first deleted in the SC portal. The created by field does not need to be a valid ThingWorx username, and most of the parameters given here are required fields.   3.  PUT the files into the project     $RESULT=$(curl -L -v --location --request PUT "<your_sc_url>/sc/api/solutions/org.ptc:somethingelseoriginal12345:1.0.0/files" ` --header "Authorization: Bearer $ACCESS_TOKEN" ` --header 'Accept: application/json' ` --header 'x-sc-primary-file:true' ` --header 'Content-MD5:08a0e49172859144cb61c57f0d844c93' ` --header 'x-sc-filename:SampleTwxExtension.zip' ` -d "@SampleTwxExtension.zip" ) $RESULT=$(curl -L --location --request PUT "https://<your_sc_url>/sc/api/solutions/org.ptc:somethingelseoriginal12345:1.0.0/files" ` --header "Authorization: Bearer $ACCESS_TOKEN" ` --header 'Accept: application/json' ` --header 'Content-MD5:fa1269ea0d8c8723b5734305e48f7d46' ` --header 'x-sc-filename:SampleTwxExtension.sha' ` -d "@SampleTwxExtension.sha" )     This is really TWO requests, because both the archive of source files and its hash have to be sent to Solution Central for verifying authenticity. In addition to the hash file being sent separately, the MD5 checksum on both the source file archive and the hash has to be provided, as shown here with the header parameter "Content-MD5". This will be a unique hex string that represents the contents of the file, and it will be calculated by Azure as well to ensure the file contains what it should.   There are a few ways to calculate the MD5 checksums and the hash: scripts can be created which use built-in Windows tools like certutil to run a few commands and manually save the hash string to a file:      certutil -hashfile SampleTwxExtension.zip MD5 certutil -hashfile SampleTwxExtension.zip SHA256 # By some means, save this SHA value to a file named SampleTwxExtension.sha certutil -hashfile SampleTwxExtension.sha MD5       Another way is to use Java to generate the SHA file and calculate the MD5 values:      public class Main { private static String pathToProject = "C:\\Users\\vfirewind\\eclipse-workspace\\SampleTwxExtension\\build\\distributions"; private static String fileName = "SampleTwxExtension"; public static void main(String[] args) throws NoSuchAlgorithmException, FileNotFoundException { String zip_filename = pathToProject + "\\" + fileName + ".zip"; String sha_filename = pathToProject + "\\" + fileName + ".sha"; File zip_file = new File(zip_filename); FileInputStream zip_is = new FileInputStream(zip_file); try { // Calculate the MD5 of the zip file String md5_zip = DigestUtils.md5Hex(zip_is); System.out.println("------------------------------------"); System.out.println("Zip file MD5: " + md5_zip); System.out.println("------------------------------------"); } catch(IOException e) { System.out.println("[ERROR] Could not calculate MD5 on zip file named: " + zip_filename + "; " + e.getMessage()); e.printStackTrace(); } try { // Calculate the hash of the zip and write it to a file String sha = DigestUtils.sha256Hex(zip_is); File sha_output = new File(sha_filename); FileWriter fout = new FileWriter(sha_output); fout.write(sha); fout.close(); System.out.println("[INFO] SHA: " + sha + "; written to file: " + fileName + ".sha"); // Now calculate MD5 on the hash file FileInputStream sha_is = new FileInputStream(sha_output); String md5_sha = DigestUtils.md5Hex(sha_is); System.out.println("------------------------------------"); System.out.println("Zip file MD5: " + md5_sha); System.out.println("------------------------------------"); } catch (IOException e) { System.out.println("[ERROR] Could not calculate MD5 on file name: " + sha_filename + "; " + e.getMessage()); e.printStackTrace(); } }     This method requires the use of a third party library called the commons codec. Be sure to add this not just to the class path for the Java project, but if building as a part of a ThingWorx extension, then to the build.gradle file as well:     repositories { mavenCentral() } dependencies { compile fileTree(dir:'twx-lib', include:'*.jar') compile fileTree(dir:'lib', include:'*.jar') compile 'commons-codec:commons-codec:1.15' }       Potential Pitfalls: Solution Central will only accept MD5 values provided in hex, and not base64. The file paths are not shown here, as the archive file and associated hash file shown here were in the same folder as the cURL scripts. The @ syntax in Powershell is very particular, and refers to reading the contents of the file, in this case, or uploading it to SC (and not just the string value that is the name of the file). Every time the source files are rebuilt, the MD5 and SHA values need to be recalculated, which is why scripting this process is recommended.   4. Do another PUT request to publish the project      $RESULT=$(curl -L --location --request PUT "https://<your_sc_url>/sc/api/solutions/org.ptc:somethingelseoriginal12345:1.0.0/publish" ` --header "Authorization: Bearer $ACCESS_TOKEN" ` --header 'Accept: application/json' ` --header 'Content-Type: application/json' ` -d '"{\"publishedBy\": \"vfirewind\"}"' )     The published by parameter is necessary here, but it does not have to be a valid ThingWorx user for the request to work. If this request is successful, then the solution will show up as published in the SC Portal:    Other Pitfalls Remember that for this process to work, the extensions within the source file archive must contain certain identifiers. The group ID, artifact ID, and version have to be consistent across a couple of files in each extension: the metadata.xml file for the extension and the project.xml file which specifies which projects the extensions belong to within ThingWorx. If any of this information is incorrect, the final PUT to publish the solution will fail.   Example Metadata File:     <?xml version="1.0" encoding="UTF-8"?> <Entities> <ExtensionPackages> <ExtensionPackage artifactId="somethingoriginal12345" dependsOn="" description="" groupId="org.ptc" haCompatible="false" minimumThingWorxVersion="9.3.0" name="SampleTwxExtension" packageVersion="1.0.0" vendor=""> <JarResources> <FileResource description="" file="sampletwxextension.jar" type="JAR"></FileResource> </JarResources> </ExtensionPackage> </ExtensionPackages> <ThingPackages> <ThingPackage className="SampleTT" description="" name="SampleTTPackage"></ThingPackage> </ThingPackages> <ThingTemplates> <ThingTemplate aspect.isEditableExtensionObject="false" description="" name="SampleTT" thingPackage="SampleTTPackage"></ThingTemplate> </ThingTemplates> </Entities>       Example Projects XML File:     <?xml version="1.0" encoding="UTF-8"?> <Entities> <Projects> <Project artifactId="somethingoriginal12345" dependsOn="{&quot;extensions&quot;:&quot;&quot;,&quot;projects&quot;:&quot;&quot;}" description="" documentationContent="" groupId="org.ptc" homeMashup="" minPlatformVersion="" name="SampleExtProject" packageVersion="1.0.0" projectName="SampleExtProject" publishResult="" state="DRAFT" tags=""> </Project> </Projects> </Entities>       Another large issue that may come up is that requests often fail with a 500 error and without any message. There are often more details in the server logs, which can be reviewed internally by PTC if a support case is opened. Common causes of 500 errors include missing parameter values that are required, including invalid characters in the parameter strings, and using an API URL which is not the correct endpoint for the type of request. Another large cause of 500 errors is providing MD5 or hash values that are not valid (a mismatch will show differently).    Another common error is the 400 error, which happens if any of the code that SC uses to parse the request breaks. A 400 error will also occur if the files are not being opened or uploaded correctly due to some issue with the @ syntax (mentioned above).  Another common 400 error is a mismatch between the provided MD5 value for the zip or SHA file, and the one calculated by Azure ("message: Md5Mismatch"), which can indicate that there has been some corruption in the content of the upload, or simply that the MD5 values aren't being calculated correctly. The files will often say they have 100% uploaded, even if they aren't complete, errors appear in the console, or the size of the file is smaller than it should be if it were a complete upload (an issue with cURL).   Conclusion Debugging with cURL can be a challenge. Note that adding "-v" to a cURL command provides additional information, such as the number of bytes in each request and a reprint of the parameters to ensure they were read correctly. Even still, it isn't always possible for SC to indicate what the real cause of an issue is. There are many things that can go wrong in this process, but when it goes right, it goes very right. The SC API can be entirely scripted and automated, allowing for seamless inclusion of externally-developed tools into a mature dev ops process.
View full tip
User Load Testing in ThingWorx Java Client Tutorial Written by Tori Firewind, IoT EDC   Introduction As stated in previous posts, user load testing is a critical component of ensuring a ThingWorx solution is Enterprise-ready. Even a sturdy new feature that seems to function well in development can run into issues once larger loads are thrown into the mix. That's why no piece of code should be considered production-ready until it has undergone not just unit and integration testing (detailed in our Comprehensive DevOps Guide), but also load testing that ensures a positive user experience and an adequately sized server to facilitate the user load.    The EDC has spent quite a few posts detailing the process of setting up an accurate, real-world testing suite using JMeter for ThingWorx. In this piece, we detail an alternative approach that makes use of the Java Spring Boot Framework to call rest requests against the ThingWorx server and simulate the user load. This Java Client tutorial produces a very immature user load client, one which would still take a lot of development to function as flexibly as the JMeter tutorial counterpart. For Java developers, however, this is still a very attractive approach; it allows for more custom, robust testing suites that come only as an investment made in a solid testing tool.   For someone experienced in Java, the risk is smaller of overlooking some aspect of simulation that JMeter may have handled automatically. For example, JMeter automatically creates more than one HTTP session, and it's much easier to implement randomized user logins instead of one account. The Java Client could do it with some extra work (not demonstrated here), but it uses just the Administrator login by default for a quick and dirty sort of load test, one focused less on the customer experience and more on server and database performance under the strain of the user requests (the method used in our sizing guidance, for instance, to see if a server is sized correctly).   The amount of time required to develop a Java Client isn't so bad for a Java developer, and when compared with learning the JMeter Framework, might be a better investment. A tool like this can handle a greater number of threads on a single testing VM; JMeter caps out around 250 threads per client on an 8Gb VM (under ideal conditions), while a Java Client can have thousands of threads easily. Likewise, a Java Client has less memory overhead than JMeter, less concern for garbage collection, and less likelihood that influence from heap memory management will affect the test results.   However, remember that everything in a Java Client has to be built from scratch and maintained over time. That means that beyond the basic tutorial here, there needs to be some kind of metrics gathering and analysis tool implemented (JMeter has built-in reporting tools), the calls need to be randomized, and not called at set intervals like they are here (which is not a very accurate representation of user load compared to a real-world scenario), and the number of users accessing the system at once should probably vary over time (to resemble peak usage hours). JMeter has a recording tool to ensure all the necessary REST requests to simulate a mashup load are made, so great care has to be taken to ensure all of the necessary REST calls for a mashup are made by the Java Client if a true simulation is called for by that approach.    Java Client Tutorial   Conclusion Neither a Java Client nor a JMeter testing suite is inherently better than the other, and both have their place within PTC's various testing processes. The best test of all is to stand up any sort of user load testing client, either of these approaches, at the same time as the UAT or QA user experience testing. QA testers who load and click about on mashups in true, user fashion can then see most accurately how the mashups will perform and what the users will experience in the Enterprise-ready, production application once the changes go out.
View full tip
In ThingWorx Analytics, you have the possibility to use an external model for scoring. In this written tutorial, I would like to provide an overview of how you can use a model developed in Python, using the scikit-learn library in ThingWorx Analytics. The provided attachment contains an archive with the following files: iris_data.csv: A dataset for pattern recognition that has a categorical goal. You can click here to read more about this dataset TestRFToPmml.ipynb: A Jupyter notebook file with the source code for the Python model as well as the steps to export it to PMML RF_Iris.pmml: The PMML file with the model that you can directly upload in Analytics without going through the steps of training the model in Python The tutorial assumes you already have some knowledge of ThingWorx and ThingWorx Analytics. Also, if you plan to run the Python code and train the model yourself, you need to have Jupyter notebook installed (I used the one from the Anaconda distribution). For demonstration purposes, I have created a very simple random forest model in Python. To convert the model to PMML, I have used the sklearn2pmml library. Because ThingWorx Analytics supports PMML format 4.3, you need to install sklearn2pmml version 0.56.2 (the highest version that supports PMML 4.3). To read more about this library, please click here Furthermore, to use your model with the older version of the sklearn2pmml, I have installed scikit-learn version 0.23.2.  You will find the commands to install the two libraries in the first two cells of the notebook.   Code Walkthrough The first step is to import the required libraries (please note that pandas library is also required to transform the .csv to a Dataframe object):   import pandas from sklearn.ensemble import RandomForestClassifier from sklearn2pmml import sklearn2pmml from sklearn.model_selection import GridSearchCV from sklearn2pmml.pipeline import PMMLPipeline   After importing the required libraries, we convert the iris_data.csv to a pandas dataframe and then create the features (X) as well as the goal (Y) vectors:   iris_df = pandas.read_csv("iris_data.csv") iris_X = iris_df[iris_df.columns.difference(["class"])] iris_y = iris_df["class"]   To best tune the random forest, we will use the GridSearchCSV and cross-validation. We want to test what parameters have the best validation metrics and for this, we will use a utility function that will print the results:   def print_results(results): print('BEST PARAMS: {}\n'.format(results.best_params_)) means = results.cv_results_['mean_test_score'] stds = results.cv_results_['std_test_score'] for mean, std, params in zip(means, stds, results.cv_results_['params']): print('{} (+/-{}) for {}'.format(round(mean, 3), round(std * 2, 3), params))   We create the random forest model and train it with different numbers of estimators and maximum depth. We will then call the previous function to compare the results for the different parameters:   rf = RandomForestClassifier() parameters = { 'n_estimators': [5, 50, 250], 'max_depth': [2, 4, 8, 16, 32, None] } cv = GridSearchCV(rf, parameters, cv=5) cv.fit(iris_X, iris_y) print_results(cv)   To convert the model to a PMML file, we need to create a PMMLPipeline object, in which we pass the RandomForestClassifier with the tuning parameters we identified in the previous step (please note that in your case, the parameters can be different than in my example). You can check the sklearn2pmml  documentation  to see other examples for creating this PMMLPipeline object :   pipeline = PMMLPipeline([ ("classifier", RandomForestClassifier(max_depth=4,n_estimators=5)) ]) pipeline.fit(iris_X, iris_y)   Then we perform the export:   sklearn2pmml(pipeline, "RF_Iris.pmml", with_repr = True)   The model has now been exported as a PMML file in the same folder as the Jupyter Notebook file and we can upload it to ThingWorx Analytics.   Uploading and Exploring the PMML in Analytics To upload and use the model for scoring, there are two steps that you need to do: First, the PMML file needs to be uploaded to a ThingWorx File Repository Then, go to your Analytics Results thing (the name should be YourAnalyticsGateway_ResultsThing) and execute the service UploadModelFromRepository. Here you will need to specify the repository name and path for your PMML file, as well as a name for your model (and optionally a description)   If everything goes well, the result of the service will be an id. You can save this id to a separate file because you will use it later on. You can verify the status of this model and if it’s ready to use by executing the service GetDetails:   Assuming you want to use the PMML for scoring, but you were not the one to develop the model, maybe you don’t know what the expected inputs and the output of the model are. There are two services that can help you with this: QueryInputFields – to verify the fields expected as input parameters for a scoring job   QueryOutputFields – to verify the expected output of the model The resultType input parameter can be either MODELS or CLUSTERS, depending on the type of model,    Using the PMML for Scoring With all this information at hand, we are now ready to use this PMML for real-time scoring. In a Thing of your choice, define a service to test out the scoring for the PMML we have just uploaded. Create a new service with an infotable as the output (don’t add a datashape). The input data for scoring will be hardcoded in the service, but you can also add it as service input parameters and pass them via a Mashup or from another source. The script will be as follows:   // Values: INFOTABLE dataShape: "" let datasetRef = DataShapes["AnalyticsDatasetRef"].CreateValues(); // Values: INFOTABLE dataShape: "" let data = DataShapes["IrisData"].CreateValues(); data.AddRow({ sepal_length: 2.7, sepal_width: 3.1, petal_length: 2.1, petal_width: 0.4 }); datasetRef.AddRow({ data: data}); // predictiveScores: INFOTABLE dataShape: "" let result = Things["AnalyticsServer_PredictionThing"].RealtimeScore({ modelUri: "results:/models/" + "97471e07-137a-41bb-9f29-f43f107bf9ca", //replace with your own id datasetRef: datasetRef /* INFOTABLE */, });   Once you execute the service, the output should look like this (as we would have expected, according to the output fields in the PMML model):   As you have seen, it is easy to use a model built in Python in ThingWorx Analytics. Please note that you may use it only for scoring, and the model will not appear in Analytics Builder since you have created it on a different platform. If you have any questions about this brief written tutorial, let me know.
View full tip
Solution Central and Azure Active Directory Written by: Tori Firewind, IoT EDC   As we’ve said in a previous post, Solution Central (SC) is a crucial part of any mature dev ops pipeline. In its latest version (3.1.0), it manages custom solutions even more easily due to the SC API. However, this comes with a few requirements that can be a little tricky.   One of the more complex configuration pieces for using this new API involves a cloud-hosted Active Directory (AD) application within Azure AD. In order to make use of the new API, your organization’s users must exist on an Azure AD tenant that is separate from the PTC tenant. Most PTC customers are placed on this PTC-owned tenant by default, so additional configuration may be required to set up the AD instance within Azure before the SC API can be used. The type of tenant has to be Azure, of course, as that is what PTC uses: a multi-tenancy Azure infrastructure for all authentication.   In this usage, “tenant” is a cloud-hosting, infrastructure term which essentially refers to an Azure VM hosting an Active Directory server, as well as managing the many AD components that would otherwise require a lot of oversight. Users within that AD server are grouped so that only those solutions published by their own organizations are visible within Solution Central. In this way, the term “tenant” can also refer to a partition of some kind of data; a Solution Central tenant includes the users, the solutions, and is sort of like a sub-tenant of the larger PTC infrastructure. PTC uses a global Solution Central tenant for deployment of its own solutions, like DPM (Digital Performance Management), which is therefore available to every user in the PTC Azure AD tenant or a tenant which has been connected using the tutorial below.   There are good reasons to want to use your own Azure AD integrated into Solution Central that do not involve using the SC API. For one thing, it allows for direct control over the users that have access; otherwise, a ticket to PTC support is necessary every time a user needs access granted or removed. The tutorial below is a great reference for anyone using Solution Central, with steps 1-4 offering an easy guide for integrating your own Azure AD and simplifying your user management.   To use the SC API, however, there are additional steps required to create an application for retrieving an oauth token. This application needs the “solution-publisher” role or else bad request/forbidden errors will pop up. This role is automatically available in your Azure AD tenant once it is linked to the PTC AD tenant, but it does have to be manually assigned to the application, whose sole function is to request this access token for authenticating requests against the SC server.   The Azure application you need to create is essentially a plugin with permission to publish solutions against the SC API. It functions a little like a “login” in database terminology, serving the function of authenticating to an endpoint (in this case not tied to a user or any kind of identity). This application must be able to request an access token successfully and return that to the scripts which call upon it in order to perform the project creation and publication requests. The tutorial below steps you through how to create this application and request all of your solutions via the SC API.   Tutorial: Create Azure AD Application to Access SC via API Create a new tenant in Azure AD for users who will have access to the SC API Create a ticket with PTC to provide the tenant ID and begin the onboarding process Once that process completes, you will receive an email with a custom link to login to the Solution Central portal for your organization, where only your solutions exist Users will then need to be added as “Custom Global Administrators” on the SC enterprise application within Azure Portal to grant them access to login to Solution Central in a browser In order for us to be able to use the SC API, however, more work needs to be done; an application to request an oauth token for requests must be created in Azure Portal Navigate to “App Registrations” from the Azure AD page in Azure Portal and then click “New registration” Enter the application name (ours is called “gradle-plugin-tokenfetcher” in the examples shown here), and select the “single tenant” radio button Enter a URL for redirect URI and for “Select a platform” select “Web” Click “Register”, and wait for the application created notification Now we need to add permissions to see Solution Central Open the app from under “App registrations” and select the “API permissions” tab Click “Add a permission” and in the pop-up window that appears, select the “APIs my organization uses” tab, which should have PTC Solution Central listed, if this tenant has been linked to the PTC tenant per step 2 above Select “Application Permissions” and then check the “solution-publisher” role Click “Add permissions” The application now has access to Solution Central as a publisher, able to send solution publications over the API and not just via the Platform interface   The application is ready now, so we can create a request to test that it has access to SC Using Windows Powershell or something similar, create a script to make a couple of cURL requests against first the Azure AD and then the Solution Central API (attached as well): The tenant ID and the directory ID are the same value (listed on the tenant under “Overview”), and the client ID and application ID are the same as well (listed on the application, shown here), so don’t be confused by terminology The client app secret is the “Value” provided by the system when a new client secret is created under “Certificates & Secrets” (remember to copy this as soon as it is made and before clicking away, as after that, it will no longer be visible): The Solution Central app ID can be found under “App registrations”, listed within the details for the “solution-publisher” role: This access token request piece must be done before every request to the SC API, so this secret should be kept in some kind of password management tool (or a global environment variable in GitLab) so that it isn’t found anywhere in the source code If the script pings the SC API successfully, then a list of solutions will be returned
View full tip
Announcements