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

ThingWorx Navigate is now Windchill Navigate Learn More

IoT & Connectivity Tips

Sort by:
    Step 6: Create Master   Now that we have created our Menu Entity, we can create a Master Mashup to hold a Menu Widget. We'll use the Menu Entity to configure the Menu Widget.     Navigate to Browse > Visualization > Masters.    Click +New.    Leave the defaults and click OK.    In the Name field, type MNWM_Master. If Project is not already set, search for and select PTCDefaultProject.    At the top, click Save.    At the top, click Design.     Add Header   Now that we've created the Master Entity, we need to add space for the Menu Widget.   At the top-left, click the Layout tab.    Click Add Top.   With the new top-section still selected, scroll down in the Layout tab, and select Container Size > Fixed Size.   In the new Height field, type 50, then hit your keyboard's Tab key to apply the change.    At the top, click Save.   Add Menu Widget Now that we have somewhere to put it, we can finally add the Menu Widget and then configure it.   In the top-left, click the Widgets tab.   Drag-and-drop a Menu Widget onto the top Canvas section.   Ensure the Menu Widget is still selected, as well as the Properties tab in the bottom-left.   In the Filter field, type menu.   For the Menu Property, search for and select MNWM_Menu.    At the top, click Save.     Step 7: Menu Navigation   We now have all the elements created to navigate using a Menu. The only thing left is to assign the Master to our Homepage and then view our work.     Return to MNWM_Homepage_Mashup.    In the top-left, click the Explorer tab.   Ensure that Mashup is selected. On the bottom-left Properties tab, in the Filter field, type master.   For the Master Property, search for and select MNWM_Master.    At the top, click Save. At the top, click View Mashup. You may need to enable "pop-ups" in your browser.   Click Park.   Click Amphitheater.   Note that you may wish to set MNWM_Master for the other pages of your application, just in case anyone were to navigate directly there via URL. But simply setting it on the homepage is enough for us to see that Menu navigation is functioning correctly.       Step 8: Next Steps   Congratulations! You've successfully completed the Mashup Navigation with Menus guide. In this guide, you learned how to:   Create a Mashup to be used as a "Home" page Create more Mashups as subpages Create a Menu Entity to track Mashups Create a Master Mashup as a Header Utilize a Menu Widget for navigation   Learn More    Capability     Resource Experience Track Issues with Pareto Chart   Additional Resources   If you have questions, issues, or need additional information, refer to:    Resource       Link Community Developer Community Forum Support Foundation Help Center - Menu Entity Support Foundation Help Center - Menu Widget    
View full tip
    Step 5: Limiting Composer Access   If you would like to limit a User even more, there are a few things you can do. Go back to the Administrator account and open one of the accounts we created, such as User.OtherAgencies, you will notice the Enabled and Locked checkboxes. Enabled allows you to set whether an account can be used in ThingWorx during runtime. Locked dictates whether an account can be logged into at all.     Suppose we would like for the user to only see emptiness when they try to access the Composer. Follow the below steps to limit ThingWorx Composer access even more.   1. Open one of the Users we created earlier, ie User.OtherAgencies and click on the User Profile tab.  The user profile configuration allows an administrator to control which categories and entities should be displayed for an individual User.     2. You will see various sections and checkboxes. Uncheck all of them to stop access to importing, exporting, creating new Entities, being able to see existing Entities, and much more.     3. Click Save.   Now if you attempt to log into the ThingWorx Composer, you will notice a very difference experience without the ability to see current Entities. Perform this update for all the Users we created, except for User.IT and User.AgencySuperUser.     Step 6: Creating Clearance Levels   ThingWorx does not include default security clearance levels for you. What it does include are Thing Groups. Thing Groups are a reference-able entity type in ThingWorx that allow for Things and Thing Groups as its members. They also provide ThingWorx administrators the ability to manage at scale exposure of Things to only those that require access.   Before we create out first Thing Group, let us create some Entities that will house resources. The first will be an image that is top secret (shown below). In ThingWorx, this would be of type Media. After, we will create a file repository that will contain super-secret documents, a repository for job applications, and another repository for documents that are publicly accessible.   Our Top Secret Image:     Create the Media Entity    Let us store our image in ThingWorx. This image will need extra credentials to access it. This authentication can be performed with a basic username/password setup or SSO utilizing your own configurations.   1.  In the ThingWorx Composer, click the + New button in the top left.    2. In the dropdown list, click Media.   3. In the Name field, use TopSecretImage.   4. Set the Project field to an existing Project (ie, PTCDefaultProject) and click Save. 5. Click Change and add an image or use the image above.     6. Click on the Configuration tab.     7. For the Authentication Type field, select basic. You can select other types based on your Single Sign On and server level configurations, but we will keep this scenario simple.     8. Set a Username and Password that would be used to access our top secret Media.     9. Click Save.   Create the File Repositories   Let us create the setup for our repositories.   1.  In the ThingWorx Composer, click the + New button in the top left.    2. In the dropdown list, click Thing.     3. In the Name field, use TopSecretDocuments and FileRepository as the Base Thing Template.     4. Click Save.  5. Repeat steps 1-4 to create two File Repositories titled JobApplications and PublicDocuments.     Security Levels and Resource Lockdown    We now have our several resources and areas for differing levels of access. We will create 3 Thing Groups to mimic security levels. Our top-secret image will exist independently on ThingWorx, but also inside of a file repository for some level of redundancy. That file repository will belong to one Thing Group, while the other two file repositories will have their own separate Thing Groups.   1. Open the TopSecretDocuments File Repository Thing.  2. Click on the Services tab.     3. Scroll down to the SaveImage and click the play button.      4. Enter a path (such as /SecretImage.png) for the image to reside on the server and click Change to add an image.     5. Click the Execute button.    You now have your image in a File Repository. Let us add this Entity to a Thing Group, then configure the permissions at the Thing Group level.   1.  In the ThingWorx Composer, click the + New button in the top left.      2. In the dropdown list, click Thing Group.     3. In the Name field enter Clearance.Top.     4. Set the Project field to an existing Project (ie, PTCDefaultProject) and click Save. 5. Click the Services tab and click the play button to execute the AddMembers Service.     6. Click on the members Input Info Table and click the + Add button.      7. Enter TopSecretDocuments as the name of the member and Thing as the type. 8. Click Add and Save. Set the Project field to an existing Project (ie, PTCDefaultProject).      9. With you members set, click Execute. 10. Repeat steps 1-9 to create two more Thing Groups and add the other File Repository Entities that we created earlier. Name these Thing Groups Clearance.Public and Clearance.HumanResources. If we wanted to, we could create a Thing Group to add here as a member of another Thing Groups’ hierarchy.   Thing Group Permissions    Time to set the permissions. With the Clearance.Top Thing Group selected, follow the below instructions. As mentioned before, in a production system, you would have more Users and User Groups to completely setup this scenario.   1. Click Permissions. 2. For Visibility, enter PTCDefenseDepartment into the filter.  3. Expand the Organization and select the Agents unit and click Save. 4. Click the Run Time tab. 5. Set the permissions for the Agency.Agents User Group to have full access as shown below:  6. Click Save.  7. Repeat steps 1-6 for our other security clearance Thing Groups. Set the permissions to a department and User Group that you see fit.     Step 7: Next Steps   Congratulations! You've successfully completed the Securing Resources and Private Data guide. In this guide, you learned how to:   Securing data and private information Use Services, Alerts, and Subscriptions to handle processes without human interaction Handling group and organization permissions   The next guide in the Utilizing ThingWorx to Secure Your Aerospace and Defense Systems learning path is Connecting External Databases and Model.    Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build ThingWorx Solutions in Food Industry Build Design Your Data 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
View full tip
    Step 8: Verify Connectivity   The EMS is now attempting to talk to ThingWorx Foundation.   However, ThingWorx does not have detailed information about the Edge device that is attempting to connect to it, so it will show up in the Unbound category of Remote Things.   Open ThingWorx Composer.     On the left, click Monitoring.   Click Status -> Remote Things.     Click Unbound.     Confirm that you see the PiThing listed in the Unbound section. NOTE: The name PiThing comes from the config.lua script. PiThing is simply the name that is in that script, hence the name that you see in ThingWorx. To change the name of the device, you could stop both wsems and luaScriptResource, edit config.lua to use a different Thing name other than PiThing, and then restart both of the EMS programs. At that point, the Thing showing up in Remote Things -> Unbound would be whatever name you changed to in config.lua.   Create a Remote Thing   Now that the EMS is communicating with ThingWorx Foundation, let's create a Remote Thing to which Foundation can tie said connection.   In ThingWorx Composer, click Browse > Modeling > Things.     At the top-left, click + New.       In the Name field, enter PiThing. Note that the name must match the spelling and capitalization of the Thing's name that you entered in the EMS's config.lua for it to auto-connect.   If Project is not already set, search for and select PTCDefaultProject. In the Base Thing Template field, search for remotethingwith.     Select RemoteThingWithTunnelsAndFileTransfer. At the top, Click Save. Note the status-indication pop-up indicating that PiThing is now connected.       Use Services to Explore EMS Files   Now that your Remote Thing is Saved and Connected, we can use some of the built-in Services to explore the EMS folders and files which we previously created for testing purposes.   At the top of PiThing, click Services.   Under the Execute column, click the Play Symbol for BrowseDirectory.   In the top-left path field, type / and click the bottom-right Execute button. Note the other and tw folders which we previously created for testing.   In the top-left path field, type /tw and click the bottom-right Execute button. Note the tw_test_01.txt file which we previously created for testing.     As the tw_test_01.txt file (and its parent folder) were items which we custom-created for this guide, you should now be 100% convinced that connectivity between Foundation and the EMS is dynamically working.   If so desired, you could explore into other folders (or even add additional files to these folders), run the BrowseDirectory Service again, and confirm that Foundation is now aware of the EMS and actively communicating.     Step 9: Next Steps   Congratulations! You've successfully completed the Setup a Raspberry Pi as an IoT Device guide, and learned how to:   Set up Raspberry Pi Install, configure, and launch the EMS Connect a remote device to ThingWorx   The next guide in the Medical Device Service learning path is Medical Data Storage and Display.    Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Manage Data Model Introduction Connect Connect Industrial Devices and Systems   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support ThingWorx Edge MicroServer (EMS) Help Center External Raspberry Pi Documentation
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 4: Scheduling Automated Processes   There are many processed that are handled by a corporation. With something as important as food, there is a lot of red tape and regulation.   We will further our Fizos application to monitor food temperatures, expiration dates, product state, and other issues that are factors into the condition of the product. To reduce waste and increase the safety of the food being produced, our application will create entities to model our products after and create a high-level rules engine for the usage and handling of these products.   Let's start with implementing the task of factory inspections. To implement this, we'll use a scheduler to kickstart our daily process and start filling in some of the necessary data.   Schedulers are a great way to execute routine processed. The execute using a configuration similar to that of a cron job on the Linux operating system. In the next guide, schedules will be used to start our deliveries and help execute certain functions of our business logic.   Creating Factories   Before we begin, we'll be using Data Tags. These tags will help organize, filter, search, and analyze what is happening throughout our applications.   In the ThingWorx Composer, click the + New in the top left of the screen.   Select Data Tag in the dropdown.   Set the name as Fizos.FactoryTags. Set the Project (ie, PTCDefaultProject). Add new terms now or you can add them later. We'll be adding them later. You can utilize tags with almost anything in this scenario. The more data, the better.   Now let's begin creating the factory data.   Open the Fizos.Factories.DataTable Data Table and go to the services tab.   Open the AddDataTableEntries service to be executed. This service will allow us to create some general data to work with. You can create as many as you like for this test. Click the values parameter to start creating entries. After clicking + Add, you'll see our Features property. This is where we can find the factory tags we just created, and create as many terms as we like. For simplicity, click New Term create two tags, Sausage and Atlanta. These options will provide us with the purpose of the factory and a location.   4. Save your entry and create a second entry with any location and tags you like. We aren't adding vehicles as of yet, but we will in the next section. 5. After saving, don't forget to execute the service with the two entries saved. If you did it correctly, the values parameter of the service, should show at least a 2 inside of the parentheses. You can also add data to the other parameters if you like. See below:     You now have two factories. We need to inspect these factories daily. What does an inspection entail exactly? You can create custom factories based on the type of products manufactured or have a generic system. Nevertheless, we will log and store these reports in a data table. Let's go. 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.FactoryInspections.DataShape. All of our factory inspections will be based off this Data Shape. Set the Project (ie, PTCDefaultProject) and click Save to store all changes now.   Add the list of properties below: Name                      Base Type     Aspects            Description GUID String primary key Report identifier FactoryID Integer 0 minimum Factory identifier DateRequest DateTime N/A Date the inspection was requested DateCompleted DateTime N/A Date the inspection was completed Report JSON N/A This will hold the inspection report data   The fields for the Fizos.FactoryInspections.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.FactoryInspections.DataTable. Our Data Table will hold all of our records on factory inspections. For the Data Shape field, select Fizos.FactoryInspections.DataShape. Set the Project (ie, PTCDefaultProject) and click Save to store all changes now.   This entity will be used to house our data and provide assistance with our analytics. For this scenario, we will create the scheduler that starts a generic process process. In the ThingWorx Composer, click the + New in the top left of the screen.   Select Schedulers in the dropdown.   Select Scheduler in the pop-up.   4. Name the new Schedule Fizos.Factory.Schedule. 5. For the Run As User field, select the Fizos.Factory.User that was provided in the download. 6. Set the Project (ie, PTCDefaultProject). 7. Click Save and your entity should match the below configuration.   8. For the Schedule field, set it to 0 0 7 * * ?. This will run the process every day at 7 AM.      9. Switch to the Subscriptions tab and add a new subscription. 10. Name this new subscription PerformDailyInspections and select ScheduledEvent as the event input.     11. Add the following code to the source section: var factories = Things["Fizos.Factories.DataTable"].GetDataTableEntries({}); var tableLength = factories.rows.length; for (var x=0; x < tableLength; x++) { var row = yourInfotableHere.rows[x]; Things["Fizos.ProductsBusinessLogic"].InspectFactory({ FactoryID: row.ID }); }   This code will execute the inspection request service. Now let's expand on the Fizos.ProductsBusinessLogic to produce and handle the result of a request. Open Fizos.ProductsBusinessLogic in Edit mode and go to the Services tab. Open the InspectFactory Service and add the below code. This code will create an inspection request in the data table and you can add code to simulate sending out this request to a user's device or have users query the data table for open requests. var table = Things["Fizos.Factories.DataTable"].GetDataTableEntryByKey({ key: factoryID }); var factory = table.rows[0]; var guid = generateGUID(); // Fizos.FactoryInspections.DataShape entry object var newEntry = new Object(); newEntry.GUID = guid; newEntry.FactoryID = factoryID; newEntry.DateRequest = new Date(); newEntry.DateCompleted = undefined; newEntry.Report = undefined; var values = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape({ infoTableName : "InfoTable", dataShapeName : "Fizos.FactoryInspections.DataShape" }); values.AddRow(newEntry); Things["Fizos.FactoryInspections.DataTable"].AddDataTableEntry({ sourceType: "Source Code", values: values, source: "InspectFactory", }); // Use guid for tracking report request // Create inspection request in ThingWorx attached to guid. This could be stored in a data table or a property field // Send out employee to factory 3. Open the ReceiveInspection Service and add the below code. This code can be accessed via a REST request to the system. This code can be modified to include error handling and conditions to support new requests coming in. var table = Things["Fizos.FactoryInspections.DataTable"].GetDataTableEntryByKey({ key: guid }); var data = table.rows[0]; var update = {}; update.GUID = guid; update.FactoryID = data.FactoryID; update.DateRequest = data.DateRequest; update.DateCompleted = new Date(); update.Report = report; var values = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape({ infoTableName : "InfoTable", dataShapeName : "Fizos.FactoryInspections.DataShape" }); values.AddRow(update); Things["Fizos.FactoryInspections.DataTable"].AddOrUpdateDataTableEntry({ sourceType: "Service Code", values: values, source: "ReceiveInspection" }); // Have employee log data using guid // Track everything inside of logs or data table   You now have a system that will run every day creating requests, storing those requests, and updating those requests with the final reports.     Step 5: Next Steps   Congratulations! You've successfully completed the ThingWorx Solutions in Food Industry guide. In this guide, you learned 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   The next guide in the Complex and Automatic Food and Beverage Systems learning path is Factory Line Automation.    Learn More   We recommend the following resources to continue your learning experience:    Capability     Guide Build Design Your Data 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  
View full tip
    Step 3: Creating Customer Data   Now let’s begin creating the customer data. Just enough examples for us to understand what is happening at each step. Let’s create at least 4 customers by following the steps below:   Open the Fizos.Customers.DataTable Data Table and go to the services tab. Open the AddDataTableEntries service to be executed. This service will allow us to create some general data to work with. You can create as many as you like for this test. Click the values parameter to start creating entries. After clicking + Add, and enter data for customers. Try to add at least 1 Factor data tag for each customer.     Save your entry and create a second entry with any location and tags you like. We aren’t adding vehicles as of yet, but we will in the next section. After saving, don’t forget to execute the service with the two entries saved. If you did it correctly, the values parameter of the service, should show at least 1 inside of the parentheses. See below for an example:     We just added customers manually. While convenient for our test, what we truly want is a system that is hands off. What we need is, a way to add customers programatically. Whether a customer is ordering on a website you created for them or they are checking out as a guest (we still want to track this). Below, you’ll see a quick service to add a new user. This service can be created inside of the Fizos.Customers.DataTable data table.   var customer = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape({ infoTableName : "InfoTable", dataShapeName : "Fizos.Customers.DataShape" }); var count = me.GetDataTableEntryCount(); var newEntry = {}; newEntry.ID = count + 1; newEntry.UUID = generateGUID(); newEntry.Type = Type; newEntry.Factors = "Fizos.CustomerTags:FirstTime"; newEntry.Name = Name; newEntry.Email = Email; newEntry.Address = Address; newEntry.Phone = Phone; customer.AddRow(); me.AddDataTableEntry({ sourceType: "Service", values: customer, source: "AddNewCustomer" }); We can adapt these for the customers that would rather not have accounts and be considered guests. Instead of the FirstTime data tag, you might want to add a Guest tag. For name, you could have it empty. The other fields, you’ll still want to likely have. This can give you insight into who these customers are that rather the guest checkout/ordering.     Step 4: Expanding Logistics Models   Let's do a quick review of what we have before we jump forward. In this Learning Path, we've setup scheduled factory inspections, machine automation, created customers, and setup order creation. What we're missing is the handling of deliveries.   In this learning path, we have talked about how to handle design aspects that could be held in a data table or have entities created to model each one. While there are many pros and cons to each method, we will do a mixture of both. Having the logistics data in data tables provide us with an easy form of querying data. Having entities match up with vehicles/transportation allows us to have greater tracking and live updates.   Let's create the vehicle/transportation data model, come up with logic on how to do deliveries from the factories we created earlier in this learning path, then setup a schedule or timer to kickstart the process.   Vehicles Data Model We already have our Data Table of vehicles. Let's create the templates and entities that will be a 1 to 1 between Thing and vehicle.   In the ThingWorx Composer, click the + New in the top left of the screen.   Select Thing Shape in the dropdown.   In the name field, enter Fizos.Vehicles.ThingShape and select a Project (ie, PTCDefaultProject). This Entity will have Services implemented by all types of vehicles. Save your changes and create three Thing Templates which implement this Thing Shape. See below for examples:   Fizos.Vans.ThingTemplate: These are smaller vehicles used to make short or last step deliveries.     Fizos.Trucks.ThingTemplate: These are trucks of different types making larger deliveries.     Fizos.Planes.ThingTemplate: These are planes used to deliver products to long distance locations.     Handling Shipping and Deliveries The cost of shipping and delivering goods is often the last thing people want to think about. Sometimes the cost of shipping goods is more expensive than the goods themselves. So how can we make this one of our strongest factors? By continuing trying to make our design simpler and less costly. We all know that it won't be an easy feat. The best way to do this is to have a system where we can have analytics and continuously improve on.   Let's start with the beginner steps of creating our straight-forward delivery service. Then, we will add Value Streams and tracking to see where we can make improvements. Finally, the solutions get better as we repeat these steps. No one solution is perfect, and no logic will be without holes or issues. Nevertheless, you continuously work on it, so that you can save cost and improve customer experience.   Open Fizos.Vehicles.ThingShape and go to the Properties tab. Create the following list of Properties. These properties are the generic concepts for a vehicle that can deliver a package. Name Base Type Aspects Details FuelCapacity Number 0 minimum, unit: liters logged, persistent AverageFuelConsumption Number 0 minimum, unit: liters logged, persistent MaxMass Number 0 minimum, unit: kilograms logged, persistent MaxVolume Number 0 minimum, unit: cubic meters logged, persistent CurrentLocation Location N/A logged, persistent CurrentOrders InfoTable(Fizos.Orders.DataShape) N/A logged, persistent Your properties should look like the following: Inside the Fizos.Vehicles.ThingShape entity, go to the Services tab. Create the following list of Services. These services are also generic in nature and are based on the concept of a vehicle going to a pick up location, goods being loaded onto the vehicle, the vehicle traveling to a destination, then delivering goods. Name Input Return Type Override Async Description PickUpGoods PickUpLocation: Location Nothing Yes Yes Go to a pickup location (factory or otherwise), and pick up goods. LoadGoods Orders: InfoTable (Fizos.Orders.DataShape) Nothing Yes Yes Perform the task of loading goods onto a vehicle (adding rows to the CurrentOrders property) Travel Destination: Location Nothing Yes Yes Travel for destination A to destination B DeliverGoods Orders: InfoTable (Fizos.Orders.DataShape) Nothing Yes Yes Perform the task of unloading goods at a current location As you can see, the goods are orders. In a real world environment, we would create a separate Data Shape and Data Table for packages to hold a number of orders. We are doing this without the packages Data Table for simplicity in this example. One reason why our products have mass and volume properties is to help with the idea of loading a vehicle and the type of boxes or packaging to use. This could be another way to cut cost. Your Services should look like the following: The same way we were able to create a system that was automated, we will create events that will notify subscribers of certain tasks being complete. This way, the next level of service can be performed instantly by our robot army. Inside the Fizos.Vehicles.ThingShape entity, go to the Events tab. Create the following list of events. These Events will connect to a task being completed. For example, when the vehicle has arrived to a location, an Event will be triggered and thus the next task can begin. For a bit more automation, add an Event you might think is needed, like when fuel is needed in the vehicle.   Name Data Shape Description DestinationReached AlertEvent This alert is fired when the vehicle has reached a location (whether for delivery or pickup). OrdersLoaded AlertEvent This alert is fired when all orders have been loaded onto a vehicle. DeliveryCompleted AlertEvent This alert is fired when the vehicle has completed a delivery. This delivery might have been the last order delivery and vehicle needs to head back for more orders to be picked up. Your Services should look like the following: Let's take a quick break to go over how this will work. A Service in the Fizos.Logistics Entity will search for all Things that implement the Fizos.Vehicles.ThingShape Entity. Each list of these Entities will have it's PickUpGoods Service called with the desired pickup location. When the destination is reached inside of the PickUpGoods Service, the DestinationReached Alert will be triggered. A Subscription waiting for this Event at the Thing level, will call the LoadGoods Service based on the condition of no orders being in the vehicle CurrentOrders Property. This LoadGoods Service will finish and trigger a OrdersLoaded Event. A subscription waiting for this Event at the Thing level, will call the Travel service. The Service will be called with the customer location as the destination OR the location of another site to perform other tasks. When the destination is reached inside of the Travel Service, the DestinationReached Alert will be triggered. A Subscription waiting for this Event at the Thing level, will call the DeliverGoods Service based on the condition of orders being left in the CurrentOrders Property. When the delivery is complete, the DeliveryCompleted Alert will be triggered. A Subscription waiting for this Event at the Thing level, will decide whether to go to a factory or pickup location to restart the process or wait for more instructions. You may have noticed a few things here. For starters, we are starting this from the Fizos.Logistics entity instead of a scheduler. For this process, you can start it with a scheduler, but being a 24 hour company, we don't have a schedule to start deliveries. That being said, the click of a button would do the job.   You can also see that we haven't given you the service code for some of these services. For some of these functions, they're almost duplicates of prior services. What will be more challenging and fun is the logic for which orders go to which delivery method. This is a mixture of vehicle properties, order properties, customer type, and customer location.     Step 5: Next Steps   Congratulations! You've successfully completed the Automated Distribution and Logistics guide.   In this guide, you learned how to: Create automated logistical processes Use services, alerts, and subscriptions to handle processes without human interaction Integrating complex logic with straight forward step by step systems   The next guide in the Complex and Automatic Food and Beverage Systems learning path is Securing Industry Data.    Learn More We recommend the following resources to continue your learning experience:   Capability            Guide Build ThingWorx Solutions in Food Industry Build Design Your Data 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 Help Center
View full tip
  Step 4: Simulated Model   Models are primarily used by Analytics Manager (which will be discussed in the next guide), but they can still be used to estimate the accuracy of predictions.   When Models are calculated, they inherently withhold a certain amount of data (~20%). The prediction model is then run against the withheld data. This provides a form of "accuracy measure".   The withheld-data is selected randomly, so you'll actually get a slightly different model and accuracy measure each time that you create a Model versus the same dataset.   On the left, click Analytics Builder > Models.   Click New….   In the Model Name field, enter simulated_model. In the Dataset field, select simulated_dataset.   Click Submit. After ~60 seconds, the Model Status will change to COMPLETED.     Select the model that was created in the previous step, i.e. simulated_model. Click View… to open the Model Information page.   As with Signals and Profiles, our Model is once again "too good". In fact, it's perfect.   The expected "Precision" is 1.0, i.e. 100%. The True vs False Positive rate shown in the graph goes straight up to the top immediately.   While you want a graph that is "high and left", you're very unlikely to ever see real-world scenarios such as shown here.   Still, you've been able to progress the process of using Foundation (and now Analytics) to build an analytical model of MotorCo's prototype engine.   What needs to happen now is to receive real world data from your R&D engineers.     Step 5: Upload Real World Data   In your process of using the EMS Engine Simulator, the idea has always been to get a headstart on the engine developers.   At some point, they would wire sensors into the EMS and start providing real world data.   In our scenario, that has now happened. Real world data is being fed from the EMS to Foundation, Foundation is collecting that data in an Info Table Property, and you've even exported the data as a .csv. file.   This new dataset is over periods of both good and bad grease conditions. The engineers monitoring the process can flip a sensor switch connected to the EMS to log the current grease situation as either good or bad at the same time that the vibration sensors are taking readings.   We will now load this real world dataset into Analytics in the same manner that we did earlier with the simulated dataset.   Download the attached analytics_vibration.zip file to your computer. Unzip the analytics_vibration.zip file to access the vibration_data_and_header.csv and vibration_metadata.json files. On the left, click Analytics Builder > Data. Under Datasets, click New....   In the Dataset Name field, enter vibration_dataset. In the File Containing Dataset Data section, search for and select vibration_data_and_header.csv. In the File Containing Dataset Field Configuration section, search for and select vibration_metadata.json.   Click Submit.     Step 6: Real World Signals and Profiles   Now that the real-world vibration data has been uploaded, we’ll re-run Signals and Profiles just as we did before.   Hopefully, we’ll start seeing some patterns.   On the left, click Analytics Builder > Signals. At the top, click New….   In the Signal Name field, enter vibration_signal. In the Dataset field, select vibration_dataset.   Click Submit. Wait ~30 seconds for Signal State to change to COMPLETED     The results show that the five Frequency Bands for Sensor 1 are the most highly correlated with determining our goal of detecting a low grease condition.   For Sensor 2, only bands one and four seem to be related, while bands two, three, and five are hardly relevant at all.   This is a very different result than our earlier simulated data. Instead, it looks like it’s possible that the vibration-frequencies getting pickup up by our first sensor are explicitly more important.   Profiles   We’ll now re-run Profiles with our real-world dataset. On the left, click Analytics Builder > Profiles. Click New….   In the Profile Name field, enter vibration_profile. In the Dataset field, select vibration_dataset.   Click Submit. After ~30 seconds, the Signal State will change to COMPLETED.     The results show several Profiles (combinations of data) that appear to be statistically significant.   Only the first few Profiles, however, have a significant percentage of the total number of records. The later Profiles can largely be ignored.   Of those first Profiles, both Frequency Bands from Sensor 1 and Sensor 2 appear.   But in combination with the result from Signals (where Sensor 1 was always more important), this could possibly indicate that Sensor 1 is still the most important overall.   In other words, since Sensor 1 is statistically significant both by itself and in combination (but Sensor 2 is only significant in combination  with Sensor 1), then Sensor 2 may not be necessary.     Click here to view Part 3 of this guide.
View full tip
  Send voice and text messages with Twilio.   GUIDE CONCEPT   This project will demonstrate how you can create applications that provide information to users, even when they are away from their computer. Users who are on the go can benefit from your application by receiving text and voice messages.   Following the steps in this guide, you will learn how to configure and use the Twilio Widget and explore it’s ability to send messages.   We will teach you how data can be used to send pertinent information to any cell phone.   YOU'LL LEARN HOW TO   Download and import the Twilio Widget extension Create a Thing using the Twilio Thing Template Configure the Twilio Thing to use your Twilio account Send text messages using a Service   NOTE:  The estimated time to complete this guide is 30 minutes.     Step 1: Install Twilio Extension   Download the Twilio Extension from IQNOX.com. Note:  IQNOX is a PTC Partner and will be maintaining and supporting specific extensions going forward.  It will be necessary to create an account on the IQNOX website, but the ThingWorx extensions are free. In the lower-left side of Composer, click Import/Export, then Import.   In the Import From File pop-up, under Import Option select Extension from the drop-down, then click Browse. Navigate to the .zip file you downloaded.   Click Import in the Import From File pop-up, then click Close after file is successfully imported.     Step 2: Create Twilio Thing   In this step, you will create a Thing that represents a connection with the Twilio service.   Start on the Browse, folder icon tab on the far left of ThingWorx Composer.  Under the Modeling tab, hover over Things then click the + button. Type twilio-connector in the Name field.   NOTE: This name, with matching capitalization, is required for the example code which will be entered in a later step. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. In the Base Thing Template text box, click the + and select Twilio.     Click Save.     Step 3: Configure Twilio Thing   Now that we have created a Thing to represent the Twilio connection, we will configure it with your Twilio account credentials.   When the Twilio Extension is installed, it does not include the Twilio account credentials required to send messages.   You will need Twilio account credentials to complete this step. If you do not already have a Twilio account, you can click on this link to create a Twilio account.   Open the twilio-connection Thing if it is not already open. Click on the Configuration tab. Click the pencil icon next to the authToken field.   Copy your AUTH TOKEN from your Twilio account dashboard.   Paste your AUTH TOKEN into the New Password and Confirm Password fields under authToken.   Click the pencil icon next to the accountSID field. Copy your ACCOUNT SID from your Twilio account dashboard, and paste it into the New Password and Confirm Password fields under accountSID. Follow the steps in your Twilio account dashboard to get a trial phone number.   Copy your PHONE NUMBER from your Twilio account dashboard, and paste it into the callerID field.   Click Save.     Step 4: Test Twilio Thing   Now that we have created a Thing to represent the Twilio connection and configured it with Twilio account credentials, we will confirm that everything is working.   Click the Services tab at the top of the twilio-connector Thing.     Click the link to the SendSMSMessage Service in the Services Name column. Enter a phone number in the to field. Enter a test message in the text field.   Click the Execute button to send the SMS message. The service should execute without any errors within a couple of seconds and the phone number will receive your message. Click Close to end testing the service.     Step 5: Sample Alerting App   At this point, you have created and tested a Thing that can send text messages. This step will demonstrate sending a message when a Property Value is out of the desired range.   Import Simulated Freezer Thing   Download and unzip the attached sample Things_freezer.zip. In Composer, click the Import/Export icon at the lower-left of the page.   Click Import. Leave all default values and click Browse to select the Things_freezer.twx file that you just downloaded. Click Open, then Import. When you see the success message, click Close.   Explore Imported Entities   Navigate to the freezer Thing by using the search bar at the top of the screen. Click the Subscriptions tab.   Click reportFreezer under Name. Open the Subscription Info tab. Select the Enabled checkbox.   Click Done then Save to save any changes.   Verify Data Simulation   Open the freezer Thing and click Properties and Alerts tab. Click the Set value in the alertedPhone Property row, in the Value column.   Enter a phone number to receive the SMS alert, then click the Check icon above where you entered the phone number. Click the pencil icon in the temp Property row, in the Value column. Enter a value for the temp property that is greater than 30, and click the Check icon. In a couple seconds, the phone number you entered will receive an alert that includes the value you entered.      Step 6: Next Steps   Congratulations!   In this guide, you learned how to:   Create a Thing using the Twilio Thing Template Configure the Twilio Thing to use your Twilio account Send text messages using a Service   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Twilio Extension Help Center
View full tip
    Step 5: Create InfoTable   Now that we have connected values coming from our EMS engine simulator, we want a method of permanent storage whenever we feel it's appropriate to take a sample.   From repeated sampling, we'll be able to build up a historical record usable for both manual inspection, as well as automatic analysis via ThingWorx Analytics (though ThingWorx Analytics is beyond the scope of this guide).   To hold these records, we'll use an Info Table Property.   But any time that you create an Info Table, you first need a Data Shape to format the columns.   Click Browse > MODELING > Data Shapes.     At the top-left, click + New.   In the Name field, type esimDataShape.     If Project is not already set, search for and select PTCDefaultProject. At the top, click Field Definitions.     We now want to add a separate Field Definition for each entry of our engine simulator data, i.e. low_grease, s1_fb1 through s1_fb5, and s2_fb1 through s2_fb5.   In addition, we'll add an additional field named identifier which simply keeps a rolling count of the current log entry number.   Click + Add.     In the Name field on the right slide-out, type identifier Change the Base Type to NUMBER. Check Is Primary Key   At the top-right, click the "Check with a +" button for Done and Add.     Repeatedly add additional definitions as per the chart below: Note that you will NOT check the "Is Primary Key" box, as you only need one, i.e. identifier. Name Base type low_grease NUMBER s1_fb1 NUMBER s1_fb2 NUMBER s1_fb3 NUMBER s1_fb4 NUMBER s1_fb5 NUMBER s2_fb1 NUMBER s2_fb2 NUMBER s2_fb3 NUMBER s2_fb4 NUMBER Create one additional entry for s2_fb5 and NUMBER, but click the "Check" button for DONE. At the top, click Save.     Create Info Table   Now that we have a Data Shape we can add an Info Table Property to EdgeThing. Return to the Properties and Alerts tab of EdgeThing.   At the top-left, click + Add.   In the Name field of the slide-out on the right, type infoTableProperty.   Change the Base Type to INFOTABLE.   In the new Data Shape field, search for and select esimDataShape.   Check the Persistent checkbox.   At the top-right, click the "Check" button for Done. At the top, click Save.     Click here for Part 4 of this guide.
View full tip
  Step 7: Real World Model   We’ll now rerun model creation with the Real World data.   Even though Signals and Profiles are possibly telling us that only Sensor 1 is needed, the first Model you’ll create will contain all the data, while the second Model will exclude Sensor 2. We’ll then compare the Models to see which one is going to work the best for predicting engine failures.   On the left, click Analytics Builder > Models. Click New….   In the Model Name field, enter vibration_model. In the Dataset field, select vibration_dataset.   Click Submit. After ~60 seconds, the Model Status will change to COMPLETED. Select the model that was created in the previous step, i.e. vibration_model. Click View… to open the Model Information page. Note that your model may differ slightly from the picture below, as the automatically-withheld "test" data is randomly chosen.       Unlike our simulated dataset, this real-world data is not perfect. However, it’s still pretty good, and is much more representative of what a real-world scenario would indicate.   The True Positive Rate shown on the Receiver Operating Characteristic (ROC) chart are much higher than the False Positives.   The curve is relatively high and to the left, which indicates a high accuracy level.   You may also click on the Confusion Matrix tab in the top-left, which will show you the number of True Positive and True Negatives in comparison to False Positives and False Negatives.     NOTE: The number of correct predictions is much higher than the number of incorrect predictions.   As such, we now know that our Sensors have a relatively good chance at predicting an impending failure by detecting low grease conditions before they cause catastrophic engine failure.   Refined Model   We can now compare this first Model that includes both Sensors to a Model using only Sensor 1, since we suspect that Sensor 2 may not be necessary to achieve our goal. On the left, click Analytics Builder > Models. Click New…. In the Model Name field, enter vibration_model_s1_only. In the Dataset field, select vibration_dataset.   On the right beside Excluded Fields from Model, click the Excluded Fields button.   Select s2_fb1 through s2_fb5.   While all the s2 values are selected, click the green "right-arrow", i.e. > button, in the middle.   At the bottom-left, click Save.   Click Submit. After ~60 seconds, the Model State will change to COMPLETED. With vibration_model_s1_only selected, click View….     The ROC chart is comparable to the original model (including Sensor 2).   Likewise, the Confusion Matrix (on the other tab) indicates a good ratio of correct predictions versus incorrect predictions.     NOTE: These Models may vary slightly from your own final scores, as what data is used for the prediction versus for evaluation is random.   ThingWorx Analytics’s Models have indicated that you are likely to receive roughly the same accuracy of predicting a low-grease condition whether you use one sensor or two!   If we can get an accurate early-warning of the low grease condition with just one sensor, it then becomes a business decision as to whether the extra cost of Sensor 2 is necessary.     Step 8: Next Steps   Congratulations! You've successfully completed the Build an Engine Analytical Model guide, and learned how to:   Load an IoT dataset Generate machine learning predictions Evaluate the analytics output to gain insight   The next guide in the Vehicle Predictive Pre-Failure Detection with ThingWorx Platform learning path is Manage an Engine Analytical Model.   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Analyze Operationalize an 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 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 5: Widget Properties   You can configure Properties to change the style of the map as well as specify a custom image to use for map markers. Other Properties allow two linear paths and polynomial regions to also be displayed on the map Widget with optional tooltip data.   Bindable   Name Type  Default Direction  Description Data Infotable None Input Source for the data that is displayed as discrete markers LocationField MenuName None Input Field that contains Location type data to plot markers MarkerField MenuName None Input Field that contains data of type Image used to plot markers ShowMarkerTooltip Boolean True Input Hovering over map markers will display a tooltip when set to true ToolTipField1 thru 4 MenuName None Input Optional field displayed in tooltip when the user hovers over a map marker ToolTipLabel1 thru 4 String None Input Optional label for tooltip data RouteData Infotable None Input Source for the data that is displayed as a connected route RouteLocationField MenuName None Input Field that contains Location type data to plot connected route line ShowRoute Boolean False Input Show route data on map when set to true PlannedRouteData Infotable None Input Source for the data that is displayed as a second connected route PlannedRouteLocationField MenuName None Input Field that contains Location type data to plot a second connected route line ShowPlannedRoute Boolean False Input Show planned route data on map when set to true RegionData Infotable None Input Source for the data that is displayed as a region RegionLocationData Infotable None Input Region location data source RegionLocationsField MenuName None Input Field which will provide location table information for region RegionLayerField MenuName None Input Field that contains Numeric data used for region layer number ShowRegions Boolean False Input Show region data on map when set to true ShowRegionTooltips Boolean True Input Hovering over region will display a tooltip when set to true RegionToolTipField1 thru 4 MenuName None Input Optional field displayed in tooltip when the user hovers over a region RegionToolTipLael1 thru 4 String None Input Optional label for region tooltip data RegionFillOpacity Number 1 Input Opacity of region fill color from 0 being transparent to 1 being opaque SelectedLocation Location None Input/Output The currently selected location CurrentZoom Number 8 Output The currently displayed zoom level ( 1 - 15 ) Zoom Number 8 Input Number used to set the zoom level ( 1 - 15 ) ShowMarkers Boolean True Input Shows map markers if set to true ShowPathMarkers Boolean True Input Shows map markers if set to true ShowTraffic Boolean False Input Shows traffic data color overlay on map if set to true NEBoundary Location None Output The northeast boundary location NWBoundary Location None Output The northwest boundary location SEBoundary Location None Output The southeast boundary location NWBoundary Location None Output The southwest boundary location Visible Boolean True Input Widget is visible if set to true     Static   Name Type  Default Description DisplayName String None Name used for widget in user facing interactions Description String None Description used for widget in user facing interactions MapType Roads/Satellite/Hybrid/Terrain Roads The type of map content displayed MapSkin Normal/Blue/Grey Normal Options for styling maps monochromatically AutoZoomBehavior Data change/Initial Data only Data Change Controls when map will automatically zoom to show all markers ClusterLocations Boolean False Combines multiple location markers that are near one another into a single marker if true MultiSelect Boolean False Enable multiple marker selection   Widget Events   DoubleClicked- Triggered when user double clicks on the Google Map. Changed- Triggered when the data for this widget is modified. BoundsChanged- Triggered when the bounding box of the displayed map changes.     Step 6: Next Steps   If you have questions, issues, or need additional information, refer to:   Resource     Link Community Developer Community Forum Support Google Map Widget Help Center Free Google Maps Widget Extension IQNOX  
View full tip
  Step 5: Format Timed Values   At the top, click the Services section of scts_thing.   In the Ihnerited Services section, you will see the built-in services of the Statistical Calculation Thing Shape. These services can perform a variety of analytical calculations.   Timed Values Service   The Statistical Calculation Thing Shape can only perform analytics operations on time-series datasets. However, accessing a time-series Value Stream can have a performance hit on the system.   Instead, a Property with an Info Table using a timestamp/value Data Shape is used as the universal input to each built-in service of the Statistical Calculation Thing Shape.   For efficiency, we only reference the Value Stream once to create a formatted timedValues that is used as an input to all other service calls.   At the top, click Services.   Click + Add.   In the Name field, enter timed_values_service. In the Javascript field, copy and past the following code: me.timed_values = me.QueryTimedValuesForProperty({ propertyName: "numbers", maxItems: 10, startTime: me.start_time, endTime: me.end_time });   At the bottom, click Save and Execute.   Click Done, and return to Properties and Alerts. On the timed_values property row, click the pencil icon for Set value of property.   In the pop-up, note that there are now seven entries - each with the 1, 5, 9, 5, 9, 1, and 9 values and the timestamps when you entered them.   In the pop-up, click Cancel. If needed, in the top-right, click the icon to close the slide-out.   Step 6: Calculation Services   Now that the numbers, start_time, end_time, and timed_values service inputs have been set, you can use the built-in Services of the Statistical Calculation Thing Shape to perform a variety of analytics calculations.   Mean Service   First, you will utilize the built-in CalculateMeanValue service.   The dataset is the following: 1, 5, 9, 5, 9, 1, 9.   As such, the mean should be (1+5+9+5+9+1+9)/7 = 39/7 = 5.571...   Return to the Services section. At the top, click + Add. In the Name field, enter mean_service. In the Javascript code section, copy and paste the following: me.mean_result = me.CalculateMeanValue({ timedValues: me.timed_values }); At the top, click Save and Continue.   At the bottom, click Execute. Click Done, then return to the Properties and Alerts section. Note that the mean_result property now has the value 5.571....     Median Service   Next, you will utilize the built-in CalculateMedianValue service.   With our dataset having 5 as the middle value, that should be the result.   Return to the Services section. At the top, click + Add. In the Name field, enter median_service. In the Javascript code section, copy and paste the following: me.median_result = me.CalculateMedianValue({ timedValues: me.timed_values }); At the top, click Save and Continue. At the bottom, click Execute. Click Done, and return to the Properties and Alerts section. Note that the median_result Property now has the value 5.     Mode Service   You will now utilize the built-in CalculateModeValue service.   With the dataset having 9 as the most common value, that should be the result.   Return to the Services section. At the top, click + Add. In the Name field, enter mode_service. In the Javascript code section, copy and paste the following: me.mode_result = me.CalculateModeValue({ timedValues: me.timed_values }); At the top, click Save and Continue.   At the bottom, click Execute. Click Done, and return to the Properties and Alerts section. On the mode_result row and under the Value column, click the "pencil" icon for Set value of property.   In the popup, note that the mode_result Property now has the value 9.   Click Cancel to close the popup. If necessary, at the top-right, click the button to close the slide-out.   Standard Deviation Service   Lastly, you will utilize the built-in CalculateStandardDeviationValue service.   There are multiple free Standard Deviation calculators to check the answer.   Accordingly, the Standard Deviation should be 3.59894...   Return to the Service section. At the top, click + Add. In the Name field, enter standarddev_service. In the Javascript code section, copy and paste the following: me.standarddev_result = me.CalculateStandardDeviationValue({ timedValues: me.timed_values }); At the top, click Save and Continue.   At the bottom, click Execute. Click Done, and return to the Properties and Alerts section. Note that the standarddev_result property now has the value 3.59894...       Step 7: Other Options   The Mean, Median, Mode, and Standard Deviation services you have completed are just a sampling of what the Statistical Calculation Thing Shape offers.   Below is a table of additional built-in services:   Calculation Service Name Description Binned Data Distribution for Bin Size CalculateBinnedDataDistributionForBinSize Calculate the binned distribution of data points based on the desired bin size. Binned Data Distribution for Number of Bins CalculateBinnedDataDistributionForNumberOfBins Calculate the binned distribution of data points based on the desired number of bins. Confidence Interval Values CalculateConfidenceIntervalValues Confidence Interval Values Based on a specified confidence interval percentage, calculate the minimum, median, and maximum interval values. Five Number Property Values CalculateFiveNumberPropertyValues Calculate the five number values: minimum, lower quartile, median, upper quartile, and maximum. Fourier Transform CalculateFourierTransform Calculate the results of running the fast Fourier transform on the specified values. Maximum Value CalculateMaximumValue Calculate the maximum property value in the provided infotable. Minimum Value CalculateMinimumValue Calculate the minimum property value in the provided infotable. Sampling Frequency Values CalculateSamplingFrequencyValues Calculate the sampling frequency values: minimum, median, and maximum.     Step 8: Next Steps   Congratulations!   In this guide, you have learned how to:   Create a Value Stream and Data Shape Create a Thing with the Statistical Calculation Thing Shape Modify a property to record values to the Value Stream Utilize various built-in services for analytical calculations   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Build a Predictive Analytics Model Build Operationalize an Analytics Model   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Descriptive Analytics Help Center
View full tip
This video continues Module 3: Data Profiling of the ThingWorx Analytics Training videos. It describes metadata, and how it is used to ensure that your data is handled appropriately when running Signals, Profiles, Training, Scoring, and other jobs inside ThingWorx Analytics.
View full tip
  Display project burn up/down via a convenient Mashup Widget.   GUIDE CONCEPT   Long term projects need to be managed. As a project is scoped, requirements get defined and delivery-timeframes are estimated. As work is done, requirements are completed.   One way to track this project progress is with a Waterfall Chart.   This guide will show you how to utilize a Waterfall Chart Widget to easily display the project workflow.        YOU'LL LEARN HOW TO   Create a Data Shape Create a Thing Create an Info Table Property Populate an Info Table with appropriate data for a Waterfall Chart Create a Mashup Utilize a Waterfall Chart to display project progress   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes     Step 1: Create Data Shape   In this scenario, we'll store the Waterfall Chart's data in a Property type called an Info Table.   An Info Table is a spreadsheet-like Property, but in order to define the columns of the table, we first have to define a Data Shape. We'll do that in this step.   In the left-side navigation, click Browse > Modeling > Data Shapes.   At the top, click + New.   In the Name field, type TPWC_DataShape. If Project is not already set, search for and select PTCDefaultProject .   At the top, click Field Definitions.   At the top-left, click + Add.   On the right-side slide-out, in the Name field, type month. Note that you want to leave "Base Type" as the default of "STRING". Check Is Primary Key.   Click the "check with a plus" button for Done and Add.   In the Name field, type amount. Change Base Type, to NUMBER.   Click the "check" button for Done.   At the top, click Save .     Step 2: Create Thing   Now that we have our Data Shape, we can create a Thing to document the project progress over time.   As already mentioned, we'll use an Info Table Property, formatted by the previously-created Data Shape, to do so.   Click Browse > Modeling > Things.   Click + New.   In the Name field, type TPWC_Thing. If Project is not already set, search for and select PTCDefaultProject. In the Base Thing Template field, search for and select GenericThing. At the top, click Save.   Add Info Table Property Now that we have our Thing instantiated, we want to add an Info Table Property. At the top, click Properties and Alerts.   Click + Add.   On the right-side slide-out, in the Name field, type InfoTable_Property. Change Base Type to INFOTABLE. In the Data Shape field, search for and select TPWC_DataShape. Note that the Data Shape field will not appear until you set Base Type to INFOTABLE. Check Persistent.   At the top-right, click the "check" button for Done. At the top, click Save.   Set Value of Property Now that we have a place in which to store spreadsheet-like values, we'll do so manually for testing.  On the InfoTable_Property row, under the Value column, click the "pencil" icon for Set value of property.   On the pop-up, click + Add.   Enter the following values in each field as per the table below: Field Name Value month January amount 380   Click Add.   Repeat Steps 2-4 multiples times until all of the below values have been entered. Note that amount should be left blank for both Mid-Term and Total. Note that you may enter fewer than all the values listed below if so desired, though your final Waterfall Chart will not match the following screenshots. month amount February 85 March 50 April 1000 May -300 June 0 Mid-Term   July 30 August -655 September -100 October -250 November 350 December -100 Total     On the pop-up, click Save.   At the top, click Save.   Step 3: Create Mashup   Now that we have our data in-place for testing (and could be connected to automated systems after we finish testing), we need to visualize the data.   As mentioned, we'll use a Waterfall Chart Widget, but first, we need to create a Mashup into which we can place the Widget.   Click Browse > Visualization > Mashups.   Click + New.   Leave the defaults and click OK.   In the Name field, type TPWC_Mashup. If Project is not already set, search for and select PTCDefaultProject. At the top, click Save.   At the top, click Design.   At the top-left, click the Widgets tab.   Drag-and-drop a Waterfall Chart Widget onto the central Canvas.   At the top, click Save.     Click here to view Part 2 of this guide.
View full tip
    Step 5: Properties   In the Delivery Truck application, there are three Delivery Truck Things. Each Thing has a number of Properties based on its location, speed, and its deliveries carried out. In this design, when a delivery is made or the truck is no longer moving, the Property values are updated. The deliveryTruck.c helper C file is based on the DeliveryTruck Entities in the Composer. After calling the construct function, there are a number of steps necessary to get going. For the SimpleThing application, there are a number of methods for creating Properties, Events, Services, and Data Shapes for ease of use.   Properties can be created in the client or just registered and utilized. In the SimpleThingClient application, Properties are created. In the DeliveryTruckClient application, Properties are bound to their ThingWorx Platform counterpart. Two types of structures are used by the C SDK to define Properties when it is seen fit to do so and can be found in [C SDK HOME DIR]/src/api/twProperties.h:    Name                   Structure            Description Property Definitions twPropertyDef Describes the basic information for the Properties that will be available to ThingWorx and can be added to a client application. Property Values twProperty Associates the Property name with a value, timestamp, and quality.   NOTE: The C SDK provides a number of Macros located in [C SDK HOME DIR]/src/api/twMacros.h. This guide will use these Macros while providing input on the use of pure function calls.   The Macro example below can be found in the main source file for the SimpleThingClient application and the accompanying helper file simple_thing.c.   TW_PROPERTY("TempProperty", "Description for TempProperty", TW_NUMBER); TW_ADD_BOOLEAN_ASPECT("TempProperty", TW_ASPECT_ISREADONLY,TRUE); TW_ADD_BOOLEAN_ASPECT("TempProperty", TW_ASPECT_ISLOGGED,TRUE);   NOTE: The list of aspect configurations can be seen in [C SDK HOME DIR]/src/api/twConstants.h. Property values can be set with defaults using the aspects setting. Setting a default value in the client will affect the Property in the ThingWorx platform after binding. It will not set a local value in the client application.   For the DeliveryTruckClient, we registered, read, and update Properties without using the Property definitions. Which method of using Properties is based on the application being built.   NOTE: Updating Properties in the ThingWorx Platform while the application is running, will update the values in the client application. To update the values in the platform to match, end the Property read section of your property handler function with a function to set the platform value.   The createTruckThing function for the deliveryTruck.c source code takes a truck name as a parameter and is used to register the Properties, functions, and handlers for each truck.   The updateTruckThing function for the deliveryTruck.c source code takes a truck name as a parameter and is used to either initialize a struct for DeliveryTruck Properties, or simulate a truck stop Event, update Properties, then fire an Event for the ThingWorx platform.   Connecting properties to be used on the platform is as easy as registering the property and optionally adding aspects. The following shows the properties that correlate to those in the DeliveryTruck entities in the Composer. To do this within the code, you would use the TW_PROPERTY macro as shown in the deliveryTruck.c. This macro must be proceeded by either TW_DECLARE_SHAPE, TW_DECLARE_TEMPLATE or TW_MAKE_THING because these macros declare variables used by the TW_PROPERTY that follow them.   //TW_PROPERTY(propertyName,description,type) TW_PROPERTY(PROPERTY_NAME_DRIVER, NO_DESCRIPTION, TW_STRING); TW_PROPERTY(PROPERTY_NAME_DELIVERIES_LEFT, NO_DESCRIPTION, TW_NUMBER); TW_PROPERTY(PROPERTY_NAME_TOTAL_DELIVERIES, NO_DESCRIPTION, TW_NUMBER); TW_PROPERTY(PROPERTY_NAME_DELIVERIES_MADE, NO_DESCRIPTION, TW_NUMBER); TW_PROPERTY(PROPERTY_NAME_LOCATION, NO_DESCRIPTION, TW_LOCATION); TW_PROPERTY(PROPERTY_NAME_SPEED, NO_DESCRIPTION, "TW_NUMBER);   Read Properties   Reading Properties from a ThingWorx platform Thing or the returned Properties of a Service can be done using the TW_GET_PROPERTY macro. Examples of its use can be seen in all of the provided applications. An example can be seen below:   int flow = TW_GET_PROPERTY(thingName, "TotalFlow").number; int pressue = TW_GET_PROPERTY(thingName, "Pressure").number; twLocation location = TW_GET_PROPERTY(thingName, "Location").location; int temperature = TW_GET_PROPERTY(thingName, "Temperature").number;   Write Properties   Writing Properties to a ThingWorx platform Thing from a variable storing is value uses a similarly named method. Using the TW_SET_PROPERTY macro will be able to send values to the platform. Examples of its use can be seen in all of the provided applications. An example is shown below:   TW_SET_PROPERTY(thingName, "TotalFlow", TW_MAKE_NUMBER(rand() / (RAND_MAX / 10.0))); TW_SET_PROPERTY(thingName, "Pressure", TW_MAKE_NUMBER(18 + rand() / (RAND_MAX / 5.0))); TW_SET_PROPERTY(thingName, "Location", TW_MAKE_LOC(gpsroute[location_step].latitude,gpsroute[location_step].longitude,gpsroute[location_step].elevation));   This macro utilizes the twApi_PushSubscribedProperties function call to push all property updates to the server. This can be seen in the updateTruckThing function in deliveryTruck.c.   Property Change Listeners   Using the Observer pattern, you can take advantage of the Property change listener functionality. With this pattern, you create functions that will be notified when a value of a Property has been changed (whether on the server or locally by your program when the TW_SET_PROPERTY macro is called).   Add a Property Change Listener   In order to add a Property change listener, call the twExt_AddPropertyChangeListener function using the:   Name of the Thing (entityName) Property this listener should watch Function that will be called when the property has changed   void simplePropertyObserver(const char * entityName, const char * thingName,twPrimitive* newValue){ printf("My Value has changed\n"); } void test_simplePropertyChangeListener() { { TW_MAKE_THING("observedThing",TW_THING_TEMPLATE_GENERIC); TW_PROPERTY("TotalFlow", TW_NO_DESCRIPTION, TW_NUMBER); } twExt_AddPropertyChangeListener("observedThing",TW_OBSERVE_ALL_PROPERTIES,simplePropertyObserver); TW_SET_PROPERTY("observedThing","TotalFlow",TW_MAKE_NUMBER(50)); } NOTE: Setting the propertyName parameter to NULL or TW_OBSERVE_ALL_PROPERTIES, the function specified by the propertyChangeListenerFunction parameter will be used for ALL properties.   Remove a Property Change Listener   In order to release the memory for your application when done with utilizing listeners for the Property, call the twExt_RemovePropertyChangeListener function.   void simplePropertyObserver(const char * entityName, const char * thingName,twPrimitive* newValue){ printf("My Value has changed\n"); } twExt_RemovePropertyChangeListener(simplePropertyObserver);       Step 6: Data Shapes   Data Shapes are an important part of creating/firing Events and also invoking Services.   Define With Macros   In order to define a Data Shape using a macro, use TW_MAKE_DATASHAPE.   NOTE: The macros are all defined in the twMacros.h header file.   TW_MAKE_DATASHAPE("SteamSensorReadingShape", TW_DS_ENTRY("ActivationTime", TW_NO_DESCRIPTION ,TW_DATETIME), TW_DS_ENTRY("SensorName", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("Temperature", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("Pressure", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("FaultStatus", TW_NO_DESCRIPTION ,TW_BOOLEAN), TW_DS_ENTRY("InletValve", TW_NO_DESCRIPTION ,TW_BOOLEAN), TW_DS_ENTRY("TemperatureLimit", TW_NO_DESCRIPTION ,TW_NUMBER), TW_DS_ENTRY("TotalFlow", TW_NO_DESCRIPTION ,TW_INTEGER) );   Define Without Macros   In order to define a Data Shape without using a macro, use the twDataShape_CreateFromEntries function. In the example below, we are creating a Data Shape called SteamSensorReadings that has two numbers as Field Definitions.   twDataShape * ds = twDataShape_Create(twDataShapeEntry_Create("a",NULL,TW_NUMBER)); twDataShape_AddEntry(ds, twDataShapeEntry_Create("b",NULL,TW_NUMBER)); /* Name the DataShape for the SteamSensorReadings service output */ twDataShape_SetName(ds, "SteamSensorReadings");     Step 7: Events and Services   Events and Services provide useful functionality. Events are a good way to make a Service be asynchronous. You can call a Service, let it return, then your Entity can subscribe to your Event and not keep the original Service function waiting. Events are also a good way to allow the platform to respond to data when it arrives on the edge device without it having to poll the edge device for updates.   Fire Events   To fire an Event you first need to register the Event and load it with the necessary fields for the Data Shape of that Event using the twApi_RegisterEvent function. Afterwards, you would send a request to the ThingWorx server with the collected values using the twApi_FireEvent function. An example is as follows:   twDataShape * ds = twDataShape_Create(twDataShapeEntry_Create("message", NULL,TW_STRING)); /* Event datashapes require a name */ twDataShape_SetName(ds, "SteamSensorFault"); /* Register the service */ twApi_RegisterEvent(TW_THING, thingName, "SteamSensorFault", "Steam sensor event", ds); …. struct { char FaultStatus; double Temperature; double TemperatureLimit; } properties; …. properties. TemperatureLimit = rand() + RAND_MAX/5.0; properties.Temperature = rand() + RAND_MAX/5.0; properties.FaultStatus = FALSE; if (properties.Temperature > properties.TemperatureLimit && properties.FaultStatus == FALSE) { twInfoTable * faultData = 0; char msg[140]; properties.FaultStatus = TRUE; sprintf(msg,"%s Temperature %2f exceeds threshold of %2f", thingName, properties.Temperature, properties.TemperatureLimit); faultData = twInfoTable_CreateFromString("message", msg, TRUE); twApi_FireEvent(TW_THING, thingName, "SteamSensorFault", faultData, -1, TRUE); twInfoTable_Delete(faultData); }   Invoke Services   In order to invoke a Service, you will use the twApi_InvokeService function. The full documentation for this function can be found in [C SDK HOME DIR]/src/api/twApi.h. Refer to the table below for additional information.    Parameter         Type                  Description entityType Input The type of Entity that the service belongs to. Enumeration values can be found in twDefinitions.h. entityName Input The name of the Entity that the service belongs to. serviceName Input The name of the Service to execute. params Input A pointer to an Info Table containing the parameters to be passed into the Service. The calling function will retain ownership of this pointer and is responsible for cleaning up the memory after the call is complete. result Input/Output A pointer to a twInfoTable pointer. In a successful request, this parameter will end up with a valid pointer to a twInfoTable that is the result of the Service invocation. The caller is responsible for deleting the returned primitive using twInfoTable_Delete. It is possible for the returned pointer to be NULL if an error occurred or no data is returned. timeout Input The time (in milliseconds) to wait for a response from the server. A value of -1 uses the DEFAULT_MESSAGE_TIMEOUT as defined in twDefaultSettings.h. forceConnect Input A Boolean value. If TRUE and the API is in the disconnected state of the duty cycle, the API will force a reconnect to send the request.   See below for an example in which the Copy service from the FileTransferSubsystem is called:   twDataShape * ds = NULL; twInfoTable * it = NULL; twInfoTableRow * row = NULL; twInfoTable * transferInfo = NULL; int res = 0; const char * sourceRepo = "SimpleThing_1"; const char * sourcePath = "tw/hotfolder/"; const char * sourceFile = "source.txt"; const char * targetRepo = "SystemRepository"; const char * targetPath = "/"; const char * targetFile = "source.txt"; uint32_t timeout = 60; char asynch = TRUE; char * tid = 0; /* Create an infotable out of the parameters */ ds = twDataShape_Create(twDataShapeEntry_Create("sourceRepo", NULL, TW_STRING)); res = twDataShape_AddEntry(ds, twDataShapeEntry_Create("sourcePath", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("sourceFile", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("targetRepo", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("targetPath", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("targetFile", NULL, TW_STRING)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("async", NULL, TW_BOOLEAN)); res |= twDataShape_AddEntry(ds, twDataShapeEntry_Create("timeout", NULL, TW_INTEGER)); it = twInfoTable_Create(ds); row = twInfoTableRow_Create(twPrimitive_CreateFromString(sourceRepo, TRUE)); res = twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(sourcePath, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(sourceFile, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(targetRepo, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(targetPath, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromString(targetFile, TRUE)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromBoolean(asynch)); res |= twInfoTableRow_AddEntry(row, twPrimitive_CreateFromInteger(timeout)); twInfoTable_AddRow(it,row); /* Make the service call */ res = twApi_InvokeService(TW_SUBSYSTEM, "FileTransferSubsystem", "Copy", it, &transferInfo, timeout ? (timeout * 2): -1, FALSE); twInfoTable_Delete(it); /* Grab the tid */ res = twInfoTable_GetString(transferInfo,"transferId",0, &tid);   Bind Event Handling   You may want to track exactly when your edge Entities are successfully bound to or unbound from the server. The reason for this is that only bound items should be interacting with the ThingWorx Platform and the ThingWorx Platform will never send any requests targeted at an Entity that is not bound. A simple example that only logs the bound Thing can be seen below. After creating this function, it will need to be registered using the twApi_RegisterBindEventCallback function before the connection is made.   void BindEventHandler(char * entityName, char isBound, void * userdata) { if (isBound) TW_LOG(TW_FORCE,"BindEventHandler: Entity %s was Bound", entityName); else TW_LOG(TW_FORCE,"BindEventHandler: Entity %s was Unbound", entityName); } …. twApi_RegisterBindEventCallback(thingName, BindEventHandler, NULL);   OnAuthenticated Event Handling   You may also want to know exactly when your Edge device has successfully authenticated and made a connection to the ThingWorx platform. Like the bind Event handling, this function will need to be made and registered. To register this handler, use the twApi_RegisterOnAuthenticatedCallback function before the connection is made. This handler form can also be used to do a delay bind for all Things.   void AuthEventHandler(char * credType, char * credValue, void * userdata) { if (!credType || !credValue) return; TW_LOG(TW_FORCE,"AuthEventHandler: Authenticated using %s = %s. Userdata = 0x%x", credType, credValue, userdata); /* Could do a delayed bind here */ /* twApi_BindThing(thingName); */ } … twApi_RegisterOnAuthenticatedCallback(AuthEventHandler, NULL);     Click here to view Part 3 of this guide.
View full tip
  Use the statistical calculation Thing Shape to execute useful analysis services   GUIDE CONCEPT   This project will introduce the Statistical Monitoring Thing Shape.   This guide demonstrates using Descriptive Analytics from ThingWorx Predictive Analytics to perform common statistical monitoring analysis on time-series data. You will learn to use the Statistical Monitoring ThingShape's built-in services to return the number of values in a data set that are: above or below a threshold, inside or outside a defined range, or following a trend that is: increasing, decreasing, or alternating.       YOU'LL LEARN HOW TO   Create a Thing with the Statistical Monitoring Thing Shape Create a Property and Value Stream to record changes in Property values Use Services that perform Standard Analytical Monitoring   NOTE: The estimated time to complete this guide is 30 minutes.     Step 1: Introduction   Descriptive analytics lets you perform common statistical monitoring calculations on changes in a Property value over time.   Output from monitoring Services can be used in IoT applications built with ThingWorx to provide trend and numerical limits feedback.   This guide introduces the Statistical Monitoring Thing Shape which adds Services to Things and Thing Templates for reporting Property values that are: above or below a threshold, inside or outside a defined range, or following a trend that is: increasing, decreasing, or alternating.     These Services analyze time-series data which is stored in ThingWorx Foundation as changes to a Property value logged to a Value Stream.   To ensure optimum performance, both a time range and a maximum number of value changes must be specified.     Step 2: Create Prerequisites   Statistical monitoring Services operate on Property values that change over time. To create this time series data, Property value changes are logged in a Value Stream. In this step, you will create a Value Stream, then a Thing with a Property that logs changes to that Value Stream.   Create Value Stream   Follow the steps below to create a value stream which you will later tie to a Thing.       1. On the ThingWorx Composer Browse tab, click Data Storage > Value Streams, then click the +New button         2. Select ValueStream and click OK.         3. In the Name field, enter scts_valuestream.         4. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject.       5. At the top, click Save.   Create Thing   Now, you will create a Thing with a property and configure it to use the previously-created value stream. You will also apply the statistical monitoring Thing Shape to the Thing, which makes the built-in analytics services available.       1. On the ThingWorx Composer Browse tab, click MODELING > Things then click the + New button          2. In the Name field, enter scts_thing.       3. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject.       4. In the Base Thing Template field, search for and select GenericThing.       5. In the Implemented Shapes field, search for and select StatisticalMonitoringThingShape.       6. In the Value Stream field, search for and select scts_valuestream.         7. At the top, click Save.    Add Property   You will now add a property to scts_thing.       1. At the top, click Properties and Alerts         2. Click + Add.       3. In the right slide-out's Name field, enter numbers.       4. Change the Base Type to NUMBER.       5. Click Persistent.       6. Click Logged.         7. Click Advanced Settings to open the bottom panel, in the Data Change Type drop-down select Always.         8. At the top-right, click the "check" icon for DONE.         9. At the top, click Save.     Step 3: Enter Sample Data   In this step, you will enter sample data that will illustrate the available Services.   This dataset: 2, 3, 4, 3, 2, 2, 1, 2, 1, 1, 2, 3, 3, 4, 3, 2 is shown graphed.      Enter Data   Perform the steps below to enter the above values into the Numbers Property.       1. Under the Value column and on the Numbers property row, click the "pencil" icon for Set value of property.         2. In the right-side slide-out, enter 2.         3. At the top-right, click the "check" icon for Done.       4. At the top, click Save.       5. Repeat steps 1-4 above, but changing the value each time as per the table below:   Value Change Count Entered Value 2nd 3 3rd 4 4th 3 5th 2 6th 2 7th 1 8th 2 9th 1 10th 1 11th 2 12th 3 13th 3 14th 4 15th 3 16th 2     Step 4: Test Monitoring Services   Now that value changes to the numbers Property have been logged in a Value Stream, you can use the built-in Services of the Statistical Monitoring Thing Shape to return how many of values meet different monitoring criteria.   Trend Service   You will test the built-in GetNumberOfConsecutivePointsFollowingATrend Service. This Service will return how many of points in the largest group of values following one of the three trend types INCREASING, DECREASING, and ALTERNATING.       1. Click the Service tab in the scts_thing Thing.       2. Click the GetNumberOfConsecutivePointsFollowingATrend Service.         3. In the PropertyName field enter numbers.       4. In the NumberOfPoints field enter 16 to check all entered points.       5. In the Trend field enter INCREASING to find the largest number of points with an increasing trend.       6. Click the green Execute button and note the Result property in the Output panel has the value 6         7. Repeat the steps above changing the Trend to DECREASING and note the result is 5.     Range Service   We'll now test the built-in GetNumberOfPointsBasedOnARange Service. This Service will return the number of points INSIDE or OUTSIDE a range of values specified by a MIN and MAX value.       1. Click the Close button in the Services tab in the scts_thing Thing.       2. Click the GetNumberOfPointsBasedOnARange Service.         3. In the PropertyName field enter numbers.       4. In the NumberOfPoints field enter 16 to check all entered points.       5. In the Min field enter 1.5 to set the lower end of the range criteria.       6. In the Max field enter 2.5 to set the upper end of the range criteria.       7. In the RegionOfInterest field enter INSIDE to find the largest number of points with an increasing trend.       8. Keep the default IncludeMin and IncludeMax set to True.       9. Click the green Execute button and note the Result property in the Output panel has the value 6.         10. Repeat the steps above changing the RegionOfInterest to OUTSIDEand note the result is 10.     Threshold Service   You will now test the built-in GetNumberOfPointsBeyondAThreshold Service. This Service will return the number of points ABOVE or BELOW a specified value.       1. Click the Services tab in the scts_thing Thing.       2. Click the GetNumberOfPointsBeyondAThreshold Service.         3. In the PropertyName field enter numbers.       4. In the NumberOfPoints field enter 16 to check all entered points.       5. In the Threshold field enter 3 to set the threshold criteria.       6. In the Direction field enter ABOVE to find the number of points above the threshold value.       7. Keep the default IncludeThreshold set to True.       8. Click the green Execute button and note the Result property in the Output panel has the value 7.       9. Repeat the steps above changing the Direction to BELOWand note the result is 14.       Click here to view Part 2 of this guide.
View full tip
    Keys to utilizing the C and Java SDK for ThingWorx application development   GUIDE CONCEPT   This project will introduce to coding examples utilized for SDKs to be used with Java and C. You can also use the Java SDK for Android development.   Following the steps in this guide, you will be better prepared to creating your own application using one of our SDKs.   We will teach you how to handle Properties, Entities, data, make Service calls and creating Remote Services.     YOU'LL LEARN HOW TO   How to create, update, and retrieve Property values Utilize Data Shapes for handling data and triggering Events Construct Info Tables for Services and retrieving data after Service calls Add key features of an edge/remote application   NOTE: The estimated time to complete this guide is 30 minutes.     Step 1: Connection Process   he ThingWorx SDKs follows a three-step process when connecting to the ThingWorx Platform.   NOTE: In this context, Client refers to the application and the SDK running on the device and Server refers to the ThingWorx Platform.   Websocket   The client opens a Websocket to the server using the host and port. With the ThingWorx platform you can connect via HTTP and HTTPS with access to Services, Properties, Events, Entities, and Resources.   Authentication   In order to connect and access information from the server, you must utilize an authorization method. Application Keys provide a secure method for the SDK to log into the platform and perform transactions. The client sends an authentication message to the server containing an Application Key.   Binding   Binding is an optional step in the client connection process. The SDK client allows one or more VirtualThings to be associated with a Websocket connection, using their names or identifiers. Binding a property in your ThingWorx application to that of your source code provides several benefits, including being able to update properties while offline.     Click here to view Part 2 of this guide.
View full tip
  Learn how to create systems to handle logistics and production distribution   GUIDE CONCEPT   This project will introduce complex aspects of the ThingWorx Composer 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 logistical 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   This guide builds on the knowledge gained in Factory Line Automation.   Download FoodIndustry.zip attached to this guide and extract/import the contents.   For the completed example, download the automated_food_industry.zip, also attached here. This download provides three Users and a Security Group. Please watch your count for Users or the import could fail.   In this tutorial we continue with our real-world scenario for the Fizos food company. We already have our factory data, and automated cooking processed for our sausage product lines. Now, let's see how we can use the data model we built before into making a smarter system of deliveries. We will take into consideration the locations of our factories, the vehicles we have available, our customers (stores and individuals), and see how much we can automate.   Setting Up Orders   One important part of being in business is having a product that people or companies want to buy. You'll need a way to track these sales and we're going to start with doing just that. Let's create our order shapes and tables.   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.Orders.DataShape and select a Project (ie, PTCDefaultProject). All of our orders will be based off this Data Shape.     Click Save then Edit to store all changes now. Add the list of properties below: Name Base Type Aspects Description ID Integer 0 minimum, primary key, default 0 Row identifier CustomerId Integer N/A String used as unique identifer across multiple platforms Type String N/A Type of customer (individual or another company) Factors Tag Data Tag This will hold the different type of data points or tags that will help to analyze a customer's order Products Infotable Data Shape: Fizos.DataShapes.Products List of orders TotalPrice Number Minimum 0 Price of the order Status String N/A The current order status (ie, processed, shipped, completed, etc) Completed Boolean N/A Whether the order has been completed   The Properties for the Fizos.Orders.DataShape Data Shape are as follows:   6. In the ThingWorx Composer, click the + New in the top left of the screen.   7. Select Data Table in the dropdown and select Data Table in the prompt.   8. In the name field, enter Fizos.Orders.DataTable. Our differing types of customers will fall under this template. 9. For the Data Shape field, select Fizos.Orders.DataShape and select a Project (ie, PTCDefaultProject).     10. Click Save then Edit to store all changes now. 11. This Entity will be used to house our data and provide assistance with our analytics.   We now have our model of orders ready to be stored. Of course, our orders are simplified. We can add much more to get them rolling, but the most important aspect right now is our Factors field. While we know a ton of information about customers, we can also analyze what kind of products they're buying and their ordering habits.     Step 2: Expanding Customer Models    Let's start with our customers. We created the data shape for customers before when we decided to put them in data tables. This time, we'll add some customers, but also expand on our modeling of what a customer entails. In this step, as with all the steps in this learning path, you can go as granular as you like. If you'd like to make 100 data tags, then it helps with understanding your customer, but it might be too much based on your goals. Remember, more data means more processing of that data.   Creating Customer Data Tags   These data tags will help us decide priority, relationships, and much more.   In the ThingWorx Composer, click the + New in the top left of the screen.     Select Data Tag in the dropdown.     In the name field, enter Fizos.CustomerTags and select a Project (ie, PTCDefaultProject). Check the Dynamic checkbox. This allows for new vocabulary terms to be created during runtime.   Click on the Vocabulary Terms tab, and add the following terms and then add as many more as you see fit: Name  Store  Individual  Office  Company  FirstTime  Repeat  Partner  LongTerm  ShortTerm  Old  MiddleAged  Young  Loyal We just added a number of data tags based on customer type, age, times the customer has bought from us, etc. This will help us with characterizing and modeling our customers. We'll also cheat a bit and use these data tags to help with deliveries. If you're a partment brand, we might work faster to send goods. For example, the code below returns the list of orders that were made by partners. We can add this as a service to our Fizos.Logistics template.   var index; var customerId; var partnerObj = {}; var query = { "filters": { "type": "EQ", "fieldName": "Completed", "value": false } }; var orders = Things["Fizos.Orders.DataTable"].QueryDataTableEntries({ query: query }); var customers = Things["Fizos.Customers.DataTable"].GetDataTableEntries(); var result = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape({ infoTableName : "InfoTable", dataShapeName : "Fizos.Orders.DataShape" }); var partners = Resources["InfoTableFunctions"].TagFilter({ inclusive: true, fieldName: "Factors", t: customers, tags: "Fizos.CustomerTags:Partner" }); for(index = 0; index < partners.rows.length; index++) { customerId = partners.rows[index].ID; partnerObj[customerId] = true; } for(index = 0; index < orders.rows.length; index++) { customerId = orders.rows[index].CustomerId; if(partnerObj[customerId] === true) { var newEntry = new Object(); newEntry.ID = orders.rows[index].ID; newEntry.CustomerId = orders.rows[index].CustomerId; newEntry.Type = orders.rows[index].Type; newEntry.Products = orders.rows[index].Products; newEntry.Factors = orders.rows[index].Factors; newEntry.TotalPrice = orders.rows[index].TotalPrice; result.AddRow(newEntry); } } This code will retrieve all orders that are not in a completed state. It will then figure out which orders are for partners and return those orders. You can see in this simple example how Data Tags can be used.     Click here to view Part 2 of this guide.
View full tip
  Step 6: Create Event Router   What do you do when a user can perform multiple events in which data is generated, and want those outputs to go through the same exact process? An Events Router Function is your solution. The Events Router Function allows for multiple data sources to be funneled to one location. Let's create a simple example in our MyFunctionsMashup Mashup. In this Mashup, we'll add two Text Field Widgets and a Label Widget. The two Text Field Widgets will take user input and then an Events Router will send the output to the Label. Let's start!   Open the MyFunctionsMashup Mashup to the Design tab. Click on the Widgets tab. Type in the Filter text box for Text Field.   Drag and drop TWO (2) Text Field Widgets to the Mashup Canvas. Type in the Filter text box for Label.   Drag and drop ONE (1) Label Widget to the Mashup Canvas. We now have all the Widgets we need for this example. Let's get started on the Events Router Function. Click the + button in the Functions panel. Select Events Router in the dropdown.   Set the Name to routeUserInput.   Click Next. Set the Inputs field to 2.   Click Done. We have our Events Router setup. Now, we'll bind our new items together. Click the Bind (arrows) button on the routeUserInput Events Router.   Click the down arrow next to Input1. Select Add Source.   In the Widgets tab, scroll to the bottom and select Text Property of the first of the two recent Text Fields we created (it should be third to last).   Click Next. Click the down arrow next to Input2. Select Add Source.   In the Widgets tab, scroll to the bottom and select Text Property of the second of the two recent Text Fields we created (it should be second to last).   Click Next. Click the down arrow next to Output. Select Add Target.   In the Widgets tab, scroll to the bottom and select LabelText Property of the recent Label we created (it should be last).   Click Next. Click Done. Click Save for the Mashup. You have just created an Events Router that will update a Label based on the typed input from two Text Fields. View your Mashup and play around with the bottom two text boxes. For a completed example, download and unzip, then import the attached FunctionsGuide_Entities.zip.     Step 7: Next Steps   Congratulations! You've successfully completed the Explore UI Functions guide, and learned best practices for building a complex Mashup that navigations, multiple data inputs, confirmations, and all working together effectively for an enhanced user experience.   Learn More   We recommend the following resources to continue your learning experience:    Capability    Guide Experience Object-Oriented UI Design Tips   Additional Resources   If you have questions, issues, or need additional information, refer to:    Resource       Link Community Developer Community Forum Support Mashup Builder Support Help Center
View full tip
Announcements