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

Community Tip - You can change your system assigned username to something more personal in your community settings. X

IoT Tips

Sort by:
  Learn how to send and receive JSON and XML payloads to SOAP and REST services.   GUIDE CONCEPT   This project will introduce how to create services that can send and receive XML and JSON payloads.   Following the steps in this guide, you will develop services to handle, send, and receive XML and JSON.   We will teach you how to use the ThingWorx Platform to handle REST requests and send payload for external SOAP and REST services.   YOU'LL LEARN HOW TO   Efficiently handle, send, and receive XML and JSON in ThingWorx Make requests to external REST services Make requests to external SOAP services   NOTE:  The estimated time to complete all parts of this guide is 60 minutes.     Step 1: Completed Example   Download the attached JSONXMLEntities.zip from attached files and import it into ThingWorx Composer.   In this tutorial, you will learn how to make and handle requests to live external REST and SOAP services. The entities file provided contains the following files and entities as a completed version of the scenario that will be covered:   Name Description JSONRequestThing Thing with examples of making requests using JSON XMLRequestThing Thing with examples of making requests using XML JSONHandlerThing Thing with examples of handling JSON requests and returning organized data XMLHandlerThing Thing with examples of handling XML requests and returning organized data This guide will use services provided by Microsoft Azure. Create a free account to utilize Microsoft Azure Web API services. In order to utilize this web api, obtain a FREE API key from Microsoft Azure Portal using these Microsoft Azure instructions. You are able to use other Web APIs for this guide.   Follow the next steps in order to get started.     Step 2: Sending JSON Based Requests   Whether making a request to a public web service or sending data to a device running an application, ThingWorx is able to utilize different REST request methods (GET, POST, PUT, DELETE, etc) using the ContentLoaderFunctions Resource. This same resource provides services for XML payloads, but JSON is the default formatting for REST. See the "Sending XML Based Requests" section in this guide for working with XML. This guide will not explain REST or REST methods, only how to use these REST methods.   To get started, create a Thing using the below steps. You will create new services in this Thing to make REST requests and add a service to help with HTML encoding. NOTE: Examples of these services can be found in the JSONRequestThing entity, which is provided in the download. In ThingWorx Composer, click the + New at the top of the screen. Select Thing in the dropdown. Name the Thing JSONRequestExample and set the Base Thing Template to GenericThing. Click Save. Click the Services tab. Create a new service called EncodeQueryToHTML. Add the following Input: Name Base Type Required query String True   8. Add the following JavaScript to help encode the string and return an HTML friendly string. try { var result = ""; if(query) { result = query.replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, "'"); } } catch(error) { logger.error("JSONRequestThing.EncodeQueryToHTML(): Error Encoding String - " + error.message); }   9. Click Save and Continue to save your changes.   GET Requests   For GET requests to a REST service, you will use the GetJSON service of the ContentLoaderFunctions Resource. This service takes parameters from the proxy information to how to handle SSL issues. All of the parameters are optional. Perform the following steps to create your ThingWorx service to make REST Get requests.   In the Services tab of the JSONRequestExample Thing, create a new service called JSONGetRequest. The service will have the below properties as Input. Name Base type Required url String True header JSON False   3. In the Snippets section, filter and search for GetJSON. 4. Once you've found GetJSON under the ContentLoaderFunctions section, add it to the editor. You'll see all of the possible parameters for the request. In this example, we'll only set the url and header values. 5. Update the code snippet to include the parameters. Use the below code as a reference. var params = { headers: header /* JSON */, url: url /* STRING */ }; // result: JSON var result = Resources["ContentLoaderFunctions"].GetJSON(params);   6. Set the Output as JSON. 7. Click Save and Continue to save your changes. This code will enable REST requests to be sent to an available web service. You will need to include the query string in the URL. In the provided sample, open the JSONRequestThing Thing and check out the JavaScript for the SearchMicrosoftBing service for a more complex example. Note that you are setting the subscription key needed for a Microsoft Azure request and how to encode raw string input into a query string. Check out the Microsoft Azure documentation of the varying query strings that can be used.     POST/PUT Requests POST and PUT requests are created similarly to GET requests. The methods in the ContentLoaderFunctions Resource is PostJSON and PutJSON. These services include a JSON based paramter titled content. This parameter will allow you to compose the body of the request.   Based on how the REST service is implemented, data will be in the content parameter or the headers parameter. See below for steps on creating a POST request. In the Services tab of the JSONRequestExample Thing, create a new service called JSONPostRequest. The service will have the below properties as parameters. Name Base Type Required url String True header JSON False body JSON False   3. In the Snippets section, filter and search for PostJSON. 4. Once you've found PostJSON under the ContentLoaderFunctions section, add it to the editor. 5. Update the parameter object to use the parameters for the service. Keep in mind, there are different ways this can be done. If the URL or the header will always be the same, then save these values as properties on the Thing and add parameters if the URL for this request will need them. 6. Test the new service with a running REST application or use both the GET and POST methods to setup your Azure Active Directory.   DELETE Requests   In ThingWorx, the DELETE method will be called similarly to the GET method. There will be a number of parameters that can be used and you will need to call the DELETE service of the ContentLoaderFunctions Resource. Follow to below instructions.   Duplicate the JSONGetRequest service you created earlier in order to get a head start on the new service. When prompted, title this new service JSONDeleteRequest and save. In the code area, use the snippet once again to add the delete service from ContentLoaderFunctions. Update the JavaScript code to utilize the delete service. Save, and you're done!   A simple test for calling this delete method via Azure, is using the REST service to delete an email template. The URI and parameters can be found in the Azure API.     Click here to view Part 2 of this guide.
View full tip
  Send voice and text messages with Twilio.   GUIDE CONCEPT   This project will demonstrate how you can create applications that provide information to users, even when they are away from their computer. Users who are on the go can benefit from your application by receiving text and voice messages.   Following the steps in this guide, you will learn how to configure and use the Twilio Widget and explore it’s ability to send messages.   We will teach you how data can be used to send pertinent information to any cell phone.   YOU'LL LEARN HOW TO   Download and import the Twilio Widget extension Create a Thing using the Twilio Thing Template Configure the Twilio Thing to use your Twilio account Send text messages using a Service   NOTE:  The estimated time to complete this guide is 30 minutes.     Step 1: Install Twilio Extension   Download the Twilio Extension from IQNOX.com. Note:  IQNOX is a PTC Partner and will be maintaining and supporting specific extensions going forward.  It will be necessary to create an account on the IQNOX website, but the ThingWorx extensions are free. In the lower-left side of Composer, click Import/Export, then Import.   In the Import From File pop-up, under Import Option select Extension from the drop-down, then click Browse. Navigate to the .zip file you downloaded.   Click Import in the Import From File pop-up, then click Close after file is successfully imported.     Step 2: Create Twilio Thing   In this step, you will create a Thing that represents a connection with the Twilio service.   Start on the Browse, folder icon tab on the far left of ThingWorx Composer.  Under the Modeling tab, hover over Things then click the + button. Type twilio-connector in the Name field.   NOTE: This name, with matching capitalization, is required for the example code which will be entered in a later step. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. In the Base Thing Template text box, click the + and select Twilio.     Click Save.     Step 3: Configure Twilio Thing   Now that we have created a Thing to represent the Twilio connection, we will configure it with your Twilio account credentials.   When the Twilio Extension is installed, it does not include the Twilio account credentials required to send messages.   You will need Twilio account credentials to complete this step. If you do not already have a Twilio account, you can click on this link to create a Twilio account.   Open the twilio-connection Thing if it is not already open. Click on the Configuration tab. Click the pencil icon next to the authToken field.   Copy your AUTH TOKEN from your Twilio account dashboard.   Paste your AUTH TOKEN into the New Password and Confirm Password fields under authToken.   Click the pencil icon next to the accountSID field. Copy your ACCOUNT SID from your Twilio account dashboard, and paste it into the New Password and Confirm Password fields under accountSID. Follow the steps in your Twilio account dashboard to get a trial phone number.   Copy your PHONE NUMBER from your Twilio account dashboard, and paste it into the callerID field.   Click Save.     Step 4: Test Twilio Thing   Now that we have created a Thing to represent the Twilio connection and configured it with Twilio account credentials, we will confirm that everything is working.   Click the Services tab at the top of the twilio-connector Thing.     Click the link to the SendSMSMessage Service in the Services Name column. Enter a phone number in the to field. Enter a test message in the text field.   Click the Execute button to send the SMS message. The service should execute without any errors within a couple of seconds and the phone number will receive your message. Click Close to end testing the service.     Step 5: Sample Alerting App   At this point, you have created and tested a Thing that can send text messages. This step will demonstrate sending a message when a Property Value is out of the desired range.   Import Simulated Freezer Thing   Download and unzip the attached sample Things_freezer.zip. In Composer, click the Import/Export icon at the lower-left of the page.   Click Import. Leave all default values and click Browse to select the Things_freezer.twx file that you just downloaded. Click Open, then Import. When you see the success message, click Close.   Explore Imported Entities   Navigate to the freezer Thing by using the search bar at the top of the screen. Click the Subscriptions tab.   Click reportFreezer under Name. Open the Subscription Info tab. Select the Enabled checkbox.   Click Done then Save to save any changes.   Verify Data Simulation   Open the freezer Thing and click Properties and Alerts tab. Click the Set value in the alertedPhone Property row, in the Value column.   Enter a phone number to receive the SMS alert, then click the Check icon above where you entered the phone number. Click the pencil icon in the temp Property row, in the Value column. Enter a value for the temp property that is greater than 30, and click the Check icon. In a couple seconds, the phone number you entered will receive an alert that includes the value you entered.      Step 6: Next Steps   Congratulations!   In this guide, you learned how to:   Create a Thing using the Twilio Thing Template Configure the Twilio Thing to use your Twilio account Send text messages using a Service   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Twilio Extension Help Center
View full tip
    Use the Pareto Chart Widget to visualize how issues compound to cause problems.   GUIDE CONCEPT   The Pareto Chart Widget is a useful method of displaying aggregate information.  In particular, it is often used to display multiple issues and how they combine to form an overall, larger problem.    This can be helpful when trying to determine "easy wins" by pointing out where your efforts will have the greatest impact.       YOU'LL LEARN HOW TO   Create a Data Shape Create a Thing Create an Info Table Property Populate an Info Table with appropriate data for a Pareto Chart Create a Mashup Utilize a Pareto Chart to display issue-aggregation   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes       Step 1: Scenario   In this guide, we'll assume a scenario where a factory is being automated using ThingWorx Foundation. In particular, this factory has some known issues with a robot arm that performs welding at a point along a conveyor belt.    When this welding robot has these issues, the factory line has to come to a complete halt while maintenance is performed on it.   Management has decided that these slow-downs are costing enough money that the robot arm needs some extra attention, up to and including modification to help alleviate these maintenance stops.    However, they're not sure what to tackle first. Every issues leads to a slow down, but some happen more frequently than others.    After talking with maintenance, four primary issues are identified, i.e.   Excess temperature on the welding end has caused some welds to fail due to simply burning through the material. Some of the joints need regular lubrication, preventing the arm from getting to the correct location in time as the part moves down the conveyor belt. The welding filler-material sometimes runs out, causing a stop while more is reloaded. The welding shielding gas sometimes runs out, causing a stop while more is reloaded.   Your task, then, is to start counting the number of times each of these failures occur. In addition, you need to create a small GUI which displays both how often these errors occur, and how they contribute to the overall downtime.    To accomplish this, you'll use a Pareto Chart Widget.     Step 2: Create Data Shape   In this scenario, we'll store the Pareto Chart's data in a Property type called an Info Table.   An Info Table is a spreadsheet-like Property, but in order to define the columns of the table, we first have to define a Data Shape. We'll do that in this step.   In the left-side navigation, click Browse > Modeling > Data Shapes. At the top, click + New. In the Name field, type TIPC_DataShape. If Project is not already set, search for and select PTCDefaultProject. At the top, click Field Definitions. At the top-left, click + Add. On the right-side slide-out, in the Name field, type month. Note that you want to leave "Base Type" as the default of "STRING". Check Is Primary Key. Click the "check with a plus" button for Done and Add. Add each of the following Field Definitions, entering the Name and selecting the Base Type from the drop-down as described in the table: Note that you will NOT enable "Is Primary Key" on any other Field Definitions, as you only need one Primary Key. Note that you will simply click the "check" button for Done after the last entry . Name Base Type  excess_temperature NUMBER  need_lubricant NUMBER  low_filler NUMBER  low_gas NUMBER At the top, click Save.   Step 3: Create Thing   Now that we have our Data Shape, we can create a Thing to hold the collected counts of various issues.   As already mentioned, we'll use an Info Table Property, formatted by the previously-created Data Shape, to do so.   Click Browse > Modeling > Things.   Click + New. In the Name field, type TIPC_Thing. If Project is not already set, search for and select PTCDefaultProject. In the Base Thing Template field, search for and select GenericThing.   At the top, click Save.     Add Info Table Property   Now that we have our Thing instantiated, we want to both add an Info Table Property, as well as set some Default Values.   At the top, click Properties and Alerts.   Click + Add.   On the right-side slide-out, in the Name field, type InfoTable_Property. Change Base Type to INFOTABLE. In the Data Shape field, search for and select TIPC_DataShape. Note that the Data Shape field will not appear until you set Base Type to INFOTABLE. Check Persistent.   At the top-right, click the "check" button for Done. At the top, click Save.   Set Value of Property Now that we have a place in which to store spreadsheet-like values, we'll do so manually for testing.   On the InfoTable_Property row, under the Value column, click the "pencil" icon for Set value of property.   On the pop-up, click + Add.   Enter the following values in each field as per the table below: Field Name Value month  January excess_temperature 5 need_lubricant 2 low_filler 1 low_gas 2   Click Add.   Click + Add again, enter the following values, and finish input by clicking Add, as per above. Field Name Value month February excess_temperature 7 need_lubricant 1 low_filler 3 low_gas 2 6. Click + Add again, enter the following values, and finish input by clicking Add, as per above. Field Name Value month March excess_temperature 6 need_lubricant 2 low_filler 1 low_gas 1   7. On the pop-up, click Save.   8. At the top, click Save.   Step 4: Create Mashup   Now that we have our data in-place for testing (and could be connected to automated systems after we finish testing), we need to visualize the data.   As mentioned, we'll use a Pareto Chart Widget, but first, we need to create a Mashup into which we can place the Widget.   Click Browse > Visualization > Mashups.   Click + New.   Leave the defaults and click OK.   In the Name field, type TIPC_Mashup. If Project is not already set, search for and select PTCDefaultProject. At the top, click Save .   At the top, click Design.   At the top-left, click the Widgets tab.   Drag-and-drop a Pareto Chart Widget onto the central Canvas.   At the top, click Save.   Click here to view Part 2 of this guide.
View full tip
  Step 5: Format Timed Values   At the top, click the Services section of scts_thing.   In the Ihnerited Services section, you will see the built-in services of the Statistical Calculation Thing Shape. These services can perform a variety of analytical calculations.   Timed Values Service   The Statistical Calculation Thing Shape can only perform analytics operations on time-series datasets. However, accessing a time-series Value Stream can have a performance hit on the system.   Instead, a Property with an Info Table using a timestamp/value Data Shape is used as the universal input to each built-in service of the Statistical Calculation Thing Shape.   For efficiency, we only reference the Value Stream once to create a formatted timedValues that is used as an input to all other service calls.   At the top, click Services.   Click + Add.   In the Name field, enter timed_values_service. In the Javascript field, copy and past the following code: me.timed_values = me.QueryTimedValuesForProperty({ propertyName: "numbers", maxItems: 10, startTime: me.start_time, endTime: me.end_time });   At the bottom, click Save and Execute.   Click Done, and return to Properties and Alerts. On the timed_values property row, click the pencil icon for Set value of property.   In the pop-up, note that there are now seven entries - each with the 1, 5, 9, 5, 9, 1, and 9 values and the timestamps when you entered them.   In the pop-up, click Cancel. If needed, in the top-right, click the icon to close the slide-out.   Step 6: Calculation Services   Now that the numbers, start_time, end_time, and timed_values service inputs have been set, you can use the built-in Services of the Statistical Calculation Thing Shape to perform a variety of analytics calculations.   Mean Service   First, you will utilize the built-in CalculateMeanValue service.   The dataset is the following: 1, 5, 9, 5, 9, 1, 9.   As such, the mean should be (1+5+9+5+9+1+9)/7 = 39/7 = 5.571...   Return to the Services section. At the top, click + Add. In the Name field, enter mean_service. In the Javascript code section, copy and paste the following: me.mean_result = me.CalculateMeanValue({ timedValues: me.timed_values }); At the top, click Save and Continue.   At the bottom, click Execute. Click Done, then return to the Properties and Alerts section. Note that the mean_result property now has the value 5.571....     Median Service   Next, you will utilize the built-in CalculateMedianValue service.   With our dataset having 5 as the middle value, that should be the result.   Return to the Services section. At the top, click + Add. In the Name field, enter median_service. In the Javascript code section, copy and paste the following: me.median_result = me.CalculateMedianValue({ timedValues: me.timed_values }); At the top, click Save and Continue. At the bottom, click Execute. Click Done, and return to the Properties and Alerts section. Note that the median_result Property now has the value 5.     Mode Service   You will now utilize the built-in CalculateModeValue service.   With the dataset having 9 as the most common value, that should be the result.   Return to the Services section. At the top, click + Add. In the Name field, enter mode_service. In the Javascript code section, copy and paste the following: me.mode_result = me.CalculateModeValue({ timedValues: me.timed_values }); At the top, click Save and Continue.   At the bottom, click Execute. Click Done, and return to the Properties and Alerts section. On the mode_result row and under the Value column, click the "pencil" icon for Set value of property.   In the popup, note that the mode_result Property now has the value 9.   Click Cancel to close the popup. If necessary, at the top-right, click the button to close the slide-out.   Standard Deviation Service   Lastly, you will utilize the built-in CalculateStandardDeviationValue service.   There are multiple free Standard Deviation calculators to check the answer.   Accordingly, the Standard Deviation should be 3.59894...   Return to the Service section. At the top, click + Add. In the Name field, enter standarddev_service. In the Javascript code section, copy and paste the following: me.standarddev_result = me.CalculateStandardDeviationValue({ timedValues: me.timed_values }); At the top, click Save and Continue.   At the bottom, click Execute. Click Done, and return to the Properties and Alerts section. Note that the standarddev_result property now has the value 3.59894...       Step 7: Other Options   The Mean, Median, Mode, and Standard Deviation services you have completed are just a sampling of what the Statistical Calculation Thing Shape offers.   Below is a table of additional built-in services:   Calculation Service Name Description Binned Data Distribution for Bin Size CalculateBinnedDataDistributionForBinSize Calculate the binned distribution of data points based on the desired bin size. Binned Data Distribution for Number of Bins CalculateBinnedDataDistributionForNumberOfBins Calculate the binned distribution of data points based on the desired number of bins. Confidence Interval Values CalculateConfidenceIntervalValues Confidence Interval Values Based on a specified confidence interval percentage, calculate the minimum, median, and maximum interval values. Five Number Property Values CalculateFiveNumberPropertyValues Calculate the five number values: minimum, lower quartile, median, upper quartile, and maximum. Fourier Transform CalculateFourierTransform Calculate the results of running the fast Fourier transform on the specified values. Maximum Value CalculateMaximumValue Calculate the maximum property value in the provided infotable. Minimum Value CalculateMinimumValue Calculate the minimum property value in the provided infotable. Sampling Frequency Values CalculateSamplingFrequencyValues Calculate the sampling frequency values: minimum, median, and maximum.     Step 8: Next Steps   Congratulations!   In this guide, you have learned how to:   Create a Value Stream and Data Shape Create a Thing with the Statistical Calculation Thing Shape Modify a property to record values to the Value Stream Utilize various built-in services for analytical calculations   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Build a Predictive Analytics Model Build Operationalize an Analytics Model   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Descriptive Analytics Help Center
View full tip
  Setup methods and schemes to secure your data   Guide Concept   Securing data is often something thought of after an application is designed. It should always be the first and more important.   These concepts and steps will allow you to focus on development of your application while still allowing the ability to utilize the power of ThingWorx!   We will teach you how to design a secure environment and application from scratch     You'll learn how to   How to design and implement organizations and organization sections Creating secure User Groups with specific goals Limit access to resources   NOTE:  The estimated time to complete this guide is 30 minutes     Step 1: Examples and Strategy   If you’d like to skip ahead, download and unzip the completed example of the Aerospace and Defense learning path: AerospaceEntitiesGuide1.zip. Import the .twx files included.   In an ever-changing world, you are going to need to protect everything that is considered private. This includes your data, the data people provide you, and the resources you consider important. All of this can be done using the ThingWorx environment. ThingWorx provides a system for security that can be configured endlessly. There is the security being handled at the server level internally and with Apache, in which you have access to. The security being handled in the ThingWorx Composer, which you can customize. Lastly, there is the security you provide at the client side for users accessing your application or system.   Let us start working on securing our system before we add extra users and workers. First, we will create and organization and organization levels within our agency to help designate access. We will create the security access to the ThingWorx Composer, which is where our data will be held for now in this learning path. We will then create access levels for internal employees, including administrators, developers, and workers based on security clearance levels.     Step 2: Setup Organizations and Departments   Creating Our Organizations   If you need a refresher on how to create security groups and permissions, take a look back at our Configure Permissions Guide. If you are ready to get started, follow the instructions below:   1.  In the ThingWorx Composer, click the + New button in the top left.    2. In the dropdown list, click Organizations.      3. In the Name field, give our agency name, such as PTCDefenseDepartment.   4. Set the Project field to an existing Project (ie, PTCDefaultProject) and click Save to save your work. 5. Go to the Organization tab and you will see the beginning of our Organization.     Creating Our Departments    Let us add some departments in our Organizations. We will add a few here but add as many as you like. Just keep in mind, these departments do not need to match every department in the actual Organization. These departments will be used for access to different resources.   1. Click on the first unit and update the Name field to DefenseDepartment. Click the check mark to save your changes.   NOTE: You can add the spaces if it looks better to you. You will be using these departments throughout this learning path. You can also change these later.   2. Under our first unit (DefenseDepartment), click the green + button. Name this unit HumanResources.     3. Repeat the last step to create three more departments under our DefenseDepartment unit. Name these new units Agents, Visitors, and IT.   4. Under the Visitors unit, click the green + button to add a unit and name it Applicants.     5. Repeat the last step to add one more unit under the Visitors unit. Name this group OtherAgencies. Your setup should have the following departments.      You now have a complete start to our agency. What does that mean exactly? An Organization allows us to limit resources to only members of that overall Organization or specific unit within that Organization. You will get firsthand experience as we move further in this guide.    Let us create our Security Groups to those that will absolutely need it. This is a big decision point into how you would like to do this and there is no truly wrong answer. Will each user for this application or utility have their own User account in ThingWorx or share User accounts based on usage? Will you grant access to this application through LDAP, database verification, or a Create An Authentication Extension. The list of questions into what is supported for authentication in ThingWorx is almost endless.     Step 3: Setup Users and User Groups   Creating User Groups and Users   For simplicity and timing, we will create a User Group and User for each department (be mindful of the number of allowed Users in the ThingWorx version you are using). We will also create a super user account that will provide us with full access. Finally, we will need to create an extra User Groups for ThingWorx Composer access.     First, User Groups   1. In the ThingWorx Composer, click the + New at the top left of the screen.     2. Select User Groups in the dropdown.     3. Name the User Group Agency.ComposerAccess.     4. Set the Project field to an existing Project (ie, PTCDefaultProject) and click Save. 5. Repeat steps 1-4 to create a User Group for each department (Agency.HumanResources, Agency.Agents, Agency.Visitors, Agency.Applicants, Agency.OtherAgencies, and Agency.IT).   Now, Users   1. In the ThingWorx Composer, click the + New at the top left of the screen.     2. Select User in the dropdown.     3. Name the User User.AgencySuperUser and add a password.     4. Set the Project field to an existing Project (ie, PTCDefaultProject) and click Save. 5. Repeat steps 1-4 to create a User for each department (User.HumanResources, User.Agents, User.Visitors, User.Applicants, User.OtherAgencies, and User.IT).   Adding Members to User Groups   Assign each user to the corresponding User Group using the below instructions.   1. Open the Agency.HumanResources User Group.  2. Click on the Manager Members tab.     3. Filter and select the User you want to add in the Available Members section. In this case, User.HumanResources. 4. Click the arrow on that User’s row or drag and drop the User to the Members section.      5. Click Save. 6. Repeat steps 1-5 for each department User Group you created earlier with their corresponding User.   We should have an extra User Group (Agency.ComposerAccess) and an extra User (User.AgencySuperUser). We will utilize these Entities below. For now, only our IT department needs access to the ThingWorx Composer.   1. Open the Agency.ComposerAccess User Group.  2. Click on the Manager Members tab.     3. Filter and select the User Group you want to add in the Available Members section. In this case, Agency.IT. 4. Click the arrow on that User’s row or drag the User to the Members section.      5. Click Save.   Our super user will need top level access to everything in ThingWorx. To do this, we will add the User to the Administrators User Group.   1. On the left-hand side of the ThingWorx Composer, click Browse. 2. Click on User Groups on the left panel.     3. At the top of the screen, click the filter button near the search bar. 4. Check the checkbox for Show System Objects and click Apply.     5. Filter and select the Administrators User Group.    6. Click on the Manager Members tab.     7. Filter and select the User you want to add in the Available Members section. In this case, User.AgencySuperUser. 8. Click the arrow on that User’s row or drag the User to the Members section.    9. Click Save.     Step 4: Setup Permissions   Setting Bulk Permissions   1. On the left panel, select Permissions.   2. Click Collections on the menu that appears.     3. Select the checkbox at the top to select all available Entities then click Edit Permissions.     4. On the Visibility tab, click the + button in the Search Organizations filter. 5. Enter PTCDefenseDepartment and click the expand arrows to select the IT department. A more granular Visibility level can be set on the specific Entities when created later in this learning path.     6. Select the Design Time tab. 7. Enter Agency.ComposerAccess in the search bar and select the Agency.ComposerAccess User Group.   8. Select the check marks for Create, Read, Update, and Delete. A more expansive design for a production environment would create more Users and User Groups to have such access.     9. Set the permissions for the other groups we have created to not allow any Create, Read, Update, and Delete permissions for groups outside of Agency.ComposerAccess and Agency.IT. It should look like the below configuration.     10. Set the same permissions in the Run Time tab for the User Groups we have created.     11. Click Save.   Now, if you log into the ThingWorx Composer using any account other than our super user account or the User.IT account, you’ll see that you may be able to see Entities, but you cannot open them. You will see an unauthorized popup. If you have access to a browser with a Private or Incognito mode, use it instead of logging out of your Administrator account.     Click here to view Part 2 of this guide.
View full tip
    Step 4: Launch IoT Hub Connector   Open a shell or a command prompt window. On a Windows machine, open the command prompt as Administrator. The AZURE_IOT_OPTS environment variable must be set before starting the Azure IoT Hub Connector. Below are sample commands using the default installation directory. On Windows: set AZURE_IOT_OPTS=-Dconfig.file=C:\ThingWorx-Azure-IoT-Connector-<version>\azure-iot-<version>-application\conf\azure-iot.conf -Dlogback.configurationFile=C:\ThingWorx-Azure-IoT-Connector-<version>\azure-iot-<version>-application\conf\logback.xml On Linux: export AZURE_IOT_OPTS="-Dconfig.file=/var/opt/ThingWorx-Azure-IoT-Connector-<version>/azure-iot-<version>-application/conf/azure-iot.conf -Dlogback.configurationFile=/var/opt/ThingWorx-Azure-IoT-Connector-<version>/azure-iot-<version>-application/conf/logback.xml" NOTE: You must run the export command each time you open a shell or command prompt window. Change directories to the bin subdirectory of the Azure IoT Hub Connector installation. Start the Azure IoT Hub Connector with the appropriate command for your operating system. On Windows: azure-iot.bat On Linux: /azureiot   NOTE: On Windows you may have to shorten the installation directory name or move the bin directory closer to the root directory of your system to prevent exceeding the Windows limit on the classpath length. The Connection Server should start with no errors or stack traces displayed. If the program ends, check the following: Java version is 1.8.0, update 92 or greater and is Java(TM) not OpenJDK Open azure-iot.conf and confirm ThingWorx Foundation is set to the correct URL and port. Confirm the platform scheme is ws if http is used to access ThingWorx. Confirm all Azure credentials are correct for your Azure account. In ThingWorx Foundation click the Monitoring tab then click Connection Servers. You should see a server named azure-iot-cxserver-{server-uuid}, where {server-uuid} is a unique identifier that is assigned automatically to the server.     Step 5: Import Device from Azure   With the ThingWorx Azure IoT Connector, you can import into ThingWorx any existing devices that are currently provisioned to the Azure IoT Hub.   Add Device Azure IoT Hub If you have not provisioned any devices to your Azure IoT Hub you can learn more about Azure IoT Hub device identity before following the steps below to create a test device. In your Azure Portal, click All Resources, then select the name of your IoT Hub. Under Explorers click IoT devices, then click + Add. Enter a name for your device, then click Save When the device name appears in the list it is ready to us     Import Device into ThingWorx We will manually execute a service in ThingWorx that will import Azure IoT Hub devices into ThingWorx. In ThingWorx Composer, navigate to the ConnectionServicesHub Thing. Click Services tab and scroll to the ImportAzureIotDevices service and click the execute Arrow.   NOTE: The * in the pattern field will act as a wildcard and import all devices, you can enter a string to match that will only import a subset of all available devices.     Click Execute to import the devices then click Done. Click Things in the left column to see the Things that were created.     Step 6: Set-up and Run Demo   The ThingWorx Azure IoT Connector download includes a Java application that simulates a device connecting to your Azure IoT Hub. A ThingTemplate is also included and can be imported into ThingWorx.   Import Demo Templates In ThingWorx Composer, click Import/Export menu, then click From File and browse to ../demo/edgedevice- demo/platform/entities/CPUDemo_AllEntities.xml     Click Import then click Close when the import successful message is displayed. Create a new Thing using the imported template azureDemo1, enter a name for your Thing and click Save. NOTE: You will enter this name in the demo config file in the next step.   Configure Demo Application In the ../demo/edge-device-demo/conf subdirectory, open the edge-device.conf file with a text editor. Edit the deviceId to be the name of the Thing you created in step 3. Edit the iotHubHostName to use the name of your hub plus the domain: azure-devices.net. For example, sample-iot-hub.azuredevices.net. Edit the registryPolicyKey property to use the Primary Key for the registryReadWrite policy in the Azure IoT Hub. Below is an example configuration: // Azure Edge Device Demo configuration azure-edge-device { // Name of the remote thing on the ThingWorx platform, which should match the Azure Device ID deviceId = "alstestedgething" // Name of the hub host in Azure iotHubHostname = "alsiot.azure-devices.net" // Policy name used by this thing (could require services as well in future) registryPolicyName = "registryReadWrite" // The Key related to the policy above registryPolicyKey = "pzXAi2nonYWsr3R7KVX9WuzV/1234567NZVTuScl/Kg=" } Run Demo Script   Open a shell or Command Prompt, set the EDGE_DEVICE_DEMO_OPTS environment variable to refer to the file you just edited: Linux - export EDGE_DEVICE_DEMO_OPTS="-Dconfig.file=../conf/edge-device.conf" Windows - set EDGE_DEVICE_DEMO_OPTS="-Dconfig.file=../conf/edge-device.conf" Launch the demo from the ../demo/edge-device-demo/bin subdirectory, using the edge-device-demo command. Return to the ThingWorx Composer and open the Properties page of the Azure Thing that you created previously. Click the refresh button to see the properties change every five seconds. Open the azure-iot-demo Mashup and view the Load Average and CPU gauges, and the increases in the values of the Cycle and Uptime fields. NOTE: If the edgedevice-demo is running on Windows, the Load Average does not register. Step 7: Next Steps   Congratulations! You've successfully completed the Connect Azure IoT Hub to ThingWorx Quickstart. By following the steps in this lesson, you imported a device created in Azure into ThingWorx and saw how data from an Azure device could be used in a ThingWorx Mashup. Learn More We recommend the following resources to continue your learning experience: Capability Guide Connect Choose a Connectivity Method Build Design Your Data Model Experience Create Your Application UI   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Getting Started with ThingWorx  
View full tip
  Use the Statistical Calculation Thing Shape to Execute Common Statistical Functions   GUIDE CONCEPT   This project will introduce the Statistical Calculation Thing Shape.   The steps in this guide outline how to utilize Descriptive Analytics in ThingWorx Analytics to perform common mathematical analyses on data sets. You will learn how to use the Statistical Calculation Thing Shape's built-in functionality to calculate the mean, median, mode, and other useful insights.     YOU'LL LEARN HOW TO   Create a Value Stream and Data Shape Create a Thing with the Statistical Calculation Thing Shape Modify a Property to record values to the Value Stream Utilize various built-in services to perform the Mean, Median, Mode, and Standard Deviation calculations   NOTE: The estimated time to complete this guide is 30 minutes.     Step 1: Introduction   Descriptive Analytics enables users to perform on-demand common statistical calculations and enable statistical monitoring. Output from these Services can then easily be added to IoT applications built with the ThingWorx platform.   For example, output generated by Descriptive Analytics can be used to build solution-specific visualizations (Mashups or Widgets), create Alerts based on logged Property values, or generate transformed data for machine learning processes.   Descriptive Analytics includes two microservers, each with its own set of statistical Services. This guide will deal specifically with the Statistical Calculation Thing Shape.   This Thing Shape will add a variety of built-in Services to any Thing or Thing Template you choose, such as calculations for Mean, Median, Mode, or Standard Deviation.   To perform these statistical calculations, a Property must have time-series data logged to a Value Stream.   In addition, the Statistical Calculation Thing Shape has been optimized to perform calculations only on particular time ranges and with a maximum entry-count. This helps minimize some of the performance hits that can occur from repeatedly accessing Value Streams.   You perform this "data grooming" via the QueryTimedValuesForProperty Service, which is also part of the Statistical Calculation Thing Shape.   In addition to the name of a Property with values logged to a Value Stream, you also provide a Start Date, End Date, and Max Item Count.   The QueryTimedValuesForProperty Service then formats the values from the Value Stream to work with for the other built-in statistical calculation Services.   Step 2: Create Prerequisites   The inputs to the built-in Services of the Statistical Calculation Thing Shape require time-series data stored in a Value Stream. Setting a Thing's Properties to be Logged will store valid time-series data on which to perform Descriptive Analytics.   Create Value Stream   Follow the steps below to create a Value Stream that you will later tie to a Thing.   On the ThingWorx Composer Browse tab, click DATA STORAGE > Value Streams, + New.   Select ValueStream and click OK.   In the Name field, enter scts_valuestream. If Project is not already set, search for and select PTCDefaultProject.   At the top, click Save.   Create Data Shape   You will need a Data Shape to format the timed_values Property we will create in the next step.   On the ThingWorx Composer Browse tab, click MODELING > Data Shapes, + New.   In the Name field, enter scts_timed_values_datashape. If Project is not already set, search for and select PTCDefaultProject.   At the top, click Field Definitions.   Click + Add. On the right slide-out, in the Name field, enter value. Change the Base Type to NUMBER.   At the top-right, click the "check with a +" icon for Done and Add. In the Name field, enter timestamp. Change the Base Type to LONG.   At the top-right, click the "check" icon for Done. At the top, click Save.       Step 3: Create Thing   Next, you will create a Thing and tie the previously-created Value Stream to it.   You will assign the Statistical Calculation Thing Shape to get a variety of built-in analytics Services to manipulate the data. You will also create a series of Properties to facilitate the new Services.   On the ThingWorx Composer Browse tab, click MODELING > Things, + New.   In the Name field, enter scts_thing. If Project is not already set, search for and select PTCDefaultProject. In the Base Thing Template field, search for and select GenericThing. In the Implemented Shapes field, search for and select StatisticalCalculationThingShape. In the Value Stream field, search for and select scts_valuestream.   At the top, click Save.   Add Properties   Next, you will add a series of Properties to scts_thing.   Perform the following steps repeatedly until all Properties have been added.   At the top, click Properties and Alerts.   Click + Add. On the right slide-out, in the Name field, enter numbers. Change the Base Type to NUMBER. Click Persistent. Click Logged.   At the top-right, click the "check with a +" icon for Done and Add. Repeat steps 3-7 until all of the properties in the table below have been added. NOTE: For the final standarddev_result Property, do NOT click Done and Add; you'll just click the check for Done instead. Property Name Base Type Data Shape Persistent  Logged start_time DATETIME N/A Checked NOT checked end_time DATETIME N/A Checked NOT checked timed_values INFOTABLE scts_timed_values_datashape Checked NOT checked mean_result NUMBER N/A Checked NOT checked median_result NUMBER N/A Checked NOT checked mode_result INFOTABLE none, i.e. leave it blank Checked NOT checked standarddev_result NUMBER N/A Checked NOT checked     At the top-right, click the "check" icon for DONE. At the top, click Save.   Step 4: Set Properties   You will now set the properties to guarantee that each calculation gives us a different answer.   Mean is the average. Median is the "middle" number from the dataset. Mode is the most common number. Standard Deviation is a measure of the "dispersion" of the dataset.   You will use the following dataset: 1, 5, 9, 5, 9, 1, 9.   The mean is 39 / 7 = 5.571...   The median is 5, as 5 is the middle of 1, 5, and 9.   Mode is 9, because 9 appears most commonly in the dataset.   Standard Deviation is 3.5989...   Perform the following steps to enter the above values into the numbers property.   Set numbers   Under the Value column and on the numbers property row, click the "pencil" icon for Set value of property.   On the right slide-out, enter 1.   At the top-right, click the "check" icon for Done. At the top, click Save.   Repeat steps 1-4 above, changing the value each time according to the table below: Value Change Count  Entered Value 2nd 5 3rd 9 4th 5 5th 9 6th 1 7th 9   You also need to set the start_time and end_time. These are dates used to define the time-period in which the Statistical Calculation Thing Shape will search for values.   For instance, you could set the calculations to run at midnight, and then use the past 24-hours as your time-period.   For this example, set dates to be 24 hours prior to the time at which you set the above values of the numbers property, through 24 hours in the future.   Set start_time   Under the Value column and on the start_time Property row, click the "pencil" icon for Set value of property.   On the right slide-out, search for and select the previous day.   At the top-right, click the "check" icon for Done. At the top, click Save.   Set end_time   Under the Value column and on the end_time property row, click the "pencil" icon for Set value of property.   On the right slide-out, search for and select the following day. At the top-right, click the "check" icon for Done. At the top, click Save.     Click here to view Part 2 of this guide.
View full tip
  Connect Devices and Equipment Using Industry-Standard Protocol Drivers in ThingWorx   GUIDE CONCEPT   This guide has step-by-step instructions for connecting ThingWorx Kepware Server to ThingWorx Foundation.   This guide will demonstrate the ease of connecting edge industrial equipment to ThingWorx Foundation without installing any software on production equipment.   We will also show how connecting different systems and devices improves operations through the creation of business intelligence.     YOU'LL LEARN HOW TO   Connect ThingWorx Kepware Server to ThingWorx Foundation Secure the connection with an Application Key Create an IndustrialGateway Thing Map ThingWorx Kepware Server Tags to ThingWorx Foundation Thing Properties Visualize Data from connected digital assets   Note: The estimated time to complete this guide is 30 minutes     Step 1: Installation   Download the ThingWorx Kepware Server executable application from MyKepware. If you desire installation instructions, you may find them in the attached guide: install-thingworx-kepware-server.zip . Navigate to START -> PTC. Click ThingWorx Kepware Server 6 Configuration.                           For additional information on ThingWorx Kepware Server, click Help -> Server Help on the Menu Bar.         Step 2: Create Gateway   To make a connection between ThingWorx Kepware Server and Foundation Server, you must first create a Thing.   WARNING: To avoid a timeout error, create a Thing in ThingWorx Foundation BEFORE attempting to make the connection in ThingWorx Kepware Server.   In ThingWorx Foundation Composer, click Browse > Modeling -> Things.   Click + NEW. In the Name field, type IndConn_Server, including matching capitalization. In the Description field, enter an appropriate description, such as Industrial Gateway Thing to connect to ThingWorx Kepware Server. If the Project field is not already set, search for and select PTCDefaultProject. In the Base Thing Template field, search for and select IndustrialGateway.   Click Save.     Step 3: Create an AppKey   To secure the connection between ThingWorx Foundation and ThingWorx Kepware Server, you need to utilize an Application Key.   In ThingWorx Foundation, click Browse > Security -> Applications Keys.   Click + New. In the Name field, type IndConn_AppKey. If Project is not already set, search for and select PTCDefaultProject. Set User Name Reference to the Administrator User. Click Yes on the warning pop-up.   Assign an Expiration Date that is far enough in the future to not interfere with your trial.   Click Save.   Under Key ID, click the page icon to the right of the Application Key string to copy it.     Step 4: Connect to Foundation   Now that you’ve created an IndustrialGateway Thing and an Application Key, you can configure ThingWorx Kepware Server to connect to ThingWorx Foundation.   Return to the ThingWorx Kepware Server Windows application. Right-click Project. Select Properties….   In the Property Editor pop-up, click ThingWorx. In the Enable field, select Yes from the drop-down. In the Host field, enter the IP address or URL of your ThingWorx Foundation server. Enter the Port number. If you are using the "hosted" Developer Portal trial, enter 443.     In the Application Key field, copy and paste the Application Key you just created. In the Trust self-signed certificates field, select Yes from the drop-down. In the Trust all certificates field, select Yes from the drop-down. In the Disable encryption field, select No from the drop-down if you are using a secure port. Select Yes if you are using an http port. Type IndConn_Server in the Thing name field, including matching capitalization. If you are connecting with a remote instance of ThingWorx Foundation and you expect any breaks or latency in your connection, enable Store and Forward. Click Apply in the pop-up. Click Ok.   In the ThingWorx Kepware Server Event window at the bottom, you should see a message indicating Connected to ThingWorx.     NOTE: If you do not see the "Connected" message, repeat the steps above, ensuring that all information is correct. In particular, check the Host, Port, and Thing name fields for errors.     Click here to view Part 2 of this guide.
View full tip
  Utilizing the ThingWorx monitoring system   Guide Concept   Being able to view your logs is an important part of knowing what is happening in your system. You can't keep things secure if you don't know who is doing what.   These concepts and provide you with ways to find information about what is going on in your application and system.   We will teach you how to access the monitoring panel and help keep your application running the way you need it to.     You'll learn how to   How to log data and capture useful information How to filter and find what you need in the monitoring pages.   NOTE:  The estimated time to complete this guide is 30 minutes     Step 1: Example and Strategy   If you’d like to skip ahead, download the completed example of the Aerospace and Defense learning path: AerospaceEntitiesGuide1.zip. Extract, then import the .twx files included.   In the last guide, we ended with viewing the Monitoring section of ThingWorx. What you’ll now learn is a more detailed method to knowing exactly what is happening in your application. Part of the magic in logging comes from informative statements and how you perform your error handling.   We will create an Entity with a number of services that will allow us to see what is happening in our application. In order to automate these services and view the logs that they generate, we’ll be using Schedulers. When we have everything running, we’ll go over how to utilize the Monitoring section to its strengths.     Step 2: Utilizing Logging Functions   Errors happen. Sooner or later, there will be an error. When you have an error in your application, you need to know about it and have information to help resolve the problem. There are 5 main logging functions under the universal logger object – info, debug, trace, warn, and error.   Function  Description  info Used for high level and general information. debug Used for debugging an application and capturing data. trace Used for low level and tracking what is happening. warn Used to warn for possible errors or problems. error Used for showing an error in a log.   Let’s create a Thing that performs logging for different data types (complex types will be handled in the next section).   1.  In the ThingWorx Composer, click the + New button in the top left.  2. In the dropdown list, click Thing.   3. In the Name field, give our agency name, such as  LoggingServices. 4. In the Base Thing Template field, select GenericThing. 5. Select a Project, such as PTCDefaultProject. Set this as the default context if you wish.   6. Click Save.     Let's start creating our services.   1. Click the Services tab. 2. Click the Add button to create a new JavaScript service.   3. Enter LogInformation in the Name field of the service. 4. Enter the below lines as the code for the service.   logger.trace("LoggingServices.LogInformation(): Entering Service."); logger.info("LoggingServices.LogInformation(): Logging at Information Level"); try { var x = 10; var y = 20; var z = 0; logger.debug("LoggingServices.LogInformation(): Logging Addition - " + (x + y)); logger.debug("LoggingServices.LogInformation(): Logging Division - " + (y / z)); } catch(error) { logger.error("LoggingServices.LogInformation(): Error - " + error); } logger.trace("LoggingServices.LogInformation(): Ending Service."); 5. Click the Save and Continue button. Hit the Execute button.   When triggered, this service will print the trace information for the service, the information level logging, the sum of the x and y variables, and our error message (because of our division by 0 attempt). In the next section, we’ll cover the log file types and how to filter to get what we want.       Step 3: Logging Complex Objects   As you know, with JavaScript, objects can be seen as JSON. That being said, The JSON.stringify function is very handy in printing out complex objects in ThingWorx (NOTE: In order to print out an InfoTable, use <infotable>.toJSON() ). Let’s create a new service to log more complex types.   1.     Open our LoggingServices Thing that we created in the earlier sections. 2.     Click the Services tab. 3.     Click the Add button to create a new service. 4.     Enter LogComplexObjects  in the Name field. 5.     Enter the below statements into the code area.   logger.trace("LoggingServices. LogComplexObjects (): Entering Service."); logger.info("LoggingServices. LogComplexObjects (): Logging at Information Level"); try { var x = {}; x.y = 20; x.z = 0; logger.debug("LoggingServices. LogComplexObjects (): Logging Addition - " + (x + y)); logger.debug("LoggingServices. LogComplexObjects (): Logging Division - " + (y / z)); } catch(error) { logger.error("LoggingServices. LogComplexObjects (): Error - " + error); } logger.trace("LoggingServices. LogComplexObjects (): Ending Service.");   After you execute this service, you should be able to see the outcome in the ScriptLog. Try utilizing some of the filtering methods we mentioned in order to find the log statements.       Step 4: Viewing and Filtering Logs   In the table below, you’ll see what each of the logs showcase. Keep in mind, while some of these logs are accessible in the ThingWorx composer, you can view all of these logs on the server in the /ThingworxStorage/logs directory.   Log Description   Application Log  The Application Log contains all of the messages that ThingWorx logs while operating. Depending on your settings, this log can display errors only or every execution of the platform.  Communication Log  The Communication Log contains all communication activity with ThingWorx.  Configuration Log  The Configuration Log contains all of the messages that the ThingWorx application generates for any create, modify, and delete done in ThingWorx. For example, if a Thing or Mashup is created, modified, or deleted, that information will be included in the ConfigurationLog.  Database Log  The DatabaseLog contains all messages related to database activity.  Script Log  The ScriptLog contains all of the messages that the ThingWorx application generates while executing JavaScript services. You can use logger.warn(or logger.info, logger.trace, logger.debug, logger.error). By default, the log displays warnings and errors, so we recommend using the warn function to log this information from the services you are running. Generally, ThingWorx will only publish errors that were incurred while running a service to this log.  Security Log  The Security Log contains all of the messages that the ThingWorx application generates regarding users. This information can include login data and page requests depending on the log level.  Script Error Log  The Script Error Log contains the stack trace for scripts created in the platform and is only available in the ScriptErrorLog.log file. Not accessible in the Composer.   Let’s go to the Monitoring section of the ThingWorx Composer and view the results from the server we triggered earlier.   1.     Click on the Monitoring section on the left-hand side of the Composer.   2.     Click on ScriptLog. Based on your role on this team, this might be the log that you view the most.     3.     You should be able to see or find the logs we recently generated from executing our new service.   The logging views in Composer will generally show you the last 24-hour period. This can be helpful if you know something ran within the last day. Based on the amount of logging your system performs, that can be way too large a window. Let’s start playing with the filters and searches.       # Function  1 The search text box allows you to search for specific words in the log based on your time window. Once you have entered the word, hit the **ENTER/RETURN key on your keyboard. 2 The filter button provides a menu that provides more features to filter the logs. See below. 3 The configure button provides a pop-up that allows you to filter incoming log statements based on a certain logging level. See below. 4 The date range will default to the last 24 hours but can be updated to a wider or smaller window. You will need to click the Apply button when ready. 5 The max rows field provides how many records will come back in the view. The search will continue until it hits this number, or your date range is met. You can shorten this field for faster searching or increase it up to 1000 to showcase more information. You will need to click the Apply button when ready. 6 Apply and Reset buttons. Apply will run the search you currently have on the screen. Reset will reset the date range and max rows ONLY. 7 Auto Refresh allows for the logs to continue rolling in based on your current filters. Think of this as a specified **tail command on a server log. 8 This grid provides the actual logging information. The information provided here can be used to also help filter what you’re looking for. If you see specific thread has the data you need, use the filter menu (2) to filter based on that thread. You can also click on these items to view the log statement clearer. 9 This log message field provides the message from the grid (8) entry clicked on.     The Filter Menu   The filter menu provides very helpful filters. See below for some information on how it works.   # Function 1 This User field allows you to filter the logs to the user that ran the service or function. This is helpful when you know a specific person has logged in and having problems with your application. 2 The Origin field can help when trying to zero in your search. If you notice in the log message grid, there is an origin field. Use this field to help fine tune your search. 3 The Thread field is amazing when you have multiple processes running and would like to see the logs from one process only. You’ll need to find a log entry before you know which thread to filter on. 4 This is similar to the Origin field in the sense that once you find the instance value for a log entry, it can be used here to help filter. 5 The log level range is exactly as the name states. It will help filter message based on logging level.     The Configure Pop-up     The configure pop-up helps with logging going forward. If you only want to see debug level information or you’d like to see everything down to the trace messages, configure it here and you’ll see the change as new messages come in.     Step 5: Next Steps   Congratulations! You've successfully completed the Tracking Activities and Stats guide, and learned how to use the ThingWorx Platform to help track what is happening in your application.   Learn More   We recommend the following resources to continue your learning experience:    Capability     Guide Build Design Your Data Model Manage Data Model Implementation Guide   Additional Resources   If you have questions, issues, or need additional information, refer to:    Resource       Link Community Developer Community Forum Support REST API Help Center
View full tip
  Step 6: Building the Data Model   You can build your data model using different methods. You can build your data model where the Data Shapes match with your tables, but what you'll realize over time is that you will often need custom Data Shapes. When you query for data, you will often need data from differing tables to be in one result set. Because of this, I suggest against making your data model based on the tables. You can start the basis for your model with the tables in mind, but know that this won't be the basis for long.   Create Data Shapes   Let's start by setting up two queries and the Data Shapes to match. The first query will be to find the list of classes a student is assigned to and query will be completed here. The second query will be to find all student in an active class and we'll ask you to create it based on how we did the first one.   1. In the ThingWorx Composer, click the + New button in the top left.    2. In the dropdown list, click Data Shapes.   3. Name the Data Shape DataShape.StudentCourses   4. Add the set of fields below. You may notice, we included information from the Person table that we might already have. This is perfectly fine based on how much data you expect to come back. This will allow you to reuse this database for other purposes later where the person information might change. This can be very beneficial when you're calling a service with this Data Shape (or InfoTable based on this Data Shape). Allowing you to keep the input simple.    Name Base Type  Additional Info   id  STRING Primary Key   person_key  STRING  N/A  person_name_first  STRING  N/A  person_name_last  STRING  N/A  course_key  STRING  N/A  course_name  STRING  N/A  course_professor  STRING  N/A   Let's add in our database query and use our new Data Shape.    1. Open the DatabaseController.Facilities entity and go to the Services tab. If you have not done so as yet, add the configuration information to allow your queries to connect to a database. 2. Create a new service of type SQL (Query) called GetStudentEnrollment. 3. Click Save and Continue to save your changes.   4. Add a parameter to the service title email. It will have a String base type and be required. 5. Add the following query to the canvas.         SELECT person_key, person_name_first, person_name_last, course_key, course_name, course_professor FROM Person person INNER JOIN PersonCourses pc ON person.person_key = pc.person_key INNER JOIN Courses courses ON courses.course_key = pc.course_key WHERE person.person_email = [[email]]​           6. For the output of the service, InfoTable should be there by default. If not, switch the output to be an InfoTable. For the Data Shape, set it to the Data Shape we just created, DataShape.StudentCourses.   You now have a database where you can run your queries and use the responses to bind to Widgets in Mashups.    We have our database connection and a data model setup to handle our current queries. This might be where you begin to question if you would like to add Data Tables. This is more of a design choice. You might want to keep datasets in a Data Table for quick access or separation. Nevertheless, if you already have you database, you won't need many (if any) Data Tables.     Step 7: Next Steps   Congratulations! You've successfully completed the guide for Connecting to an External Database, and learned how to use the ThingWorx Platform to connect to database, query for data, and write new data.   The next guide in the Utilizing ThingWorx to Secure Your Aerospace and Defense Systems learning path is Low Level Device Connection.   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Design Your Data Model Build Configure Permissions   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum
View full tip
    Step 7: Access Data   Now that we have a basic display in-place, we need to access the backend data.   To do so, we'll make use of built-in Mashup Data Services.   At the top-right, ensure that the Data tab is selected.   Click the green + button.   In the Entities Filter field of the Add Data Pop-up, search for and select MDSD_Thing. In the Services Filter field, type getprop. Click the arrow beside GetProperties. Note that the GetProperties() Service has been added to the right section. Check the Execute on Load checkbox.   At the bottom-right of the pop-up, click Done. Note how the GetProperties() Mashup Data Service has been added to the top-right under the Data tab.   Bind Info Table Property   Now that we have access to the Data Service within the Mashup, we'll use it to pull backend data into the Mashup (specifically, the aggregated Info Table Property), and then bind it to the Grid Widget.   Expand the GetProperties Service.   Drag-and-drop MDSD_InfoTable_Property onto the Grid Advanced Widget.   On the Select Binding Target Pop-up, select Data.   Note how the bottom-center Connections Window indicates that the aggregated Info Table Property is now bound to the grid.   Access the Aggregation Service   Because we selected the Execute on Load option for GetProperties(), the Service will grab the information from the aggregated Info Table Property and propagate that into the Grid Advanced Widget on initially opening the Mashup in a web browser.   However, we currently have no way to call our custom aggregation Service besides diving into the backend as we did when we first created it and performed testing.   Instead, we want the Mashup itself to have the ability to call the aggregation Service.   We'll do so via the Button Widget's Clicked Event, but we first need to gain access to our custom Service in the Mashup.   In the top-right Data tab beside Things_MDSD_Thing, click the green </> button. Note that the Add Data Pop-up opens with the MDSD_Thing pre-selected.   On the left of the Add Data Pop-up, expand Select Service Category, and choose **Uncategorized**. Note our custom MDSD_Aggregation_Service.   Beside MDSD_Aggregation_Service, click the right arrow to add it to the Selected Services section. Note that we do NOT want to check "Execute on Load", because don't want the Service called upon initially opening the Mashup in a web browser.   At the bottom-right, click Done. Note the MDSD_Aggregation_Service has been added to the far-right Data tab.   Bind Button to Aggregation Service   Now that we can reference the aggregation Service in the Mashup, we'll bind it to pressing the Button Widget.   Click the Button Widget to select it.   Click the top-left of the Button Widget to reveal the Drop Down Menu.   Drag-and-drop the Clicked Event onto the MDSD_Aggregation_Service under the Data Tab.   On the bottom-right, with the MDSD_Aggregation_Service selected, drag-and-drop the MDSD_Aggregation_Service's ServiceInvokeCompleted Event onto GetProperties in the Data Tab. This causes the completion of the aggregation Service to re-call GetProperties, which updates the grid; as such, a new entry into the Info Table Property created by the custom Service will immediately show up in the Grid Widget. In the top-right, click the GetProperties Service to see all of its interactions in the bottom-center Connections window.   At the top, click Save.       Step 8: Test Application   Our MVP MRI Service Application is now complete.   Let's test it.   At the top, click View Mashup. Note the pre-existing single entry from our Service test which we executed directly from the backend.   Click Retrieve MRI Statistics.   Wait a moment and click Retrieve MRI Statistics again. Note that each click adds another entry to the Grid Widget.   Each time that you press the Button Widget, what you're really doing is calling our custom aggregation Service in the Foundation backend.   This Service then goes out and pulls in information from our various EMS-connected Edge sub-systems.   To add additional sub-systems (maybe a "friction" detection on the patient-bed indicating that it needs additional grease) all you would have to do is repeat the steps in this Learning Path, i.e. connect the additional sub-system with the EMS, add another Field Definition to the Data Shape, and modify the aggregation Service to retrieve that info and store it in the Info Table Property.   In addition, you may wish to improve the GUI. Rather than using a Positioning: Static Mashup, you could utilize a Responsive setup, sub-divide the Canvas into various sections, and then add items such as your company's logo. This would also make the GUI more friendly to different screen resolutions.   You can even add business logic to the Mashup itself. For instance, the Auto Refresh Widget (Legacy) can effectively be used as a "timer". In the same way that the Button Widget's Clicked Event calls the aggregation Service, the Auto Refresh Widget could be used to trigger the Service call at a set interval. Then, as long as the Mashup was open, the Button Widget would only be needed when you wanted an immediate status update.   For more information on implementing additional business logic, refer to the Create Custom Business Logic guide.   Or the Time Selector Widget could be used to restrict the information in the Grid Widget to only the timeframe you wanted to investigate.       Step 9: Next Steps   Congratulations! You've successfully completed the Medical Data Storage and Display guide, and learned how to:   Create a Data Shape and Info Table Property to store Medical Data Create a Service to combine data from multiple Edge devices into a single, logical Thing Create a Mashup to view and retrieve Medical data   This is the last guide in the Medical Device Service learning path.   Learn More   We recommend the following resources to continue your learning experience:    Capability     Guide Build Methods for Data Storage Experience Create Your Application UI   Additional Resources   If you have questions, issues, or need additional information, refer to:    Resource       Link Community Developer Community Forum Support ThingWorx Help Center  
View full tip
    Step 4: Create Thing   Now that we have a Data Shape to format the combination of data coming from the various sub-systems, we can now instantiate a Thing with an Info Table Property to hold all of said data.   Click Browse > Modeling > Things.   Click + New. In the Name field, type MDSD_Thing. If Project is not already set, search for and select PTCDefaultProject. In the Base Thing Template field, search for and select Generic Thing.   At the top, click Save.   Add Info Table Property   We now have a Thing to aggregate the MRI sub-system information, but we still need a Property to perform the actual storage.   We'll use an Info Table Property for this, with the columns of the Info Table formatted by the Data Shape we created in the previous step.   At the top, click Properties and Alerts.   Click + Add.   On the right in the Name field, type MDSD_InfoTable_Property. Change the Base Type to INFOTABLE. In the Data Shape field, search for and select MDSD_DataShape.   Check the box for Persistent.   At the top-right, click the "Check" button for Done. At the top, click Save.     Step 5: Create Service   Now that we have a Thing with an Info Table Property to store our aggregated data from multiple MRI sub-systems, we need to develop a Service which will grab said data and propagate that information into the Info Table Property.   At the top of MDSD_Thing, click Services.   Click + Add.   Under Service Info in the Name field, type MDSD_Aggregation_Service.     Access to MRI Sub-systems   We now need to access the various sub-systems of the MRI that are already talking to ThingWorx Foundation.   Once again, we'll only be doing so for two sub-systems in this MVP example. But the general premise will extend to as many remote devices as is necessary.   You will simply add more references as additional sub-systems are needed.   In the Javascript code window, copy-and-paste in var embedded_properties = Things["MDSD_Embedded_Thing"].GetPropertyValues(); This provides a reference to the embedded microcontroller's Properties. All Things are accessible in Foundation via the "Things" array, and you simply need to provide the Thing-name to index into the array; this functions similarly to a "global" variable, so that any Thing can reference any other Thing. The built-in GetPropertyValues Service simply returns the values of all Properties of the Thing being referenced. In the Javascript code window, copy-and-paste in var pc_properties = Things["MDSD_PC_Thing"].GetPropertyValues(); This provides a reference to the PC's Properties.     Add Values to Info Table   Now that we have references to the sub-systems, we'll add their individual Property values to each field of the Info Table Property.   We'll do this via the built-in AddRow() Service.   To begin an AddRow Service call, copy-and-paste me.MDSD_InfoTable_Property.AddRow({ The me reference is MDSD_Thing, since we're inside said Entity. The MDSD_InfoTable_Property is the Property we added in this guide's previous step. The built-in AddRow Service will add each following Property value to a field of the Info Table formatted by the previously-created Data Shape.   Copy-and-paste Coolant_Percent:embedded_properties.Coolant_Percent, This stores the embedded microcontroller's "Coolant Percent" in the first field of a row of the aggregated Info Table.   Copy-and-paste Field_Strength:embedded_properties.Field_Strength, Likewise, this references the second Property of the embedded microcontroller to store in the second field of the Info Table.   Copy-and-paste Magnet_Temperature:embedded_properties.Magnet_Temperature,   Now that we have all the embedded microcontroller's values, copy-and-paste the following lines for the PC's values: Number_of_Scans:pc_properties.Number_of_Scans,SSD_Space_Open:pc_properties.SSD_Space_Open, Unused_RAM:pc_properties.Unused_RAM,   We also want to record the Timestamp (via the built-in Date Service) when these entries were added; copy-and-paste Timestamp:Date.now()   Finally, close off the AddRow Service with some braces, i.e. copy-and-paste });   Review the entire Service in Foundation and ensure that it matches the Javascript code below. var embedded_properties = Things["MDSD_Embedded_Thing"].GetPropertyValues(); var pc_properties = Things["MDSD_PC_Thing"].GetPropertyValues();me.MDSD_InfoTable_Property.AddRow({ Coolant_Percent:embedded_properties.Coolant_Percent, Field_Strength:embedded_properties.Field_Strength, Magnet_Temperature:embedded_properties.Magnet_Temperature, Number_of_Scans:pc_properties.Number_of_Scans, SSD_Space_Open:pc_properties.SSD_Space_Open, Unused_RAM:pc_properties.Unused_RAM, Timestamp:Date.now() }); For the MDSD_Aggregation_Service, click Done. Click Save.   Test Service   Before going further, we should test the Service to ensure that it is correctly adding entries to the aggregate Info Table Property.   On the MDSD_Aggregation_Service row, under the Execute column, click the Play icon.   At the bottom-right of the Execute Service pop-up, click Execute.   Click Done, and return to Properties and Alerts. Notice under the Value column that the Info Table Property now has an entry.   Under the Value column, click the Pencil icon for Edit.   Review the values and confirm that every field has a valid entry. Note that your values will differ from those in the picture due to the random nature of the simulator. On the pop-up, click Cancel. At the top, click Save.     Step 6: Create Mashup   Now that we have a Thing that has logically aggregated the infomation into a single Info Table Property (and a Service to carry out said aggregation), we can start to visualize the data with a Mashup.   For more information on Mashups, reference the Create Your Application UI guide.   Click Browse > Visualization > Mashups.   Click + New.   On the New Mashup Pop-up, leave the defaults, and click OK. In the Name field, type MDSD_Mashup.   If Project is not already set, search for and select PTCDefaultProject. At the top, click Save.   At the top, click Design.   At the top-left, click the Layout tab.   For Positioning, select the Static radio-button.   At the top-left, click the Widgets tab. At the top, click Save.   Widgets   We now have a "Static Positioning" Mashup, which will let us drag-and-drop Widgets without them auto-expanding to fill the entire space. This will alow us to have multiple Widgets without worrying about sub-dividing the Mashup.   In particular, we're interested in the Grid Widget to display our aggregated data, as well as a Button Widget to call the Service to perform the aggregation.   On the left in the Filter Widgets field, type grid.   Drag-and-drop a Grid Advanced Widget onto the central Canvas area.   In the Filter Widgets field, type button.   Drag-and-drop a Button Widget onto the central Canvas area.   Re-size (by clicking-and-stretching) and move the two Widgets such that they look roughly like the picture below.   Click the Button Widget to select it. In the Filter Properties field of the bottom-left Properties section, type label.   In the Label field, type Retrieve MRI Statistics, and then hit the Tab keyboard key to lock in the change.   At the top, click Save.     Click here to view Part 3 of this guide.
View full tip
    Step 3: Streams Mass data is typically stored in a structure functionally similar to a spreadsheet. Each separate column of the spreadsheet is exclusively one type of data (with each field directly beneath it holding different entries of that same type), while the rows determine the specific entry. Combine a column’s “type” with the row’s “index”, and you have the particular piece of data about which you care. ThingWorx mass data storage functions in roughly the same way. However, ThingWorx does have one differentiation from many spreadsheet implementations. In ThingWorx, the type that defines each column is not held internally to the data structure itself. Instead, it is abstracted out as a Data Shape. A Data Shape is the definition of what each column contains. A Stream requires a Data Shape in order to define its structure. Create Data Shape On the ThingWorx Composer Browse tab, click Modeling -> Data Shapes, + New.   In the Name field, enter Test_Data_Shape.   If Project is not already set, search for and select PTCDefaultProject.  At the top, click Field Definitions.   Click + Add. On the right in the Name field, enter Index_Field . Change the Base Type to INTEGER. Check the Is Primary Key checkbox. All Data Shapes must have a Primary Key, and Index_Field is an appropriate choice, as it will keep track of the number of entries.   At the top-right, click the "Check with a +" button for Done and Add. In the Name field, enter Value_Field. Change the Base Type to NUMBER.   At the top-right, click the "Check" button for Done. At the top, click Save. Once again, the Data Shape does nothing by itself. It simply defines that some other mass data structure (such as a Stream) follows the particular format of the Data Shape. So a Stream assigned the Test_Data_Shape above would have two fields per entry, i.e. an Index and a Value. Create Stream Streams are a mass data storage option optimized for Time-Series data. They are utilized in much the same way as Value Streams, but possess additional functionality.   For one, Streams do not have to be tied to Things in the way that Value Streams are. They can be entirely independent, or even accept inputs from multiple different Things. This can be useful when you want to have a master list of what every similar Thing was doing at particular points throughout some timeframe. On the ThingWorx Composer Browse tab, click DATA STORAGE -> Streams, + New.   On the Choose Template pop-up, select Stream and click OK.   In the Name field, enter Test_Stream.   If Project is not already set, search for and select PTCDefaultProject. In the Data Shape field, search for and select Test_Data_Shape. At the top, click Save.   Create Thing Now that the Stream is created, you'll create a Thing from which you can log some Properties. On the ThingWorx Composer Browse tab, click MODELING -> Things, + New.   In the Name field, enter Stream_Test_Thing. If Project is not already set, search for and select PTCDefaultProject. In the Thing Template field, search for and select GenericThing.   At the top, click Properties and Alerts.   Click + Add. In the Name field, enter Index_Property. Change the Base Type to Integer. Check the Persistent checkbox.   At the top-right, click the "Check with a +" button for Done and Add. In the Name field, enter Value_Property. Change the Base Type to Number. Check the Persistent checkbox.   At the top-right, click the "Check" button for Done. Add Service Since you now have both a Thing and a Stream, we can write a Service which logs the Properties' values when the Service is executed. At the top, click Services.   At the top, click + Add. In the Name field, enter Add_Stream_Entry_Service.   On the left under New Service, click the Snippets tab.   In the Filter field, type add str.   Expand the Stream, Blog, Data Table section to reveal the Add Stream Entry Snippet.   Click the right arrow beside Add Stream Entry. An Add Stream Entry pop-up will open.   In the Search Streams field, enter test.   Select Test_Stream.   Click the Insert Code Snippet button. Note that a section of Javascript code has now been added to the Script window.     Modify Snippet The inserted Javascript Snippet has already done most of the work of creating a custom Service for us. All which you need to do now is modify the code Snippet to store the particular Property values from your Thing. On the 10th line of code, double-click undefined to select it.   On the left, click the Me/Entities tab.   Under the Me/Entities tab, expand Properties. Note that this is not the Properties and Alerts at the top of Composer.   Click the right arrow beside Value_Property. Note that undefined has been replaced by me.Value_Property.   On the 11th line of code, double-click the remaining undefined to select it.   Click the right arrow beside Index_Property. Note that the second “undefined” has been replaced by “me.Index_Property”.   At the top, click Done to close the Add_Stream_Entry_Service editing window.   At the top, click Save.     Click here to view Part 3 of this guide.
View full tip
  Create an Engine Failure Prediction GUI to warn about customer issues.   GUIDE CONCEPT   This guide will use ThingWorx Foundation's Mashup Builder to create a Graphical User Interface (GUI) to display results from Analytics Manager comparisons of your analytical model to real-time data.   Following the steps in this guide, you will learn how to utilize Widgets and backend data to quickly visualize customer failure conditions.     YOU'LL LEARN HOW TO   Create a Mashup Add Widgets to represent different data Bring Backend Data into the Mashup Tie data to Widgets View Analytical Results in a convenient GUI   NOTE:  The estimated time to complete all parts of this guide is 30 minutes.     Step 1: Scenario   In this guide, we're finishing up with the MotorCo scenario where an engine can fail catastrophically in a low-grease condition.   In previous guides, you've gathered and exported engine vibration-data from an Edge MicroServer (EMS) and used it to build an engine analytics model. You've even put that analytical model into service to give near-immediate results from current engine-vibration readings.   The goal of this guide is to create a GUI to visualize those predicted "low grease" conditions to facilitate customer warnings.     GUI-creation to visualize analytical model deployment can be extremely helpful for the automative segment in particular. For instance, each car that comes off the factory line could have an EMS constantly sending data from which an analytical model could automatically detect engine trouble.   This could enable your company to offer an engine monitoring subscription service to your customers.   This guide will show you how to visualize the results of an engine analytic model for a "smart, connected products" play.     Step 2: Create Mashup   Mashups are ThingWorx Foundation's method of creating Graphical User Interfaces (GUIs).   Mashups are created through the Mashup Builder interface.   Before you can use this drag-and-drop interface, you must first create a new Mashup.      1. In ThingWorx Foundation Composer, click Browse > Visualization > Mashups.      2. Click + New.        3. Leave the defaults and click OK.        4. In the Name field, type EFPG_Mashup.      5. If Project is not already set, search for and select PTCDefaultProject.        6. At the top, click Save.        7. At the top, click Design. You are now in the Mashup Builder interface, where you can drag-and-drop graphical elements (Widgets) to create your GUI.      8. At the top-left, click the Layout tab.        9. Change Positioning to Static. This removes any auto-positioning or dynamic-sizing from our Mashup, so that we can place and size Widgets manually.      10. At the top, click Save again.       Step 3: Add Widgets   We now want to add several Widgets to our Mashup by dragging-and-dropping them into the central Canvas area.   Return to the Widgets tab in the top-left.       2. In the Filter Widgets field, type label.        3. Drag-and-drop five (5) Label Widgets onto the central Canvas area.      4. Select the Label Widgets, go to the Properties in the bottom-left, and change the Label's LabelText to s1_fb1 through s1_fb5.         5. Filter Widgets for text field, and then drag-and-drop five (5) Text Field Widgets onto the central Canvas area.        6. Drag-and-drop two (2) more Label Widgets onto the central Canvas area.      7. Change their LabelText Properties to Result_low_grease and Result_low_grease_mo.        8. Drag-and-drop two (2) more Text Field Widgets onto the central Canvas area.        9. In the top-left Widget's tab, change Category to Legacy.      10. Drag-and-drop an Auto Refresh Widget onto the Canvas.        11. At the top, click Save.         Step 4: Add Data   Now that we have a rough set of Widgets in place to display Data in our Mashup, we need to bring in backend Data from Composer.      1. In the top-right, ensure the Data tab is active.      2. Click the green + button.        3. In the Entity Filter field, search for and select EdgeThing.      4. In the Services Filter field, type getprop.      5. Click the right-arrow beside GetProperties.      6. On the right, check Execute on Load.        7. In the bottom-right, click Done.      8. On the right, expand GetProperties.        9. At the top, click Save.       Step 5: Bind Data   Now that backend Data is accessible inside Mashup Builder, we need to bind it to the various Widgets.   Drag-and-drop Data > Things_EdgeThing > GetProperties > s1_fb1 to the top-left Text Field under the s1_fb1 Label Widget.           2. On the Select Binding Target pop-up, click Text.         3. Repeat for s1_fb2 through s1_fb5 on the 2nd-5th Text Field Widgets.       4. Drag-and-drop Data > Things_EdgeThing > GetProperties > Result_low_grease to the top-right Text Field under the Result_low_grease Label Widget, and select Text on the Binding pop-up.       5. Repeat for Result_low_grease_mo on the Text Field just below.       6. Click the Auto Refresh Widget to select it.       7. In the bottom-left Properties, set RefreshInterval to 1.         8. With the Auto Refresh Widget still selected, click the top-left corner to reveal a drop-down.       9. Drag-and-drop the Refresh Event onto Things_EdgeThing > GetProperties.       10. On the right, click the GetProperties Mashup Data Service to reveal all of its interactions in the bottom-center Connections window.              11. At the top, click Save.       Step 6: View Mashup   In the last guide, we disabled the Analysis Event after confirming that appropriate analytical jobs were being created and completed whenever new data from our EMS Engine Simulator entered Foundation.   We now need to re-enable that Event so that we can see the results in our Mashup.       1. Return to Analytics > Analytics Manager > Analysis Events.       2. Select the Event, and click Enable.   View Analytical Results   With the Analysis Event enabled, we can now view our Mashup to watch engine-failure-predictions be displayed in real time.       1. Return to EFPG_Mashup.       2. At the top, click View Mashup.       3. Wait and notice how the refresh occurs every second, including both true and false analytics results for the "low grease" condition.      4. When you are satisfied that you have observed enough true/false results, return to Analytics > Analytics Manager > Analysis Events and Disable the event.   Through this Learning Path, you have done all of the following:   Connect a remote device to Foundation using the Edge MicroServer (EMS) Fed relevant product-data to the Foundation backend Formatted and exported that data in a manner which Analytics could understand Imported that data and used it to build an Analytics Model of your remote device Started feeding real-time remote data into the model to achieve immediate failure-prediction results Create a GUI to easily visualize those results   You now have a completed Minimum Viable Product (MVP) for a Service Play with MotorCo's new engines.   These new engines may have a known-failure condition, but (because you've instrumented those engines to provide constant data) you can monitor them and predict failures before they actually happen.   This could easily be an up-sell scenario for MotorCo's customers. They could simply purchase the engine. Or they could both purchase the engine and enroll in a service contract where you notified them of impending issues.   What was originally a single-point source of income is now ongoing        Step 7: Next Steps   Congratulations. You've completed the Engine Failure-Prediction GUI guide. In this guide you learned how to:   Create a Mashup Add Widgets to represent different data Bring Backend Data into the Mashup Tie data to Widgets View Analytical Results in a convenient GUI   The next guide in the Vehicle Predictive Pre-Failure Detection with ThingWorx Platform learning path is Enhanced Engine Failure Visualization.   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Implement Services, Events, and Subscriptions Guide   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Analytics Manager Help Center
View full tip
  Step 4: Write Data to External Database   You’ve connected to the database, you’re able to query the database. Now let’s handle inserting new data into the database. The update statements and data shown below are based on the table scripts provided in the download. Examples of how the ThingWorx entity should look can be seen in the SQLServerDatabaseController and OracleDatabaseController entities that you've downloaded   Running an Insert   Follow the steps below to set up a helper service to perform queries for the database. While other services might generate the query to be used, this helper service will be your shared execution service. In the DatabaseController entity, go to the Services tab.     2. Create a new service of type SQL (Command) called RunDatabaseCommand. 3. Keep the Output as Integer. 4. Add the following parameter:   Name Base Type Required command String True         5. Add the following code to your new service:   <<command>>       6. Click Save and Continue. Your service signature should look like the below example.     You now have a service that can run commands to the database. Run your service with a simple insert.   There are two ways to go from here. You can either query the database using services that call this service, or you can create more SQL Command services that query the database directly. Let’s go over each method next, starting with a service to call the helper.   In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service JavaScriptInsert_PersonsTable. Set the Output as InfoTable, but do not set the DataShape for the InfoTable. Add the following code to your new service: try { var command = "INSERT INTO Persons (person_key, person_name_first, person_name_last, person_email, person_company_name, " + "person_company_position, person_addr1_line1, person_addr1_line2, person_addr1_line3, person_addr1_city, person_addr1_state, " + "person_addr1_postal_code, person_addr1_country_code, person_addr1_phone_number, person_addr1_fax_number, person_created_by, " + "person_updated_by, person_created_date, person_updated_date) VALUES ('" + key + "', '" + name_first + "', '" + name_last + "', '" + email + "', '" + company_name + "', '" + company_position + "', '" + addr1_line1 + "', '" + addr1_line2 + "', '" + addr1_line3 + "', '" + addr1_city + "', '" + addr1_state + "', '" + addr1_postal_code + "', '" + addr1_country_code + "', '" + addr1_phone_number + "', '" + addr1_fax_number + "', '" + created_by + "', '" + updated_by + "', '" + created_date + "', '" + updated_date + "')"; logger.debug("DatabaseController.JavaScriptInsert_PersonsTable(): Query - " + command); var result = me.RunDatabaseCommand({command: command}); } catch(error) { logger.error("DatabaseController.JavaScriptInsert_PersonsTable(): Error - " + error.message); }         5. Add the following parameter:   Name Base Type Required key String True name_first String True name_last String True company_name String True company_position String True addr1_line1 String True addr1_line2 String True addr1_line3 String True addr1_city String True addr1_state String True addr1_postal_code String True addr1_country_code String True addr1_phone_number String True addr1_fax_number String True created_by String True updated_by String True created_date String True updated_date String True         6. Click Save and Continue.   Any parameter, especially those that were entered by users, that is being passed into a SQL Statement using the Database Connectors should be fully validated and sanitized before executing the statement! Failure to do so could result in the service becoming an SQL Injection vector.   Now, let’s utilize a second method to create a query directly to the database. You can use open and close brackets for parameters for the insert. You can also use <> as a method to mark a value that will need to be replaced. As you build your insert statement, use [[Parameter Name]] for parameters/variables substitution and <<string replacement >> for string substitution.   1. In the Services tab of the DatabaseController entity, create a new service of type SQL (Command).   2. Name the service SQLInsert_PersonsTable. 3. Add the following code to your new service: INSERT INTO Persons (person_key ,person_name_first ,person_name_last ,person_email ,person_company_name ,person_company_position ,person_addr1_line1 ,person_addr1_line2 ,person_addr1_line3 ,person_addr1_city ,person_addr1_state ,person_addr1_postal_code ,person_addr1_country_code ,person_addr1_phone_number ,person_addr1_fax_number ,person_created_by ,person_updated_by ,person_created_date ,person_updated_date) VALUES ([[key]] ,[[name_first]] ,[[name_last]] ,[[email]] ,[[company_name]] ,[[company_position]] ,[[addr1_line1]] ,[[addr1_line2]] ,[[addr1_line3]] ,[[addr1_city]]]] ,[[addr1_state]] ,[[addr1_postal_code]] ,[[addr1_country_code]] ,[[addr1_phone_number]] ,[[addr1_fax_number]] ,[[created_by]] ,[[updated_by]] ,[[created_date]] ,[[updated_date]]);       4. Add the following parameter:   Name Base Type Required key String True name_first String True name_last String True company_name String True company_position String True addr1_line1 String True addr1_line2 String True addr1_line3 String True addr1_city String True addr1_state String True addr1_postal_code String True addr1_country_code String True addr1_phone_number String True addr1_fax_number String True created_by String True updated_by String True created_date String True updated_date String True         5. Click Save and Continue.   Examples of insert services can be seen in the provided downloads.     Step 5: Executing Stored Procedures   There will be times when a singluar query will not be enough to get the job done. This is when you'll need to incorporate stored procedures into your database design.   ThingWorx is able to use the same SQL Command when executing a stored procedure with no data return and a SQL query when executing a stored procedure with an expected result set. Before executing these services or stored procedures, ensure they exist in your database. They can be found in the example file provided.   Execute Stored Procedure   Now, let's create the service to handle calling/executing a stored procedure.   If you are expecting data from this stored procedure, use EXEC to execute the stored procedure. If you only need to execute the stored procedure and do not expect a result set, then using the EXECUTE statement is good enough. You're also able to use the string substitution similar to what we've shown you in the earlier steps.   In the DatabaseController entity, go to the Services tab. Create a new service of type SQL (Command) called RunAssignStudentStoredProcedure. Add the following parameter:   Name Base Type Required student_key String True course_key String True         4. Add the following code to your new service:   EXECUTE AddStudentsToCourse @person_key = N'<<person_key>>', @course_key = N'<<course_key>>'; You can also perform this execute in a service based on JavaScript using the following code: try { var command = "EXECUTE AddStudentsToCourse " + " @student_key = N'" + student_key + "', " + " @course_key = N'" + course_key + "'"; logger.debug("DatabaseController.RunAssignStudentStoredProcedure(): Command - " + command); var result = me.RunDatabaseCommand({command:command}); } catch(error) { logger.error("DatabaseController.RunAssignStudentStoredProcedure(): Error - " + error.message); }         5. Click Save and Continue.   Execute Stored Procedure for Data   Let's create the entity you will use for both methods. This can be seen in the example below:     In the DatabaseController entity, go to the Services tab. Create a new service of type SQL (Query) called GetStudentCoursesStoredProcedure. Set the Output as InfoTable, but do not set the DataShape for the InfoTable. Add the following parameter:   Name Base Type Required course_key String True         5. Add the following code to your new service:   EXEC GetStudentsInCourse @course_key = N'<<course_key>>'   You can also perform this execute in a service based on JavaScript using the following code:   try { var query = "EXEC GetStudentsInCourse " + " @course_key = N'" + course_key + "'"; logger.debug("DatabaseController.GetStudentCoursesStoredProcedure(): Query - " + query); var result = me.RunDatabaseQuery({query:query}); } catch(error) { logger.error("DatabaseController.GetStudentCoursesStoredProcedure(): Error - " + error.message); }       6. Click Save and Continue.   You've now created your first set of services used to call stored procedures for data. Of course, these stored procedures will need to be in the database before they can successfully run.     Click here to view Part 3 of this guide.
View full tip
  Learn how to store and display medical device data for a Service opportunity.   Guide Concept   In this guide, you’ll learn how to combine information from multiple Edge devices into a single, logical Thing.   You’ll then create a GUI to display this combined information (as well as retrieve new information on demand) to facilitate a “Medical Service Play”.     You'll learn how to   Create a Data Shape and Info Table Property to store Medical Data Create a Service to combine data from multiple Edge devices into a single, logical Thing Create a Mashup to view and retrieve Medical data   NOTE:  The estimated time to complete ALL parts of this guide is 60 minutes     Step 1: Medical Learning Path   So far in this Learning Path, you've been able to connect both an embedded controller (simulated by a Raspberry Pi) and a PC to ThingWorx Foundation.   This is important, as medical devices can be complicated pieces of technology controlled by multiple "intelligent" subsystems. It is not always practical (or desirable) to have these subsystems communicate with each other, even if they all need to work together to function optimally.   Fortunately, Foundation has the capability to combine relevant data from multiple Edge devices into a single, logical Thing.   In this step of the Learning Path, you will do just that to facilitate a "Service Play".   The scenario is that your company manufactures and services Magnetic Resonance Imaging (MRI) devices.     Rather than simply servicing the MRI when there is an issue (and after a very expensive device has been damaged from something going wrong), your company maintains a continuing service contract with the hospital to monitor the MRI and perform preventative maintenance on it BEFORE anything goes wrong.   The value proposition to the hospital is the ability to keep their expensive investment in perfect operating order rather than suffering an unexpected failure. In turn, your company reaps the benefits of receiving a steady source of income from said service contract.   In order to achieve this level of preventative maintenance, your company needs to constantly monitor the MRI's various functions.   The MRI is composed of multiple working parts, but for this scenario, we'll limit our Minimum Viable Product (MVP) Service Application to the following:   An embedded device which monitors various hardware elements (such as magnet temperature and remaining coolant) A Windows PC (common in hospital equipment) which is used by a Medical Technician to control the MRI In particular, it's important to note that this PC has access to patient medical data, which can be subject to Health Insurance Portability and Accountability Act (HIPAA) violations. Fortunately here again, it's possible to segregate this information into protected and non-protected sections to limit your company's liability. We'll only propogate non-protected, generalized information to Foundation, such as the total number of scans that have been run thus far. This can facilitate your company getting a connected device approved by a hospital worried about HIPAA-compliance.   To help you run through this guide, we'll also utilize a pair of "simulators" to mimic data coming from the EMS-es on the Pi and PC, rather than directly taking information from them. So if you had any issues with the previous steps getting the EMS running on these devices, you can still complete this guide without issue.     Step 2: Import Simulators   As mentioned, we'll be using a pair of simulators to mimic connections to both an embedded microcontroller and a PC, both of which are part of the MRI.   Perform the following steps to import the simulators.   Download and unzip the MDSD_Entities.zip file attached to this article. In the bottom-left of Foundation Composer, click Import/Export.   Click Import.   On the Import pop-up, click Browse. Navigate to the download location and select the MDSD_Entities.twx file.   Click Open.   Click Import.   Click Close.   Note how there are now several MDSD Entities. These represent Things connected to different parts of the MRI which are communicating to Foundation via the EMS Agent (as per the previous guides in this Learning Path).   Investigate Simulators   Since there are multiple sub-systems which are all communicating directly to Foundation (but we really only want to check the status of the MRI as one logical entity), we need to know what exactly is being communicated back.   What is being communicated was likely determined by your company's Edge Developers when they implemented the EMS agent on said sub-systems.   Perform the following steps to investigate the simulators.   Click MDSD_Embedded_Thing.   Click Properties and Alerts.   So the embedded microcontroller has sensors which are tracking the following:    Property                           Units                       Description Coolant Percent Percent Amount of coolant left to refrigerate the super-conducting magnets Field Strength Tesla Strength of the magnetic field Magnet Temperature Degrees Celsius Temperature of the magnets   Next, let's look at the other simulator. Return to Browse > All. Click MDSD_PC_Thing. Click Properties and Alerts.   The PC is tracking information from the MRI controlling software, including the following:   Property Units  Description Number of Scans Scans Aggregate count of all scans the MRI has performed since last reset SSD Space Open Megabytes Amount of space left on the hard-drive Unused RAM Megabytes Amount of RAM still available to the system   Both of these remote devices are communicating valuable information.   The embedded microcontroller is feeding us information about the hardware of the MRI itself. Refilling coolant as needed is likely one of the service contract stipulations and will be a regular service need. And a Field Strength drop or Magnet Temperature rise could indicate more significant issues which could damage the MRI if not promptly addressed.   The PC gives us information about the operation of the MRI. Hard-drive or RAM running low could indicate that the hardware specs of the PC need to be upgraded, while the Number of Scans can give us a rough estimate of how much refrigerant should have been used versus the currently available level. If only a handful of Scans have been run, but the amount of coolant has dropped by a significant amount, then there could be a leak somewhere which would need to be addressed.   The combination of the Embedded and PC data is enough for us to begin working on a constantly-monitoring application which will facilitate our Service Play.       Step 3: Create Data Shape   Now that we're aware of what information is coming from the separate sub-systems of the MRI, we need to combine them into a single, logical Thing for the purposes of a Service Play.   To do so, we'll create a Thing which represents the MRI as a whole. Additional sub-systems can be added to to the collective information of this Thing as is necessary. But, as stated, this is simply an MVP, so we'll stick to the embedded and PC sub-systems at present.   A good way to aggregate multiple data points into a single item is via an Info Table Property. However, any time you create an Info Table, you also need a Data Shape to format the "columns" of the spreadsheet-like Property.   For more information on the storage of "mass-data", please refer to the Methods for Data Storage guide.   Perform the following steps to create a Data Shape.   Click Browse > Modeling > Data Shapes.   Click + New. In the Name field, type MDSD_DataShape.   If Project is not already set, search for and select PTCDefaultProject. At the top, click Field Definitions.   Click + Add.   Embedded Definitions   We now want to add Field Definitions to the Data Shape which map the information that we want to collate between the various sub-systems.   We'll start with the Embedded Microcontroller Properties.   On the far-right in the Name field, type Coolant_Percent. Change the Base Type to Number.   At the top-right, click the "Check with a +" for Done and Add. In the Name field, type Field_Strength. Change the Base Type to Number.   Click the "Check with a +" for Done and Add. In the Name field, type Magnet_Temperature. Change the Base Type to Number.   Click the "Check" button for Done. At the top, click Save.   PC Definitions   Additional Definitions can be added at anytime as other sub-systems are included.   We'll now include the PC Properties.   Click + Add. In the Name field, type Number_of_Scans. Change the Base Type to Number.   Click the "Check with a +" for Done and Add. In the Name field, type SSD_Space_Open. Change the Base Type to Number.   Click the "Check with a +" for Done and Add. In the Name field, type Unused_RAM. Change the Base Type to Number.   Click the "Check" button for Done. At the top, click Save.   Timestamp   It might also be benificial to include a Timestamp of when the values of both the embedded microcontroller and PC were added.   Click + Add. In the Name field, type Timestamp. Change the Base Type to DATETIME.   Click the Check button for Done. Click Save.     Click here to view Part 2 of this guide.
View full tip
    Step 6: Create Master   Now that we have created our Menu Entity, we can create a Master Mashup to hold a Menu Widget. We'll use the Menu Entity to configure the Menu Widget.     Navigate to Browse > Visualization > Masters.    Click +New.    Leave the defaults and click OK.    In the Name field, type MNWM_Master. If Project is not already set, search for and select PTCDefaultProject.    At the top, click Save.    At the top, click Design.     Add Header   Now that we've created the Master Entity, we need to add space for the Menu Widget.   At the top-left, click the Layout tab.    Click Add Top.   With the new top-section still selected, scroll down in the Layout tab, and select Container Size > Fixed Size.   In the new Height field, type 50, then hit your keyboard's Tab key to apply the change.    At the top, click Save.   Add Menu Widget Now that we have somewhere to put it, we can finally add the Menu Widget and then configure it.   In the top-left, click the Widgets tab.   Drag-and-drop a Menu Widget onto the top Canvas section.   Ensure the Menu Widget is still selected, as well as the Properties tab in the bottom-left.   In the Filter field, type menu.   For the Menu Property, search for and select MNWM_Menu.    At the top, click Save.     Step 7: Menu Navigation   We now have all the elements created to navigate using a Menu. The only thing left is to assign the Master to our Homepage and then view our work.     Return to MNWM_Homepage_Mashup.    In the top-left, click the Explorer tab.   Ensure that Mashup is selected. On the bottom-left Properties tab, in the Filter field, type master.   For the Master Property, search for and select MNWM_Master.    At the top, click Save. At the top, click View Mashup. You may need to enable "pop-ups" in your browser.   Click Park.   Click Amphitheater.   Note that you may wish to set MNWM_Master for the other pages of your application, just in case anyone were to navigate directly there via URL. But simply setting it on the homepage is enough for us to see that Menu navigation is functioning correctly.       Step 8: Next Steps   Congratulations! You've successfully completed the Mashup Navigation with Menus guide. In this guide, you learned how to:   Create a Mashup to be used as a "Home" page Create more Mashups as subpages Create a Menu Entity to track Mashups Create a Master Mashup as a Header Utilize a Menu Widget for navigation   Learn More    Capability     Resource Experience Track Issues with Pareto Chart   Additional Resources   If you have questions, issues, or need additional information, refer to:    Resource       Link Community Developer Community Forum Support Foundation Help Center - Menu Entity Support Foundation Help Center - Menu Widget    
View full tip
  Utilize the Menu Widget to navigate between multiple Mashups.   Guide Concept   Frequently, your application needs to display more information than can comfortably fit on a single page, but manually linking to multiple Mashups can be tedious.   Instead, you can utilize a Menu Entity, Menu Widget, and a Master Mashup to provide consistent navigation between all the pages of your application.      You'll learn how to   Create a Mashup to be used as a "Home" page Create more Mashups as subpages Create a Menu Entity to track Mashups Create a Master Mashup as a Header Utilize a Menu Widget for navigation   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes     Step 1: Scenario   In this guide, we'll assume a scenario where you're an application designer for LightCo, a company that designs and sells smart, connected street, interior, and other lighting products.    In particular, LightCo is interested in using ThingWorx Foundation to operate and control lighting for industrial and city applications.    There's a tentative deal in the works with a city park replacing all their path lighting with high-efficiency models. There's also an outdoor amphitheater in the park that could be added to the deal if the functionality to properly control it is present.     LightCo's intention is to use Foundation to provide a level of control for this application that otherwise wouldn't be possible, as a differentiator versus the competition bidding on the same project.   Since control of both the park-lighting and amphitheater lighting needs to be separate, putting both controls on the same Mashup page would not only be counterintuitive but could possibly lead to errors.    So, in this guide, we'll setup our base page layout for this lighting application. We'll create both a homepage (where we could add login or other elements), as well as separate pages for the park vs the amphitheater. We'll then create a Master Mashup with a Menu for easy navigation between these three initial pages.       Step 2: Create Home Page   First, we want to create a Mashup to represent our homepage.    There doesn't have to be much to it, as we could come back later to develop it further. We just need it to be pre-created to later include it in our Menu.    In Foundation, click Browse > Visualization > Mashups.   At the top-left, click +New.   Leave the defaults and click OK.   In the Name field, type MNWM_Homepage_Mashup. If Project is not already set, search for and select PTCDefaultProject.   At the top, click Save.   At the top, click Design.     Homepage Layout   As mentioned, we don't really want to design our final Homepage right now. Instead, we're simply getting it started to leave ourselves a relatively blank canvas that we can utilize later.    Still, we need to add something. If nothing else, we need something that we can see so that we know we're on the correct page when we click through our Menu options.   We know we'll want our company's name, i.e. LightCo, and probably an image, login, or something else below. So let's subdivide the Mashup into a smaller top part for the name and a bigger bottom section for future functionality.   In the top-left, ensure that the Layout tab is active.   Click Add Top.   Scroll down in the Layout tab to reveal Container Size.   With the top-section of the Canvas selected, click Fixed Size.   In the Height field, type 100 and hit your keyboard's Tab key to apply the change.   Click Save.   Add Company Name   In the top section, we'll add a Label Widget for our company's name.   At the top-left, click the Widgets tab.   Drag-and-drop a Label Widget onto the top section of the Canvas.   With the Label Widget selected, in the bottom-left Properties tab, change LabelText to LightCo and hit your keyboard's Tab key to apply it.   With the Label Widget still selected, in the bottom-left, click the Style Properties tab.   Under Style Properties, expand Base > Label.   Change font-size to 48px.   Click Save.     Step 3: Create Subpage One   Now that we have a basic LightCo homepage in-place, we need subpages to separately control the park-lighting vs the amphitheater-lighting.    But, yet again, we're not designing the actual pages yet. We're just creating them so we can reference them in a Menu.    An easy way to create additional Mashups that have similar layouts is with the Duplicate action. We'll do so now.    Return to Browse > Mashups.   To the left of MNWM_Homepage_Mashup, click the checkbox.   At the top, click Duplicate.   In the Name field, type MNWM_ParkLighting_Mashup. If Project is not already set, search for and select PTCDefaultProject.   At the top, click Save. At the top, click Design.   Change Label Title   Since we used Duplicate to clone the homepage, we see the same header/page Layout which we previously designed. That Layout can be useful for separating page-titles from functionality, so let's keep it.   But we also see the LightCo LabelText we previously created. Since this is the Park Lighting Control page, we need to change it.   In the top section of the Canvas, click the Label Widget to select it.   In the bottom-left, return to the Properties tab.   In the LabelText field, replace the current text with Park Lighting Control, and hit your keyboard's Tab key to apply the change.   At the top, click Save.     Step 4: Create Subpage Two   In the same way that we used Duplicate to mirror the homepage into a park-lighting page, we'll now do the same for the amphitheater-lighting page.    Return to Browse > Mashups. To the left of MNWM_Homepage_Mashup, click the checkbox. At the top, click Duplicate. In the Name field, type MNWM_AmphitheaterLighting_Mashup. If Project is not already set, search for and select PTCDefaultProject.   At the top, click Save. At the top, click Design.   Change LabelText   Just as we did with the Park Lighting Control LabelText, we now want to change this duplicate to read Amphitheater Lighting Control.   In the top section of the Canvas, click the Label Widget to select it. In the bottom-left, return to the Properties tab (if you're not already there). In the LabelText field, replace the current text with Amphitheater Lighting Control, and hit your keyboard's Tab key to apply the change.   Click Save.     Step 5: Create Menu   Having created all three of our starting Mashups, we'll now create a Menu Entity which provides links to each of them.   We'll be able to use this Menu Entity later to configure a Menu Widget for navigation.    Navigate to Browse > Visualization > Menus.   Click +New.    In the Name field, type MNWM_Menu. If Project is not already set, search for and select PTCDefaultProject.    At the top, click Save.   Menu Definitions   Now that we have created the Menu Entity, we can add Menu Definitions with links to all the previously-created pages.   At the top, click Menu Definition. Click +Add.   On the right-side slide-out, in the Title field, type Home. In the Link field, search for and select MNWM_Homepage_Mashup.   In the top-right, click the "check with a plus" button for Done and Add.   In the Title field, type Park. In the Link field, search for and select MNWM_ParkLighting_Mashup.   In the top-right, click the "check with a plus" button for Done and Add. In the Title field, type Amphitheater. In the Link field, search for and select MNWM_AmphitheaterLighting_Mashup.   At the top-right, click the "check" button for Done. At the top, click Save.     Click here to view Part 2 of this guide.
View full tip
  Step 5: Add Data   Now that our Mashup's Layout and Widgets have been set, we need to bring in backend data and tie it to those Widgets for display.    We'll make use of Mashup Data Services for this. The first one we'll add will be UserManagementSubsystem > GetUserCount.   Ensure that the Data tab in the top-right is active.   Click the + icon.   In the Entity field, search for and select UserManagementSubsystem.   In the Services field, type GetUserCount.   Beside the GetUserCount Service, click the right arrow. Under Selected Services, check the box for Execute on Load.     Add LicensingSubsystem > GetCurrentLicenseInfo   You're not limited to only pulling information from one Mashup Data Service.   We already have User Management's GetUserCount. We'll now also bring in information from the Licensing Subsystem.   On the same Add Data pop-up, click the X beside UserManagementSubsystem to clear it.   In the Entity field, search for and select LicensingSubsystem.   In the Services field, type GetCurrentLicenseInfo.   Beside GetCurrentLicenseInfo, click the right arrow. Under Selected Services on the GetCurrentLicenseInfo line, check the box for Execute on Load.   On the bottom-right of the pop-up, click Done.   At the top, click Save.   Bind Data   With our backend data now accessible, let's bind it to our Widgets for display.   On the Data tab, expand Subsystems_LicensingSubsystem > GetCurrentLicenseInfo > Returned Data.   Drag-and-drop Licensing's All Data onto the Grid Advanced Widget in the bottom section.   On the Select Binding Target pop-up, click Data.   Expand Subsystems_UserManagementSubsystem > GetUserCount > Returned Data > All Data.   Drag-and-drop User Management's result onto the Text Field Widget in the top section.   On the Select Binding Target pop-up, click Text.   At the top, click Save.   Automatically Refresh   If we were to click View Mashup now, we would see the User Count and Licensing info displayed in the Mashup's Widgets. However, it would never update unless we manually refreshed the page.   To automate that process, we'll use the Auto Refresh Widget.   In the top section of the Mashup, click the Auto Refresh Widget to select it.   On the top-left of the Auto Refresh Widget, click the drop-down icon to reveal additional options.   Drag-and-drop the Refresh Event onto GetCurrentLicenseInfo.   Repeat steps 1-3 to drag-and-drop the Refresh Event onto GetUserCount also.   With the Auto Refresh Widget still selected, browse the Properties section in the bottom-left.   Change RefreshInterval to 5, and hit your keyboard's Tab key to lock in the change. This will cause the Refresh Event to fire every 5 seconds.   Click Save. Click View Mashup.     Step 6: Replace License   We have now created a Minimum Viable Product (MVP) of a "licensing dashboard" to ease our administration work.   This dashboard could still be improved. For instance, a Mashup Function could be created which automatically recalculates the value from GetUserCount to more accurately match GetCurrentLicenseInfo. This can be accomplished via the Mashup Builder's bottom-right Functions tab. Or, you could even add a separate Text Field Widget to to the top section and directly access the remaining license time via the LicensingSubsystem > GetDaysRemainingInLicense Service.    Whatever you choose to do to improve the Mashup is up to you.   However, what should be done when a license is nearing its expiration? To resolve this issue, we need to replace the existing license via the AcquireLicense Service.   Within the OS of the Foundation server, navigate to the file-system folder where the current license_capability_response.bin is located. This is typically the ThingworxPlatform folder.   Move the existing license_capability_response.bin and any other existing *.bin files to another location for backup. Note that this is EXTREMELY important, as if anything goes wrong, you want to be able to restore the original license. It is very important to ensure that only one *.bin file exists in the appropriate folder Place the new .bin file into the appropriate folder and rename it to license_capability_response.bin. In Foundation, navigate to the LicensingSubsystem > Services page.   On the AcquireLicense row, click the "play" icon for Execute Service.   On the bottom-right of the pop-up, click Execute. Note that if you receive an error, it will be necessary to restart the ThingWorx Tomcat service.  The act of restarting the service will automatically load the new license.   To close the pop-up, click Done.   After acquiring your new license, you should immediately return to the LicensingSubsystem and consult the GetCurrentLicenseInfo Service to confirm that Thing, User, expiration-date, and other issues are accurate.   If anything goes wrong with the new license transfer, you can simply replace the original license_capability_response.bin file and re-run AcquireLicense to return to your old one. Once again, it is import to perform these steps well before your expiration occurs.    Foundation checks for a valid license periodically. If this happens while you have an invalid license_capability_response.bin file in-place, you will no longer be able to access the Foundation GUI.    Fortunately, these issues are self-correcting if a valid license_capability_response.bin is placed in the correct location, as these periodic checks will also pick up a valid license_capability_response.bin file automatically, even after the system has locked you out.    You should also be able to trigger an AcquireLicense action via a REST call even if the GUI is unavailable.      Step 7: Next Steps   Congratulations! You've successfully completed the Manage Licensing with Foundation Subsystems guide.   In this guide, you learned how to:   Access the Foundation Subsystems Execute built-in Services to retrieve: User counts Thing counts License expiration count Create a "License Dashboard" Mashup Update to a new License    Additional Resources   If you have questions, issues, or need additional information, refer to:    Resource       Link Community Developer Community Forum Support Foundation Help Center  
View full tip
  Use Subsystems to retrieve User/Thing-count and License-expiration information   Guide Concept   In this guide, you'll learn how a Foundation Administrator can access important license-accounting Subsystems.    In particular, we'll look at the User Management and Licensing Subsystems, and how you can use them to ensure that you're not getting close to running out of Users, Things, or your time-to-expiration.    We'll also explore how you can import a new license_capability_response.bin file when your original license is running low on time.      You'll learn how to   Access the Foundation Subsystems Execute built-in Services to retrieve: User counts Thing counts License expiration count Create a "License Dashboard" Mashup Update to a new License   NOTE: The estimated time to complete ALL parts of this guide is 30 minutes     Step 1: Introduction   ThingWorx Foundation uses a licensing system based around a file named license_capability_response.bin.  However, if you're using the downloadable installer, then it's possible that you've never even touched this part of the system before.   Besides doing the initial install, you'll also have to check to see that your license has enough Users, Things, and time left before expiration. You need to ensure that a new license is acquired and properly replaced beforehand... or else your Foundation installation may become unusable.    Therefore, this guide will run you through how to access that information, as well as how to update to a new license_capability_response.bin file when the time is right.      Step 2: Get User Count   The first item we'll investigate is checking on our number of Foundation Users.    When first developing an IoT application, low User counts are typically the norm. Only your team really needs access to Foundation itself, so having only a few Users more than your R&D-team-size is possibly going to be sufficient.    And, if your application is something along the lines of factory-monitoring, then it's possible that your User counts, even when deployed, are going to continue to stay relatively low.    However, many IoT applications involve a tremendous number of Users, as your end-customers will generate a Foundation User whenever they sign up for your application. Think something along the lines of a ride-sharing app, or even a Smart Cities play... either of those can result in thousands (if not tens-of-thousands) of Users.    As such, a Foundation system administrator will need to keep a tight track on the User counts to ensure, whenever you're approaching your upper threshold, that enough warning is given to provide time to receive and install a new license_capability_response.bin with a larger User count.    Navigate to Foundation Composer's Browse > All.   On the left-side Navigation, scroll down until you see the System section. Note that you will likely be unable to even see the System section unless you are an Administration-level User.   Click Subsystems.   Click UserManagementSubsystem.   At the top, click Services.   Scroll down and find the built-in GetUserCount Service.   On the line for GetUserCount, click the "play" icon for Execute Service.   At the bottom-right of the pop-up, click Execute.   Click Done to close the pop-up. The return value from GetUserCount is one way to reveal how many current Users are provisioned for your Foundation system.    Moving forward, we'll explore yet another way, while also looking into our Thing counts.    In particular, you might find that the GetUserCount value doesn't completely match due to some internal system accounts. These system accounts are not counted against your license, however, and may need to be accounted for when using the GetUserCount Service.        Step 3: Get Current License Info   While GetUserCounts can be helpful for getting the current amount of provisioned Users, it does nothing to compare that count to the total allowed by the license.    Instead, we'll make use of a different Subsystem, i.e. the LicensingSubsystem.    Return to Browse > System > Subsystems.   Click LicensingSubsystem.   At the top, click Services.   Scroll down until you find GetCurrentLicenseInfo.   On the GetCurrentLicenseInfo line, click the "play" icon for Execute Service.   On the bottom-right of the pop-up, click Execute.   When you're done analyzing the counts, click Done to close the pop-up.   The first thing to notice is that the InUseFeatureCount for twx_named_user possibly does not match the return of GetUserCount. As already mentioned, this is because of system accounts that are not counted against your license.    For example, for a fresh installation, the GetUserCount may return 4, while InUseFeatureCount returns 2. The 2-count is more accurate, as it is used versus your total license-amount. However, GetCurrentLicenseInfo is less useful for doing a simple comparison between a stored "last user amount" vs "current user amount".    The solution is simple. Compare the return of GetUserCount versus the return of GetCurrentLicenseInfo to determine the true total. In this case, the number of system accounts is 2, so some "GetUserCount - 2" custom-Service could be very helpful.   In addition, GetCurrentLicenseInfo returns the very important twx_things value, i.e. how many Thing Entities have been created in the system. This is typically another hard limit in your license, and needs to be watched over.    Finally, the DaysRemaining column shows how long you have before your license becomes inactive. This is something which needs to be constantly monitored to ensure that your Foundation system as a whole is still running!   Next, we'll explore making a Mashup to reference these built-in Services in a more comfortable environment which auto-updates and can be used as, effectively, a Foundation system dashboard.     Step 4: Create Dashboard Mashup   While the User Management and Licensing Subsystems can be used as previously described to determine relevant admin information, traversing through the Foundation backend can be tedious.    To make User, Thing, and License Expiration Date counts easier to monitor, we'll now create a "dashboard" which automatically pulls this information into a convenient Mashup.    Navigate to Browse > Visualization > Mashups.   Click + New.    Leave the defaults and click OK.   In the Name field, type Licensing_Mashup.   If Project is not set, search for and select PTCDefaultProject. Click Save. Click Design.   Set Layout   Now that we have a new Mashup, we'll start adding the items we'll need to display information from the Subsystems.    First, we'll change the Layout.   In the top-left, ensure that the Layout tab is active.   Click Add Top.   Ensure the new top section is selected, and set Positioning to Static.   Scroll down in the Layout tab, and set Container Size to Fixed Size.   In the new Height field, type 100, and then hit your keyboard's Tab key to lock-in your change. Note that the px will be automatically added after hitting the Tab key.   At the top, click Save.   Add Widgets   Now that we have the Layout we want, we can add Widgets to display data coming from the backend.   In the top-left, click the Widgets tab.   Drag-and-drop a Label Widget onto the top section.   With the Label still selected, in the bottom-left Properties section, change LabelText to User Count, and hit Tab.   Drag-and-drop a Text Field Widget, also in the top section, and below the Label.   In the top-left Widgets tab, change Category to Legacy. Drag-and-drop an Auto Refresh Widget in the top section as well.    In the top-left Widgets tab, change Category back to Standard. Drag-and-drop a Grid Advanced Widget onto the Bottom section.   At the top, click Save.   Click here to view Part 2 of this guide.
View full tip
Announcements