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

Community Tip - Have a PTC product question you need answered fast? Chances are someone has asked it before. Learn about the community search. X

IoT Tips

Sort by:
Learn how to use the DBConnection building block to create your own DB tables in ThingWorx.
View full tip
  Learn how to create solutions the can help take you to the next level     Guide Concept   This project will introduce more complex aspects of the ThingWorx application and solution building.   Following the steps in this guide, you will develop your own IoT application or get a jump start in how to utilize ThingWorx for your needs.   We will teach you how to create a focused rules engine or service level logic to be used with the ThingWorx Platform.     You'll learn how to   Create automated processing, data, and endpoints that can handle that data without manual interaction Use services, alerts, and subscriptions to increase performance Begin making your data model and cornerstone entities to understand how a complex business logic is built   NOTE:  The estimated time to complete this guide is 60 minutes     Step 1: Completed Example   Download the attached FoodIndustry.zip and extract/import the contents. These are to be used as you work through this learning path. For the completed example, download the FoodIndustryComplete.zip. Unzip the download and import the Entities included.   In this tutorial we walk you through a real-world scenario for a food company looking to improve their processes. We manufacture the best sausages in town! We sell directly to people and through participating store locations. The focus will be to provide meaningful data for decision making, constant updates on food quality, logistics, transparency, and safety. See the below table for the list of mashups that we will create in this guide and included in the download.    Name                           Description Fizos.LandingPage The main page that showcases highlights and possibly important information Fizos.Deliveries A look into product delivery and logistics Fizos.Alerts Details about any important actionable information Fizos.Factory.User A user to be used for our automated process   There is a large set of Entities provided in this download. The application created in this guide is a part of a final version of what we will create throughout this learning path. If you have not learned about Services, Events/Alerts, and Subscriptions, please take a walk through our Implementing Services, Events, and Subscriptions.   This guide will begin the base of our data model, create data for our factories, and show how we can create automated processes using that data. We will then expand on these items as we move forward in this learning path.     Step 2: Utilizing IoT in the Food Industry   Whenever creating a product in ThingWorx, you should evaluate whether to create them using the data model (Things, Thing Templates, Thing Shapes, etc) or create them using Data Tables and Data Shapes. You have to decide the method that works best for you. One way to think about this is whether to have a single ThingWorx entity to encapsulate your product data OR having so many products (especially when easily volatile), that you rather track it at a higher level.   In our scenario, we won't need to track sausages as the individual level, so we can track the machines creating, holding, and packaging them. This also allows for us to run analytics on the data and export the data into our favorite tools to further process the data.   In the ThingWorx Composer, click the + New in the top left of the screen.   Select Data Shape in the dropdown.     3. In the name field, enter Fizos.DataShapes.Products. This data shape will form high level information about our differing products as a whole. 4. Set the Project (ie, PTCDefaultProject) and click Save to store all changes.     5. Click on the Field Definitions tab. 6. Click the + Add button and enter Name in the Name field of the new Field Definition.    7. Setup your Field Definitions to match the below definitions:  Name      Base Type       Aspects ID Integer Primary Key. Default 0. Minimum 0. Name String N/A State String N/A SKU String N/A Price Number Minimum 0. Mass Number Default 0. Minimum 0. Volume Number Default 0. Minimum 0.     We now have the data shape for products. We can go two different routes here as we create the data table for the products. We can make one data table for ALL company products or we can create a data table for each machine that houses these products. If you wanted the latter options, you could have the machine properties and services assocoated directly on the data table. This is a great option to condense the number of entities being used.   The level of granularity or simplicity is up to you. For this guide, we'll keep things simple and have one data table for all products. When we create the machine entities, we will have a table of the product IDs to help keep track of what products are contained in the machine. In the ThingWorx Composer, click the + New in the top left of the screen.   Select Data Table in the dropdown and select Data Table in the prompt.   In the pop-up, select Data Table.   In the name field, enter Fizos.DataTables.Products. All of our product line will fit this abstract entity. For the Data Shape field, select Fizos.DataShapes.Products. Set the Project field with an existing Project (ie, PTCDefaultProject) and click Save to store all changes.   We now have our setup complete for company products. Now let's create a DataShape for any Event involving this product template. In the ThingWorx Composer, click the + New in the top left of the screen.   Select Data Shape in the dropdown.   In the name field, enter Fizos.ProductsEvent and in the Project field, select an existing Project (ie, PTCDefaultProject). All of our product line will use this DataShape as an alert/event. Click Save to store all changes, then click Edit. Performed the steps used earlier to create the below properties for the Fizos.ProductsEvent Data Shape:  Name           Base Type        Aspects State String N/A SKU String N/A Price Number Minimum 0. Name String N/A     Now let's create a Thing Template, Stream, and a ValueStream to track some of what is happening with our products at a high level. The ValueStream will automatically track our data. The Stream, we will add data in the latter sections. In the ThingWorx Composer, click the + New in the top left of the screen.   Select Thing Template in the dropdown.   3. In the name field, enter Fizos.Products as the name and GenericThing as the Base Thing Template. 4. Select a Project (ie, PTCDefaultProject) and click Save to store all changes.       Now, our new Stream. In the ThingWorx Composer, click the + New in the top left of the screen.   Select Stream in the dropdown.   3. Select Stream in the pop-up.   4. In the name field, enter Fizos.ProductsStream and set the Project field (ie, PTCDefaultProject). 5. In the Data Shape field, select Fizos.ProductsEvent.   6. Click Save to store all changes.   Now, the Value Stream.   In the ThingWorx Composer, click the + New in the top left of the screen.   Select Value Stream in the dropdown.   3. Select ValueStream in the pop-up.   4. In the name field, enter Fizos.ProductsValueStream. 5. Set the Project field (ie, PTCDefaultProject) and click Save to store all changes.   6. Open the Fizos.Products Thing Template and set the Fizos.ProductsValueStream as the Value Stream.   We're all set with high level tracking of all of our products. At this point, we can start the creation of the entity that will help provide the business logic for all products. In the ThingWorx Composer, click the + New in the top left of the screen.   Select Thing in the dropdown.   In the name field, enter Fizos.ProductsBusinessLogic. All of our product line will fit this abstract entity. For the Base Thing Template field, select GenericThing and set the Project field to an existing Project (ie, PTCDefaultProject). Click Save to store all changes.   Click on the Services tab. Click the + Add button and create the two Services below.  Name                          InputReturn Type           Override Async  Desc InspectFactory Integer - factoryID Nothing Yes Yes Start an inspection for a specific factory ReceiveInspection JSON - report/ String - guid Nothing Yes Yes Log/Store an inspection for a specific factory   At this point, you have the building blocks to begin your industry business logic and rules engine. In the next section, we'll do more development and further build out our model.     Click here to view Part 2 of this guide.  
View full tip
  Expedite your application development with new ThingWorx features.   GUIDE CONCEPT   This project will introduce you to a variety of features designed to expedite the IoT application development workflow. In particular, there are several features that make the creation of custom Services quicker and easier when writing and testing your code.   Following the steps in this guide, you will learn how to access features that will help you throughout your software development lifecycle: development, execution, and testing.   We will teach you how to became a faster and more efficient IoT application developer.     YOU'LL LEARN HOW TO   Use Snippets to generate code Execute and test Services Save Service test cases to facilitate QA process Utilize the code auto-completion feature Test code at design time with Lint warnings and errors   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL parts of this guide is 30 minutes.        Step 1: Completed Example   Download and extract the completed files for this tutorial attached to this article: ToolsTipsTricks.zip file.   The file provided to you contains a completed example of the Entities covered in this guide. Utilize this file to see a finished example and return to it as a reference if you become stuck during this guide and need some extra help or clarification.   Keep in mind, this download uses the exact names for Entities used in this tutorial. If you would like to import this example and also create Entities on your own, change the names of the Entities you create.       Step 2: Templates and Using Code Snippets    Expedite your application development process by utilizing code Snippets provided in ThingWorx. The JavaScript code snippets will give you insight into best practices for performing common development tasks.   Follow the steps below to create a Service that will: Check a list of Things Find Things with a temperature over an input parameter threshold, and Return the captured list of Things   Create a Thing Template   Utilizing a Thing Template expedites your development process because the Things inherit properties from the Template. In the steps below, it can relate to a real-world scenario where Things might represent parts that belong to an assembly line.   In the top left of the Home screen of Composer, click the + button.       In the dropdown list, click Thing Template.       For the Name field, enter LinePartTemplate. Select GenericThing as the Thing Template and select a Project (ie, PTCDefaultProject).       Click Properties and Alerts. Create a number Property named PartTemperature. Create a string Property named PartName.     Click Save. Now that you've saved the Template, you can create Things that inherit the properties PartTemperature and PartName. Create a couple new Things with LinePartTemplate as the Thing Template. For testing purposes, set a different value for the PartTemperature Property of each Thing. NOTE: When you run the Service later, you'll be able to see the different Things with values - some within a temperature threshold based on the conditions we set.   Using Service Call Setup   Code Snippets help shorten time to develop Services, but you are also provided with a way to call Services from an entity plus the default input parameters needed to make the call.   In the top left of the Home screen of Composer, click the + button.       In the dropdown list, click Thing.       For the Name field, enter LineCheckSystem. Select GenericThing as the Thing Template and select a Project (ie, PTCDefaultProject).     Switch to the Services tab. Create a Service called ListHotLineParts. Switch to the Me/Entities tab.   Select the Other entity radio option. Enter LinePartTemplate into the search field and select it when it pops up.   Expand the Services section.  Enter GetImplementingThingsWithData into the search field and select the arrow next to it.   You should now see a Snippet of JavaScript inserted into the Service code window. The GetImplementingThingsWithData Service is used to get all the Things with a specific Thing Template as it's base template. The return of this call will provide you with an InfoTable of all the Things you created on your own in the last section. Refer to LineTemplateThing1 in the completed download for an example.     Using Code Snippets   Lets's update the Snippet inserted in the last section.   Update the variable name from result to partsList. Switch to the Snippets tab of the Service. In the search bar, enter/filter Infotable for loop. Expand the Info Table section and click the arrow next to Infotable for loop.   All places where yourInfotableHere is located, replace it with the name of your list, partsList.   Click Done. Click Save.   At this point, you have created a loop that will iterate through the set of Things created with LinePartTemplate set as the Thing Template.   Since the JavaScript snippets were provided and all you had to do was update the variable names, now you must retrieve the input from the user on what the temperature threshold will be. This will be handled in the next section.     Build Return Value List   You can set the threshold to what is considered a "Hot" part in two different ways. Use a static value in order to keep things standardized OR create an input variable to make things more flexible. In the steps below, we are adding an input variable to finish off our Service.   Go to the Inputs tab of the Service. Add an input parameter called TemperatureThreshold that is a Number. Keep the other settings clear. Go to the Outputs tab, select INFOTABLE in the dropdown.  In the Data Shape search field, use the + New Data Shape sign to create a new DataShape. An example is shown below. I’ve named this Data Shape LinePartDataShape. Switch to the Snippets tab of the Service. In the JavaScript code, put your cursor on a new line before the for loop (ie, line 1). In the search bar, filter for Create Infotable from datashape and select it in the Infotable section by clicking the arrow next to it. Select the newly created LinePartDataShape DataShape when a popup appears and click Insert Code Snippet. You will see the newly inserted snippet that creates an Info Table from our new Data Shape.   Add a check inside of the for loop for the PartTemperature of the current item in the list of parts. if(row.PartTemperature > TemperatureThreshold){ } Move the cursor inside of the condition we just added. In the search bar, filter and select Create infotable entry from datashape in the Info Table section by clicking the arrow next to it. Select the newly created LinePartDataShape Data Shape when a popup appears and click Insert Code Snippet. You will see the newly inserted snippet that creates an entry for the Info Table. Update the inserted code snippet to assign the new entry values to that of a row in the Info Table. After updating the with code below, ensure to keep your cursor inside the conditional on a new line. var newEntry = new Object(); newEntry.PartName = row.PartName; // STRING newEntry.PartTemperature = row.PartTemperature; // NUMBER Your entire code thus far should match the following: var params = { infoTableName : "InfoTable", dataShapeName : "LinePartDataShape" }; // CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(LinePartDataShape) var result = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape(params); // result: INFOTABLE dataShape: "RootEntityList" var partsList = ThingTemplates["LinePartTemplate"].GetImplementingThingsWithData(); var tableLength = partsList.rows.length; for (var x=0; x < tableLength; x++) { var row = partsList.rows[x]; if(row.PartTemperature > TemperatureThreshold){ var newEntry = new Object(); newEntry.PartName = row.PartName; // STRING [Primary Key] newEntry.PartTemperature = row.PartTemperature; // NUMBER } } In the search bar, filter and select AddRow by clicking the blue arrow next to it. Update the inserted code snippet to add the newEntry object to the result Info Table created earlier. result.AddRow(newEntry); Save your work. You now have a fully-functional Service that you were able to create faster because of code snippets and pre-loaded Services. See the below to confirm your code matches up after removing some commented lines. Click here to view Part 2 of this guide.
View full tip
  Learn how to create factory line solutions the can help take you to the next level     Guide Concept   This project will introduce more complex aspects of the ThingWorx application and solution building.   Following the steps in this guide, you will develop your own IoT application or get a jump start in how to utilize ThingWorx for your needs.   We will teach you how to create a focused rules engine or service level logic to be used with the ThingWorx Platform.     You'll learn how to   Create automated machine processes Use Services, Alerts, and Subscriptions to handle processes without human interaction Integrating complex logic with straight forward step by step systems   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL parts of this guide is 60 minutes     Step 1: Examples and Strategy   Download the attached FoodIndustry.zip and extract/import the contents. This is to be used as you work through this learning path. For the completed example, download, extract, and import FoodIndustryComplete.zip. These downloads provide three Users and a Security Group. Please watch your count for Users or the import could fail. If you're at your User count limit, delete Users before attempting to import these downloads. Unzip the download and import the Entities included.   In this tutorial we continue with our real-world scenario for the Fizos food company. We should already have our factory data in data tables and will expand on how we can make the factory line smarter. The best processed are built on great timing, quality materials, a great design, and a method to keep track of everything that is happening. We won't have control of materials here, but we can formulate a simple, but great design. Our design will be based on Alerts, Subscriptions, and Schedules.   One of the same questions we will need to ask ourselves that we did in the last guide pertaining to products, is whether to create an entity per machine used in the factory OR create data entries in a data table and process everything through services. Since we would like to have more detailed and up to date information about our machines, I will create a data model that is tied back to our factories.   We will need to start by creating our templates for overall machines, templates for specialized machines, and then entities for the particular machines we have in our factories.       Click here to view Part 2 of this guide.
View full tip
    Learn how to connect, query, insert, and handle data from an external database.   GUIDE CONCEPT   This project will introduce how to utilize and incorporate an external database with the ThingWorx Platform.   Following the steps in this guide, you will connect the ThingWorx Platform to a database, insert data, execute stored procedures, and query data.      YOU'LL LEARN HOW TO   Connect ThingWorx to external databases Query databases and and handling results Insert data and running stored procedures   NOTE: The estimated time to complete this guide is 60 minutes.     Step 1: Completed Example   Download the attached DatabaseApplication.zip and import it into ThingWorx Composer. This download will provide examples that can be used as a reference or as a final copy as you walk through this guide.   In this tutorial, you will learn how to query data and write data to live external databases. The zip file provided contains the following files and entities as a completed version of the scenario to be covered. Import the .twx files into ThingWorx in any order. Run the SQL Server table scripts in a database you have setup followed by the stored procedures.      Name                                                 Description                                                                      Type SQLServerDatabaseController A connected entity for use with an SQL Server database ThingWorx Entity OracleDatabaseController A connected entity for use with an Oracle database ThingWorx Entity AddStudentToCourse.sql Stored procedure to add students to a course in a SQL Server database Database Stored Procedure GetStudentInCourse.sql Stored procedure to information about students in a course in SQL Server database Database Stored Procedure Course.sql SQL Server table representing Courses Database Stored Procedure Person.sql SQL Server table representing Students Database Stored Procedure PersonCourses.sql SQL Server table representing the connection between Students and Courses Database Stored Procedure     This guide will use connections to a SQL Server database, however you can use ANY database that can be used with the Java programming language. Based on the database you will be using, please perform the installation process for that database and create a user with READ, WRITE, and EXECUTE permissions. Ensure the password is set for this user and keep in mind that a UI for the database connection is not needed, but it can make things a bit simpler.      Database Download                       Installation Documentation           Jar File Download SQL Server Download SQL Server Installation SQL Server Jar File Oracle Download Oracle Installation Oracle Jar File     Please follow the below steps to enable a connection between ThingWorx and your database of choice: Ensure the user you created has read, write, and execute permissions. If you would rather split roles, you can create multiple users to handle each aspect. The execute permission for stored procedures is not necessary. Download the database driver/.jar file and move it to the lib directory of the Tomcat installation (ie, /lib). Restart the Tomcat server to load the JDBC driver to make it available for the ThingWorx web application.   Step 2: Connect to External Database   ThingWorx is based on java programming language and can make connections to any database that supports a java-based connection. All that is needed is to add the .jar file for the database to the lib folder of Tomcat folder and setup the connection in the ThingWorx Platform. Follow the below steps to get started creating the connection.   Create Connection   To create a connection and begin working with an external database, you will need to create a database Thing and set up the connection string and credentials. (To see the final version of this entity, you can look at SQLServerDatabaseController.)   In ThingWorx Composer, click the + New at the top of the screen.   Select Thing in the dropdown.   Name the Thing DatabaseController and select Database as the base type. Set the Project field (ie, PTCDefaultProject).   Click Save and go to the Configurations tab. In this tab, you will enter the class name of your driver, the connection string for that database connection, and the credentials to access the database. Keep in mind, the JDBC Driver Class Name, JDBC Connection String, and the connectionValidationString values are all database type specific. For example, to connect to a SQL Server database, the below configuration can be used.      Title                                              Description                    Example JDBC Driver Class Name The specific class name of the driver being used for the connection. net.sourceforge.jtds.jdbc.Driver (SQL Server) or oracle.jdbc.driver.OracleDriver (Oracle) JDBC Connection String The connection string to locate the database by host/port/database name. jdbc:jtds:sqlserver://server:port/databaseName (SQL Server) or jdbc:oracle:thin:@hostname:port:databaseName (Oracle) connectionValidationString A simple query that should always work in a database. SELECT GetDate() (SQL Server) or SELECT SYSDATE FROM DUAL (Oracle) After entering credentials, click Save. Go the Properties and Alerts tab. You'll see properties showing the connection validation similar to the image below. If you don't have a connection as yet, work on your configuration information and validate the credentials being used. If you're still having troubles after that, see the examples section below or use the next section for help to try a query of the database.   Help and Troubleshooting For help finding the correct configuration for you, check out these JDBC Configuration Examples or try out this Connection String Reference for help with your connection string.   You've just created your first database connected Thing! Now jump to the next section and let's begin to query the database for information. Step 3: Query Data from External Database Now that you're connected to the database, you can begin querying the database for information and the flow of data. The queries 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. Running a Query As you may have noticed by working in ThingWorx and developing applications, an InfoTable is often used to work with large sets of data. An InfoTable is also how data is returned from a database query. If you're expecting only 1 value in the result set, the data will be held in the first index of the InfoTable. If you're expecting rows of data coming back, expect there to be rows of information inside of the InfoTable. 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 a shared execution service. In the DatabaseController entity, go to the Services tab. Create a new service of type SQL (Query) called RunDatabaseQuery.   3. Set the Output as InfoTable, but do not set the DataShape for the InfoTable. 4. Add the following parameter:  Name            Base Type   Required query String True 5. Add the following code to the new service: <<query>> 6. Click Save and Continue. Your service signature should look like the below example.   You now have a service that can run queries to the database. This is also a simple method to test/troubleshoot the database connection or a quick query. Run your service with a simple query. You might notice that no matter the fields in the result set, the InfoTable will match it based on field type and field name. There are two ways you can 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 our helper. In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service JavaScriptQuery_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 query = "SELECT * FROM Persons"; logger.debug("DatabaseController.JavaScriptQuery_PersonsTable(): Query - " + query); var result = me.RunDatabaseQuery({query:query}); } catch(error) { logger.error("DatabaseController.JavaScriptQuery_PersonsTable(): Error - " + error.message); }   5. Click Save and Continue. Any parameter, especially those that were entered by users, that is being passed into an 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. This is a simple way to query the database since much of your development inside of ThingWorx was already based in JavaScript. Now, let's utilize the second method to create a query directly to the database. You can use open and close brackets to create parameters for your query. You can also use <> as a method to mark a value that will need to be replaced. As you build your query, use [[Parameter Name]] for parameters/variables substitution and <> for string substitution. In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service SQLQuery_GetPersonByEmail. Ensure the Output is InfoTable. Add the following code to your new service: SELECT * FROM Persons WHERE person_email = [[email]]; 5. Add the following parameter:  Name          Base Type    Required email String True 6. Click Save and Continue. An example of using the string replacement is as follows:         DELETE FROM <> WHERE (FieldName = '[[MatchName]]'); DELETE FROM << TableName >> WHERE ( FieldName = [[MatchNumber]]);             Click here to view Part 2 of this guide.
View full tip
    Use Analytics Manager to automatically perform engine analytical calculations.   Guide Concept   This guide will use ThingWorx Analytics Manager to compare external-data from an Edge MicroServer (EMS) "Engine Simulator" to a previously-built analytical model.   Following the steps in this guide, you will learn how to deploy the model which you created in the earlier Builder guide.   We will teach you how to utilize this deployed model to investigate whether or not live data indicates a potential engine failure.   You'll learn how to   Deploy and execute computational models Define and trigger Analysis Events Map incoming data to the Model Map analytic outputs to applications   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 60 minutes       Step 1: Scenario   In this guide, we're continuing the same MotorCo scenario, where an engine can fail catastrophically in a low-grease condition.   In previous guides, you've gathered and exported engine vibration-data from an Edge MicroServer (EMS) and used it to build an engine analytics model.   The goal of this guide is to now operationalize that previously-created model to analyze individual, external readings to see if the "low grease" condition is currently happening.     Analytical model creation can be extremely helpful for the automotive segment in particular. For instance, each car that comes off the factory line could have an EMS constantly sending data from which an analytical model could automatically detect engine trouble.   This could enable your company to offer an engine monitoring subscription service to your customers.   This guide will show you how to put an analytic model of your engine into service to actively monitor performance.       Step 2: Configure Provider   In ThingWorx terminology, an Analysis Provider is a mathematical analysis engine.   Analytics Manager can use a variety of Providers, such as Excel, Mathcad, or even Analytics Server pre-built ones.   In this guide, we use the built-in AnalyticsServerConnector, a Provider that has been specifically created to work seamlessly in Manager and to use Builder Models.   From the ThingWorx Composer Analytics tab, click Analytics Manager > Analysis Providers > New....   In the Provider Name field, type Vibration_Provider. In the Connector field, search for and select TW.AnalysisServices.AnalyticsServer.AnalyticsServerConnector.   Leave the rest of the options at default and click Save.     Step 3: Publish Analysis Model   Once you have configured an Analysis Provider, you can publish Models from Analytics Builder to Analytics Manager. On the ThingWorx Composer Analytics tab, click Analytics Builder > Models.   Select vibration_model_s1_only and click Publish.   On the Publish Model? pop-up, click Yes. A new browser tab will open with the Analytics Manager's Analysis Models menu. Close that new browser tab, and instead click Analysis Models in the ThingWorx Composer Analytics navigation. This is the same interface as the auto-opened tab which you closed.   Click the model to select it. At the top, click Enable. Note the pop-up indicating that the Enable was successful.       Step 4: Modify EdgeThing   In previous guides in this Vehicle Predictive Pre-Failure Detection Learning Path, you have created various Entities, including Things such as EdgeThing.   In order to automate the process of pushing data from EdgeThing to Analytics Manager, we need to add a few more Properties to EdgeThing.   These Properties are simple STRING variables, and we'll also set Default Values for them to configure parameters of Analytics Manager.   The first is causalTechnique, which tells Analytics Manager which criteria to use when measuring the impact of a feature on a range of goal values.   The second is goalField, which is simply the data field for which Analytics Manager should try to identify the correlation. In this case, it'll be our primary issue, i.e. low_grease.   It is not mandatory that these suggested Property names match, but they are the names used within ThingWorx Analytics. You could use any Property name you wanted, as you'll be mapping from a particular Property to the functionality within Analytics in a later step.   Return to EdgeThing > Properties and Alerts.   Click + Add.   In the Name field, type causalTechnique. Check Has Default Value. In the text field under "Has Default Value", type FULL_RANGE. Note that you MUST type FULL_RANGE, including capitalization, as that is a command within Analytics Server.   Click the "Check with a +" icon for Done and Add. In the Name field, type goalField. Check Has Default Value. In the text field under "Has Default Value", type low_grease. Note that you MUST type low_grease, including being all lower-case, as that is the exact name of the Analytics Server goal.   Click the "Check" icon for Done. Click Save.   Results Storage   We also need a place in which to store the results that Analytics Manager returns. We'll utilize a few additional Properties for that as well.   On the EdgeThing > Properties and Alerts tab, click + Add. In the Name field, type Result_low_grease. Check the Base Type to BOOLEAN. Check Persistent.   Click the "Check with a +" icon for Done and Add. In the Name field, type Result_low_grease_mo. Change the Base Type to NUMBER. Check Persistent.   Click the "Check" icon for Done. Click Save.       Step 5: Create Event   Events are automatic analysis jobs which are submitted based on a pre-defined condition. In this step, we'll configure an Analysis Event, which will execute automatically whenever there is a data-change in our simulated engine.   On the ThingWorx Composer Analytics tab, click Analytics Manager > Analysis Events.   Click New.... If not already selected, change Source Type (Required) to Thing.   In Source, search for and select EdgeThing. In Event, select DataChange. In Property, select s1_fb1. If there are multiple s1_fb1 Properties, select the first one, as the second one is the s1_fb1 entry in the Info Table Property. In Provider Name, select Vibration_Provider. In Model Name, select the published Model.   Click Save.       Click here to view Part 2 of this guide.  
View full tip
    Step 6: Map Data   Now that the event is created, we need to map the Properties of EdgeThing to the fields required to invoke an Analysis Job.   We'll start with the Inputs.   Select the previously-created Event, and click Map Data....   Click Inputs Mapping.   In Source Type, select Thing. In Source, search for and select EdgeThing.   On the left, scroll down and select s1_fb1. Note that you do NOT want the s1_fb1 that is part of the InfoTable Property, because the Info Table Property only stores recorded data, not live data. On the right, select _s1_fb1, the first frequency band required for the Model to make a prediction.   Click the Map button in the center.   Repeat this mapping process for for s1_fb2 through s1_fb5.   Map causalTechnique to causalTechnique in the same manner. This is a String Property in EdgeThing with a Default Value of "FULL_RANGE". Map goalField to goalField in the same manner. This is a String Property in EdgeThing with a Default Value of "low_grease".   Map Results   Now that the Inputs are mapped, we also want to map the Results.   Click Results Mapping on the left.   Map _low_grease to Result_low_grease. Map _low_grease_mo to Result_low_grease_mo.   Click Close to close the mapping pop-up.   Enable Event   Now that we've done the mapping from Foundation to Analytics, let's Enable the Analysis Event so that it can automatically generate and process Analysis Jobs. Select the mapped Analysis Event. Select Enable.   Now that you have enabled the Analysis Event, the new data will be submitted to Analytics Manager whenever EdgeThing's s1_fb1 Property changes.   An Analysis Job will automatically run, with a predictive score sent back and stored in EdgeThing's Result_low_grease (Boolean) and Result_low_grease_mo (Number) Properties.     Step 7: Check Jobs   In this step, we'll confirm that the automatic analysis of information coming from remote devices is operational.   On the ThingWorx Composer Analytics tab, click Analytics Manager > Analysis Jobs.   Uncheck Filter Completed Jobs.   Select a Job and click View.... Click Results.   NOTE: You will see true or false, corresponding to either a low grease or no low grease condition. Using this technology, you could create a paid customer service, where you offered to monitor remote engines, in return for automatically shutting them down before they experience catastrophic engine failure.   For that example implementation, you would utilize the EdgeThing.Result_low_grease BOOLEAN Property to trigger other actions.   For instance, you could create an Alert Event which would be triggered on a true reading.   You could then have a Subscription which paid attention to that Alert Event, and performed an action, such as sending an automatic shutdown command to the engine when it was experiencing a likely low grease event.   NOTE: We recommend that you return to the ThingWorx Composer Analytics > Analytics Manager > Analysis Events tab and Disable the Event prior to continuing. Since the simulator generates an Event every ~1 seconds, this can create a large number of Events, which can fill up your log.       Step 8: Next Steps   Congratulations. You've completed the Manage an Engine Analytical Model guide. In this guide you learned how to:   Define an Analysis Provider that uses the built-in Analytics Server Connector Publish a Model from Analytics Builder to Manager Create an Analysis Event which takes data from ThingWorx Foundation and decides whether or not a failure is likely   The next guide in the Vehicle Predictive Pre-Failure Detection with ThingWorx Platform learning path is Engine Failure-Prediction GUI.   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
  Connect to an existing database and design a connected data model.   GUIDE CONCEPT   There are times you already have your database designed and only need to integrate the ThingWorx environment.   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 create a data model around your database design and connect to that database.     YOU'LL LEARN HOW TO   How to connect an external database and created services to be used with it How to design and implement a new data model based on an external resource Using data models with database services   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 attached to this guide:  AerospaceEntitiesGuide1.zip.   By now, you likely know how to create a data model from scratch. You have likely already created services that work with Info Tables. What you might not have completed, is combining both a new data model, handling data in services, and connecting it all to an external database.   Our organization, PTC Defense Department, has existed for years and has an existing database setup. Developers in our organization refuse to remodel the database, so we must model the ThingWorx data model to our database schema. With ThingWorx, this is not a difficult task, but there are numerous decisions and options that we will explore in this guide.     Step 2: Database Connections   ThingWorx is based on the Java programming language and can make connections to any database that supports a Java-based connection. Dropping the JAR file for the database JDBC driver to the lib folder of Tomcat is all that is needed for connection to the ThingWorx Platform. Follow the below steps to get started creating the connection.   To establish the connection and begin working with an external database, you will need to create a Database Thing and configure the connection string and credentials. Let us start with our database connection. If you have not done so already, download the Aerospace and Defense database scripts: DatabaseApplication.zip. Use the README.txt file to create the database schema. It is based on Microsoft SQL Server, but you can configure the scripts to your database preferences.   NOTE: You will not need to connect to a database to utilize this guide as a learning utility. For your services to work, you will need to connect to a database.   1. In ThingWorx Composer, click the + New at the top-left of the screen.     2. Select Thing in the dropdown.     3. Name the Thing `DatabaseController.Facilities` and select Database as the Base Thing Template.     4.Click Save and go to the Configurations tab.   In this tab, you will enter the class name of your driver, the connection string for that database connection, and the credentials to access the database.   Keep in mind, the JDBC Driver Class Name, JDBC Connection String, and the connection Validation String values are all database type specific. For example, to connect to a SQL Server database, the below configuration can be used.   Title Description  Example   JDBC Driver Class Name  The specific class name of the driver being used for the connection.  net.sourceforge.jtds.jdbc.Driver (SQL Server) or oracle.jdbc.driver.OracleDriver (Oracle)  JDBC Connection String  The connection string to locate the database by host/port/database name.  jdbc:jtds:sqlserver://server:port/databaseName (SQL Server) or jdbc:oracle:thin:@hostname:port:databaseName (Oracle)  connectionValidationString  A simple query that should always work in a database.  SELECT GetDate() (SQL Server) or SELECT SYSDATE FROM DUAL (Oracle)   5. After entering credentials, click Save.     6. Go the Properties and Alerts tab.   The connected Property should be checked. This property informs us of the current connection to the database. The lastConnection Datetime Property should show a current timestamp. This property informs us of the last time there was a valid connection to the database. This is an easy way to confirm the connection to the database.   If you do not have a connection, work on your configurations in the Configurations tab and validate the credentials being used. If you are still having troubles, see the examples section below or use the next section for help to try a query of the database.   Help and Troubleshooting   For help finding the correct configuration for you, check out these JDBC Configuration Examples or try out this Connection String Reference for help with your connection string.   You have just established your first database connection! Now jump to the next section and let us begin to build a data model to match the database schema.   Step 3: Query Data from External Database   Now that you're connected to the database, you can begin querying the database for information and the flow of data. The queries 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.   Running a Query   As you may have noticed by working in ThingWorx and developing applications, an InfoTable is often used to work with large sets of data. An InfoTable is also how data is returned from a database query. If you're expecting only 1 value in the result set, the data will be held in the first index of the InfoTable. If you're expecting rows of data coming back, expect there to be rows of information inside of the InfoTable.   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 a shared execution service.   In the DatabaseController entity, go to the Services tab. Create a new service of type SQL (Query) called RunDatabaseQuery.           3. Set the Output as InfoTable, but do not set the DataShape for the InfoTable.       4. Add the following parameter: Name Base Type Required query String True       5. Add the following code to the new service:   <<query>>       6. Click Save and Continue. Your service signature should look like the below example.       You now have a service that can run queries to the database. This is also a simple method to test/troubleshoot the database connection or a quick query.   Run your service with a simple query. You might notice that no matter the fields in the result set, the InfoTable will match it based on field type and field name.   There are two ways you can 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 our helper.   In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service JavaScriptQuery_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 query = "SELECT * FROM Persons"; logger.debug("DatabaseController.JavaScriptQuery_PersonsTable(): Query - " + query); var result = me.RunDatabaseQuery({query:query}); } catch(error) { logger.error("DatabaseController.JavaScriptQuery_PersonsTable(): Error - " + error.message); }       5. Click Save and Continue.   Any parameter, especially those that were entered by users, that is being passed into an 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.   This is a simple way to query the database since much of your development inside of ThingWorx was already based in JavaScript.   Now, let's utilize the second method to create a query directly to the database. You can use open and close brackets to create parameters for your query. You can also use <> as a method to mark a value that will need to be replaced. As you build your query, use [[Parameter Name]] for parameters/variables substitution and <> for string substitution.   In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service SQLQuery_GetPersonByEmail. Ensure the Output is InfoTable. Add the following code to your new service: SELECT * FROM Persons WHERE person_email = [[email]];       5. Add the following parameter:   Name Base Type Required email String True         6. Click Save and Continue.   An example of using the string replacement is as follows: DELETE FROM <> WHERE (FieldName = '[[MatchName]]'); DELETE FROM << TableName >> WHERE ( FieldName = [[MatchNumber]]);       Click here to view Part 2 of this guide.
View full tip
  Step 3: Create Validation and Status   With our MyFunctionsMashup Mashup open, let's add a Validation. A Validation is similar to an Expression, except you have the added capability of triggering Events based on a True or False outcome of your validation. We will use the Validation to check and confirm the Text Field we created only has the values we added in our Functions. Let's also add two Status Message Functions that will show whether or not a user has added any text outside of what we want.   Open the MyFunctionsMashup Mashup to the Design tab. Click the green + button in the Functions area.    In the New Function modal, select Validator.   Set the Name to isDataClean.   Click Next.  Click Add Parameter. Set the Name to text and ensure the Base Type is STRING.   Add the following code to the Expression are: if(text === "NO") { result = true; } else if(text === "YES") { result = true; } else { let array = text.split("YES").join(""); array = array.split(",").join(""); let count = array.trim().length; if(count) { result = false; } else { result = true; } }   9. Click Done.   We have our Validator in place, now we need our two Status Message Functions. Why two? You can setup one Status Message to perform the task, but for this case, we're keeping things simple.   Click the + button in the Functions area. Select Status Message in the dropdown.    Set the Name to GoodInputProvided.   Click Next. Ensure Message Type is Info. In the Message field, enter Text is all good!.   Click Done. Let's create another Status Message Function. Set the Name to BadnputProvided.   Click Next. Change Message Type to Error. In the Message field, enter Text is BAD!.   Click Done.   We now have two Status Message Functions and a Validator to help with checking our text data. Let's connect everything together. This time, let's use the Bind button.   Expand the Validator section in the Functions tab. Click the Bind (arrows) button on the isDataClean Validator. This window will help us configure connections a bit easier.    Click the down arrow by the True Event. Click Add Trigger Service.   Click Functions. Check the checkbox by GoodInputProvided.   Click Next. Click the down arrow by the False Event. Click Add Trigger Service.   Click Functions. Check the checkbox by BadInputProvided.   Click Next. You should currently have the following setup:    Let's add in our connections to the Text Field and when we'll run this Validation.    Click the down arrow by the text Property.   Click Add Source. With the Widgets tab selected, scroll down and select the Text Property of our Text Field.   Click Next. Click the down arrow by Evaluate Service. Select Add Event Trigger.   With the Widgets tab selected, scroll down and select the Clicked Property of our Button.   Click Next. You should currently have the following setup:   Click Done. Click Save and view your updated Mashup.   Your Validator is complete. You now have a way to tell when a user has inputed their own text into the text box. To try things out, add some crazy characters, hit the button, and see what happens. You might notice that you have your Expressions running at the same time as your Validator. Switch up the bindings to get it to run the way you want it to.     Step 4: Create Confirmation Modal   With our MyFunctionsMashup Mashup open, let's add a Confirmation Function. A Confirmation Function provides a quick modal that will give users a method to confirm actions or events before they take place. If you've ever almost deleted a production database (don't judge me!), then you know how handy a confirmation screen can be. Let's add a button that will trigger a confirmation as to whether we would like to run the Validator we created in the last section.   Open the MyFunctionsMashup Mashup to the Design tab. Click the + button in the Functions panel. Select Confirmation in the dropdown.   Set the Name to confirmDataValidation. Click Next.   Set the Title Text to Confirm Data Validation?. Set the Message Text to Would you like to perform a data validation?.   Set the Cancel Button Label to No Thanks!. Scroll down and set the Action Button Label to Yes Sir!.   Click Done. Click the Widgets tab in the top left. Filter for and select a Button Widget.   Drag and drop a Button Widget onto the Canvas.   With the new Button selected, click the down arrow that appears on the Button. Drag and drop the Clicked Event of the Button to the OpenConfirmation Service of our Confirmation Function.     We now have our Confirmation Function and a Button that will open the Confirmation when clicked. Let's add the final step by connecting the Confirmation to our Validation Function.   Click the Bind (arrows) button for our isDataClean Validator.   Click the down arrow by the Evaluate Service. Select Add Event Trigger.   Click the Functions tab. Select the ActionClick Event of our Confirmation Function.   Click Next. Click Done. Click Save for our Mashup.   We now have a way to independently validate that the text in our text box does not contain random values added by the user. View the Mashup and test things out by clicking on the second button and adding some crazy characters to our text box.       Step 5: Create Navigation   Thus far, we have been sticking to one Mashup. Let's venture out a bit by showing a different Mashup. Inside of our MyFunctionsMashup Mashup, we will add a Navigation Function. This will allow us to go to or just show a different UI based on some kind of user input or event. For our example, when a user clicks No Thanks! in our Confirmation Function, let's send them to a different Mashup.   Follow the steps to create a Navigation Function, a destination Mashup, and tie the two together.    Create Destination Mashup Navigate to Browse > Visualization > Mashups.   Click + New. Keep the defaults and click OK. In the Name field, type MyNavigationDestination.   Click Save. Click the Design tab at the top to open the Mashup canvas. Click the Widgets tab.   Filter and search for the word Label. Drag and drop a Label Widget to the Mashup canvas. If you like, enlarge the Label sizing.    In the Label Widget Properties section, scroll down to the LabelType Property.       Click the dropdown and select Large Header.   In the LabelText Property field, type MY DESTINATION UI SCREEN. Click Save. You have now created a simple UI that we will go to when we click our navigation button. Next, we'll tie together our navigation button and our freshly created Mashup.   Create Navigation Function Reopen the MyFunctionsMashup Mashup to the Design tab. Click the + button in the Functions panel. Select Navigation in the dropdown.   Set the Name to travelToDestination.   Click Next. Set the Target Window Type to ModalPopup. Set the Pop-up Title to New Popup Here.   Set the Pop-up Width to 400. Set the Pop-up Height to 400.   Click the + button at Target Mashup. Type MyNavigationDestination into the search bar. Select the MyNavigationDestination Mashup when it appears.   Click Done. Select the Bind (arrows) button for our new travelToDestination Navigation Function.   Click the down arrow next to Navigate Service. Click Add Event Trigger.   Click the Functions tab. Select the CancelClick Event of our confirmDataValidation Confirmation Function.   Click Done. Click Save for the Mashup.   We now have a modal that will appear after we click the No Thanks! button in our Confirmation Function. View the Mashup and try out what you've done by clicking the bottom button, then clicking No Thanks!     Click here to view Part 3 of this guide.  
View full tip
    Step 7: Add Grid   It might also be helpful to display the data you've used to build the ThingWorx Analytics model.   In the future, this might be split out into an entirely separate page/Mashup that is exclusively devoted to backend model creation, but that would be beyond the scope of this guide.   For now, we'll simply display that collected data via the Grid Widget      1. On the EEFV_Mashup, drag-and-drop a Grid Advanced Widget onto the bottom-left Canvas section..     2. On the top-right Data tab, click the green </> button beside Things_EdgeThing. Note that this will open the Add Data pop-up, but with EdgeThing pre-selected.   3. In the Services Filter field, type getproperties.   4. Click the right-arrow beside GetProperties to add it to Selected Services on the right.   5. Check Execute on Load.     6. Click Done.   7. Under the Data tab, expand GetProperties to reveal the options.     8. Drag-and-drop Things_EdgeThing > GetProperties > infoTableProperty onto the Grid Advanced Widget.     9. On the Select Binding Target pop-up, click Data.     10. Click Save.   11. Click View Mashup.         Step 8: Add Controls   Throughout this Learning Path, it has been recommended that you stop Analysis Events when not actively using their functionality.   However, this requires going into the backend of ThingWorx Analytics to disable the event, which is not ideal.   Instead, let's enable or disable the Analysis Event from inside the Mashup by adding some Button Widgets to directly interface the Analytics backend for us.       1. Click the bottom-right Canvas section to select it.         2. In Mashup Builder top-left, click the Layout tab.         3. Under Positioning, click the Static radio-button.         4. Click the Widgets tab.       5. Drag-and-drop a Button Widget onto the bottom-right section.         6. Drag-and-drop another Button Widget onto the bottom-right section.       7. Drag-and-drop a Text Field Widget onto the bottom-right section.       8. Click Save.       Bring in More Data   Now that we have Buttons to trigger enable/disable, as well as a Text Field to display information, we now need to bring in some additional Mashup Data Services to interact with the ThingWorx Analytics backend.       1. Click the green + button at the top of the Data tab.       2. In the Entity Filter field, search for and  select TW.AnalysisServices.EventManagementServicesAPI.       3. In the Services Filter field, search for and add QueryAnalysisEvents by clicking the right arrow.       4. Check Execute on Load.         5. In Services Filter, search for and select EnableAnalysisEvent by clicking the right arrow. Note that you should NOT check "Execute on Load", as we'll trigger this Service only when the Button is clicked.     6. In Services Filter, search for and select DisableAnalysisEvent by clicking the right arrow. Likewise, do NOT check "Execute on Load" here either.       7. Click Done.         8. Click Save.     Display Event Key   To enable or disable Analytics Events, we need to know the eventId, which is returned by QueryAnalysisEvent Service as the parameter labeled key.   We'll bind that to the Text Field Widget for later usage in enabling/disabling.        1. Change the top-button's Label Property to Enable Analytics Event.       2. Change the bottom-button's Label Property to Disable Analytics Event.         3. Under the Data tab, expand QueryAnalysisEvents > Returned Data > All Data to reveal the options. .       4. Drag-and-drop QueryAnalysisEvents > Returned Data > All Data > key to the TextField Widget.         5. On the Select Binding Target pop-up, click Text.         6. Click Save.     Enable/Disable Analytics Events   Now that we know the key/eventId, we can call the EnableAnalysisEvent and DisableAnalysisEvent services.       1. Under the Data tab, expand EnableAnalysisEvent > Parameters to reveal eventId.       2. Click the Text Field Widget to select it, and then click the top-left drop down to reveal the options.         3. Drag-and-drop the Text Field's Text Property onto EnableAnalysisEvent > Parameters > eventId.         4. Repeat steps 1-3 for DisableAnalysisEvent.         5. Click the Enable Analytics Event Button Widget to select it, then click the top-left to reveal the drop down option .       6. Drag-and-drop the Clicked Event onto the EnableAnalysisEvent Service under the Data tab.         7. Repeat steps 5-6 for DisableAnalysisEvent, using the other Button Widget.         8. Click Save     Step 9: View Mashup   Throughout this guide, we've added various additional functionality to our MVP Mashup. At this point, you could continue to update the Mashup as you see fit.   For instance, you could change the background color of the top-left section to better match the header. Or you could further modify the original Mashup shown in the Contained Mashup Widget so that it better fits in the allowed space. You could add another Label Widget to the Header section to also display the company's motto / tag-line.   Regardless, when you are done with modifications, Save and click View Mashup.     Note that you can left-click-and-drag on the Time Series Chart to select particular time ranges. Or you could add a Time Selector Widget to the bottom-right section to control it there.   Similarly, you could add controls for the Grid Widget to only show the Identifier ranges in which you were interested.   Or you could split out the Model-creation values to a completely separate Mashup as previously discussed.   The extent to which you develop your Mashup is entirely up to you.        Step 10: Next Steps   Congratulations. You've completed the Enhanced Engine Failure Visualization guide. In this guide, you learned how to:   Create a Mashup with a Header Divide your Mashup into Sub-sections Use a Contained Mashup to reuse development Store historical data in a Value Steam Display historical data in a Line Chart Show spreadsheet data via a Grid Advanced Widget Tie Mashup controls into the ThingWorx backend   This is the last guide in the Vehicle Predictive Pre-Failure Detection with ThingWorx Platform learning path.   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
  Utilize the C SDK to build an app that creates a secure connection to ThingWorx with low level device access.   Guide Concept   This project will cover using the ThingWorx C SDK to develop applications for the purpose of secure and low level development.   Following the steps in this this guide, you will be ready to develop your own IoT application with the ThingWorx C SDK.   We will teach you how to use the C programming language to connect and build IoT applications to be used with the ThingWorx Platform.       You'll learn how to   Establish and manage a secure connection with a ThingWorx server, including SSL negotiation and connection maintenance. Enable easy programmatic interaction with the Properties, Services, and Events that are exposed by Entities running on a ThingWorx server. Basic concepts of the C Edge SDK How to create an application that can communicate with other devices   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL parts of this guide is 60 minutes       Step 1: Completed Examples   Download the completed files attached to this tutorial: C_SDK.zip.   This tutorial will guide you through working with the C SDK on differing levels. Utilize this file to see a finished example and return to it as a reference if you become stuck creating your own fully flushed out application. With the C SDK, you can connect to whatever device you have at a level most programming languages wouldn't be able to. Now think of your secure system, your fighter jet, or even you communication devices. All these systems and levels need to have a way to secure transfer data and the C SDK is how we do it.   Keep in mind, this download uses the exact names for entities used in this tutorial. If you would like to import this example and also create entities on your own, change the names of the entities you create.     Step 2: Environment Setup   In order to compile C code, download the attached C compiler: C-SDK-2-2-12-1052.zip.    Operating System          Notes Windows You will need a 3rd party compiler such as MinGW GCC, Cygwin GCC or you can follow these Microsoft instructions to download and use the Microsoft Visual C++ Build Tool. Mac Download the Apple Developer Tools. Linux/Ubuntu A compiler is included by default.   NOTE: You can use CMake, version 2.6.1 or later to build projects or make files, which then are used to build the applications that you develop with the C SDK. Before you can begin developing with the ThingWorx C SDK, you need to generate an Application Key and modify the source code file. You can use the Create an Application Key as a reference.   Modify Source File   Extract the files from the C SDK samples zip file. At the top level of the extracted files, you will see a folder called examples, which provides examples of how to utilize the C SDK. Open a terminal, go to your workspace, and create a new project. After you've created this project in your workspace, import the entire C SDK downloaded from the PTC Support site for ease of use (mainly the src folder and the CMakeList.txt file). You can start creating your connection code or open the main.c source file in the examples\SteamSensor\src directory for an example.    Operating System        Code Linux/Ubuntu gedit main.c OR vi main.c Mac open –e main.c Windows start main.c   5. Modify the Server Details section at the top with the IP address for your ThingWorx Platform instance and the application key you would like to use. Change the TW_HOST definition accordingly. Change the TW_PORT definition accordingly. Change the TW_APP_KEY definition to the keyId value saved from the last step. /* Server Details */ #define TW_HOST "https://pp-XXXXXXXXX.devportal.ptc.i" #define TW_PORT 80 #define TW_APP_KEY "e1d78abf-cfd2-47a6-92b7-37dc6dd34618" NOTE: Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a user and place the user as a member of Admins.   Compile and Run Code   To test your connection, you will only need to update the main.c in the SteamSensor example folder.   CMake can generate visual studio projects, make build files or even target IDEs such as Eclipse, or XCode. CMake generates a general description into a build for your specific toolchain or IDE.   If you have not downloaded and installed CMake, do it now at the CMake website. NOTE: CMake comes as a command line and a GUI application. The steps in this guide use the command line version only. Inside the specific example folder you would like to run, ie SteamSensor. Create a directory to build in, for this example call it cmake. mkdir cmake cd cmake 4. Run the CMake command listed below. This assumes CMake is already on your PATH. cmake -G "Visual Studio 15 2012" .. 5. CMake has now produced a set of project files which should be compatible with your development environment.  Operating System    Command                                        Notes Unix command-> make A set of make files Windows **msbuild tw-c-sdk.sln /t:build** A visual studio solution NOTE: CMake does its best to determine what version of Visual Studio you have but you may wish to specify which version to use if you have more than one installed on your computer. Below is an example of forcing CMake to use a specific version of Visual Studio: cmake -G "Visual Studio 15 2017" .. If your version of Visual Studio or other IDE is unknown, use cmake -G to see a list of supported IDEs.   You also have the alternative of opening the tw-c-sdk.sln from within Visual Studio and building in this IDE.   NOTE: By default, CMake will generate a build for the creation of a release binary. If you want to generate a debug build, use the command-> cmake -DBUILD_DEBUG=ON.   6. Once your build completes you will find the build products in the cmake directory. From here, open the project in your IDE of choice. NOTE: You should receive messages confirming successful binding, authentication, and connection after the main.c file edits have been made.       Step 3: Run Sample Code   The C code in the sample download is configured to run and connect to the Entities provided in the ThingWorxEntitiesExport.xml file. Make note of the IP address of your ThingWorx Composer instance. The top level of the exported zip file will be referred to as [C SDK HOME DIR]. Navigate to the [C SDK HOME DIR]/examples/ExampleClient/src directory. Open the main.c source file.  Operating System      Command Linux/Ubuntu gedit main.c OR vi main.c Mac open –e main.c Windows start main.c   3. Modify the Server Details section at the top with the IP address for your ThingWorx Platform instance and the Application Key you would like to use. Change the TW_HOST definition accordingly. NOTE: By default, TW_APP_KEY has been set to the Application Key from the admin_key in the import step completed earlier. Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a user and place the user as a member of the Admins security group. /* Server Details */ #define TW_HOST "127.0.0.1" #define TW_APP_KEY "ce22e9e4-2834-419c-9656-e98f9f844c784c"   4. If you are working on a port other than 80, you will need to update the conditional statement within the main.c source file. Search for and edit the first line within the main function. Based on your settings, set the int16_t port to the ThingWorx platform port. 5. Click Save and close the file. 6. Create a directory to build in, for this example call it bin.  Operating System            Command Linux/Ubuntu mkdir bin Mac mkdir bin Windows mkdir bin   7. Change to the newly created bin directory.  Operating System              Command Linux/Ubuntu cd bin Mac cd bin Windows cd bin   8. Run the CMake command using your specific IDE of choice. NOTE: Include the two periods at the end of the code as shown below. Use cmake -G to see a list of supported IDEs. cmake ..   9. Once your build completes, you will find the build products in the bin directory, and you can open the project in your IDE of choice. NOTE: You should receive messages confirming successful binding, authentication, and connection after building and running the application. 10. You should be able to see a Thing in your ThingWorx Composer called SimpleThing_1 with updated lastConnection and isConnected properties. SimpleThing_1 is bound for the duration of the application run time.   The below instructions will help to verify the connection.   Click Monitoring. Click Remote Things from the list to see the connection status. You will now be able to see and select the Entity within the list.       Step 4: ExampleClient Connection   The C code provided in the main.c source file is preconfigured to initialize the ThingWorx C Edge SDK API with a connection to the ThingWorx platform and register handlers. In order to set up the connection, a number of parameters must be defined. This can be seen in the code below.   #define TW_HOST "127.0.0.1" #define TW_APP_KEY "ce22e9e4-2834-419c-9656-ef9f844c784c #if defined NO_TLS #define TW_PORT = 80; #else #define TW_PORT = 443; #endif   The first step of connecting to the platform: Establish Physical Websocket, we call the twApi_Initialize function with the information needed to point to the websocket of the ThingWorx Composer. This function:   Registers messaging handlers Allocates space for the API structures Creates a secure websocket err = twApi_Initialize(hostname, port, TW_URI, appKey, NULL, MESSAGE_CHUNK_SIZE, MESSAGE_CHUNK_SIZE, TRUE); if (TW_OK != err) { TW_LOG(TW_ERROR, "Error initializing the API"); exit(err); }   If you are not using SSL/TLS, use the following line to test against a server with a self-signed certificate: twApi_SetSelfSignedOk();   In order to disable HTTPS support and use HTTP only, call the twApi_DisableEncryption function. This is needed when using ports such as 80 or 8080. A call can be seen below:   twApi_DisableEncryption();   The following event handlers are all optional. The twApi_RegisterBindEventCallback function registers a function that will be called on the event of a Thing being bound or unbound to the ThingWorx platform. The twApi_RegisterOnAuthenticatedCallback function registered a function that will be called on the event the SDK has been authenticated by the ThingWorx Platform. The twApi_RegisterSynchronizeStateEventCallback function registers a function that will be called after binding and used to notify your application about fields that have been bound to the Thingworx Platform.   twApi_RegisterOnAuthenticatedCallback(authEventHandler, TW_NO_USER_DATA); twApi_RegisterBindEventCallback(NULL, bindEventHandler, TW_NO_USER_DATA); twApi_RegisterSynchronizeStateEventCallback(NULL, synchronizeStateHandler, TW_NO_USER_DATA);   NOTE: Binding a Thing within the ThingWorx platform is not mandatory, but there are a number of advantages, including updating Properties while offline.    You can then start the client, which will establish the AlwaysOn protocol with the ThingWorx Composer. This protocol provides bi-directional communication between the ThingWorx Composer and the running client application. To start this connection, use the line below:   err = twApi_Connect(CONNECT_TIMEOUT, RETRY_COUNT); if(TW_OK != err){ exit(-1); }   Click here to view Part 2 of this guide.      
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
    Step 5: Tie Data to Widgets   The Mashup now has access to the backend data via get/set Data Services.   In this step, you will tie these Data Services to the Checkbox Widgets to pull and push information.   Click the Data tab in the upper right   Under GetProperties, click and drag the arrow next to Channel2_myPLC_Coil2 onto the Left Checkbox. On the Select Binding Target pop-up, click State.   Click the Data tab again Drag Channel2_myPLC_Coil3 onto the right Checkbox. On the Select Binding Target pop-up, click State.   Enable Automatic Updates   The GetProperties Mashup Data Service will now propagate the State of Coil2 and Coil3 from the PLC onto these Checkbox Widgets.   The GetProperties Service will be called automatically when the Mashup loads, so the Checkboxes states will be accurate on initial viewing.   However, the backend data state changes, you will need the GetProperties Service to be automatically called again to update the Checkbox Widgets.   Fortunately, it is simple to trigger this behavior.   Click the Data tab Click GetProperties to select it.   On the right of the Mashup Builder, Click the Data Properties tab     Click the Automatically Update Values checkbox   Allow Bidirectional Sets   You also want to enable bi-directional communication, not only displaying the current value of the PLC, but also setting it via the Mashup GUI.   The SetProperties Mashup Data Service can accomplish this.   Click the Right Checkbox to select it.   Click the Checkbox Widget's top-left drop-down menu to expose the available options.   Drag State over the Data tab to expand it. Drop onto SetProperties > Channel2_myPLC_Coil3.   Click the right Checkbox drop-down menu again.   Click Configure Bindings.   Click the down arrow to the right of Changed.   Click Add Trigger Service. Click the Data tab. Select the setProperties check box.   Click Next to close the Trigger Services window. Click Done to close the Configure Bindings pop-up. At the top, click Save.     Step 6: View Mashup    Your Mashup is now complete with two Checkbox Widgets and connections from those Widgets to the backend data.   The left Checkbox represents Coil2, and will change its state depending on whether you have touched the lead to the appropriate input on the PLC.   The right Checkbox represents Coil3, and will display the current status as well as allow you to set the status of Output Coil 3 via checking or unchecking the box.   At the top, click View Mashup to display your web application. You may need to set your browser to allow pop-ups.     Select the right checkbox. Note how the PLC's Output Coil 3 will immediately turn on.   Touch the lead to the PLC's I-02, i.e. Input 2. The left checkbox will indicate the status of Input 2 within a couple of seconds. Step 7: Troubleshooting   If the connection to the PLC stops working and there is a Thumbs Down icon next to your properties, the ThingWorx Kepware Server trial edition drivers are not connected to your PLC. The trial edition stops running after 2 hours and must be stopped and restarted. Right-click on ThingWorx Kepware Server icon in system tray.     Click Stop Runtime service. Wait a minute for the process to stop, then click Start Runtime service. If Connected Components Workbench does not connect to PLC, check the IP address of the PLC using RS Linx Classic software that was installed as part of Connected Components Workbench. RS Linx Classic is located Start > All Programs > Rockwell Software > RSLinx > RSLinx Classic Click AB_ETHIP-1, Ethernet and IP addresses of connected PLCs will be discovered NOTE: A changed PLC IP Address (typically seen through Connected Components Workbench) will require an IP Address change in ThingWorx Kepware Server settings.     Step 8: Next Steps   Congratulations! You've successfully completed the Visualize an Allen-Bradley PLC guide.   In addition, assuming you have been utilizing this guide as part of the Rockwell Automation Learning Path, this represents the end of your journey.   You've learned how to:   Create a Mashup Add Widgets Access backend data via Mashup Data Services Tie data to Widgets Create a simple web application that monitors and controls a PLC   This is the last guide in the Using an Allen-Bradley PLC with ThingWorx learning path. Learn More   Capability Resource Analyze Monitor an SMT Assembly Line Additional Resources   For additional information on ThingWorx Kepware Server:   Resource Link Documentation Kepware documentation Support Kepware Support site
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
  Connect a Raspberry Pi to ThingWorx using the Edge MicroServer (EMS).   GUIDE CONCEPT   This project will utilize the Edge MicroServer (EMS) to connect ThingWorx Foundation to a Raspberry Pi.   YOU'LL LEARN HOW TO   Set up Raspberry Pi Install, configure, and launch the Edge MicroServer (EMS) Connect a remote device to ThingWorx Foundation   NOTE:  The estimated time to complete all parts of this guide is 60 minutes.     Step 1: Introduction   A Raspberry Pi is a small, single-board computer that utilizes an ARM processor and typically runs a variant of Linux.   Due to its small size, relatively affordable cost, and ability to run a full operating system, the Pi is a near-ideal device to utilize as a Proof-of-Concept (PoC) IoT Edge device.   In addition, there is a version of the ThingWorx Edge MicroServer (EMS) built to work on ARM processors. Therefore, this guide will explore getting the EMS running on a Raspberry Pi to connect to ThingWorx Foundation.       As stated in the Overview, you may purchase a Pi directly from the Raspberry Pi web site or from a distribution partner such as Digi-Key or RS.   You will also need an SD card (8+GB... 16+GB recommended) with the Raspbian operating system installed... though this guide will instruct you on installing the Raspbian OS on a microsdhc flash card if you prefer to purchase an SD card separately.   You may alternately wish to purchase a "Pi Canakit". Canakits, depending on the version, typically include a Pi, SD card with a version of Raspbian pre-installed, and various other items like sensors, a case, an HDMI cable, and other accessories.   To make this guide as straight-forward as possible, we'll assume a monitor, USB keyboard, USB mouse, and WiFi connectivity to interact with the Pi.   Note that the Pi has an HDMI port, so you may also need an HDMI-to-DVI convertor or similar if your monitor doesn't natively support HDMI.     Step 2: Format MicroSDHC Card   The microSDHC flash card which the Pi accepts may (or may not) come pre-installed with the Raspbian OS. If Raspbian is pre-installed and working, you may skip this step.   However, these flash cards are susceptible to corruption, especially if proper static-control guards are not followed or if the Pi is powered-down without going through a proper shutdown procedure.   As such, the steps immediately below will assume that you are installing (or re-installing) Raspbian on your microSDHC card.   Depending on your PC's ports, you may also require a microSDHC adapter to insert the flash card into your computer.   Locate your microSDHC card. Remember that 8+GB is mandatory, but 16+GB is recommended to ensure that the Pi has enough swap-space.   Locate your flash card adapter. Note that you may have a different type of adapter. Simply ensure that your PC can recognize the microSDHC card.   Insert the microSDHC card into the adapter.     Insert the adapter-plus-microsdhc card into your PC.     Assuming a Windows PC and either a pre-installed or corrupted flash card, you will receive a pop-up stating that it needs to be formatted prior to use; click Format disk.   On the following Format SDHC Card pop-up, click Start.   On the following Format Confirmation pop-up, click OK.     On the following Format Complete pop-up, click OK.   On the previous Format pop-up which is still open, click Close.   You now have a formatted microSDHC card which Windows can recognize.       Step 3: Flash MicroSDHC Card   Now that the flash card is accessible to Windows, you want to install the Raspbian OS on it.   Once again, this step assumes that you are installing (or re-installing) the Raspbian OS.   If your microSDHC card came pre-installed with Raspbian, then you may skip this step.   Download the Raspbian OS .zip file. Navigate to the download location and locate the Raspbian .zip file.   3. Right-click on the file and select Extract All....   4. On the Extract Pop-up, click Extract.   5. Download the balenaEtcher "flasher" software. 6. Navigate to the download location and locate the balenaEtcher .exe file.   7. Double-click on the balenaEtcher .exe to begin the installation process.   8. On the balenaEtcher installer pop-up, click I Agree. After the installation completes, balenaEtcher will automatically open.   9. Click Select image and navigate to the previously-extracted Raspbian OS .img file.   10. Select the .img file and click Open. Assuming the only microSDHC card currently inserted into your PC is the one for the Pi, then the SD SCSI Disk Device will be pre-selected; otherwise, choose the correct flash disk.   11. Click Flash!. Accept allowing the etcher to make changes to your computer.   12. Wait for balenaEtcher to complete the flashing process; this may take ~5-10 minutes.   13. Remove the microSDHC card and adapter from your PC.     Click here to view Part 2 of this guide.
View full tip
  Step 5: Import Extension   Now that we have a valid dataset, we want to export it as a .csv file, which can be imported into ThingWorx Analytics in a future guide to generate an analytical model.   An easy way to do this is with the CSV Parser Extension, which you’ll now import.       1. Download the CSV Parser Extension from our third party provider IQNOX.   Note:  An account is required but the download is free.     2. At the bottom-left, click Import/Export.       3. On the drop-down, click Import.       4. For Import Option, select Extension.       5. Click Browse and navigate to the extension you downloaded above.       6. Click Open.       7. Click Import.       8. Click Close.       9. On the Refresh Composer? pop-up, click Yes.      Step 6: Create File Repository   ThingWorx Foundation uses File Repositories to read and write files from disk (including .csv files created by the CSV Parser Extension).   In this step, we’ll create a File Repository Entity.       1. Return to Browse > All.       2. Click MODELING > Things.       3. Click + New.       4. In the Name field, type ESDS_File_Repository.       5. If Project is not already set, search for and select PTCDefaultProject.       6. In the Base Thing Template field, search for and select FileRepository.      7. At the top, click Save.        Step 7: Create .csv Export Service   We have imported an Extension which gives us tools to manipulate .csv files. We have created a File Repository to which the export can save the file. We'll now make use of some of this new functionality.    We’ll do so by creating a Service which calls built-in functions of the CSV Parser Extension.       1. Return to EdgeThing.       2. Click Services.       3. Click + Add.       4. On the drop-down, select Local (JavaScript).       5. In the Name field, type exportCSVservice.       6. In the blank JavaScript field, copy-and-paste the following code:           var sFile = "vibrationCSVfile.csv"; var paramsCSV = { path: sFile, data: me.infoTableProperty, fileRepository: "ESDS_File_Repository", withHeader: true }; Resources["CSVParserFunctions"].WriteCSVFile(paramsCSV);               7. Click Save and Continue. Note that you should NOT click the top Save button, as that will erase your Service.         Step 8: Export the Engine Data   We now have all the tools in place to export the infoTableProperty as a .csv file to our new File Repository.   All that’s left is to call the appropriate functions.       1. Ensure that you’re still on the Services tab of EdgeThing, and have the exportCSVservice open.       2. At the bottom, click Execute.       3. Return to ESDS_File_Repository.       4. Click Services.       5. Scroll down and find the GetFileListingsWithLinks Service.       6. Click the “Play” icon for Execute service.       7. At the bottom-right, click Execute.       8. On the right, click Thingworx/FileRepositories/ESDS_File_Repository/vibrationCSVfile.csv.     9. The .csv export of the vibration data will now be in your local folder to which your browser saves downloads.       Step 9: Next Steps   Congratulations! You've completed the Engine Simulator Data Storage guide, and learned how to:   Create a Timer Subscribe to a Timer to Trigger a Service Generate Mass Amounts of Test Data Import the CSV Parser Extension Create a File Repository Export the Test Data as a Comma-Seperated Values (.csv) file Download from a File Repository   The next guide in the Vehicle Predictive Pre-Failure Detection with ThingWorx Platform learning path is Build an Engine Analytical Model   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Analyze Build a Predictive Analytics Model Build Implement Services, Events, and Subscriptions   Additional Resources   If you have questions, issues, or need additional information, refer to:        Resource Link Community Developer Community Forum Support Analytics Builder 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 5: Contained Mashup   Our Minimum Viable Product (MVP) Mashup which we created in the last guide did have valid information.   Being able to display the inputs coming from the engine, as well as the analytical results coming from ThingWorx Analytics, are certainly items we don’t want to lose in this new, more complete Mashup.   Rather than recreating that work from scratch, we’ll simply include that previous Mashup in one of our sub-section via the Contained Mashup Widget.       1. Click on the top-left section to select it, and ensure that you’re on the Widgets tab in the top-left.       2. Drag-and-drop a Contained Mashup Widget onto the top-left section.       3. With the Contained Mashup Widget selected, return to the Properties tab in the bottom-left.       4. Scroll down and locate the Name Property.       5. Search for and select EFPG_Mashup       6. Click Save.     Add Column Labels   The original Mashup we created (and have now embedded in the new one) had some labels for the inputs and outputs. However, you had to know what things like “s1_fb1” meant to understand that that was an input.   We can go back to the original EPFG_Mashup, make some modifications for greater clarity, and those changes will also carry over to our new Mashup.       1. Reopen the old EPFG_Mashup on the Design tab.       2. Move all of the Widgets down to leave some extra room at the top.       3. Drag-and-drop two Divider Widgets onto the Canvas above both the Inputs and Results columns.       4. Select a Divider Widget, and go to its Style Properties.       5. Expand Base > Line to reveal the background Style Property.       6. Click on the default gray color to see the available options.       7. Choose the built-in black at the bottom, and click Select.       8. Make the same modification to the other Divider Widget.       9. Drag-and-drop two more Label Widgets onto the Canvas above the two columns.       10. Change their LabelText Properties to Inputs and Results, respectively.     Change Background and Size       1. From the Explorer tab in the top-left, select the container.       2. Select the Style Properties tab in the bottom-left and expand Base > Container.       3. Change the background Style Property to a color you prefer.       4. With the container still selected in the Explorer tab, drag the corners of the Mashup to reduce its size.       5. You could even move the Results column over, place the Auto Refresh Widget underneath, and then reduce the container size even further.       6. Click Save.     View Mashup Thus Far   With the changes to the previous EFPG_Mashup now complete, let’s ensure that everything carried over to our new Mashup.       1. Return to EEFV_Mashup.       2. Click Save.       3. Click View Mashup.   Note how the various changes we made to the base Mashup are also being shown, via a Contained Mashup Widget, in our new Mashup.   Splitting out functionality to a separate Mashup that is then embedded where needed is a great way to re-use content and simplify development.       Step 6: Add Chart   Our original Mashup (which has now been embedded in our new one) shows the instantaneous analytical results based on the inputs coming from the Edge MicroServer (EMS).   However, when investigating remote customer issues, it might be helpful to see some historical trends. A temporary "blip" of a low-grease indication might be worrisome, but it may not require immediate intervention unless the issue was occuring consistently or for extended periods of time.   Fortunately, creating a historical record is relatively simple in ThingWorx Foundation.   All that is really needed is a place in which to store the past records.   One of the easiest such storage methods is a Value Stream.       1. In ThingWorx Foundation, click Browse > Data Storage > Value Streams.       2. Click + New.       3. On the Choose Template pop-up, select ValueStream and click OK.       4. In the Name field, type EEFV_ValueStream.       5. If Project is not already set, search for and select PTCDefaultProject.       6. At the top, click Save.     Link Value Stream and Begin Storage   Now that we have a Value Stream to act as a storage location, we want to link it to EdgeThing.   After EdgeThing knows where to store historical data, we can simply instruct it which Property we want to archive by setting it to Logged.       1. Return to EdgeThing and its General Information tab.       2. In the Value Stream field, search for and select EEFV_ValueStream.       3. Click Save.       4. Still on EdgeThing, click Properties and Alerts.       5. Click Result_low_grease_mo to trigger the slide-out from the right-side.         6. Check Logged.       7. Click the Check icon in the top-right to close the slide-out.       8. Click Save.     Add Line Chart and Data   As per most guides in this Learning Path, it is assumed that you have an active connection to the EMS Engine Simulator and have your Analytics Event currently set to active.   This provides both the engine-sensor inputs and the analytical results for our Mashup.   After adding the Value Stream above, you'll need to let it run for a bit for the historical data to be archived. After it's run for a while and we have a valid history build-up, you can display that history in a Line Chart.       1. Return to EEFV_Mashup on the Design tab.       2. Click on the top-right section to select it.         3. From the Widgets tab, drag-and-drop a Line Chart onto the top-right section.         4. In the top-right of Mashup Builder, ensure the Data tab is selected.         5. Click the green + button.         6. On the Add Data pop-up in Entity Filter, search for and select EdgeThing.       7. In Services Filter, type queryprop.       8. Click the right arrow button besides QueryPropertyHistory.       9. Check Execute on Load.         10. Click Done.       11. Expand Data > Things_EdgeThing > QueryPropertyHistory > Returned Data.       Bind Data and View Mashup   Now that we have both our method of displaying the historical data, i.e. a Line Chart, as well as a method to bring backend data into the Mashup, i.e. QueryPropertyHistory, we can bind them together and see how our Mashup is progressing.       1. From the right under the Data tab, drag-and-drop EdgeThing > QueryPropertyHistory > Returned Data > All Data onto the Line Chart in the top-right of the Canvas.         2. On the Select Binding Target pop-up, click Data.         3. With the Line Chart selected, explore its Properties in the bottom-left.       4. Change XAxisField to timestamp.         5. Click Save.       6. Click View Mashup.     Your own Line Chart will vary depending on what values your Engine Simulator is sending to Foundation and Analytics.   NOTE: Remember that the Analysis Event needs to be Enabled for new values to be fed into Result_low_grease_mo.     Click here to view Part 3 of this guide.  
View full tip
    Step 3: Important Factors   If the company cannot ship or deliver their products fast enough, that will cause food waste and less revenue. At the same time, having nonstop access to meaningful data about the logistics side of the company provides a new level of decision-making capabilities.   Let’s first see what some of the pitfalls are that causes bad logistics or room for improvement. We can keep these items in mind as we work on our application.   Customer behavior – More attention can be put on how customers are shopping in certain areas. It’s not enough to know what areas are buying the most products and send them more shipments. Deadhead miles and load management will help save unnecessary costs. Shipment tracking and route planning – The traveling salesman problem is one that scientists have been working on for ages. There is no one solution to this problem, but there are many bad ones. Planning methods and routes is almost magic, but the more methodical the process, the more can be saved here. Something as simple and selecting the routes based on the number of right turns to reduce gas can save millions on yearly gas expenses. Method of travel utilization – Sea. Air. Road. Train. Each method has its benefits and down sides. When you pick a method, also incorporate how to utilize all the space provided. This could be using smaller boxes, a different type of packaging material, or playing Tetris in a trailer.   Customer Models   Understanding your customer and their habits is of utmost importance. We'll start by creating some of the base models used for customers in this applications. You will build on top of these models as you progress through this learning path.   In the ThingWorx Composer, click the + New in the top left of the screen.   Select Data Shape in the dropdown.   In the name field, enter Fizos.Customers.DataShape. All of our customers will be based off this Data Shape. Set the Project (ie, PTCDefaultProject) and click Save to store all changes. Click on the Field Definitions tab and click the + Add button to add new Field Definitions.   Add the list of Properties below:  Name       Base Type      Aspects                           Description ID Integer 0 minimum, primary key, default 0 Row identifier UUID String N/A String used as unique identifer across multiple platforms Type String N/A Type of customer (individual or another company) Factors Tags Data Tag This will hold the different type of data points or tags that will help to analyze a customer's characteristics and behavior Name String N/A Customer name Email String N/A Customer email Address String N/A Customer address Phone String N/A Customer phone number   The Properties for the Fizos.Customers.DataShape Data Shape should match the following:   7. In the ThingWorx Composer, click the + New in the top left of the screen.   8. Select Data Table in the dropdown and select Data Table in the prompt.   9. In the name field, enter Fizos.Customers.DataTable. Our differing types of customers will fall under this template.   10. For the Data Shape field, select Fizos.Customers.DataShape. 11. Set the Project (ie, PTCDefaultProject) and click Save to store all changes.   12. This entity will be used to house our data and provide assistance with our analytics. Vehicle Models   To build a plan for your logistics solutions, you first need to have the data necessary for your vehicles and factories. Let's begin housing this data to help us with our planning. In the ThingWorx Composer, click the + New in the top left of the screen.   Select Data Shape in the dropdown.   In the name field, enter Fizos.Vehicles.DataShape. All of our vehicles will be based off this Data Shape. Set the Project (ie, PTCDefaultProject) and click Save to store all changes.   Add the list of properties below: Name          Base Type       Aspects                               Description ID Integer 0 minimum, primary key, default 0 Row identifier FactoryID Integer 0 minimum, default 0 Factory row identifier Location Location N/A String used as unique identifer across multiple platforms Features Tags Data Tag This will hold the different type of data points or tags that will help to plan what this vehicle can and will build Size String N/A Factory size   The properties for the Fizos.Factories.DataShape Data Shape are as follows:   In the ThingWorx Composer, click the + New in the top left of the screen.   Select Data Table in the dropdown and select Data Table in the prompt.   In the name field, enter Fizos.Vehicles.DataTable. Our differing types of vehicles will be inside of this Data Table. For the Data Shape field, select Fizos.Vehicles.DataShape. Set the Project (ie, PTCDefaultProject) and click Save to store all changes.   This entity will be used to house our data and provide assistance with our analytics.   Factory Models   In the ThingWorx Composer, click the + New in the top left of the screen.   Select Data Shape in the dropdown.   In the name field, enter Fizos.Factories.DataShape. All of our factories will be based off this Data Shape. Set the Project (ie, PTCDefaultProject) and click Save to store all changes.   Add the list of properties below: Name        Base Type       Aspects                                  Description ID Integer 0 minimum, primary key, default 0 Row identifier Location Location N/A String used as unique identifer across multiple platforms Features Tags Data Tag This will hold the different type of data points or tags that will help to plan what this factory can and will build Size String N/A Factory size   The properties for the Fizos.Factories.DataShape Data Shape are as follows:     In the ThingWorx Composer, click the + New in the top left of the screen.   Select Data Table in the dropdown.   In the name field, enter Fizos.Factories.DataTable. Our differing types of factories will be inside of this Data Table. For the Data Shape field, select Fizos.Factories.DataShape. Set the Project (ie, PTCDefaultProject) and click Save to store all changes.   This entity will be used to house our data and provide assistance with our analytics.   Centralized Logistics   Our application needs an efficient system of logistics. We already have sensors for our food entities, so see below how we work to move in the right direction. We'll be using a Thing Template to allow our new services to be overriden later if we so choose.   In the ThingWorx Composer, click the + New in the top left of the screen.   Select Thing Template in the dropdown.   In the name field, enter Fizos.Logstics. All of our product line will fit this abstract entity. For the Base Thing Template field, select GenericThing. Set the Project (ie, PTCDefaultProject) and click Save to store all changes.   Add the list of Services below. The level of the complexity in these Service vary based on how you would like to start your daily routine, the number of employees, number of deliveries and facilities, etc. Name                                    Return Type   Override    Async     Description PerformDailyDeliveries Nothing Yes Yes Start process of regular product deliveries.   The list of services should look like the following:     Click here to view Part 3 of this guide.
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
Announcements