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 OPC UA Tag in ThingWorx   We will now create a Device in Kepware with a Tag whose value will be shown in ThingWorx.   Right-click on Channel1 that was just created, then click Next to accept the default name Device1       Click Next six times to accept the default settings, Then click the Select import items button.     Expand the remote OPC UA server URL, then expand OpcPlc and Telemetry.     Click SlowUint1 to select it, then click Add items >>. Click OK, Next, Finish. Return to ThingWorx Composer. Under Browse > Modeling > Industrial Connections, open IndConn_Server. Expand Channel1 > Device1 > OpcPlc, then click Telemetry.     Click the check-box next to SlowUint1. Click Bind to New Entity.     Select RemoteThing, then click OK. Enter azure-opcua-plc in the Name field, then click Save.     Click Properties and Alerts, then Click Refresh to see the property value changing every 10 seconds.     Step 7: Next Steps   Congratulations! You've successfully completed the Connect to an Azure OPC UA Server guide, and learned how to:   Create an OPC UA Server in Azure Configure Kepware as on OPC UA Client Connect Kepware to ThingWorx Foundation Monitor OPC UA data in ThingWorx Composer   Learn More   We recommend the following resources to continue your learning experience: Capability Guide Experience Create Your Application UI   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Getting Started with ThingWorx Documentation Kepware documentation Support Kepware Support site
View full tip
  Create users, security groups, and provide a method to authenticate with LDAP.   Guide Concept   LDAP allows for a layer of security within your company or organization to be utilized for authentication or user management.   These concepts and steps will allow you to focus on development of your application while still allowing the ability to utilize the power of ThingWorx!   We will teach you how to enable LDAP authentication in ThingWorx and configuring ThingWorx to connect to a LDAP server.   You'll learn how to   How to enable LDAP Authentication on ThingWorx Configuring ThingWorx to connect to an LDAP server Importing users from LDAP   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 60 minutes     Step 1: Completed Example   Download the completed files for this tutorial: ApacheDSExample.xml. This guide will cover authentication with an ApacheDS LDAP server.   In this tutorial, we walk through security concepts within ThingWorx. Utilize this file to see a finished example and return to it as a reference if you become stuck creating your own fully flushed out application.   Keep in mind, this download uses the exact names for entities used in this tutorial. If you would like to import this example and also create entities on your own, change the names of the entities you create.       Step 2: Understanding Directory Services   ThingWorx provides built-in LDAP Directory Support for clear-text connections (port 389). In order to enable LDAP Authentication, a Directory Service Entity must be imported and configured. The sample download provided is setup for Apache DS. An Active Directory example and a OpenLDAP example are attached, but will not be covered here. Other LDAP providers will need a similar file.   Users can exist in any Directory Services location as all Directory Services will be tried in order of priority when a user logs in. For the default setting, LDAP Directory Service will have priority over the ThingWorx one once enabled. To modify this configuration on the provided example, follow the below steps (if you have not done so already, import the XML file that was provided into The ThingWorx Composer):   From the ThingWorx Composer, go to the SECURITY section and click Directory Service. Open the Directory Service Entity you imported, ApacheDS. Enable LDAP in the General Properties section by checkicking the Enabled checkbox.   4. (Optional) Set the priority for the authentication if you have multiple Directory Service entities configured: Use the Priority property to assign an order of authentication to log in. The lower the number the higher the priority (1 is the highest priority). 5. Click Save to save ApacheDS and enable LDAP authentication. ThingWorx will contact the LDAP server to check for the given username when a user then tries to authenticate. If the user is not found or if the authentication on the LDAP server fails then the ThingWorx Directory Service will be tried.     Step 3: Configure ThingWorx and ApacheDS   This section will create an LDAP server, create the connection, and configure LDAP utilizing ApacheDS and Apache Directory Studio. In order to fully run this example, you will need to initially create this server OR deploy this server to a ThingWorx accessible location.   If you do not have an LDAP server already setup, utilize the below instructions to get started. If you already have a LDAP server setup, skip to the Configure ThingWorx For LDAP Connection section to configure the connection in ThingWorx.   Create New LDAP Server and Connection:   Open Apache Directory Studio. Right-click in the LDAP Servers section and select New -> New Server.   Select your version of ApacheDS in the menu and click Finish.   Right-click the newly created LDAP server and select Open Configuration.   Update the Port for the LDAP server to 389 and uncheck the LDAPS server.   Click Partitions at the bottom of the configuration and click Add.   Set the new Partition ID to ThingWorx. Set the Suffix value of the Partition to ou=people, dc=thingworx.   Save and close the configurations. Right-click the LDAP server and select Run. Once the State of the LDAP server has changed to Started, right-click the LDAP server and select Create Connection.   Utilize the ApacheDS adding entries guide to create users for your new LDAP server then follow the below instruction to create the ThingWorx connection. Configure ThingWorx For LDAP Connection: The sample XML files provided are configured with the most common attribute for the platform. From the ThingWorx Composer, go to the SECURITY section and click Directory Service. Open the Directory Service Entity you imported, ApacheDS. Generally, only one Entity listed unless multiple authentication realms have been configured. Click Congifurations to bring up Directory Service configuration details. Update the configuration parameters for the LDAP server: server: The hostname of the LDAP server userIdAttribute: LDAP attribute that is used to uniquely identify the user logging in. This property should be set to the name of the attribute containing the user's username. port: Connection port for the LDAP server. LDAP standard port is 389. If the LDAP server's connection port is 636, it is very likely that the server is expecting LDAPS, which ThingWorx does not currently support. adminBindDN: The full distinguished name for the user that the ThingWorx server will use for browsing the LDAP directory tree. The user that is defined here must have Read permissions on the directory tree. Generic Format: uid=admin, ou=Users, dc=company, dc=com userBaseDN: Distinguished name for the parent organizational unit (OU) containing any user that will need to log in. *Generic Format*: ou=ThingWorxUsers, ou=Users, dc=company, dc=com adminPassword: The password for the user configured in adminBindDN above   Click Save to update the ApacheDS Directory Service.       Step 4: Import Users Into ThingWorx   Handling Password Configurations: User must have a corresponding ThingWorx user created on the server before a user can log into ThingWorx via LDAP. These users must be created manually before they can log into the ThingWorx server All User entities created on ThingWorx matching LDAP users must have a password set, otherwise LDAP will not be able to log in. This password should NOT be the user's LDAP password The password used within ThingWorx should be secure/randomly generated. If LDAP authentication fails, ThingWorx will fall back on the password set for this user. The code provided below generates a random password for the users it creates Custom Service for User and Password Generation: A custom service can be created on a Service-Providing Thing instance that creates a specific user and assign it a home mashup: A Service-Providing Thing is an entity that uses the *GenericThing** ThingTemplate. It does not store properties. Instead, it provides useful Services that retrieve and compile data from many Thing instances for use in Mashups and/or other services. To create a Service-Providing Thing: Create a new Thing, and name it LDAPServiceHelper. Set the Thing Template to GenericThing. Click Services and create a new Service called CreateLDAPUser. Set the Inputs to be the following: Username (STRING, required) HomeMashup (MASHUPNAME, optional) Use the following for the source code: // ThingWorx will fall back on ThingWorx Directory Service (Local authentication) // if LDAP authentication fails, which means the password that we have to set for // the new user could also be used to log the user in. // Using a random string will make it highly unlikely that a user / attacker can // use the ThingWorx password to log in. var randompass = Math.random().toString(36).slice(-10); var params1 = { name: Username, password: randompass, description: "Generated LDAP User" }; Resources["EntityServices"].CreateUser(params1); // By default non-admin users will be directed to SQUEAL. // If there is a specific mashup that the user should see instead, // the following code will configure it based on the HomeMashup optional parameter. // The mashup passed to this service must exist. if (HomeMashup !== null) { var params2 = { name: HomeMashup }; Users[Username].SetHomeMashup(params2); } 6. Click Done. 7. Click Save.   Execute the newly created Service for each user in the LDAP system. Once all users have been imported (or at least the ones who need immediate access) the Directory Service must be enabled for ThingWorx to begin authenticating users via LDAP.       Step 5: Next Steps   Congratulations! You've successfully completed the Enabling LDAP Authentication in ThingWorx tutorial, and learned how to:   How to enable LDAP Authentication on ThingWorx Configuring ThingWorx to connect to an LDAP server Importing users from LDAP Auto assigning to user groups based on LDAP membership Learn More We recommend the following resources to continue your learning experience:    Capability   Guide Secure Create An Authentication Extension Secure Configure Permissions   Additional Resources If you have questions, issues, or need additional information, refer to:    Resource         Link Community Developer Community Forum Support Extension Development Guide  
View full tip
    Step 10: Building and Importing   After you’ve completed your code updates, it’s time to build and import! Below are instructions for building with the framework you have set for the project.   Build Extension with Ant   Go to the Package explorer view. Right click on build-extension.xml. Hover over Run As and select Ant Build.   Your console output will indicate BUILD SUCCESSFUL. This will build your project and create the extension zip in the your_project->build->distributions folder of your project.   Build Extension with Gradle   Right click on your project ->Gradle (STS)->Tasks Quick Launcher.   Set Project from the drop-down menu to your project name and type Tasks as build. Press Enter.   Your console window will display BUILD SUCCESSFUL. Your extension has been created and stored as a zip file in your_project->build->distributions folder.     Import Extension   Go to ThingWorx Composer. In the lower left, click Import/Export, then select Import under.   Select Extension for the type of import.   Choose the zip file in the distributions folder under the build directory. Click Import. Click Close on the prompt to refresh your Composer instance.   After you have imported your new widget and refreshed Composer, you will see your new widget as an option on the Mashup Design tab.     Step 11: Tips   When a new version of an extension contains model changes for one or more of its entities, the previous version of the extension and any entities created from that extension must be deleted before installing the new version of the extension. To avoid having to recreate the entities after the new extension is installed, you can include an extension migrator with the extension that imports the entities created with the previous version.   Adding an Extension Migrator   To create a migrator class for your extensions, follow these steps: Choose the ThingWorx menu and select New Extension Migrator. Select or enter your source folder and package. Enter a name, such as CustomMigrator. Click Finish. The Java source file is created and the configfiles/metadata.xml file is updated automatically.   NOTE: If a migrator has already been created, the previous migrator class name will be replaced in the metadata.xml file with the new migrator class name. The previous migrator Java file will not be changed.   Element Selection   Use this.jqElement to limit your element selections. This will reduce the chance of introducing unwanted behaviors in the application when there might be duplicate IDs and/or classes in the DOM.   ///Don’t do the following: $('.add- btn').click(function(e){...do something...}); ///Do this: this.jqElement.find('.add-btn').click(function(e){ ...do something...});   Logging   We recommend that you use the following methods to log in the Mashup Builder and runtime environment: TW.log.trace(message[,message2,...][,exception]) TW.log.debug(message[,message2,...][,exception]) TW.log.info(message[,message2,...][,exception]) TW.log.warn(message[,message2,...][,exception]) TW.log.error(message[,message2,...][,exception]) TW.log.fatal(message[,message2,...][,exception])   You can view the log messages in the Mashup Builder by opening the log window via the Help->Log menu item; in the Mashup runtime, you can now click on the Show Log button on the top left corner of the page to show log window. If the browser you use supports console.log(), then the messages will also appear in the debugger console.   Formatting   If you have a property with baseType of STYLEDEFINITION, you can get the style information by calling: var formatResult = TW.getStyleFromStyleDefinition( widgetProperties['PropertyName']);   If you have a property of baseType of STATEFORMATTING: var formatResult = TW.getStyleFromStateFormatting({ DataRow: row, StateFormatting: thisWidget.properties['PropertyName'] });   In both cases formatResult is an object with the following defaults: { image: '', backgroundColor: '', foregroundColor: '', fontEmphasisBold: false, fontEmphasisItalic: false, fontEmphasisUnderline: false, displayString: '', lineThickness: 1, lineStyle: 'solid', lineColor: '', secondaryBackgroundColor: '', textSize: 'normal' };     Step 12: Next Steps   Congratulations! You've successfully completed the Create A Mashup Widget Extension tutorial.   You've learned how to:   Utilize the Eclipse Plugin and Extension SDK Create and configure an Extension project Create a mashup widget Extension Build and import an Extension   Learn More   We recommend the following resources to continue your learning experience:    Capability    Guide Build Application Development Tips & Tricks   Additional Resources   If you have questions, issues, or need additional information, refer to:    Resource         Link Community Developer Community Forum Help Center  Custom Widget Tips and Example    
View full tip
  A series of training videos for ThingWorx Analytics   Guide Concept   This guide provides a series of training videos covering ThingWorx Analytics Server and Platform Analytics.   It is recommended that they be viewed in order.    Additionally, a downloadable .zip with additional training materials is provided.     You'll learn how to   Use ThingWorx Analytics Understand the Analytics Thought Process Basic Analytics concepts (data types, variables, modeling) Descriptive Analytics Predictive Analytics modeling techniques Familiarity with other topics: Prescriptive Analytics, Clustering, Time Series, Anomaly Detection Acquire basic knowledge of how to create an end-to-end Smart Application Deepen your Foundation and Analytics understanding NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete all parts of this guide is 12 hours       ThingWorx Analytics Overview   This guide will present a series of training videos for ThingWorx Analytics.It is recommended that you view each guide in-order, as future videos may build on the concepts learned in earlier ones.    Download CourseFiles.zip included in this guide, as it contains important materials for particular videos.   In this course, you will learn the basics of the ThingWorx Analytics Machine Learning process. You will understand how to perform Descriptive Analytics such as identifying Signals, Profiles, or building Clusters.   You will also understand how to train a Model and use Predictive and Prescriptive Scoring. Additional topics include Time Series, Anomaly Detection, and near-real-time Scoring. You will also learn about how to create a simple smart application using Analytics together with other pieces of the overall ThingWorx platform.     ThingWorx Analytics Video Guide   Module 1: ThingWorx Analytics Overview Module 2: Use Case Discussion Module 3: Data Profiling Module 4: Data Transformation and Feature Engineering Module 5: Descriptive Analytics Module 6: Predictive Models and Model Validation Module 7: Scoring Predictive Realtime Prescriptive Module 8: Time Series Modeling Module 9: Anomaly Detection Module 10: ThingWorx Foundation and Analytics Integration Module 11: Mini Project     Next Steps   Congratulations! You've successfully completed the Analytics Training Videos guide, and learned how to:   Use ThingWorx Analytics Understand the Analytics Thought Process Basic Analytics concepts (data types, variables, modeling) Descriptive Analytics Predictive Analytics modeling techniques Familiarity with other topics: Prescriptive Analytics, Clustering, Time Series, Anomaly Detection Acquire basic knowledge of how to create an end-to-end Smart Application Deepen your Foundation and Analytics understanding   Additional Resources If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Analytics Support Help Center          
View full tip
    Step 5: Log to Value Stream   Now that you have explored the Properties of IndConn_Tag1, you’ve seen how ThingWorx Kepware Server feeds information to ThingWorx Foundation. To get an even better indication of changes and confirm continued connectivity, we will log the changes to a Value Stream in order to record the values with a TimeStamp.   Create Value Stream   Return to the ThingWorx Foundation New Composer browser. Click Browse. Click Data Storage -> Value Streams. Click + New. In the Choose Template pop-up, select ValueStream. Click OK. Type IndConn_ValueStream in the Name field. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. In the Description field, enter an appropriate description, such as Value Stream to record changes from ThingWorx Kepware Server. Click Save.   Bind Value Stream   Open the IndConn_Tag1 either by clicking on the tab at the top, or by clicking on PTCDefaultProject on the left At the top, select General Information. In the Value Stream field, enter indconn. Select IndConn_ValueStream from the sorted list. At the top, select Properties and Alerts. Click Simulation_Examples_Functions_Random3. A new set of options will expand from the right. Check the box for Persistent. Check the box for Logged. Click the Check button to close the expanded options. Click Save. All changes to the Random3 Tag, fed from ThingWorx Kepware Server, are now stored and TimeStamped in the Simulation_Examples_Functions_Random3 Property.   Step 6: Visualize the Data   We'll now create a Mashup to visualize the record of information from ThingWorx Kepware Server. In ThingWorx Foundation's Browse, click Visualization -> Mashups. Click +New. In the New Mashup pop-up, leave the default selections. Click OK. In the Name field, enter IndConn_Mashup. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. At the top, click Save. At the top, click Design. In the Filter Widgets field at the top-left, enter chart. Drag-and-drop a Line Chart onto the central canvas area. Add Data   On the right-side of the Mashup Builder, click the Data tab. Click the + button on the Data tab.        3. In the Add Data pop-up, enter indconn in the Entity field, overwriting Filter. 4. Select IndConn_Tag1 from the sorted list. 5. In the Filter field below Services, enter queryprop. 6. Click the right arrow button beside QueryPropertyHistory. The QueryPropertyHistory Service of the IndConn_Tag1 Thing will appear on the right in the Selected Services field. 7. Check the box under Execute on Load in the Selected Services field.' 8. Click Done. Note that the QueryPropertyHistory Service now appears on the right side Data tab. 9. Click the arrow to expand QueryPropertyHistory, then click to expand Returned Data. 10. Drag-and-drop All Data from the QueryPropertyHistory Service from the right onto the Time Series Chart in the center. 11. In the Select Binding Target pop-up, select Data.        Configure Chart Properties   In the bottom-left Properties of timeserieschart-1, enter xaxisfield in the Filter Properties field. Expand the drop-down for XAxisField. Select timestamp. Click Save. Click View Mashup. (You may have to enable pop-ups to view the mashup.) The IndConn_Mashup will show you the recorded history of property changes that came from ThingWorx Kepware Server. NOTE: If the Mashup visualization is blank, confirm your connection to IndConn. Return to the Test Connection section of the Bind Industrial Tag step.   Step 7: Next Steps   Congratulations! You've successfully completed the Connect Kepware Server to ThingWorx Foundation guide. You've learned how to: Connect ThingWorx Foundation to ThingWorx Kepware Server Map Tags to Properties     The next guide in the Connect and Monitor Industrial Plant Equipment learning path is Create Industrial Equipment Model. 
View full tip
Connect Kepware Server to ThingWorx Foundation Guide Part 1   Overview   This guide has step-by-step instructions for connecting ThingWorx Kepware Server to ThingWorx Foundation. This guide will demonstrate how easily industrial equipment can be connected to ThingWorx Foundation without installing any software on production equipment. NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL 2 parts of this guide is 30 minutes.    Step 1: Learning Path Overview     This guide explains the steps to connect ThingWorx Kepware Server with ThingWorx Foundation and is part of the Connect and Monitor Industrial Plant Equipment Learning Path. You can use this guide independently from the full Learning Path. If you want to learn to connect ThingWorx Kepware Server to ThingWorx Foundation, this guide will be useful to you. When used as part of the Industrial Plant Learning Path, you should have already installed ThingWorx Kepware Server and created an Application Key. In this guide, we will send information from ThingWorx Kepware Server into ThingWorx Foundation. Other guides in this learning path will use Foundation's Mashup Builder to construct a website dashboard that displays information and from ThingWorx Kepware Server. We hope you enjoy this Learning Path.   Step 2: Create Gateway   To make a connection between ThingWorx Kepware Server and Foundation Server, you must first create a Thing. WARNING: To avoid a timeout error, create a Thing in ThingWorx Foundation BEFORE attempting to make the connection in ThingWorx Kepware Server. In ThingWorx Foundation Composer, click Browse. On the left, click Modeling -> Things.   Click + NEW. In the Name field, enter IndConn_Server, including matching capitalization. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. In the Description field, enter an appropriate description, such as Industrial Gateway Thing to connect to ThingWorx Kepware Server.   In the Base Thing Template field, enter indus, then select the IndustrialGateway Thing template from the sorted list. Click Save.   Step 3: Connect to Foundation   Now that you’ve created an IndustrialGateway Thing and an Application Key, you can configure ThingWorx Kepware Server to connect to ThingWorx Foundation. Return to the ThingWorx Kepware Server Windows application. Right-click Project. Select Properties….       4. In the Property Editor pop-up, click ThingWorx.       5. In the Enable field, select Yes from the drop-down.       6. In the Host field, enter the URL or IP address of your ThingWorx Foundation server, Do not enter http://       7. Enter the Port number. If you are using the "hosted" Developer Portal trial, enter 443. 8. In the Application Key field, copy and paste the Application Key you just created. 9. In the Trust self-signed certificates field, select Yes from the drop-down. 10. In the Trust all certificates field, select Yes from the drop-down. 11. In the Disable encryption field, select No from the drop-down if you are using a secure port. Select Yes if you are using an http port. 12. Type IndConn_Server in the Thing name field, including matching capitalization. 13. If you are connecting with a remote instance of ThingWorx Foundation and you expect any breaks or latency in your connection, enable Store and Forward. 14. Click Apply in the pop-up. 15. Click Ok. In the ThingWorx Kepware Server Event window at the bottom, you should see a message indicating Connected to ThingWorx.   NOTE: If you do not see the "Connected" message, repeat the steps above, ensuring that all information is correct. In particular, check the Host, Port, and Thing name fields for errors.   Step 4: Bind Industrial Tag   Now that you've established a connection, you can use ThingWorx Foundation to inspect all available information on ThingWorx Kepware Server. ThingWorx Kepware Server includes some information by default to assist you with verifying a valid connection with ThingWorx Foundation. Create New Thing Return to ThingWorx Foundation. Click Browse. Click Modeling -> Industrial Connections.   Click IndConn_Server. At the top, click Discover.   The Discover option is exclusive to Things inheriting the IndustrialGateway Thing Template and displays information coming from ThingWorx Kepware Server. Expand Simulation Examples. Click Functions.   On the right, you’ll see several pre-defined Tags to assist with connectivity testing. Click the checkbox next to Random3. Click Bind to New Entity.   In the Choose Template pop-up, select RemoteThing and click OK.   Finalize New RemoteThing   You’ll now be in an interface to create a new Thing with a predefined Property based on ThingWorx Kepware Server Tag1. Type IndConn_Tag1 in the Name field. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. In the Description field, enter an appropriate description, such as Thing with a property fed from an Kepware Server Tag. The Base Thing Template has been automatically set to RemoteThing. The Implemented Shapes has been automatically set to IndustrialThingShape. 4. Click Save.   Test Connection   The IndConn_Tag1 Thing you created now has a Property with a value that will change with each update from ThingWorx Kepware Server. The Tag1 we utilized is a 'ramp' and therefore, the value will increase at regular intervals. At the top, click Properties and Alerts. Under Inherited Properties, you will see entries for both RemoteThing and IndustrialThingShape. The Property isConnected is checked, indicating a connection from Foundation to ThingWorx Kepware Server. The Property IndustrialThing has been automatically set to IndConn_Server. Notice the predefined Property named Simulation_Examples_Functions_Random3.   Click Refresh repeatedly. You’ll see the value increase with each Refresh. This represents data being simulated in ThingWorx Kepware Server. Click  here to view Part 2 of this guide.  
View full tip
  Step 7: Delivery Truck Model    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 DeliveryTruckThing class extends the VirtualThing class and based on the DeliveryTruck Entities in the Composer. After extending VirtualThing, there are a number of steps necessary to get going. For the DeliveryTruckThing and SimpleThing classes, there are a number of methods for creating Properties, Events, Services, and Data Shapes for ease of use.   The constructor for the DeliveryTruckThing takes in the name of the Thing, the description of the Thing, and the ConnectedThingClient instance used to make the connection. It then sends these values to the VirtualThing constructor as shown below.   public DeliveryTruckThing(String name, String description, ConnectedThingClient client) { super(name, description, client); ...   We use the initializeFromAnnotations method to initialize all of the annotations that we will create in this class. This is done as follows and a necessary call for VirtualThings in the constructor:   initializeFromAnnotations();   Create Properties   You can create Properties in two ways. Using annotations is the recommended method, but there are times in which programmatically creating Properties is the best option. For example, constructing dynamic features or allowing inline functionality would call for the coding style of Property creation. 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 a PropertyDefinition instance as shown in the SimpleThing.java property1 creation.   With Annotation @SuppressWarnings("serial") @ThingworxPropertyDefinitions(properties = { @ThingworxPropertyDefinition(name="Driver", description="The name of the driver", baseType="STRING", aspects={"isReadOnly:false"}), @ThingworxPropertyDefinition(name="DeliveriesLeft", description="The number of deliveries left", baseType="NUMBER", aspects={"isReadOnly:false"}), @ThingworxPropertyDefinition(name="Speed", description="The speed of the truck", baseType="NUMBER", aspects={"isReadOnly:false"}), @ThingworxPropertyDefinition(name="Location", description="The location of the truck", baseType="LOCATION", aspects={"isReadOnly:false"}), @ThingworxPropertyDefinition(name="TotalDeliveries", description="The number of deliveries", baseType="NUMBER", aspects={"isReadOnly:false"}), @ThingworxPropertyDefinition(name="DeliveriesMade", description="The number of deliveries made", baseType="NUMBER", aspects={"isReadOnly:false"}), })   Without Annotation //Create the property definition with name, description, and baseType PropertyDefinition property1 = new PropertyDefinition(property, "Description for Property1", BaseTypes.BOOLEAN); //Create an aspect collection to hold all of the different aspects AspectCollection aspects = new AspectCollection(); //Add the dataChangeType aspect aspects.put(Aspects.ASPECT_DATACHANGETYPE, new StringPrimitive(DataChangeType.NEVER.name())); //Add the dataChangeThreshold aspect aspects.put(Aspects.ASPECT_DATACHANGETHRESHOLD, new NumberPrimitive(0.0)); //Add the cacheTime aspect aspects.put(Aspects.ASPECT_CACHETIME, new IntegerPrimitive(0)); //Add the isPersistent aspect aspects.put(Aspects.ASPECT_ISPERSISTENT, new BooleanPrimitive(false)); //Add the isReadOnly aspect aspects.put(Aspects.ASPECT_ISREADONLY, new BooleanPrimitive(false)); //Add the pushType aspect aspects.put("pushType", new StringPrimitive(DataChangeType.NEVER.name())); //Add the defaultValue aspect aspects.put(Aspects.ASPECT_DEFAULTVALUE, new BooleanPrimitive(true)); //Set the aspects of the property definition property1.setAspects(aspects); //Add the property definition to the Virtual Thing this.defineProperty(property1);   Property values can either be set with defaults using the aspects setting. Nevertheless, setting a default value will affect the Property in the ThingWorx platform after binding. It will not set a local value in the client application. In this example, we make a request to the ThingWorx Composer for the current values of the delivery truck properties using our getter methods:   //Get the current values from the ThingWorx Composer deliveriesMade = getDeliveriesMade(); deliveriesLeft = getDeliveriesLeft(); totalDeliveries = getTotalDeliveries(); driver = getDriver(); speed = getSpeed(); location = getLocation();   Create Event Definitions   As with Properties, Events can be created using annotations or code as shown in SimpleThing.java. Here we create the DeliveryStop event that is in the DeliveryTruck instances.   With Annotation @ThingworxEventDefinitions(events = { @ThingworxEventDefinition(name="DeliveryStop", description="The event of a delivery truck stopping to deliver a package.", dataShape="DeliveryTruckShape", isInvocable=true, isPropertyEvent=false) })   Without Annotation //Create the event definition with name and description EventDefinition event1 = new EventDefinition(event, "Description for Event1"); //Set the event data shape event1.setDataShapeName("SimpleDataShape"); //Set remote access event1.setLocalOnly(false); //Add the event definition to the Virtual Thing this.defineEvent(event1);   Create Remote Services   With remote Services, the implementation is handled by the Java application and can be called either within the application or remotely, by the Composer while a connection is established. The GetTruckReadings Service, a dummy Service used as an example of how to create a remote Service, populates an Info Table and returns that Info Table for whoever would like to use it. You can see how it is possible to define remote Services that can later be bound to Things in the Composer. A Service is defined using @ThingworxServiceDefinition annotation and its result is defined using @ThingworxServiceResult. These annotations take various parameters among including:   Name Description baseType Aspects In the second line, you can see the name of the result being set by the CommonPropertyNames field to keep development consistent with creating Things in the Composer.   With Annotation @ThingworxServiceDefinition(name="GetTruckReadings", description="Get Truck Readings") @ThingworxServiceResult(name=CommonPropertyNames.PROP_RESULT, description="Result", baseType="INFOTABLE", aspects={"dataShape:DeliveryTruckShape"})   Without Annotation //Create the service definition with name and description ServiceDefinition service1 = new ServiceDefinition(service, "Description for Service1"); //Create the input parameter to string parameter 'name' FieldDefinitionCollection fields = new FieldDefinitionCollection(); fields.addFieldDefinition(new FieldDefinition("name", BaseTypes.STRING)); service1.setParameters(fields); //Set remote access service1.setLocalOnly(false); //Set return type service1.setResultType(new FieldDefinition(CommonPropertyNames.PROP_RESULT, BaseTypes.STRING)); //Add the service definition to the Virtual Thing this.defineService(service1); //Service1 Definition public String Service1(String name) throws Exception { String result = "Hello " + name; return result; }     Create Data Shapes   Data Shapes must be created using code as seen in DeliveryTruckThing.java as shown below:   // Data Shape definition that is used by the delivery stop event // The event only has one field, the message FieldDefinitionCollection fields = new FieldDefinitionCollection(); fields.addFieldDefinition(new FieldDefinition(ACTIV_TIME_FIELD, BaseTypes.DATETIME)); fields.addFieldDefinition(new FieldDefinition(DRIVER_NAME_FIELD, BaseTypes.STRING)); fields.addFieldDefinition(new FieldDefinition(TRUCK_NAME_FIELD, BaseTypes.BOOLEAN)); fields.addFieldDefinition(new FieldDefinition(TOTAL_DELIVERIES_FIELD, BaseTypes.NUMBER)); fields.addFieldDefinition(new FieldDefinition(REMAIN_DELIVERIES_FIELD, BaseTypes.NUMBER)); fields.addFieldDefinition(new FieldDefinition(LOCATION_FIELD, BaseTypes.LOCATION)); defineDataShapeDefinition("DeliveryTruckShape", fields);   NOTE: It is possible to create a Data Shape, and then use it in a Service definition within your code as StringIndex property, StringMap Data Shape, and StringMapService Service in SimpleThing.java.     Scan Cycles   To complete the implementation of the VirtualThing class, we recommend you provide an override and implementation to the processScanRequest method. This method provides a universal method for all VirtualThing implementations. This method could be used or a new method could be created for this purpose. The processScanRequest method in VirtualThing.java does not have an implementation of its own. An implementation from DeliveryTruckThing.java can be seen below:   // The processScanRequest is called by the DeliveryTruckClient every scan cycle @Override public void processScanRequest() throws Exception { // Execute the code for this simulation every scan this.scanDevice(); this.updateSubscribedProperties(1000); this.updateSubscribedEvents(1000); }   Bound Properties in Cycle   The scanDevice method in DeliveryTruckThing.java performs a number of tasks from retrieving property values to firing events. To retrieve a property using binding, a request is made to the client using the name of the property. A good programming practice is to handle how these properties are accessed and set. Note that the update method for properties and events must be used after queueing an event or setting a Property value. In the example below, getter and setter methods are used for added control. The getProperty() call is used on the VirtualThing:   public Double getSpeed() { return (Double) getProperty("Speed").getValue().getValue(); } public void setSpeed() throws Exception { setProperty("Speed", this.speed); } public Location getLocation() { return (Location) getProperty("Location").getValue().getValue(); } public void setLocation() throws Exception { setProperty("Location", this.location); }     Step 8: Services and Events   Events and Services can be very useful. Events are a good way to make a Service be asynchronous. You’re able to call a Service, let it return and 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. The DeliveryTruck Entities in the Composer contains a remote Event. You can find a remote Service within the SimpleThing_1 entity.   Fire Event To fire an Event, create a ValueCollection instance, and load it with the necessary fields for the Data Shape of that Event. Then, send the client the request to fire the Event with the collected values, the Event, and information to find the Entity the Event belongs to as shown below in DeliveryTruckThing.java:   // Set the event information of the defined data shape for a truck stop event ValueCollection payload = new ValueCollection(); // Set values to the fields payload.put(LOCATION_FIELD, new LocationPrimitive(location)); payload.put(REMAIN_DELIVERIES_FIELD, new NumberPrimitive(deliveriesLeft)); payload.put(ACTIV_TIME_FIELD, new DatetimePrimitive(DateTime.now())); payload.put(TOTAL_DELIVERIES_FIELD, new NumberPrimitive(totalDeliveries)); payload.put(DRIVER_NAME_FIELD, new StringPrimitive(driver)); payload.put(TRUCK_NAME_FIELD, new StringPrimitive(super.getBindingName())); // This will trigger the 'DeliveryStop' of a remote thing // on the platform. super.queueEvent("DeliveryStop", new DateTime(), payload);   Execute Service   To execute a Service, you must create a ValueCollection instance, and load it with the necessary parameters of the Service. The ValueCollection is created only when Services and Events are not defined by annotations. Afterwards, you would send the client the request to execute the Service with the parameter values, the Service name, the timeout setting in milliseconds for the Service to finish executing, and information to find the Entity the Service belongs to as shown below in SimpleThingClient.java:   public String callService(String name) throws Exception{ ValueCollection payload = new ValueCollection(); payload.put("name", new StringPrimitive("Timothy")); InfoTable table = handleServiceRequest(service, payload); return table.getFirstRow().getStringValue("name"); }   TIP: The code for creating the Service and Event should be in the constructor of the extended VirtualThing (or a method called from the constructor). Also, the Service code examples will work as long as the actual Service is defined. You can see from the examples that the annotation method is much cleaner.     Click here view Part 5 of this guide.
View full tip
    Step 6: Power Grid Example   In the Power Grid application, there are three Generator Things and three Consumers. Each Thing has a number of Properties based on its location, wattage, and its power lines provided with power. In this design, when a generator goes offline, comes back online, or one of the other power grid aspects are updated/created/deleted, the Property values are updated. The GeneratorThing class extends the VirtualThing class and based on the Generator entities in the Composer. After extending VirtualThing, there are a number of steps necessary to get going. For the GeneratorThing and SimpleThing classes, there are a number of methods for creating Properties, Events, Services, and Data Shapes for ease of use.   The constructor for the GeneratorThing takes in the type of electricity generator, name of the Thing, the description of the Thing, and the ConnectedThingClient instance used to make the connection. It then sends these values to the VirtualThing constructor as shown below. public GeneratorThing(String type, String name, String description, ConnectedThingClient client) { super(name, description, client); ...   We use the initializeFromAnnotations method to initialize all of the annotations that we will create in this class. This is done as follows and a necessary call for VirtualThings in the constructor:   initializeFromAnnotations();   Create Properties   You can create Properties in two ways. Using annotations is the recommended method, but there are times in which programmatically creating properties is the best option. For example, constructing dynamic features or allowing inline functionality would call for the coding style of Property creation. 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 a PropertyDefinition instance as shown in the SimpleThing.java property1 creation.   With Annotation @ThingworxPropertyDefinition(name="GeneratorType", description="Type of generator", baseType="STRING", aspects={"isReadOnly:false"}),@ThingworxPropertyDefinition(name="Wattage", description="Wattage produced", baseType="NUMBER", aspects={"isReadOnly:false"}),@ThingworxPropertyDefinition(name="Amps", description="Amps", baseType="NUMBER", aspects={"isReadOnly:false"}),@ThingworxPropertyDefinition(name="Voltage", description="Voltage", baseType="NUMBER", aspects={"isReadOnly:false"}),@ThingworxPropertyDefinition(name="UpTime", description="Number of minutes since the generator connected online", baseType="NUMBER", aspects={"isReadOnly:false"}),@ThingworxPropertyDefinition(name="Status", description="Status of the generator", baseType="NUMBER", aspects={"isReadOnly:false"}),@ThingworxPropertyDefinition(name="Location", description="Location of the generator", baseType="LOCATION", aspects={"isReadOnly:false"}),@ThingworxPropertyDefinition(name="LastSync", description="The last time we performed a sync", baseType="DATETIME", aspects={"isReadOnly:false"}),@ThingworxPropertyDefinition(name="ConnectedSince", description="Time where we last performed a successful connection", baseType="DATETIME", aspects={"isReadOnly:false"}),@ThingworxPropertyDefinition(name="TransmissionLines", description="An infotable of power lines", baseType="INFOTABLE", aspects={"isReadOnly:false"}) Without Annotation //Create the property definition with name, description, and baseType PropertyDefinition property1 = new PropertyDefinition(property, "Description for Property1", BaseTypes.BOOLEAN); //Create an aspect collection to hold all of the different aspects AspectCollection aspects = new AspectCollection(); //Add the dataChangeType aspect aspects.put(Aspects.ASPECT_DATACHANGETYPE, new StringPrimitive(DataChangeType.NEVER.name())); //Add the dataChangeThreshold aspect aspects.put(Aspects.ASPECT_DATACHANGETHRESHOLD, new NumberPrimitive(0.0)); //Add the cacheTime aspect aspects.put(Aspects.ASPECT_CACHETIME, new IntegerPrimitive(0)); //Add the isPersistent aspect aspects.put(Aspects.ASPECT_ISPERSISTENT, new BooleanPrimitive(false)); //Add the isReadOnly aspect aspects.put(Aspects.ASPECT_ISREADONLY, new BooleanPrimitive(false)); //Add the pushType aspect aspects.put("pushType", new StringPrimitive(DataChangeType.NEVER.name())); //Add the defaultValue aspect aspects.put(Aspects.ASPECT_DEFAULTVALUE, new BooleanPrimitive(true)); //Set the aspects of the property definition property1.setAspects(aspects); //Add the property definition to the Virtual Thing this.defineProperty(property1); Property values can either be set with defaults using the aspects setting. Nevertheless, setting a default value will affect the Property in the ThingWorx platform after binding. It will not set a local value in the client application. In this example, we make a request to the ThingWorx Composer for the current values of the generator properties using our getter methods: //Get the current values from the ThingWorx Composer wattage = getGeneratorWattage(); voltage = getGeneratorVoltage(); location = getLocation();   Create Event Definitions   As with Properties, Events can be created using annotations or code as shown in SimpleThing.java. Here we create the GeneratorOffline event that is in the Generator instances.   With Annotation   @ThingworxEventDefinitions(events = { @ThingworxEventDefinition(name="GeneratorOffline", description="The event of a generator going offline", dataShape="GeneratorShape", isInvocable=true, isPropertyEvent=false) })   Without Annotation   //Create the event definition with name and description EventDefinition event1 = new EventDefinition(event, "Description for Event1"); //Set the event data shape event1.setDataShapeName("SimpleDataShape"); //Set remote access event1.setLocalOnly(false); //Add the event definition to the Virtual Thing this.defineEvent(event1);   Create Remote Services   With remote Services, the implementation is handled by the Java application and can be called either within the application or remotely, by the Composer while a connection is established. The GetTruckReadings Service, a dummy Service used as an example of how to create a remote Service, populates an Info Table and returns that Info Table for whoever would like to use it. You can see how it is possible to define remote Services that can later be bound to Things in the Composer. A Service is defined using @ThingworxServiceDefinition annotation and its result is defined using @ThingworxServiceResult. These annotations take various parameters among including:   Name Description baseType Aspects In the second line, you can see the name of the result being set by the CommonPropertyNames field to keep development consistent with creating Things in the Composer. With Annotation @ThingworxServiceDefinition(name="OhmsLawCalculator", description="Get the watts/power (W) based on input voltage (V) and current (I)") @ThingworxServiceResult(name=CommonPropertyNames.PROP_RESULT, description="Result", baseType="NUMBER")   Without Annotation //Create the service definition with name and description ServiceDefinition service1 = new ServiceDefinition(service, "Description for Service1"); //Create the input parameter to string parameter 'name' FieldDefinitionCollection fields = new FieldDefinitionCollection(); fields.addFieldDefinition(new FieldDefinition("name", BaseTypes.STRING)); service1.setParameters(fields); //Set remote access service1.setLocalOnly(false); //Set return type service1.setResultType(new FieldDefinition(CommonPropertyNames.PROP_RESULT, BaseTypes.STRING)); //Add the service definition to the Virtual Thing this.defineService(service1); //Service1 Definition public String Service1(String name) throws Exception { String result = "Hello " + name; return result; }   Create Data Shapes   Data Shapes must be created using code as seen in GeneratorThing.java as shown below:   // Data Shape definition that is used by the generating going offline event   FieldDefinitionCollection fields = new FieldDefinitionCollection();fields.addFieldDefinition(new FieldDefinition(TYPE_FIELD, BaseTypes.STRING));fields.addFieldDefinition(new FieldDefinition(WATTAGE_FIELD, BaseTypes.STRING));fields.addFieldDefinition(new FieldDefinition(AMPS_FIELD, BaseTypes.NUMBER));fields.addFieldDefinition(new FieldDefinition(VOLTAGE_FIELD, BaseTypes.NUMBER));fields.addFieldDefinition(new FieldDefinition(UP_TIME_FIELD, BaseTypes.NUMBER));fields.addFieldDefinition(new FieldDefinition(STATUS_FIELD, BaseTypes.NUMBER));fields.addFieldDefinition(new FieldDefinition(LOCATION_FIELD, BaseTypes.LOCATION));fields.addFieldDefinition(new FieldDefinition(LAST_SYNC_FIELD, BaseTypes.DATETIME));fields.addFieldDefinition(new FieldDefinition(CONNECTED_SINCE_FIELD, BaseTypes.DATETIME));fields.addFieldDefinition(new FieldDefinition(POWER_LINES_FIELD, BaseTypes.INFOTABLE));defineDataShapeDefinition("GeneratorShape", fields); NOTE: It is possible to create a Data Shape, and then use it in a Service definition within your code as StringIndex property, StringMap Data Shape, and StringMapService Service in SimpleThing.java.     Scan Cycles   To complete the implementation of the VirtualThing class, we recommend you provide an override and implementation to the processScanRequest method. This method provides a universal method for all VirtualThing implementations. This method could be used or a new method could be created for this purpose. The processScanRequest method in VirtualThing.java does not have an implementation of its own. An implementation from DeliveryTruckThing.java can be seen below:   // The processScanRequest is called by the PowerGrid class every scan cycle @Override public void processScanRequest() throws Exception { // Execute the code for this simulation every scan this.scanDevice(); this.updateSubscribedProperties(1000); this.updateSubscribedEvents(1000); }   Bound Properties in Cycle   The scanDevice method in GeneratorThing.java performs a number of tasks from retrieving Property values to firing Events. To retrieve a Property using binding, a request is made to the client using the name of the Property. A good programming practice is to handle how these Properties are accessed and set. Note that the update method for Properties and Events must be used after queueing an Event or setting a Property value. In the example below (used within the Delivery Truck Example), getter and setter methods are used for added control. The getProperty() call is used on the VirtualThing: public Double getSpeed() { return (Double) getProperty("Speed").getValue().getValue(); } public void setSpeed() throws Exception { setProperty("Speed", this.speed); } public Location getLocation() { return (Location) getProperty("Location").getValue().getValue(); } public void setLocation() throws Exception { setProperty("Location", this.location); }     Click here to view Part 4 of this guide.
View full tip
    Step 3: Test Connectivity    Before you can begin developing with the ThingWorx Java SDK, you will need to generate an Application Key and add it to the source code provided.   Generate Application Key On the Home screen of Composer click + New the top left.     In the dropdown list, click Application Key.   Give your Application Key a name (i.e., MyAppKey) and set the Project (ie, PTCDefaultProject). Assign the application key to a User.   Click Save. After saving, a Key ID is generated and appears above the Expiration Date. This is the secret key that you will use to make secure connections. If you have not updated the Expiration Date field, the default will be one day. This is an example of the Application Key ID that you will use for a successfull connection.   NOTE: Using the Application Key for the default Administrator is not recommended. If administrative access is absolutely necessary, create a User and place the user as a member of Admins.   Modify Source File   At the top level, locate the SimpleClient Java source file in a package under the src folder. Open the SimpleClient.java source file and update the URI with the IP address of your ThingWorx instance. For example: config.setUri("ws://127.0.0.1:80/Thingworx/WS");   In the SimpleClient.java source file, update the Application Key with the Application Key you stored from the last section. For example: config.setSecurityClaims(new SamplePasswordCallback(cmd.getOptionValue("b3d06be7-c9e1-4a9c-b967-28cd4c49fa80"))); //SET YOUR APPLICATION KEY HERE     Compile and Run Code   Right-click the SimpleClient.java file. Scroll to Run As then select Java Application.   The output in the Eclipse console will confirm connection and authentication to the ThingWorx platform.     Step 4: Run Sample Applications   The Java code provided in the download is pre-configured to run and connect to the Entities in the ThingWorxEntitiesExport.xml file. Keep track of the IP address of the ThingWorx Composer you are using. Many of the utilized libraries are based on the use of Java 1.8. Use other versions at your own risk.   Within your Eclipse ThingWorx Development project, navigate to the com.thingworx.sdk.examples package and open ExampleClient.java.   The URI structure is as follows: ws://host_name:port_number/Thingworx/WS. Update the host_name and port_number to the host and port of your ThingWorx server. Navigate to the following line and update the IP and port if necessary: config.setUri("ws:// 127.0.0.1:80/Thingworx/WS"); TIP: To enable secure https connection, change “ws” to “wss” and port number to 443. (default port for https is 443). Navigate to the following line in ExampleClient.java and update the value of appKey to the keyId in the “admin_key” Application Key in the ThingWorx Composer. If this connect fails, attempt to use the "admin_key" Application Key in the ThingWorx Composer. Using the default admin's key is not recommended. For future development, create users and add them to be a member of the group of Administrators: config.setSecurityClaims(new SamplePasswordCallback(cmd.getOptionValue("b3d06be7-c9e1-4a9c-b967-28cd4c49fa80"))); //SET YOUR APPLICATION KEY HERE Right-click ExampleClient.java, scroll to Run As, and select Java Application. You should be able to see a new Thing in your Composer called SimpleThing_2.   To check the connected Entities, go to the Monitoring screen.   Click Monitoring. Click Remote Things from the list to see the connection status.   You will now be able to see and select the Entity within the list. NOTE: SimpleThing_1 and SimpleThing_2 will also have an update to the lastConnection property. While SimpleThing_1 is unbound, SimpleThing_2 is bound for the duration of the application run time.     Step 5: Example Client Connection   The Java code provided in the ExampleClient.java file initiates a number of actions from establishing a connection to defining Services and Properties.   Configuration   In the first step of connecting to the platform (Establish Physical Websocket), we create a ClientConfigurator instance to hold the location (URI) needed to point to the websocket of the ThingWorx Composer. It is also used to:   Configure the ThingWorx URI of the server Set the Application Key used for authentication Set the connection reconnection interval Ignore ssl errors ClientConfigurator config = new ClientConfigurator(); config.setUri("ws://127.0.0.1:80/Thingworx/WS");   Authentication   In the second step of connecting to the platform (Authenticate), we provide this ClientConfigurator instance an Application Key that belongs to the default_user that was imported to the ThingWorx Composer. The Application Key must match the keyId value for the User you would want to have the specific control and permissions.   **WARNING: It is not best practice to utilize the Administrator’s Application Keys in Edge development. For the reason that Application Keys in java source code are vulnerable to de-compilation and storing them in a configuration file is dangerous, the best practice is to create new Users, and give them any permission deemed necessary.   config.setSecurityClaims(new SamplePasswordCallback(cmd.getOptionValue("b3d06be7-c9e1-4a9c-b967-28cd4c49fa80"))); //SET YOUR APPLICATION KEY HERE   NOTE: If you are not using SSL/TLS, use this code to test against a server using a self-signed certificate: config.ignoreSSLErrors(true);   Create Client Communication   To create a client with the above configuration, create an instance of ExampleClient and pass the configurator created in the step above. ExampleClient is a class that extends ConnectedThingClient. The ConnectedThingClient facilitates communication to the ThingWorx server as well as manages any contained VirtualThing. ExampleClient.java is an example of this and creates the instance on the line: ExampleClient client = new ExampleClient(config); Create and Bind Thing Before starting the client, it is best to bind all VirtualThings that will be bound in order to decrease the necessary request messages. Binding Things before starting the client creates one bind request message to go to the ThingWorx server with all of the Things included. Starting the client then binding Things creates a bind request for each Thing that is being bound. // Create a new VirtualThing. The name parameter should correspond with the // name of a RemoteThing on the Platform. In this example, the SimpleThing_1 is used. VirtualThing thing = new VirtualThing(ThingName, "A basic virtual thing", client); // Bind the VirtualThing to the client. This will tell the Platform that // the RemoteThing 'SimpleThing_1' is now connected and that it is ready to // receive requests. client.bindThing(thing);   Start Connection   You can now start the client, which will establish the AlwaysOn protocol with the ThingWorx Composer. This protocol provides bi-directional communication between the ThingWorx Composer and the running client application.   // Start the client. The client will connect to the server and authenticate // using the ApplicationKey specified above. client.start();       Click here to view Part 3 of this guide.    
View full tip
  Use our developer toolkit to connect Java-enabled devices and build an application.     GUIDE CONCEPT This project will introduce complex aspects of the ThingWorx Java SDK and help you to get started with development.   Following the steps in this guide, you will develop your own IoT application with the ThingWorx Java SDK.   We will teach you how to use the Java programming language to connect and build IoT applications to be used with the ThingWorx Platform.   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete all parts of this guide is 60 minutes.     YOU'LL LEARN HOW TO   Establish and manage a secure connection with a ThingWorx server, including SSL negotiation and connection maintenance Enable easy programmatic interaction with the Properties, Services, and Events that are exposed by Entities running on a ThingWorx server Create applications that can be directly used with your device running the Java programming language Basic concepts of the Java Edge SDK How to use the Java Edge API to build a real-world application How to utilize resources provided in the Edge SDK to help create your own application   Step 1: Completed Example   Download the Java_SDK_Extra_Samples.zip attached to this article and extract the contents.   In this tutorial we walk you through a real-world scenario for a power grid network. The Java_SDK_Extra_Files.zip file provided to you contains the following files and Entities as a completed version of the scenario we will cover. Please keep in mind, the Java SDK can also be utilized for Android development and general Java development.   Name Description PowerGrid Source code for an extensive example of a power grid network Delivery Truck Source code for the delivery truck application ExampleClient Source code for examples on how to do different tasks FileTransfer Source code for a file transfer application Tunneling Source code for a tunneling application SimpleThing Source code for simple connections and examples SteamSensor Source code for a steam sensor that provides configuration during runtime   Once you complete your Java environment setup and import the JavaExampleEntities.xml file into ThingWorx Composer, you will be able to utilize these Entities:   Feature Entity Type Description  Generator1  Thing  Used with the power grid edge example  Generator2  Thing  Used with the power grid edge example  Generator3  Thing  Used with the power grid edge example  Consumer1  Thing  Used with the power grid edge example  Consumer2  Thing  Used with the power grid edge example  Consumer3  Thing  Used with the power grid edge example DeliveryTruck_1 Thing Used with the delivery truck edge example DeliveryTruck_2 Thing Used with the delivery truck edge example DeliveryTruck_3 Thing Used with the delivery truck edge example FileTransferExample Thing Used with the file transfer edge example TunnelExample Thing Used with the tunnel edge example SimpleThing_1 Thing Used as a simple edge example for coding and connectivity SimpleDataShape Data Shape Used as a simple edge Data Shape example for coding and connectivity DeliveryTruckShape Data Shape Used as a Data Shape with the delivery truck edge example EdgeExample Model Tag Used as a Model Tag for tagging all entities; enables quicker searches DeliveryTable Data Table Used as a Data Table with the delivery truck edge example Default_user User User created to be used with the SDK examples PTC Organization An Organization that helps with security in edge examples Admin_key Application Key An Application Key used for the Admin Default_key Application Key An Application Key used for the Default User; this is the recommended key to use   Step 2: Environment Setup   You can use the Java SDK with any IDE of your choice. The steps below demonstrate how to use the Eclipse IDE as an example.   If you have not already done so, install a Java Development Kit (JDK) from Corretto or OpenJDK in order to compile and run Java code and download the ThingWorx Java SDK. The download will include the JARs necessary to run the SDK.   The Eclipse Java IDE is a centralized location to store the code, resources, and files utilized by this guide. Download and install the latest Eclipse Java IDE from the Eclipse website.   Create Java Project   When the Eclipse Welcome window appears, click Create a new Java Project. In the New Java Project setup wizard, enter ThingWorx Development as the project name. Java 1.8 is the supported and recommended JDK.   Click Finish.    Set Up User Library   Right click the newly created ThingWorx Development project in the Package Explorer. Expand the Build Path selection and select Add Libraries.  Click User Library. Click Next.  Click User Libraries. Click New, enter ThingWorx Java SDK as the library name. Click OK.   Set Up Javadoc   With the ThingWorx Java SDK selected, click the Add External JARs button.       In the pop-up window, navigate to the location in which you unzipped the ThingWorx Java Edge SDK. Navigate to the lib folder, select all of the JARs, then click Open. Within the ThingWorx Java SDK library, expand the thingworx-common-xxxx.jar folder and select Javadoc location. Click Edit. Select the Javadoc in archive and External file radio buttons, then click Browse. In the pop-up window, navigate to the location in which you unzipped the ThingWorx Java Edge SDK. Navigate to the lib folder, highlight the thingworx-java-sdk JavaDoc JAR File, then click Open. Click OK. Repeat steps 1-8 for the thingworx-communications-client JAR’s Javadoc location field shown in step 10. Confirm that your setup looks like this:   Click OK. Select the checkbox for the ThingWorx Java SDK library, then click Finish.   Import Sample Files   Right click the ThingWorx Development project and click Import.   In the Import wizard, type File System into the filter. Click Next.     In the pop-up window, navigate to the location in which you unzipped the ThingWorx Java Edge SDK. Navigate inside the samples folder and select the src folder.     Click OK. Select the checkbox for the src folder, then click Browse.     Type ThingWorx Development/src into the text box.   Click OK. Click Finish.     Expand the ThingWorx Development project.       Click here to view Part 2 of this guide.
View full tip
  Step 7: Import Extension   In the ThingWorx Composer. in the bottom left, click Import/Export, then select Import.   NOTE: The build produces a zip file in AuthenticatorExample->build->distributions folder. This zip file will be required for importing the extension.          2. For the Import Option field, select Extension.            3. Click Browse and choose the zip file in the distributions folder (located in the Eclipse Project's build directory).       4. Click Import to finalize the import.   Navigate to New Authenticator   Navigate to and select Security > Authenticators.            2. You will now see your CustomizedAuthenticator Authenticator as a option to view/edit.            3. Click Edit or View to see this new Authenticator. You wil notice the priority is 1.   Troubleshooting   If your import did not get through with the two green checks, you may want to modify your metadata.xml or java code to fix it depending on the error shown in the logs.     Issue Solution JAR Conflict arises between two similar jars JAR conflicts arise when a similar jar is already present in the Composer database. Try to remove the respective jar resources from the metadata.xml. Add these jars explicitly in twx-lib folder in the project folder inside the workspace directory. Now, build the project and import the extension in ThingWorx Composer once again. JAR is missing Add the respective jar resource in metadata.xml using the ThingWorx->New Jar Resource. Now, build the project and import the extension in ThingWorx Composer once again. Minimum Thingworx Version [ 7.2.1] requirements are not met because current version is: 7.1.3 The version of SDK you have used to build your extension is higher than the version of the ThingWorx Composer you are testing against. You can manually edit the configfiles->metadata.xml file to change the Minimum ThingWorx version to your ThingWorx Composer version.     Step 8: Integrating Custom Authentication   Integration can be handled in different methods based on your security needs and architecture. The Authenticator we created works with the demo site we provided in the download.   Create ThingWorx User   Let's create the User that we will be processing login attempts.   In the ThingWorx Composer, click the + at the top left of the screen.   Select User in the dropdown.   Set the Project (ie, PTCDefaultProject) and enter the Name for this new user as TwxUser. Enter the Password for the new user to something easy to remember (ie, 2020Password2021).   Click Save.   Create Logger   Create a helpful logger for authentication attempts.   Create a Thing named AuthenticationStamper to go with the LoginHelper variable in the earlier Java source code. Ensure this new Thing inherits from the RemoteThing Match the properties for the AuthenticationStamper with the two properties in the below image.   Save the changes.   Create Login Helper   Create a stream for authentication attempts for helpful tracking. Create a ValueStream named AuthenticationStream and Save the Entity. In the Properties and Alerts section of the ValueStream, click Manage Bindings.   Setup the binding to match the below configurations. Bind the properties to the AuthenticationStamper Thing.   Save the changes made to the ValueStream.   Demo Page Login   With a browser, open the TestSite.html web page found in the Demo directory of the download. You should see a login page similar to that as the below image.   Enter the name of the user we created, TwxUser. Enter the password for the user. We suggested setting this to Password2019. Click Submit. You will now be authenticated and logged in.     Step 9: Next Steps   Congratulations! You've successfully completed the Create An Authentication Extension tutorial, and learned how to:   Install the Eclipse Plugin and Extension SDK Create and configure an Extension project Create Authentication Application Build and import an Extension   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Application Development Tips & Tricks   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Extension Development Guide    
View full tip
  Connect IoT data from devices to Widgets that display in your application UI.   GUIDE CONCEPT   This project will demonstrate how to bind a data source to a Widget.   Following the steps in this guide, you will be able to show state-based changes resulting from data updates.   We will teach you how to essentially connect your backend data to the Widgets in your Mashup. ThingWorx facilitates this process with built-in functionality.     YOU'LL LEARN HOW TO   Bind data to Widgets in ThingWorx Mashup   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes.      Step 1: Completed Examples    Download the Complete Data Binding Example using file BindDataEntities.zip attached to this guide. Within this file you, you will find Entities referenced in this lesson, including a finished application. Import and utilize this file to see a finished example and return to it as a reference if you become stuck during this guide and need some extra help or clarification.   Keep in mind, this download uses the exact names for Entities used in this tutorial. If you would like to import this example and also create Entities on your own, change the names of the Entities you create.     Step 2: Bind Data to Widget   In order to display data from connected devices, each Widget must be connected to a data source. You should already be familiar with how to find the Widgets in the top left panel of a Mashup screen.   Mashup Areas   In the top right of the screen in a Mashup Entity is the Data Panel. This is where Entities and Services are used to bring in data and added functionality. This area also includes the Session Tab, which includes data that is being stored in the session. You can learn more about that in the Create Session Parameters guide. You can also filter for specific Properties.       In the lower right of the screen in a Mashup Entity is the Data Properties Panel. This is where you can configure how your Service calls will react to different Events. For example, you might want to perform a call to a Service as soon as another Service call is complete. You'll do that in this section. You will also notice the Functions Tab. This table enables you to create custom functionality for you Mashup and Widgets, such as navigating to a different Mashup on the click of a button.       In the lower left of the screen in a Mashup Entity is the Widget Properties Panel. This is where you'll be able to not only customize your Widget, but connect data directly from Services and other Widgets. You will also notice the Style Properties Tab. This will provide access to change the styling and themes used for a Widget. You can also filter for specific Properties.       In the bottom middle of your screen, you'll notice the Bindings Panel. This panel shows you where your connections are in reference to Widgets, Services, and any Events that are being used to connect them. Whenever you have a problem with thinking about the flow of your Mashup, look down to this panel to get a quick idea. You'll also notice the Reminder Tab in this area. This tab just helps with things you might have forgotten to do when setting up your data binding, such as setting the display field for a Widget.       Let's now move forward with setting up our data binding.    Add Service   Open the HelloWorldPlayground Mashup. Drag and drop the Grid Advanced Widget to the left-hand column of your Canvas.      NOTE: If a pop-up appears about adding a Panel, choose Yes. 2. Click + in the Data panel.       3. Search and select the HelloWorldData Data Table from the search bar in the top left of the home screen. 4. Search for the GetFirstEntry Service and click the blue arrow. The GetFirstEntry service is part of the DataMagicians.XML file you imported.   5. Check the Execute on Load checkbox. This makes the page automatically load with content for a Widget. 6. Click Done.     Bind Data to Widget   We will bind data to a Widget, but also make the Widget editable. When it comes to making the field Editable, keep in mind any connections or Entities involved. In this case, the World field is attached to an Entity.   In the Data panel, expand the Returned Data section. Drag and drop the All Data field of the GetFirstEntry Service to the Grid Advanced Widget. A pop-up will appear to select the binding target, select Data.   In the Widget Properties panel, check the checkbox for IsEditable. This will allow users to edit the data in the Property fields. Select the Configure (Gear) button. The Configure Grid Columns window will open.   Update any fields you would like hidden (for instance, uncheck the box next to timestamp and key).     Click on source field. Check the Editable checkbox at the bottom.   Click Done to close the pop-up.   Data Panel Buttons   There is an assortment of helpful buttons in the Data panel to make our lives easier.     Top Row of Buttons   The + button that you used before adds more Entities as a resource to make Service calls. The circlular button next to it provides a reload functionality. This is useful when you've made a change to a Service and would like for it to appear here. For example, adding a new parameter to a Service call.   Buttons by Entity   The i button provides information and access to the Entity in question. The Add Service button adds a Service that belongs to the same Entity. This will definitely help with saving time. The last button is the Delete button. This will delete the Entity from the list of resources that can make Service calls.   Buttons By Service   The only button is the Delete button. This will delete the Service from the list of Service calls an Entity has available.   Adding More Functionality   Click the Add Service button on the HelloWorldData Entity in the Data pane.     Search for the UpdateDataTableEntry Service and click the arrow to select it. Leave the Execute on Load checkbox unchecked and click Done. Deselect the Execute on Load option if you would like the page to load with content in response to user input, rather than automatically at startup. Click on the UpdateDataTableEntry Service, then click on the Data Binding button in the bottom right. Click the arrow next to the Values Property under Parameters. Click Add Source. When the list of Widgets appear, click on the Editedtable of the Grid Advanced Widget that we added. Click Next and Done. Select the Grid Advanced Widget on your canvas. Drag and drop the EditCellCompelted property onto the UpdateDataTableEntry service.     NOTE: The columns returned by a data service are shown under the All Data section of the data service. They are outbound bindable, indicated by the outward facing arrows. When a data service All Data or individual column is bound, the arrows become filled in. You can also bind the data from one Widget to another.         8. Click Save and View Mashup.   You have just bound data from a service to a Widget. There are many different Widgets, and the process for binding data to a Widget is often similar. Within Composer, you can simply drag and drop to bind configurations for Events and Properties.     TIP: As, an extension to this lesson, edit the Property Display Widget to update the entry in the HelloWorldData DataTable. Editing the name of the World will result in no entries being updated. To add or update an entry when you update the Name property, used the AddOrUpdateDataTableEntry service instead of UpdateDataTableEntry.     Step 3: Next Steps    If you have questions, issues, or need additional information, refer to:   Resource Link     Community Developer Community Forum Support Help Center
View full tip
  Step 9: File Transfer Example   To handle file transfers, a virtual directory is created in the SteamSensor1 entity and in the [C SDK HOME DIR]/examples/FileTransferExample application directory. The source code used for this example is found in [C SDK HOME DIR]/examples/FileTransferExample/src/main.c.   Inside of the [C SDK HOME DIR]/examples/FileTransferExample folder, create the folder structure shown below:   /transfer/ /transfer/incoming/ /transfer/outgoing/   Inside of the /transfer/outgoing/ directory, create and open a file with the name outgoing.txt. Once the outgoing.txt document is open, add the following text, save, and close the file: Hello. This is a file coming from the client application. Navigate to the [C SDK HOME DIR]/examples/FileTransferExample/src/main.c code and update the lines below with the appropriate information for your IP, port, and the “admin_key” Application Key’s keyId value in the ThingWorx Composer:   /* Server Details */ #define TW_HOST "127.0.0.1" #define TW_PORT 80 #define TW_APP_KEY "ce22e9e4-2834-419c-9656-ef9f844c784c"   To support file transfers in your client application, you must use the   twFileManager_AddVirtualDir function in order to create the virtual directories in the entity with such a capability. It will also define the directories available for file operations. A virtual directory maps a unique name to an absolute path of a directory in the file system. All subdirectories of the specified directory are exposed to the server. You can define multiple virtual directories. The directories do not need to be contiguous. Staging Directory   As an optional, but recommended step, you should set the directory that the application should use for staging when performing file transfers. This can be seen in the line below and should be done before initializing the FileManager. The default directory of the FileManager is most likely owned by root and will require a change to either the location of the staging directory and the ownership of the staging directory, or running the application as a User with the correct permissions.   twcfg.file_xfer_staging_dir = "staging";   The example provided uses the TW_SHARE_DIRECTORY macro to create two virtual directories that will act as the root directories in the virtual file system of this application are added. The client is then started as follows with the necessary TW_ADD_FILE_TRANSFER_SHAPE function being called:   TW_ADD_FILE_TRANSFER_SHAPE(); TW_SHARE_DIRECTORY("in", "/transfer/incoming/"); TW_SHARE_DIRECTORY("out", "/transfer/outgoing/");   The creations of the payloads used to create the remote directories on the platform have been moved to a helper function below to make the design cleaner:   int setupSystemRepo(const char * remoteInPath, const char * remoteOutPath, const char * remoteFile);   After our remote directories and files have been setup, it is time to perform the file transfers. Normally, this would mean invoking the Copy service for a Subsystem, but two functions have been created to make this process easier:   int twFileManager_GetFile(const char * sourceRepo, const char * sourcePath, const char * sourceFile, const char * targetRepo, const char * targetPath, const char * targetFile, uint32_t timeout, char asynch, char ** tid) int twFileManager_SendFile(const char * sourceRepo, const char * sourcePath, const char * sourceFile, const char * targetRepo, const char * targetPath, const char * targetFile, uint32_t timeout, char asynch, char ** tid)   The table below displays an example of the first set of parameters:   Parameter Example Description sourceRepo SystemRepository The name of FileRepository or RemoteThing to transfer the file FROM. sourcePath outgoing The path specifying the location of the source file. sourceFile The name of the source file.   targetRepo SteamSensor1 The name of FileRepository or RemoteThing to transfer the file TO. targetPath incoming The path specifying the destination location of the file. targetFile incoming.txt The name of the file at the target. This name can differ from the sourceName. timeout 15,000 The amount of time (in seconds) to wait for a synchronous transfer to complete before cancelling the transfer. async false If false, the service call will block for timeout seconds or until the transfer completes. tid incoming0123 The unique TID associated with the file.   The C SDK also provides the ability to create a FileCallback function that the FileManager will call that function when any file transfer events occur. You can provide a wildcard filter so that only file transfer Events of files that match the filter call the callback function. In addition, callbacks can be set up as “one-shots” such that the callback is unregistered automatically after it is invoked the first time.   NOTE: An optional file transfer callback is registered in the code and provided. You will see the output from the function as files are sent and received.   After running this application, you will notice a new file in the transfer/incoming folder after refreshing. This is the file that we created in the ThingWorx Composer file system for the SystemRepository Entity and was able to copy from that location to our local project. We have also sent a file to the server’s SystemRepository. The BrowseFileSystem and GetFileListing services can be used to check for the folders and files created.   twFileManager_RegisterFileCallback(fileCallbackFunc, NULL, FALSE, NULL);     Step 10: Support Other Platforms   All Websocket errors indicate some general issue communicating with the ThingWorx platform. If you experience an issue connecting, refer to the table below for a list of websocket errors, their corresponding codes, and an explanation of the issue.   Code Message Troubleshooting 200 TW_UNKNOWN_WEBSOCKET_ERROR An unknown error occurred on the websocket. 201 TW_ERROR_INITIALIZING_WEBSOCKET An error occurred while initializing the websocket. Check your websocket configuration parameters for validity. 202 TW_TIMEOUT_INITIALIZING_WEBSOCKET A timeout occurred while initializing the websocket. Check the status of the connection to ThingWorx. 203 TW_WEBSOCKET_NOT_CONNECTED The websocket is not connected to ThingWorx. The requested operation cannot be performed. 204 TW_ERROR_PARSING_WEBSOCKET_DATA An error occurred while parsing websocket data. The parser could not break down the data from the websocket. 205 TW_ERROR_READING_FROM_WEBSOCKET An error occurred while reading data from the websocket. Retry the read operation. If necessary, resend the data. 206 TW_WEBSOCKET_FRAME_TOO_LARGE The SDK is attempting to send a websocket frame that is too large. The Maximum Frame Size is set when calling twAPI_Initialize and should always be set to the Message Chunk Size (twcfg.message_chunk_size). 207 TW_INVALID_WEBSOCKET_FRAME_TYPE The type of the frame coming in over the websocket is invalid. 208 TW_WEBSOCKET_MSG_TOO_LARGE The application is attempting to send a message that has been broken up in to chunks that are too large to fit in a frame. You should not see this error. 209 TW_ERROR_WRITING_TO_WEBSOCKET An error occurred while writing to the Web socket. 210 TW_INVALID_ACCEPT_KEY The Accept key sent earlier from ThingWorx is not valid.     Step 11: Next Steps   Congratulations! You've successfully completed the C SDK Tutorial, and learned how to utilize the resources provided in the Edge SDK to create your own application.   Learn More   We recommend the following resources to continue your learning experience:   Capability Link 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 C Edge SDK Help Center    
View full tip
  Build a Predictive Analytics Model - Video Guide   This project will introduce ThingWorx Analytics Builder via a convenient video-guide. Following the steps in this video, you will create an analytical model, and then refine it based on further information from the Analytics platform. We will teach you how to determine whether or not a model is accurate and how you can optimize both your data inputs and the model itself.     ThingWorx Analytics Server Installation with SSL   This video demonstrates the installation of Analytics Server with SSL protections enabled. It includes information about generating the necessary certificates and truststores to enable SSL for each component that connects with the server.     ThingWorx Platform Analytics Installation with SSL   This video demonstrates the Platform Analytics installation with SSL protections enabled. It provides information about generating the necessary certificates and truststores to enable SSL for all connected components, including RabbitMQ and Flink.     Toolbar Widget | ThingWorx 9   Watch this video to learn how to add a Toolbar widget to a mashup in ThingWorx. You'll learn how to define actions using a data service and create bindings to control and configure a Grid widget.     ThingWorx SSO: Login demonstration from Azure AD to ThingWorx   This video demonstrates the ThingWorx SSO login procedure using Azure AD. The login procedure is shown from a user point of view. Then a behind the scenes view looks at the design in ThingWorx Composer.     Menu Bar Widget ThingWorx 9   Watch this video to learn how to create a mashup layout that uses a Menu Bar widget for navigation. You'll learn how to create a layout, define menu items, and configure the widget.     ThingWorx AD FS SSO Setup   This video provides a walk-through of the steps required to set up SSO for ThingWorx in an environment where AD FS is both the CAS and the IdP. The focus is on the AD FS setup steps.     Create Your Application UI   Following the steps in this video-guide, you will learn how to use the ThingWorx Mashup Builder tool to create a Graphical User Interface (GUI) for your IoT Application. We will teach you how to rapidly create and update a Mashup, which is a custom visualization built to display data from devices according to your application's business and technical requirement     Get Started with ThingWorx for IoT   Explore the ThingWorx Foundation Internet-of-Things application building platform in a convenient, instructional video guide format.     Thingworx Mashup 101 - Do's and Don'ts   This session covers the most common and useful tips about how to correctly use Mashup builder, Widgets and Layouts – and what to avoid - to create applications with good principles of UI/UX and easier to maintain.     What's New in ThingWorx 9.1   The industry’s most complete IIoT platform just got better. Loaded with a full range of new and updated features and functionality, you can expect powerful platform capability enhancements across the board.       Standardize Connectivity to Devices, Applications, & Systems for Centralized IIot Data   You can’t implement IIoT solutions if you can’t connect to your assets, but in complex environments connectivity can seem like an insurmountable challenge. ThingWorx makes it easy to establish standardized connectivity, so you can create a secure, single-source for accessing industrial data across your IT and OT systems     Bar Chart Widget | ThingWorx 9   Watch the following video on how to add the Bar Chart widget to a mashup and configure basic widget properties.     Button Widget | ThingWorx 9   Watch the this video to learn how to add the Button widget to a mashup and use its Clicked event to trigger data services.     Line Chart Widget | ThingWorx 9   Watch the this video to learn how to add the Line Chart widget to a mashup and bind a data source.     ReImagine Your Application UI With Collection and Custom CSS   Create compelling, modern application user interfaces in ThingWorx with the latest enhancements to our Mashup visualization platform - Collection and Custom CSS. In this webinar with IoT application designer Gabriel Bucur, we'll show how the new Collection widget makes it easy to replicate visual content in your UI for menu systems, dashboards, tables, and more.     Testing Your Edge Application   Native testing is an often-overlooked aspect of edge application development. This session shares how to perform thorough testing before you push your application into live production.     Predictive Maintenance with Thingworx 101   Adopting a predictive maintenance strategy for the first time can often feel daunting, but it doesn't have to. Learn how ThingWorx can be used to leverage edge devices and turn monitoring activity into action.     ThingWorx Mashup Pitfalls: What to Avoid and What Not to Do   Designing Mashups takes time. Moreover, expanding upon a Mashup that was built for a small-scale application can get cumbersome.     IoT Security: Keeping Devices Safe in a High Risk World   Understanding access controls can be difficult. With the built-in security features and concepts in ThingWorx, you can easily give your devices access on-demand.     Edge Connectivity in Unreliable Networks   The Store and Forward feature within ThingWorx Industrial Connectivity assures users that critical data collected at the edge won't get lost during an outage.  
View full tip
    Use ThingWorx Advisors to view trends and monitor Alerts.     GUIDE CONCEPT   The intent of this guide is to provide instructions to configure trends and alerts in the ThingWorx Advisors.   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete all parts of this guide is 30 minutes.     YOU'LL LEARN HOW TO   In this guide, you will learn how to: Configure and view trends in machine performance Create and configure an alert Monitor an alert   Step 1: Configure and View Trends  To begin, you will learn how to open up ThingWorx Advisors.   In ThingWorx Foundation Composer, click Browse then Visualization > Master then click PTC.Factory.PlantStatus.Master.          2. Next click the View Mashup button.                 3. Click the Utility Selector grid in the upper left            4. Click Trending and Troubleshooting              5. Click the + icon.               NOTE : A New Trend pop-up will appear.        6. In the Trend Name text box, type Station A Temperature, then click OK.              7. In the Tags area, click the + icon to start plotting a tag             8. In the Equipment Type drop-down, choose KEPServerEX, in the Equipment drop-down,        choose your KEPServer or the simulation server.          9. In the Server Structure menu, click LineGroup1 and use the drop-down menu to select LineGroup1.1-3_CNCMill. In the Tags menu area, click Temperature then click OK, or choose a tag based on your KepServer configuration.   10. Review the trend data for Station A.     11.  Repeat these steps to apply additional property setting to Station A.   12. Check the Show Value Range box in the Tags area. Review the trend data for the properties selected.                      NOTE: The three selected tags will appear plotted in the Show Value Range table.     Click here to view Part 2 of the guide.  
View full tip
The IoT Building Block Design Framework By Victoria Firewind and Ward Bowman, Sr. Director of the IoT EDC   Building Block Overview As detailed quite extensively on its own designated Help Center page, building blocks are the future of scalable and maintainable IoT architecture. They are a way to organize development and customization of ThingWorx solutions into modular, well-defined components or packages. Each building block serves a specific purpose and exists as independently as possible from other modules. Some blocks facilitate external data integration, some user interface features, and others the manipulation or management of different kinds of equipment. There are really no limits to how custom a ThingWorx solution can be, and customizations are often a major hurdle to a well-oiled dev ops pipeline. It’s therefore crucial for us all to use a standard framework, to ensure that each piece of customization is insular, easy-to-replace, and much more maintainable. This is the foundation of good IoT application design.   PTC’s Building Block Framework At PTC, building blocks are broken down in a couple different ways: categories and types. The category of a building block is primarily in reference to its visibility and availability for use by the greater ThingWorx community. We use our own framework here at PTC, so our solution offerings are based around solution-specific building blocks, things which we provide as complete, SaaS solutions. These solution-specific building blocks combine up into single solutions like DPM, offerings which require a license, but can then easily be deployed to a number of systems. PTC solutions provide many, complex, OOTB features, like the Production Dashboard of DPM, and the OperationKPI building block.   Anyone doing any sort of development with ThingWorx, however, does still have access to many other building blocks, included with the domain specific building block category. These are the pieces used to build the solution building blocks like DPM, and they can be used to build other more custom solutions as well. Take the OperationKPI block which can vary greatly from one customer to the next in how it is calculated or analyzed. The pieces used to build the version that ships with DPM are right there, for instance, Shift and ReasonCode. They are designed to have minimal dependencies themselves, meant to be used as dependencies by custom blocks which do custom versions of the module logic found within the PTC solution-specific blocks. Then there are the common blocks as well, and these are used even more widely for things like user management and database connectivity.   The type of the building block refers really to where that building block falls in the greater design. A UI building block consumes data and displays it, so that is the View of a classic MVC design pattern. However, sometimes user input is needed, so perhaps that UI building block will depend on another block. This other block could have a utility entity that fuels UI logic, and the benefit to having that be a separate block is then the ease with which it can be subbed out from one ThingWorx instance to the next.   Let’s say there are regional differences in how people make use of technologies. If the differences are largely driven by what data is available from physical devices at a particular site, then perhaps these differences require different services to process user input or queries on the same UI mashups used across every site. Well in this case, having the UI block stand alone is smart, because then the Model and Controller blocks can be abstracted out and instantiated differently at different sites.   The two types that largely define the Model and Controller of the classic MVC are called Abstract and Implementation building blocks, and the purposes are intertwined, but distinct: abstract building blocks expose the common API endpoints which allow for the implementation blocks to vary so readily. The implementation blocks are then those which actually alter the data model, which is what happens when the InitializeSolution method is called. In that service, they are given everything they need to generate their data tables and data constraints, so that they are ready to be used once the devices are connected.   Occasionally, UI differences will also be necessary when factories or regions have different ways of doing things. When this happens, even mashups can be abstracted using abstract building blocks. Modular mashups which can be combined into larger ones can be provided in an abstract building block, and these can be used to form custom mashups from common parts across many sites in different implementation blocks all based on the same abstract one.   The last type of building block is the standard building block, which is the most generic. This one is not intended to be overridden, often serving as the combination of other building blocks into final solutions. It is also the most basic combination of components necessary to adhere to the building block design framework and interface with the shared deployment infrastructure. The necessary components include a project entity, which contains all of the entities for the building block, an entry point, which contains the metadata (name, description, version, list of dependencies, etc.) and overrides the service for automatic model generation (DeployComponent), and the building block manager. The dashed arrows indicate an entity implements another, and the solid arrows, extension. The manager is the primary service layer for the building block, and it makes most of the implementation decisions. It also has all of the information required to configure menus and select which contained mashups to use when combining modular mashups into larger views. The manager really consists of 3 entities: a thing template with the properties and configuration tables, a thing which makes use of these, and a thing shape which defines all of the services (which can often be overridden) which the manager thing may make use of.   Most building blocks will also contain security entities which handle user permissions, like groups which can be updated with users. Anyone requiring access to the contents of a particular building block then simply needs to be added to the right groups later on. This as well as model logic entities like thing shapes can be used concurrently to use organizational security for visibility controls on individual equipment, allowing some users to see some machines and not others, and so on.   All of the Managers must be registered in the DefaultGlobalManagerConfiguration table on the PTC.BaseManager thing, or in the ManagerConfiguration table of any entity that implements the PTC.Base.ConfigManagement_TS thing shape. Naming conventions should also be kept standard across blocks, and details on those best practices can be found in the Build Block Help Center.   Extending the Data Model Using Building Blocks Customizing the data model using building blocks is pretty straight-forward, but there are some design considerations to be made. One way to customize the data model is to add custom properties to existing data model entities. For instance, let’s say you need an additional field to keep track of the location of a job order, and so you could add a City field to PTC.JobOrder.JobOrder_AP data shape. However, doing this also requires substantial modification to the PTC.JobOrder.Manager thing, if the new data shape field is meant to interface with the database.   So this method is not as straight-forward as it may seem, but it is the easiest solution in an “object-oriented” design pattern, one where the data varies very little from site to site, but the logic that handles that data does vary. In this design pattern, there will be a thing shape for each implementing building block that handles the same data shape the abstract building block uses, just in different ways. A common use case for why this may happen is if the UI components vary from site to site or region to region, and the logic that powers them must also vary, but the data source is relatively consistent.   Another way to extend the data model is to add custom data shapes and custom managers to go with them. This requires you to create a new custom building block, one which extends the base entry point as needed for the type of block. This method may seem more complicated than just extending a data shape, but it is also easier to do programmatically: all you have to do is create a bunch of entities (thing templates, thing shapes, etc.) which implement base entities. A fresh data shape can be created with complete deliberation for the use case, and then services which already exist can be overridden to handle the new data shape instead. It is a cleaner, more automation friendly approach.   However, the database will still need to be updated, and this time CRUD services are necessary as well, those for creating and managing instances of the data shape. So, this option is not really less effort in the short term. In the long-term, though, scripts that automate much of the process for building block generation can be used to quickly and easily allow for development of new modules in a more complex ThingWorx solution. The ideal is to use abstract blocks defined by the nature of the data shape which each of their implementing blocks will use to hook the view into the data model.   This “data-driven” design pattern is one which involves creating a brand-new block for each customization to the data model. The functionality of each of these blocks centers around what the data table and constraints must look like for that data store, and the logic to handle the different data types should vary within each implementation block, but override the common abstract block interface so that any data source can be plugged into the thing model, and ThingWorx will know what to do with it.   The requests can then contain whatever information they contain (like MQTT), and which logic is chosen to process that data will be selected based on what information is received by the ThingWorx solution for each message. Data shapes can be abstracted in this way, so that a single subscription need exist to the data shape used in the abstract building block, and its logic knows how to call whatever functions are necessary based on whatever data it receives. This allows for very maintainable API creation for both data ingestion and event processing.
View full tip
Data Model Implementation Guide Part 1   Overview   This project will introduce you to methods for creating the data model that you have designed and are ready to implement. Following the steps in this guide, you will implement the Data Model you've already designed. After having insight into your desired Data Model, this guide will provide instructions and examples on how to build out your application using the ThingWorx platform. We will teach you how to utilize the ThingWorx platform to implement your fully functional IoT application. NOTE: This guide’s content aligns with ThingWorx 9.3. The estimated time to complete ALL 3 parts of this guide is 60 minutes. All content is relevant but there are additional tools and design patterns you should be aware. Please go to this link for more details.     Step 1: Completed Example   Download the completed files for this tutorial:  DataModelEntities.xml. The DataModelEntities.xml file provided to you contains a completed example of the completed data model implementation. Utilize this file to see a finished example and return to it as a reference if you become stuck during this guide and need some extra help or clarification. Keep in mind, this download uses the exact names for entities used in this tutorial. If you would like to import this example and also create entities on your own, change the names of the entities you create.   Step 2: Data Model Scenario   This guide will implement the scenario shown in the Data Model Design guide. Let's revisit our Smart Factory example scenario. Name Description Operations User to keep the line running and make sure that it’s producing quality products Maintenance User to keep machines up and running so that the operator can crank out products Management User in charge of dispatching production orders and making sure the quotas are being met Conveyor Belts Thing on factory line to pass items along to the next stage Pneumatic Gate Thing on factory line Robotic Arm Thing on factory line Quality Check Camera Final Thing on factory line to ensure quality In order to add this to our solution, we will want to build a "connector" between ThingWorx and the existing system. These connectors will be Things as well. Internal system connection Thing for Production Order System Internal system connection Thing for Maintenance Request System Operator   Required Functionality Description 1 File Maintenance Request 2 Get quality data from assets on their line 3 Get performance data for the whole line 4 Get a prioritized list of production orders for their line 5 Create Maintenance Requests   Required Information Description 1 Individual asset performance metrics 2 Full line performance metrics 3 Product quality readings   Maintenance   Required Functionality Description 1 Get granular data values from all assets 2 Get a list of maintenance requests 3 Update maintenance requests 4 Set triggers for automatic maintenance request generation 5 Automatically create maintenance requests when triggers have been activated   Required Information Description 1 Granular details for each asset: In order to better understand healthy asset behavior 2 Current alert status for each asset: to know if there is something going wrong with an asset 3 When the last maintenance was performed on an asset 4 When the next maintenance is scheduled for an asset 5 Maintenance request info: Creation date, due date, progress notes   Management   Required Functionality Description 1 Create production orders 2 Update production orders 3 Cancel Production orders 4 Access line productivity data 5 Elevate maintenance request priority   Required Information Description 1 Production line productivity levels (OEE) 2 List of open Maintenance requests   Overlapping Matrix   This matrix represents all of the overlapping Components that are shared by multiple types of Things in our system:   Unique Matrix   This matrix represents the unique Components to each type of Thing:     Step 3: LineAsset Thing Template   After prioritizing and grouping common functionality and information, we came up with the list below for the first Thing Template to create, LineAsset with five Properties, one Event, and one Subscription. The breakdown for the LineAsset Thing Template is as follows:   Follow the below instruction to create this Entity and get the implementation phase of your development cycle going.   Line Asset Properties   Let's build out our Properties. In the ThingWorx Composer, click the + New at the top of the screen. Select Thing Template in the dropdown.        3. In the name field, enter LineAsset and set the Project (ie, PTCDefaultProject). 4. For the Base Thing Template field, select GenericThing.     5. Click Save.  6. Switch to the Properties and Alerts tab.  7. Click the plus button to add a new Property.   The Properties for the LineAsset Thing Template are as follows: Name Base Type Aspects Data Change Type State String Persistent and Logged ALWAYS SerialNumber String Persistent, Read Only, and Logged NEVER LastMaintenance DATETIME Persistent and Logged VALUE NextMaintenance DATETIME Persistent and Logged VALUE PowerConsumption NUMBER, Min Value: 0 Persistent and Logged ALWAYS Follow the next steps for all the properties shown in our template property table. Click Add. Enter the name of the property (ie, State). Select the Base Type of the proprty from the dropdown. Check the checkboxes for the property Aspects. Select the Data Change Type from the dropdown.   Click Done when finished creating the property. Your properties should match the below configurations.     Line Asset Event   Switch to the Events tab. Click Add. Enter the name of the Event (ie, Error). Select AlertStatus as the Data Shape. This DataShape will allow us to provide simple information including an alert type, the property name, and a status message.   Click Done. Your Event should match the below configurations.          Line Asset Subscription   Switch to the Subscriptions tab. Click Add. Check the Enabled checkbox. Switch to the Inputs tab. Select the name of the Event (ie, Error). Click Done. Your Subscription should match the below configurations.             Challenge Yourself   We have left the Subscription code empty. Think of a way to handle Error Events coming from your line asset and implement it in this section.   Click here to view Part 2 of this guide. 
View full tip
In this post, I show how you can downsample time-series data on server side using the LTTB algorithm. The export comes with a service to setup sample data and a mashup which shows the data with weak to strong downsampling.   Motivation: Users displaying time series data on mashups and dashboards (usually by a service using a QueryPropertyHistory-flavor in the background) might request large amounts of data by selecting large date ranges to be visualized, or data being recorded in high resolution. The newer chart widgets in Thingworx can work much better with a higher number of data points to display. Some also provide their own downsampling so only the „necessary“ points are drawn (e.g. no need to paint beyond the screen‘s resolution). See discussion here. However, as this is done in the widgets, this means the data reduction happens on client site, so data is sent over the network only to be discarded. It would be beneficial to reduce the number of points delivered to the client beforehand. This would also improve the behavior of older widgets which don’t have support for downsampling. Many methods for downsampling are available. One option is partitioning the data and averaging out each partition, as described here. A disadvantage is that this creates and displays points which are not in the original data. This approach here uses Largest-Triangle-Three-Buckets (LTTB) for two reasons: resulting data points exist in the original data set and the algorithm preserves the shape of the original curve very well, i.e. outliers are displayed and not averaged out. It also seems computationally not too hard on the server. Setting it up: Import Entities from LTTB_Entities.xml Navigate to thing LTTB.TestThing in project LTTB, run service downsampleSetup to setup some sample data Open mashup LTTB.Sampling_MU: Initially, there are 8000 rows sent back. The chart widget decides how many of them are displayed. You can see the rowcount in the debug info. Using the button bar, you determine to how many points the result will be downsampled and sent to the client. Notice how the curve get rougher, but the shape is preserved. How it works: The potentially large result of QueryPropertyHistory is downsampled by running it through LTTB. The resulting Infotable is sent to the widget (see service LTTB.TestThing.getData). LTTB implementation itself is in service downsampleTimeseries     Debug mode allows you to see how much data is sent over the network, and how much the number decreases proportionally with the downsampling.   LTTB.TestThing.getData;   The export and the widget is done with TWX  9 but it's only the widget that really needs TWX 9. I guess the code would need some more error-checking for robustness, but it's a good starting point.  
View full tip
Create Industrial Equipment Model Guide   Overview   This project introduces how to model industrial equipment in ThingWorx Foundation. NOTE: This guide’s content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes.    Step 1: Learning Path Overview   This guide explains the steps to get started modeling industrial equipment in ThingWorx Foundation and is part of the Connect and Monitor Industrial Plant Equipment Learning Path. You can use this guide independent from the full Learning Path. Other guides are available for more complete Data Model Introduction. When using this guide as part of the Industrial Plant Learning Path, you should already have ThingWorx Kepware Server installed and sending data to ThingWorx Foundation. In the next guide in the Learning Path, we'll use Foundation's Mashup Builder to construct a GUI that displays information and from ThingWorx Kepware Server. We hope you enjoy this Learning Path.   Step 2: Create Thing Shape   Thing Shapes are components that contain Properties and Services. In Java programming terms, they are similar to an interface. In this section, you will build Thing Shapes for an electric motor. Motor Start on the Browse folder icon tab of ThingWorx Composer. Under the Modeling section of the left-hand navigation panel, hover over Thing Shapes, then click the + button. Type MotorShape in the Name field. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. Click Save.   Add Properties   Click the Properties and Alerts tab at the top of your Thing Shape.   Click + Add. Enter the Property name from the first row of the table below into the Name field of the Thing Shape. Name Base Type Persistent? Logged? serialNumber String X   currentPower Number   X 4. Select the appropriate Base Type from the drop-down menu. 5. Check Persistent and/or Logged according to the table. NOTE: When Persistent is selected, the Property value will be retained when a Thing is saved. Properties that are not persisted will be reset to the default after every Save of the parent Thing. When Logged is selected, every Property value change will be automatically logged to a specified Value Stream. 6. Click ✓+ button. TIP: When adding multiple Properties at once, click Done and Add after each, once you've entered a Name, selected a Base Type and any other criteria. If adding a single Property, click Done. 7. Repeat steps 2 through 5 for the other Properties in the the table. 8. Click the done ✓ Button. You'll see that these Properties have been created for the Motor Thing Shape. 9. Click Save.   Step 3: Create Thing Template   You can create reusable building blocks called Thing Templates in ThingWorx to maintain scalability and flexibility of your application development. With Thing Templates, you define a set of similar objects by specifying the Properties (characteristics) and Services (behaviors) that are common for all the objects. In Java programming terms, a Thing Template is like an abstract class and can be created by extending other Thing Templates. Once a Thing Template is defined and saved in ThingWorx Foundation Server, you can replicate multiple Things to model a complete set without duplicating effort. In this step, you will create a Thing Template that defines Properties for a pump. This pump Template could be used to create multiple Things that each represent a specific pump used in an industrial facility. Start on the Browse folder icon tab on the far left of ThingWorx Composer. Under the Modeling section of the left-hand navigation panel, hover over Thing Templates and click the + button. Type PumpTemplate in the Name field. NOTE: Thing Template names are case-sensitive.       4. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject.       5. In the Base Thing Template box, click + to choose GenericThing as the Template.              6. In the Implemented Shapes field, click the + to select the MotorShape Thing Shape.              7. Click Save.   Add Properties   In this step, you will specify the Properties that represent the characteristics of a Pump. Some Properties like the location may never change (static), while other Properties like power and temperature information may change every few seconds (dynamic). Select the Properties and Alerts tab under Thing Template: PumpTemplate.   Click the Edit button if the Template is not already open for editing, then click + Add next to My Properties. Enter the Property name in the Name field copied from a row of the table below. Name Base Type Persistent Logged PlantID STRING x   plant_lat_long LOCATION x   watts NUMBER x x 4. Select the Base Type of the Property from the drop down menu. 5. Check the appropriate Persistent and Logged check box. NOTE: When Persistent is selected, the Property value will be retained when the parent Thing is saved. Properties that are not persisted will be reset to the default during a system restart and whenever the Thing is saved. When Logged is selected, every Property value change will be automatically logged to a specified Value Stream. 6. Click the ✓+ button. TIP: When adding multiple Properties at once, click Check+ after each, once you've entered a Name, selected a Base Type and any other criteria. If adding a single Property, click Check button. 7. Repeat steps 3 through 6 for each of the Properties in the rows of the table. 8. After entering the final Property, click the ✓ button. 9. Click Save. You should see the following Properties in your Composer.   In the next guide of this Learning Path, we will create a single Thing based on this Template to represent a specific Pump.     Step 4: Next Steps   Congratulations! You've successfully completed the Create Industrial Equipment Model tutorial, and learned how to: Use Composer to create Thing Shapes and Thing Templates Create Model Tags to keep entities organized   The next guide in the Connect and Monitor Industrial Plant Equipment learning path is Build an Equipment Dashboard.    
View full tip
Data Model Implementation Guide Part 3   Step 7: Unique Components Thing Templates   All of the shared component groups have been created. The next stage is creating the unique component group of ThingTemplates. Each of the below sections will cover one ThingTemplate, how the final property configuration should look, and any other aspects that should be added. The breakdown for the unique component group ThingTemplates is as follows:   Robotic Arm Properties   The properties for the RoboticArm ThingTemplate are as follows: Name Base Type Aspects Data Change Type TimeSincePickup NUMBER, Min Value: 0 Persistent and Logged ALWAYS Axis1 String Persistent and Logged VALUE Axis2 String Persistent and Logged VALUE Axis3 String Persistent and Logged VALUE ClampPressure NUMBER, Min Value: 0 Persistent and Logged ALWAYS ClampStatus String Persistent and Logged ALWAYS   Your properties should match the below configurations.   Pneumatic Gate Properties   The properties for the PneumaticGate ThingTemplate are as follows: Name Base Type Aspects Data Change Type GateStatus String Persistent and Logged ALWAYS   Your properties should match the below configurations.   Conveyor Belt Properties   The properties for the ConveyorBelt ThingTemplate are as follows: Name Base Type Aspects Data Change Type BeltSpeed INTEGER, Min Value: 0 Persistent and Logged ALWAYS BeltTemp INTEGER, Min Value: 0 Persistent and Logged ALWAYS BeltRPM INTEGER, Min Value: 0 Persistent and Logged ALWAYS   Your properties should match the below configurations.   Quality Control Camera   Properties   The properties for the QualityControlCamera ThingTemplate are as follows: Name Base Type Aspects Data Change Type QualityReading INTEGER, Min Value: 0 Persistent and Logged ALWAYS QualitySettings String Persistent and Logged ALWAYS CurrentImage IMAGE Persistent and Logged ALWAYS   Your properties should match the below configurations.   Event   Create a new Event named BadQuality. Select AlertStatus as the Data Shape. Your Event should match the below configurations:     Step 8: Data Tables and Data Shapes   For the Data Model we created, an individual DataTable would be best utilized for each products, production orders, and maintenance requests. Utilizing DataTables will allow us to store and track all of these items within our application. In order to have DataTables, we will need DataShapes to create the schema that each DataTable will follow. This database creation aspect can be considered a part of the Data Model design or a part of the Database Design. Nevertheless, the question of whether to create DataTables is based on the question of needed real time information or needed static information. Products, production orders, and maintenance requests can be considered static data. Tracking the location of a moving truck can be considered a need for real time data. This scenario calls for using DataTables, but a real time application will often have places where Streams and ValueStreams are utilized (DataShapes will also be needed for Streams and ValueStreams). NOTE: The DataShapes (schemas) shown below are for a simplified example. There are different ways you can create your database setup based on your own needs and wants. DataTable Name DataShape Purpose MaintenanceRequestDataTable MaintenanceRequest Store information about all maintenanced requests created ProductDataTable ProductDataShape Store information about the product line ProductionOrderDataTable ProductionOrderDataShape Store all information about production orders that have been placed   Maintenance Requests DataShape   The maintenance requests DataShape needs to be trackable (unique) and contain helpful information to complete the request. The DataShape fields are as follows: Name Base Type Additional Info Primary Key ID String NONE YES Title String NONE NO Request String NONE NO CompletionDate DATETIME NONE NO   Unless you’ve decided to change things around, your DataShape fields should match the below configurations.   Products DataShape   The product DataShape needs to be trackable (unique) and contain information about the product. The DataShape fields are as follows: Name Base Type Additional Info Primary Key ProductId String NONE YES Product String NONE NO Description String NONE NO Cost NUMBER Minimum: 0 NO   Unless you’ve decided to change things around, your DataShape fields should match the below configurations.   Production Order DataShape   The production order DataShape needs to be trackable (unique), contain information that would allow the operator and manager to know where it is in production, and information to help make decisions. The DataShape fields are as follows: Name Base Type Additional Info Primary Key OrderId String NONE YES Product InfoTable: DataShape: ProductDataShape NONE NO ProductionStage String NONE NO OrderDate DATETIME NONE NO DueDate DATETIME NONE NO   Unless you’ve decided to change things around, your DataShape fields should match the below configurations.     Step 9: SystemConnections Implementation   We have created the ThingTemplates and ThingShapes that will be utilized within our Data Model for creating instances (Things). Before we finish the build out of our Data Model, let's create the Services that will be necessary for the MaintenanceSystem and ProductionOrderSystem Things.    This guide will not cover the JavaScript and business logic aspect of creating an application. When complete with the below sections, see the Summary page for how to create that level of definition.       Maintenance System   This is the system managed by the maintenance user and geared towards their needs.   Properties   The properties for the MaintenanceSystem Thing are as follows:     Name Base Type Aspects Data Change Type  MaintEngineerCredentials  PASSWORD  Persistent  VALUE    Your properties should match the below configurations.         Services    The Services for the MaintenanceSystem Thing are as follows:    Service Name  Parameters  Output Base Type Purpose   GetAllMaintenanceRequests  NONE  InfoTable: MaintenanceRequest  Get all of the maintenance requests filed for the maintenance user.  GetFilteredMaintenanceRequests  String: TitleFilter  InfoTable: MaintenanceRequest  Get a filtered version of all maintenance requests filed for the maintenance user.  UpdateMaintenanceRequests  String: RequestTitle  NOTHING  Update a maintenance request already in the system.    Use the same method for creating Services that were provided in earlier sections. Your Services list should match the below configurations.     Production Order System   This is the system utilized by the operator and product manager users and geared towards their needs.   Services   The Services for the ProductionOrderSystem Thing are as follows:      Service Name  Parameters Output Base Type   AssignProductionOrders String: Operator, String: ProductOrder  NOTHING   CreateProductionOrders  String: OrderNumber, String: Product, DATETIME: DueDate  NOTHING  DeleteProductionOrders  String: ProductOrder  NOTHING  GetFilteredProductionOrders  String: ProductOrder  InfoTable: ProductionOrder  GetProductionLineList  NONE  InfoTable: ProductDataShape  GetUnfilteredProductionOrders  NONE  InfoTable: ProductionOrder  MarkSelfOperator  NONE  BOOLEAN  UpdateProductionOrdersOP  String: ProductOrder, String: UpdatedInformation  NOTHING  UpdateProductionOrdersPM  String: ProductOrder, String: UpdatedInformation  NOTHING   Use the same method for creating Services that were provided in earlier sections. Your Services list should match the below configurations.       Challenge Yourself     Complete the implementation of the Data Model shown below by creating the Thing instances of the ThingTemplates we have created. When finish, add more to the Data Model. Some ideas are below.         Ideas for what can be added to this Data Model: #  Idea  1 Add users and permissions   2  Add Mashups to view maintenance requests, products, and production orders  3  Add business logic to the Data Model   Step 10: Next Steps     Congratulations! You've successfully completed the Data Model Implementation Guide. This guide has given you the basic tools to: Create Things, Thing Templates, and Thing Shapes Add Events and Subscriptions   The next guide in the Design and Implement Data Models to Enable Predictive Analytics learning path is Create Custom Business Logic.  
View full tip
  Design Your Data Model Guide Part 3   Step 7: Prioritize     The first step in the design process is to use the Thing-Component Matrix to identify and prioritize groups of Components that are shared across multiple Things. These groups will be prioritized by number of shared Components, from highest to lowest, enabling is to break out the most commonly used groups of Components and package them into reusable pieces. Let’s examine our example Thing-Component Matrix to identify and prioritize groups. In the table below, we have done this and recognized that there are FOUR groups.   NOTE: Each item in our unique Thing-Component Matrix would also count as a group on its own. This can be dealt with almost separately from our process, though, because there is no overlap between different Things. The "Templates for Unique Components" and "Adding Components Directly to Things" sections in the Iterate step of this guide covers these "one-offs."     Step 8: Largest Group     The base building block we use most often is the Thing Template. To start the design process, the first step is to create a Thing Template for the largest Component group. Applying this to our Smart Factory scenario, we'll take the largest group ("Group 1") and turn it  into a Thing Template using the Entity Relationship Diagram schematic.   Since every item on our production line shares these Components, we will name this Thing Template Line Asset. Now, let's build this using our Entity Relationship Diagram.   The result is a ThingWorx Thing Template with five Properties, one Event, and one Subscription.     Step 9: Iterate     Once an initial base template has been created for the largest group, the rest of the groups can be added by selecting the appropriate entity type (Thing Template, Thing Shape, or directly-instantiated Thing). The following Entity Decision Flowchart explains which entity type is used in which scenario:   Now that we have established our "Line Asset" Thing Template for our largest group, the next step is to iterate through each of our remaining groups. Following the flowchart, we will identify what entity type it should be and add it to our design.   Group 2 - "System Connector"   The second group represents connectors into both of our internal business systems. We will call them System Connectors.   If we look at Group 2 versus our "Largest Group" Thing Template, we can see that there is no overlap between their Components. This represents the third branch of the Entity Decision Flowchart, which means we want to create a new Thing Template.   Following this rule, here is the resulting template:   Group 3 - "Hazardous Asset"   The third group represents line assets that require emergency shutdown capabilities because under certain conditions, the machinery can become dangerous. We will call these Hazardous Assets.   If we look at our two previous Thing Templates, we can see that there is full overlap of these Components with our previous largest group, the "Line Asset" Thing Template. This represents the fourth branch of the Entity Decision Flowchart, which means we want to create a CHILD Thing Template.   Following this rule, here is the resulting Thing Template:   Group 4 - "Inventory Manager"   The fourth group represents line assets that keep track of inventory count, to ensure the number of assembled-products is equal to the number of checked-products for quality.   If we look at our existing Thing Templates, we can see that there is some overlap of the Components in our "Hazardous Asset" and "Line Asset" Thing Templates. This represents the second branch of the Entity Decision Flowchart, which means we want to create a Thing Shape.   Following this rule, here is the resulting Thing Shape:   Templates for Unique Components   Now that we have handled all our shared component groups, we also want to look at the unique component groups. Since we have already established that each group in our Unique Thing-Component Matrix does not share its Components with other Things, we can create Child Thing Templates for these line assets.   NOTE: Refer to the finished design at the bottom to reference all of the inherited Thing Templates and Thing Shapes for these Child Thing Templates.   Adding Components Directly to Things   In many cases, we will have Components that only exist for a single Thing. This frequently occurs when there will be only one of something in a system. In our case, we will only need one "System Connector" for each of the Maintenance System and the Production Order System.   Instantiate Your Things   At this point, the Data Model is fully built. All we need to do now is instantiate the actual Things which represent our real-world machines and digital-connections.     Step 10: Validate     The final step of the model breakdown design process is validation through instantiation. This is the process by which we take our designed Thing Templates / Thing Shapes / Things and actually create them on the ThingWorx platform to ensure they meet all of our requirements. This is done by tracing back through the chain of inheritance for all the Things in the data model to ensure they contain all of the required Components from the Thing-Component Matrix. Once we have verified that each Thing contains all of its requirements, the data model is complete.   Using this technique on each of your Things, you can explicitly prove that all of the requirements have been met.   Step 11: Next Steps   Congratulations! You've successfully completed the Design Your Data Model Guide covering the first three steps of the proposed data model design strategy for ThingWorx. This guide has given you the basic tools to: Create user stories Identify endpoints in your system Break down your data model using an Entity Relationship Diagram Decide when to use Thing Templates vs. Thing Shapes vs. directly-instantiated Things     The next guide in the Design and Implement Data Models to Enable Predictive Analytics learning path is Data Model Implementation.
View full tip
Announcements