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

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

IoT Tips

Sort by:
  Learn how to create systems to handle logistics and production distribution   GUIDE CONCEPT   This project will introduce complex aspects of the ThingWorx Composer and solution building.   Following the steps in this guide, you will develop your own IoT application or get a jump start in how to utilize ThingWorx for your needs.   We will teach you how to create a focused rules engine or service level logic to be used with the ThingWorx Platform.     YOU'LL LEARN HOW TO   Create automated logistical processes Use Services, Alerts, and Subscriptions to handle processes without human interaction Integrating complex logic with straight forward step by step systems   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete All parts of this guide is 60 minutes.      Step 1: Examples and Strategy   This guide builds on the knowledge gained in Factory Line Automation.   Download FoodIndustry.zip attached to this guide and extract/import the contents.   For the completed example, download the automated_food_industry.zip, also attached here. This download provides three Users and a Security Group. Please watch your count for Users or the import could fail.   In this tutorial we continue with our real-world scenario for the Fizos food company. We already have our factory data, and automated cooking processed for our sausage product lines. Now, let's see how we can use the data model we built before into making a smarter system of deliveries. We will take into consideration the locations of our factories, the vehicles we have available, our customers (stores and individuals), and see how much we can automate.   Setting Up Orders   One important part of being in business is having a product that people or companies want to buy. You'll need a way to track these sales and we're going to start with doing just that. Let's create our order shapes and tables.   In the ThingWorx Composer, click the + New in the top left of the screen.     Select Data Shape in the dropdown.     In the name field, enter Fizos.Orders.DataShape and select a Project (ie, PTCDefaultProject). All of our orders will be based off this Data Shape.     Click Save then Edit to store all changes now. Add the list of properties below: Name Base Type Aspects Description ID Integer 0 minimum, primary key, default 0 Row identifier CustomerId Integer N/A String used as unique identifer across multiple platforms Type String N/A Type of customer (individual or another company) Factors Tag Data Tag This will hold the different type of data points or tags that will help to analyze a customer's order Products Infotable Data Shape: Fizos.DataShapes.Products List of orders TotalPrice Number Minimum 0 Price of the order Status String N/A The current order status (ie, processed, shipped, completed, etc) Completed Boolean N/A Whether the order has been completed   The Properties for the Fizos.Orders.DataShape Data Shape are as follows:   6. In the ThingWorx Composer, click the + New in the top left of the screen.   7. Select Data Table in the dropdown and select Data Table in the prompt.   8. In the name field, enter Fizos.Orders.DataTable. Our differing types of customers will fall under this template. 9. For the Data Shape field, select Fizos.Orders.DataShape and select a Project (ie, PTCDefaultProject).     10. Click Save then Edit to store all changes now. 11. This Entity will be used to house our data and provide assistance with our analytics.   We now have our model of orders ready to be stored. Of course, our orders are simplified. We can add much more to get them rolling, but the most important aspect right now is our Factors field. While we know a ton of information about customers, we can also analyze what kind of products they're buying and their ordering habits.     Step 2: Expanding Customer Models    Let's start with our customers. We created the data shape for customers before when we decided to put them in data tables. This time, we'll add some customers, but also expand on our modeling of what a customer entails. In this step, as with all the steps in this learning path, you can go as granular as you like. If you'd like to make 100 data tags, then it helps with understanding your customer, but it might be too much based on your goals. Remember, more data means more processing of that data.   Creating Customer Data Tags   These data tags will help us decide priority, relationships, and much more.   In the ThingWorx Composer, click the + New in the top left of the screen.     Select Data Tag in the dropdown.     In the name field, enter Fizos.CustomerTags and select a Project (ie, PTCDefaultProject). Check the Dynamic checkbox. This allows for new vocabulary terms to be created during runtime.   Click on the Vocabulary Terms tab, and add the following terms and then add as many more as you see fit: Name  Store  Individual  Office  Company  FirstTime  Repeat  Partner  LongTerm  ShortTerm  Old  MiddleAged  Young  Loyal We just added a number of data tags based on customer type, age, times the customer has bought from us, etc. This will help us with characterizing and modeling our customers. We'll also cheat a bit and use these data tags to help with deliveries. If you're a partment brand, we might work faster to send goods. For example, the code below returns the list of orders that were made by partners. We can add this as a service to our Fizos.Logistics template.   var index; var customerId; var partnerObj = {}; var query = { "filters": { "type": "EQ", "fieldName": "Completed", "value": false } }; var orders = Things["Fizos.Orders.DataTable"].QueryDataTableEntries({ query: query }); var customers = Things["Fizos.Customers.DataTable"].GetDataTableEntries(); var result = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape({ infoTableName : "InfoTable", dataShapeName : "Fizos.Orders.DataShape" }); var partners = Resources["InfoTableFunctions"].TagFilter({ inclusive: true, fieldName: "Factors", t: customers, tags: "Fizos.CustomerTags:Partner" }); for(index = 0; index < partners.rows.length; index++) { customerId = partners.rows[index].ID; partnerObj[customerId] = true; } for(index = 0; index < orders.rows.length; index++) { customerId = orders.rows[index].CustomerId; if(partnerObj[customerId] === true) { var newEntry = new Object(); newEntry.ID = orders.rows[index].ID; newEntry.CustomerId = orders.rows[index].CustomerId; newEntry.Type = orders.rows[index].Type; newEntry.Products = orders.rows[index].Products; newEntry.Factors = orders.rows[index].Factors; newEntry.TotalPrice = orders.rows[index].TotalPrice; result.AddRow(newEntry); } } This code will retrieve all orders that are not in a completed state. It will then figure out which orders are for partners and return those orders. You can see in this simple example how Data Tags can be used.     Click here to view Part 2 of this guide.
View full tip
  Step 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
  Guidelines for selecting the optimal method for connecting to ThingWorx   GUIDE CONCEPT   In the world of IoT application development, connectivity refers to the infrastructure and protocols which connect devices to the cloud or network. Edge devices handle the interface between the physical world and the cloud.   ThingWorx provides you with several different tools for connecting to the Thingworx platform.   This guide is designed as an introduction to these tools, and will help you determine which to choose based on your specific requirements.   YOU'LL LEARN HOW TO   Pros and cons of different connection methods The connection method best suited for some typical applications Where to find detailed information about any connection method   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete this guide is 30 minutes   Step 1: Connectivity Method Options   There are many factors that will influence your decision about the ideal mechanism to connect to ThingWorx. On this page we compare and contrast different methods and give examples for where each one is a natural fit.   Connectivity Method Developer Benefit REST API Integrate seamlessly using dynamically-generated API calls Azure IoT Hub Connector Connect devices that use Azure IoT Hub Edge SDKs Build full-featured integrations for any platform ThingWorx Kepware Server Connect out-of-the-box with over 150 protocol drivers for industrial equipment Edge MicroServer Establish bi-directional connectivity with this complete, ready-to-run agent   REST API   Pros Cons Typical use case Skills Required Connection Type  Web developer can easily create integration ThingWorx cannot trigger action on the edge Push data from small devices to ThingWorx REST API development Request/Response   Using the ThingWorx REST API is an easy way for low-capability devices to connect with a ThingWorx platform. Any edge device that can make an HTTP POST can read and update properties or execute services on a ThingWorx platform. The disadvantage of this method is that it is one way from edge to platform. There is no way for the platform to initiate a service on the remote device and properties are only updated when the edge device initiates a connection with ThingWorx.   Learn more about the ThingWorx REST API:   Use REST API to Access ThingWorx Using the Connect an Arduino Developer Board tutorial REST API Documentation   Azure IoT Hub Connector   Pros Cons Typical use Case Skills Required Connection Type  Easily connect devices that use Azure IoT Hub Adds dependency and cost to application Add ThingWorx for devices connected with the Azure cloud Azure edge development AlwaysOn™   The diagram illustrates device-to-cloud integration with the Azure IoT Hub.   The ThingWorx Azure IoT Hub Connector establishes network connections to both ThingWorx Foundation and the Azure IoT Hub. Data flows in from devices, through the Azure IoT Hub hosted in the cloud, to the ThingWorx Azure IoT Hub Connector configured for a specific ThingWorx instance. The ThingWorx Azure IoT Hub Connector translates messages from the Azure IoT Hub format, to the native ThingWorx format and uses an established AlwaysOn connection to forward the information to ThingWorx Foundation.   Azure IoT Hub   Connect Azure IoT Devices   Edge SDKs   Pros Cons Typical Use case Skill Required Connection Type  Fully integrate device or remote system with ThingWorx platform Most developer flexibility All functionality must be developed by programmer Full customization or tight integration required Application development in Java, C, or .Net AlwaysOn™   These SDKs are developer tools that wrap the protocol used to connect to the ThingWorx Platform. There are SDK's available for Java, C, and .Net languages. The Edge MicroServer uses the C SDK internally. All SDKs use the ThingWorx AlwaysOn binary protocol together with the HTTP WebSocket protocol for transport. WebSocket connections can operate through a firewall allowing two-way, low latency communication between the device and server. The SDKs support the following key concepts that allow a Thing developed with an SDK to be a full-fledged entity in the ThingWorx environment:   Remote properties — Entities that define the types, identities, and values from a device or remote system Services — Actions that can be performed on demand by a device or remote system Events — Data that is sent to a subscribed device or remote system whenever the Event is triggered   You can choose from any of the SDK's to create a custom application that meets their exact requirements.   C SDK   The C SDK is the most lightweight of all the SDKs and will result in an application that uses the least amount of RAM, frequently requiring less than 200kB. It is the only SDK that is distributed as source code, allowing compilation of C SDK applications on any platform even those without an operating system.   Learn more about the C SDK:   C SDK Tutorial C SDK Documentation   Java SDK   The Java SDK is designed for portability and simplicity to ease connecting any Java-enabled device or system to ThingWorx. The Java SDK is provided as .jar files and sample Java source code. Any system that can run Java 1.7.51 or later should be able to build and run the example applications.   Learn more about the Java SDK:   Java SDK Tutorial Java SDK Documentation   .Net SDK   The .Net SDK is provided as .dll files with sample Visual C# project files and source code. Any system that can run Microsoft NET 3.5 SP1 Framework development environment should be able to build and run the example applications.   Learn more about the .Net SDK:   .Net SDK Documentation   ThingWorx Kepware Server   Pros Cons Typical Use case Skill Required Connection Type  Easily connect to hundreds of different types of industrial equipment Requires computer running Windows physically connected to device Adding ThingWorx to an industrial setting Configure settings AlwaysOn™   The ThingWorx Kepware Server Windows client lets users quickly and easily connect real-time, bi-directional industrial controls data to the ThingWorx IoT Platform via the ThingWorx AlwaysOn protocol. ThingWorx services enable users to browse, read, write, and interact with ThingWorx Kepware Server, and includes intuitive tools that simplify the modeling of industrial things.   Learn more about the ThingWorx Kepware Server:   Connect Industrial Devices and Systems ThingWorx Kepware Server Documentation ThingWorx Kepware Server Manual   Edge MicroServer   Pros Cons Typical Use case Skill Required Connection Type  Easily connect with simple scripting Requires a device running Windows or Linux Customization with Lua scripting Connecting gateway router to ThingWorx Configure settings AlwaysOn™   The ThingWorx Edge MicroServer is a binary executable available for Windows and Linux running on either ARM or x86 processors. The EMS establishes an AlwaysOn, bi-directional connection to a destination ThingWorx platform when it is started. The EMS is configured by editing a json text file to specify the target platform and credentials. The EMS uses the always on connection to provide a local HTTP server that is a reflection of the platform REST API. This local copy of the platform API allows devices that are not capable of making encrypted connections across the open internet to securely interact with the platform. The EMS package also includes the Lua Script Resource application. This application extends the ThingWorx Foundation server by connecting through the EMS HTTP server and provides a Lua interpreter that can be used to connect local resources to the ThingWorx server.   Learn more about the ThingWorx Edge MicroServer:   Connect a Raspberry Pi to ThingWorx using the Edge MicroServer Edge MicroServer Documentation   Step 2: Next Steps   Congratulations! You've successfully completed the Choose a Connectivity Method guide.   At this point, you can make an educated decision regarding which connection methods are best suited for your application and infrastructure.   The next guide in the Connect and Configure Industrial Devices and Systems learning path is Use REST API to Access ThingWorx   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Connect ThingWorx Application Development Reference Build Get Started with ThingWorx for IoT Experience Create Your Application UI   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support ThingWorx Connectors Help Center
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 7: Real World Model   We’ll now rerun model creation with the Real World data.   Even though Signals and Profiles are possibly telling us that only Sensor 1 is needed, the first Model you’ll create will contain all the data, while the second Model will exclude Sensor 2. We’ll then compare the Models to see which one is going to work the best for predicting engine failures.   On the left, click Analytics Builder > Models. Click New….   In the Model Name field, enter vibration_model. In the Dataset field, select vibration_dataset.   Click Submit. After ~60 seconds, the Model Status will change to COMPLETED. Select the model that was created in the previous step, i.e. vibration_model. Click View… to open the Model Information page. Note that your model may differ slightly from the picture below, as the automatically-withheld "test" data is randomly chosen.       Unlike our simulated dataset, this real-world data is not perfect. However, it’s still pretty good, and is much more representative of what a real-world scenario would indicate.   The True Positive Rate shown on the Receiver Operating Characteristic (ROC) chart are much higher than the False Positives.   The curve is relatively high and to the left, which indicates a high accuracy level.   You may also click on the Confusion Matrix tab in the top-left, which will show you the number of True Positive and True Negatives in comparison to False Positives and False Negatives.     NOTE: The number of correct predictions is much higher than the number of incorrect predictions.   As such, we now know that our Sensors have a relatively good chance at predicting an impending failure by detecting low grease conditions before they cause catastrophic engine failure.   Refined Model   We can now compare this first Model that includes both Sensors to a Model using only Sensor 1, since we suspect that Sensor 2 may not be necessary to achieve our goal. On the left, click Analytics Builder > Models. Click New…. In the Model Name field, enter vibration_model_s1_only. In the Dataset field, select vibration_dataset.   On the right beside Excluded Fields from Model, click the Excluded Fields button.   Select s2_fb1 through s2_fb5.   While all the s2 values are selected, click the green "right-arrow", i.e. > button, in the middle.   At the bottom-left, click Save.   Click Submit. After ~60 seconds, the Model State will change to COMPLETED. With vibration_model_s1_only selected, click View….     The ROC chart is comparable to the original model (including Sensor 2).   Likewise, the Confusion Matrix (on the other tab) indicates a good ratio of correct predictions versus incorrect predictions.     NOTE: These Models may vary slightly from your own final scores, as what data is used for the prediction versus for evaluation is random.   ThingWorx Analytics’s Models have indicated that you are likely to receive roughly the same accuracy of predicting a low-grease condition whether you use one sensor or two!   If we can get an accurate early-warning of the low grease condition with just one sensor, it then becomes a business decision as to whether the extra cost of Sensor 2 is necessary.     Step 8: Next Steps   Congratulations! You've successfully completed the Build an Engine Analytical Model guide, and learned how to:   Load an IoT dataset Generate machine learning predictions Evaluate the analytics output to gain insight   The next guide in the Vehicle Predictive Pre-Failure Detection with ThingWorx Platform learning path is Manage an Engine Analytical Model.   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Analyze Operationalize an Analytics Model Build Implement Services, Events, and Subscriptions Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Analytics Builder Help Center
View full tip
  Step 4: Simulated Model   Models are primarily used by Analytics Manager (which will be discussed in the next guide), but they can still be used to estimate the accuracy of predictions.   When Models are calculated, they inherently withhold a certain amount of data (~20%). The prediction model is then run against the withheld data. This provides a form of "accuracy measure".   The withheld-data is selected randomly, so you'll actually get a slightly different model and accuracy measure each time that you create a Model versus the same dataset.   On the left, click Analytics Builder > Models.   Click New….   In the Model Name field, enter simulated_model. In the Dataset field, select simulated_dataset.   Click Submit. After ~60 seconds, the Model Status will change to COMPLETED.     Select the model that was created in the previous step, i.e. simulated_model. Click View… to open the Model Information page.   As with Signals and Profiles, our Model is once again "too good". In fact, it's perfect.   The expected "Precision" is 1.0, i.e. 100%. The True vs False Positive rate shown in the graph goes straight up to the top immediately.   While you want a graph that is "high and left", you're very unlikely to ever see real-world scenarios such as shown here.   Still, you've been able to progress the process of using Foundation (and now Analytics) to build an analytical model of MotorCo's prototype engine.   What needs to happen now is to receive real world data from your R&D engineers.     Step 5: Upload Real World Data   In your process of using the EMS Engine Simulator, the idea has always been to get a headstart on the engine developers.   At some point, they would wire sensors into the EMS and start providing real world data.   In our scenario, that has now happened. Real world data is being fed from the EMS to Foundation, Foundation is collecting that data in an Info Table Property, and you've even exported the data as a .csv. file.   This new dataset is over periods of both good and bad grease conditions. The engineers monitoring the process can flip a sensor switch connected to the EMS to log the current grease situation as either good or bad at the same time that the vibration sensors are taking readings.   We will now load this real world dataset into Analytics in the same manner that we did earlier with the simulated dataset.   Download the attached analytics_vibration.zip file to your computer. Unzip the analytics_vibration.zip file to access the vibration_data_and_header.csv and vibration_metadata.json files. On the left, click Analytics Builder > Data. Under Datasets, click New....   In the Dataset Name field, enter vibration_dataset. In the File Containing Dataset Data section, search for and select vibration_data_and_header.csv. In the File Containing Dataset Field Configuration section, search for and select vibration_metadata.json.   Click Submit.     Step 6: Real World Signals and Profiles   Now that the real-world vibration data has been uploaded, we’ll re-run Signals and Profiles just as we did before.   Hopefully, we’ll start seeing some patterns.   On the left, click Analytics Builder > Signals. At the top, click New….   In the Signal Name field, enter vibration_signal. In the Dataset field, select vibration_dataset.   Click Submit. Wait ~30 seconds for Signal State to change to COMPLETED     The results show that the five Frequency Bands for Sensor 1 are the most highly correlated with determining our goal of detecting a low grease condition.   For Sensor 2, only bands one and four seem to be related, while bands two, three, and five are hardly relevant at all.   This is a very different result than our earlier simulated data. Instead, it looks like it’s possible that the vibration-frequencies getting pickup up by our first sensor are explicitly more important.   Profiles   We’ll now re-run Profiles with our real-world dataset. On the left, click Analytics Builder > Profiles. Click New….   In the Profile Name field, enter vibration_profile. In the Dataset field, select vibration_dataset.   Click Submit. After ~30 seconds, the Signal State will change to COMPLETED.     The results show several Profiles (combinations of data) that appear to be statistically significant.   Only the first few Profiles, however, have a significant percentage of the total number of records. The later Profiles can largely be ignored.   Of those first Profiles, both Frequency Bands from Sensor 1 and Sensor 2 appear.   But in combination with the result from Signals (where Sensor 1 was always more important), this could possibly indicate that Sensor 1 is still the most important overall.   In other words, since Sensor 1 is statistically significant both by itself and in combination (but Sensor 2 is only significant in combination  with Sensor 1), then Sensor 2 may not be necessary.     Click here to view Part 3 of this guide.
View full tip
    Generate engine-failure predictions and gain insight into your data with machine learning.   GUIDE CONCEPT   This guide will upload captured data from an Edge MicroServer (EMS) "Engine Simulator" to ThingWorx Analytics Builder.   Following the steps in this guide, 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.   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   Load an IoT dataset Generate machine learning predictions Evaluate the analytics output to gain insight     Step 1: Scenario   In this guide, we’re continuing the same MotorCo scenario, where an engine can fail catastrophically in a low-grease condition.   In previous guides, you’ve gathered and exported engine vibration-data from an Edge MicroServer (EMS).   The goal of this guide is to now import that previously-exported Comma-Separated Values (.csv) data into ThingWorx Analytics, and then create an analytical model for predictive maintenance.   Analytical model creation can be extremely helpful for the automotive segment in particular. For instance, each car that comes off the factory line could have an EMS constantly sending data from which an analytical model could automatically detect engine trouble.   This could enable your company to offer an engine monitoring subscription service to your customers.   This guide will show you how to build an analytic model of your engine to facilitate this monitoring service.     Step 2: Upload Simulated Data   This guide assumes that you are using either the hosted trial (with has both Foundation and Analytics pre-installed) or a combination of the Foundation and Analytics downloadable installers.   To confirm that Foundation is communicating with Analytics, perform the following steps:   On the ThingWorx Foundation left-side navigation column, click Analytics > Analytics Builder > Settings.   At the top-right in the Analytics Server Version field, ensure that you see an appropriate version number.     NOTE:  If you use your own dataset, it's possible that you're results in the following steps will differ from those created by the provided-dataset. If you were unable to generate a 30,000+ entry dataset in the last guide, then you may download testCSVfile.csv attached here,instead. You will also need to download and extract vibration_metadata.zip which describes each column of the dataset. On the left, click Analytics Builder > Data.   Under Datasets, click New....   In the Dataset Name field, enter simulated_dataset. In the File Containing Dataset Data section, search for and select testCSVfile.csv. In the File Containing Dataset Field Configuration section, search for and select vibration_metadata.json.   Click Submit. Note that the time it takes to import the dataset is determined by its size.       Step 3: Simulated Signals and Profiles    The Signals section of ThingWorx Analytics looks for the most statistically correlated single field in the dataset which relates to your selected goal.   This doesn't necessarily indicate that it is the cause of your goal, whether maximizing or minimizing. It just means that the dataset indicates that this single field happens to correlate with the goal that you desire.   On the left, click Analytics Builder > Signals.   At the top, click New….   In the Signal Name field, enter simulated_signal. In the Dataset field, select simulated_dataset.   Click Submit. Wait ~30 seconds for Signal State to change to COMPLETED     Unfortunately, our results aren't very good. Or, more accurately, they're too good.   Our simulated dataset has some noise in it from adding random values to our five frequency bands on each our two sensors. However, ThingWorx Analytics has instantly seen through that noise and discarded it. Instead, it's only detected that s2_fb5 isn't relevant.   If you look back at the Use the EMS to Create an Engine Simulator guide, you'll see that s2_fb5 has the same base value between both a "good grease" and a "bad grease" condition, i.e. a base of 190.   This does show already that Analytics is working, though. Since s2_fb5 didn't change between good and bad grease conditions, our Signal analysis is indicating that it's not relevant to our model.   Profiles   Now, let's do the same for a Profile.   The Profiles section of ThingWorx Analytics looks for combinations of data which are highly correlated with your desired goal.   On the left, click Analytics Builder > Profiles.   Click New....   In the Profile Name field, enter simulated_profile. In the Dataset field, select simulated_dataset.   Click Submit. Wait ~30 seconds for the Profile State to change to COMPLETED.     Just like with Signals, our Profile is too good. In fact, Analytics is indicating that just s1_fb2 by itself is the primary indicator of good vs. bad grease conditions.   This is likely due to random chance. The random noise added to s1_fb2 just happened to be slightly less than the other frequency bands, so everything else was discarded.   Regardless, ThingWorx Analytics is quickly seeing through our simulated data.   Next, we'll actually create a Model using the simulated dataset.     Click here to view Part 2 of this guide  
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
    Step 3: Test Services and Save Test Cases   In the previous step, you created an Entity with a customized Service. You can easily test and update the Service within the same editing window. This allows you to quickly modify a Service and confirm that its new behavior is functioning as expected. Test Execution   To execute a Service, you can do it while still developing and after you have created it.   During Development   Open the LineCheckSystem Thing. Select the Services tab. Click the ListHotLineParts link.   If you scroll to the bottom of the page, you will see the Execute window. Enter a value for the TemperatureThreshold and click Execute.     After Development   Open the LineCheckSystem Thing. Select the Services tab. Click the ListHotLineParts Execute play button.   Enter a value for the TemperatureThreshold and click Execute.       Saving Test Cases   Store input parameters makes testing during development and after development much faster. Whether you are testing base cases, specific scenarios, or throwing everything you possibly can at your Service, this tab will allow you to store and name test cases for later usage. During Development   Open the LineCheckSystem Thing. Select the Services tab. Click the ListHotLineParts link   If you scroll to the bottom of the page, you will see the Execute window. Enter a value for the TemperatureThreshold and click Save Input Set. When prompted, enter a name for this test case and click Save Input Set.   After Development   Open the LineCheckSystem Thing. Select the Services tab. Click the ListHotLineParts Execute play button.   Enter a value for the TemperatureThreshold and click Save Input Set.   When prompted, enter a name for this test case and click Save Input Set.   While this example is pretty simple and straightforward, it is also possible to store other values and other data types! You will be provided with a dropdown of your stored test cases. Just select a case and click Execute.     Step 4: Utilize Code Auto-Complete Feature   If it is not open already, open the ListHotLineParts Service or create a new one. On a new line, enter ThingTemplates["LinePartTemplate"]. Add a period . after the closing bracket to gain access to the Services and Properties of the Thing Template we created earlier.     You will now see the Services and Properties that were created inside of the LinePartTemplate or passed down in its object-oriented model.     Step 5: Test Code at Design Time with Linting   Linting is a process by which your development environment warns you of possible issues even before any attempt to run or test the code. Instead, an in-editor warning pops up that alerts you to the issue as you’re writing your code. Linting is yet another feature which many IDEs provide outside of the IoT realm.   Select the Lint checkbox at the top of the Service-editing section.   Type any statement that would cause a Lint warning or error to pop up. In this case, it is best programming practice to use a semi-colons at the end of JavaScript code.   Debugging   Services within the composer are based on the Rhino JavaScript engine, which is built using Java.   It is currently unavailable to see the JavaScript code running within the browser, but you are able to still log what is occurring at each step of development and runtime. ThingWorx provides logging that will go to the ScriptLog under the Monitor section on the left. The logger uses different log levels that will appear differently in the ScriptLog screen.   Level Syntax Example info logger.info logger.info("X + 1 = " + 5); trace logger.trace logger.trace("Print this InfoTable - " + table.toJSON()); warning logger.warn logger.warn("Print random JSON data - " + JSON.stringify(data)); debug logger.debug logger.debug("Adding debug information here."); error logger.error logger.error("What kind of error took place? " + err.message); Testing Tips   From the Lint website, here are some common mistakes that JavaScript Lint looks for: Missing semicolons at the end of a line. Curly braces without an if, for, while, etc. Code that is never run because of a return, throw, continue, or break. Case statements in a switch that do not have a break statement. Leading and trailing decimal points on a number. A leading zero that turns a number into octal (base 8). Comments within comments. Ambiguity whether two adjacent lines are part of the same statement. Statements that don't do anything. JavaScript Lint also looks for the following less common mistakes: Regular expressions that are not preceded by a left parenthesis, assignment, colon, or comma. Statements that are separated by commas instead of semicolons. Use of increment (++) and decrement (--) except for simple statements such as "i++;" or "--i;". Use of the void type. Successive plus (e.g. x+++y) or minus (e.g. x---y) signs. Use of labeled for and while loops. if, for, while, etc. without curly braces. (This check is disabled by default.)     Step 6: Next Steps    Congratulations! You've successfully completed the Application Development Tools, Tips & Tricks, and learned how to:   Use Snippets to generate code Execute and test Services Save Service test cases to facilitate QA process Utilize the code auto-completion feature Test code at design time with Lint warnings and errors   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Build Create Custom Business Logic 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 Help Center
View full tip
  Expedite your application development with new ThingWorx features.   GUIDE CONCEPT   This project will introduce you to a variety of features designed to expedite the IoT application development workflow. In particular, there are several features that make the creation of custom Services quicker and easier when writing and testing your code.   Following the steps in this guide, you will learn how to access features that will help you throughout your software development lifecycle: development, execution, and testing.   We will teach you how to became a faster and more efficient IoT application developer.     YOU'LL LEARN HOW TO   Use Snippets to generate code Execute and test Services Save Service test cases to facilitate QA process Utilize the code auto-completion feature Test code at design time with Lint warnings and errors   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL parts of this guide is 30 minutes.        Step 1: Completed Example   Download and extract the completed files for this tutorial attached to this article: ToolsTipsTricks.zip file.   The file provided to you contains a completed example of the Entities covered in this guide. Utilize this file to see a finished example and return to it as a reference if you become stuck during this guide and need some extra help or clarification.   Keep in mind, this download uses the exact names for Entities used in this tutorial. If you would like to import this example and also create Entities on your own, change the names of the Entities you create.       Step 2: Templates and Using Code Snippets    Expedite your application development process by utilizing code Snippets provided in ThingWorx. The JavaScript code snippets will give you insight into best practices for performing common development tasks.   Follow the steps below to create a Service that will: Check a list of Things Find Things with a temperature over an input parameter threshold, and Return the captured list of Things   Create a Thing Template   Utilizing a Thing Template expedites your development process because the Things inherit properties from the Template. In the steps below, it can relate to a real-world scenario where Things might represent parts that belong to an assembly line.   In the top left of the Home screen of Composer, click the + button.       In the dropdown list, click Thing Template.       For the Name field, enter LinePartTemplate. Select GenericThing as the Thing Template and select a Project (ie, PTCDefaultProject).       Click Properties and Alerts. Create a number Property named PartTemperature. Create a string Property named PartName.     Click Save. Now that you've saved the Template, you can create Things that inherit the properties PartTemperature and PartName. Create a couple new Things with LinePartTemplate as the Thing Template. For testing purposes, set a different value for the PartTemperature Property of each Thing. NOTE: When you run the Service later, you'll be able to see the different Things with values - some within a temperature threshold based on the conditions we set.   Using Service Call Setup   Code Snippets help shorten time to develop Services, but you are also provided with a way to call Services from an entity plus the default input parameters needed to make the call.   In the top left of the Home screen of Composer, click the + button.       In the dropdown list, click Thing.       For the Name field, enter LineCheckSystem. Select GenericThing as the Thing Template and select a Project (ie, PTCDefaultProject).     Switch to the Services tab. Create a Service called ListHotLineParts. Switch to the Me/Entities tab.   Select the Other entity radio option. Enter LinePartTemplate into the search field and select it when it pops up.   Expand the Services section.  Enter GetImplementingThingsWithData into the search field and select the arrow next to it.   You should now see a Snippet of JavaScript inserted into the Service code window. The GetImplementingThingsWithData Service is used to get all the Things with a specific Thing Template as it's base template. The return of this call will provide you with an InfoTable of all the Things you created on your own in the last section. Refer to LineTemplateThing1 in the completed download for an example.     Using Code Snippets   Lets's update the Snippet inserted in the last section.   Update the variable name from result to partsList. Switch to the Snippets tab of the Service. In the search bar, enter/filter Infotable for loop. Expand the Info Table section and click the arrow next to Infotable for loop.   All places where yourInfotableHere is located, replace it with the name of your list, partsList.   Click Done. Click Save.   At this point, you have created a loop that will iterate through the set of Things created with LinePartTemplate set as the Thing Template.   Since the JavaScript snippets were provided and all you had to do was update the variable names, now you must retrieve the input from the user on what the temperature threshold will be. This will be handled in the next section.     Build Return Value List   You can set the threshold to what is considered a "Hot" part in two different ways. Use a static value in order to keep things standardized OR create an input variable to make things more flexible. In the steps below, we are adding an input variable to finish off our Service.   Go to the Inputs tab of the Service. Add an input parameter called TemperatureThreshold that is a Number. Keep the other settings clear. Go to the Outputs tab, select INFOTABLE in the dropdown.  In the Data Shape search field, use the + New Data Shape sign to create a new DataShape. An example is shown below. I’ve named this Data Shape LinePartDataShape. Switch to the Snippets tab of the Service. In the JavaScript code, put your cursor on a new line before the for loop (ie, line 1). In the search bar, filter for Create Infotable from datashape and select it in the Infotable section by clicking the arrow next to it. Select the newly created LinePartDataShape DataShape when a popup appears and click Insert Code Snippet. You will see the newly inserted snippet that creates an Info Table from our new Data Shape.   Add a check inside of the for loop for the PartTemperature of the current item in the list of parts. if(row.PartTemperature > TemperatureThreshold){ } Move the cursor inside of the condition we just added. In the search bar, filter and select Create infotable entry from datashape in the Info Table section by clicking the arrow next to it. Select the newly created LinePartDataShape Data Shape when a popup appears and click Insert Code Snippet. You will see the newly inserted snippet that creates an entry for the Info Table. Update the inserted code snippet to assign the new entry values to that of a row in the Info Table. After updating the with code below, ensure to keep your cursor inside the conditional on a new line. var newEntry = new Object(); newEntry.PartName = row.PartName; // STRING newEntry.PartTemperature = row.PartTemperature; // NUMBER Your entire code thus far should match the following: var params = { infoTableName : "InfoTable", dataShapeName : "LinePartDataShape" }; // CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(LinePartDataShape) var result = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape(params); // result: INFOTABLE dataShape: "RootEntityList" var partsList = ThingTemplates["LinePartTemplate"].GetImplementingThingsWithData(); var tableLength = partsList.rows.length; for (var x=0; x < tableLength; x++) { var row = partsList.rows[x]; if(row.PartTemperature > TemperatureThreshold){ var newEntry = new Object(); newEntry.PartName = row.PartName; // STRING [Primary Key] newEntry.PartTemperature = row.PartTemperature; // NUMBER } } In the search bar, filter and select AddRow by clicking the blue arrow next to it. Update the inserted code snippet to add the newEntry object to the result Info Table created earlier. result.AddRow(newEntry); Save your work. You now have a fully-functional Service that you were able to create faster because of code snippets and pre-loaded Services. See the below to confirm your code matches up after removing some commented lines. Click here to view Part 2 of this guide.
View full tip
  Step 5: Widget Properties   You can configure Properties to change the style of the map as well as specify a custom image to use for map markers. Other Properties allow two linear paths and polynomial regions to also be displayed on the map Widget with optional tooltip data.   Bindable   Name Type  Default Direction  Description Data Infotable None Input Source for the data that is displayed as discrete markers LocationField MenuName None Input Field that contains Location type data to plot markers MarkerField MenuName None Input Field that contains data of type Image used to plot markers ShowMarkerTooltip Boolean True Input Hovering over map markers will display a tooltip when set to true ToolTipField1 thru 4 MenuName None Input Optional field displayed in tooltip when the user hovers over a map marker ToolTipLabel1 thru 4 String None Input Optional label for tooltip data RouteData Infotable None Input Source for the data that is displayed as a connected route RouteLocationField MenuName None Input Field that contains Location type data to plot connected route line ShowRoute Boolean False Input Show route data on map when set to true PlannedRouteData Infotable None Input Source for the data that is displayed as a second connected route PlannedRouteLocationField MenuName None Input Field that contains Location type data to plot a second connected route line ShowPlannedRoute Boolean False Input Show planned route data on map when set to true RegionData Infotable None Input Source for the data that is displayed as a region RegionLocationData Infotable None Input Region location data source RegionLocationsField MenuName None Input Field which will provide location table information for region RegionLayerField MenuName None Input Field that contains Numeric data used for region layer number ShowRegions Boolean False Input Show region data on map when set to true ShowRegionTooltips Boolean True Input Hovering over region will display a tooltip when set to true RegionToolTipField1 thru 4 MenuName None Input Optional field displayed in tooltip when the user hovers over a region RegionToolTipLael1 thru 4 String None Input Optional label for region tooltip data RegionFillOpacity Number 1 Input Opacity of region fill color from 0 being transparent to 1 being opaque SelectedLocation Location None Input/Output The currently selected location CurrentZoom Number 8 Output The currently displayed zoom level ( 1 - 15 ) Zoom Number 8 Input Number used to set the zoom level ( 1 - 15 ) ShowMarkers Boolean True Input Shows map markers if set to true ShowPathMarkers Boolean True Input Shows map markers if set to true ShowTraffic Boolean False Input Shows traffic data color overlay on map if set to true NEBoundary Location None Output The northeast boundary location NWBoundary Location None Output The northwest boundary location SEBoundary Location None Output The southeast boundary location NWBoundary Location None Output The southwest boundary location Visible Boolean True Input Widget is visible if set to true     Static   Name Type  Default Description DisplayName String None Name used for widget in user facing interactions Description String None Description used for widget in user facing interactions MapType Roads/Satellite/Hybrid/Terrain Roads The type of map content displayed MapSkin Normal/Blue/Grey Normal Options for styling maps monochromatically AutoZoomBehavior Data change/Initial Data only Data Change Controls when map will automatically zoom to show all markers ClusterLocations Boolean False Combines multiple location markers that are near one another into a single marker if true MultiSelect Boolean False Enable multiple marker selection   Widget Events   DoubleClicked- Triggered when user double clicks on the Google Map. Changed- Triggered when the data for this widget is modified. BoundsChanged- Triggered when the bounding box of the displayed map changes.     Step 6: Next Steps   If you have questions, issues, or need additional information, refer to:   Resource     Link Community Developer Community Forum Support Google Map Widget Help Center Free Google Maps Widget Extension IQNOX  
View full tip
  Add a Google Map to your UI that visually presents geographical data.   GUIDE CONCEPT This project will introduce how to visually present geographical data in your application. Showing data on a map is a valuable feature for IoT application.   Following the steps in this guide, you will utilize the Google Maps Widget and explore it’s ability to show multiple Things.   We will teach you how to use Geological data to convey pertinent information in your UI.   YOU'LL LEARN HOW TO   Download and import the Google Maps Widget extension Create a Mashup and add a Google Maps Widget Configure the Google Maps Widget to display the locations of multiple Things   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: Configure Google Maps Widget   When you download the Google Maps Widget, it does not include an API key. Google allows some limited use of their map API without a key, however it is recommended that you obtain and add your own Google Maps API key or Client ID (for Google Maps API for Work licenses) to the Google Maps Widget.   The ThingWorx hosted server has already been configured with the Google Maps Widget, including an API key for evaluation use.   Refer to the Google Maps API documentation to obtain your own API key, then follow the steps below.   Download the Google Maps widget from PTC Partner, IQNOX NOTE:  It is necessary to create an account on IQNOX, but the download is free       2. In the lower-left side of Composer, click Import/Export, then Import.           3. In the Import From File pop-up, under Import Option select Extension from the drop-down, then click Browse        4. Navigate to the .zip file you downloaded.          5. Click Import in the Import From File pop-up, then click Close after file is successfully imported.        6. In the ThingWorx Browse tab, in the System section, click on Subsystems, then PlatformSubsystem.            7. Click on the Configuration tab, then click the Edit button if you are not already in edit mode.        8. Scroll down to the Required string to connect with Google for Google widgets field where you enter the Google Maps JavaScript URL with your API key: https://maps.googleapis.com/maps/api/js?key=<Your API key>            9. Click Save     Step 2: Add Google Maps Widget to Mashup   Click the Browse folder icon on the top left of ThingWorx Composer.       2. Select Mashups in the left-hand navigation, then click + New to create a new Mashup.                          3. For Mashup Type select Responsive.               NOTE: A Responsive Mashup scales with a browser's screen size. In the steps below we will create 5 containers, one for each widget, to organize how the widgets are presented.        4. Click OK.        5. Enter a name for your Mashup.        6. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject.        7. Click Save        8. Select the Design tab to display Mashup Builder.        9. Click the Widget tab on the top-left, then enter map inside the Filter Widgets field.        10. Drag-and-drop the Google Map widget onto the Mashup.         Step 3: Download Sample Entities   We have created a file with sample entities for this exercise.   Download demoTractors.xml to your computer.       2. Click Import/Export in the lower left of Composer, then select Import          3. Click From File in the drop down, then Browse.        4. Browse to the demoTractors.xml file and click Open.        5. Click Import, then Close after entities are successfully imported.     Step 4: Add Markers to Google Maps Widgets   To display markers on the map you must bind an Info Table to the Widget's Data Property and specify which column has location information. In this example we will use the QueryImplementingThingsWithData Service to bind a group of Things created with the same Template.   Click the + button in the Data tab on the right side of the Mashup Builder window             2. In the Add Data pop-up, click Thing Templates from the Entity Type drop down.                3. Select a Template from the list that has a Location property and was used to create Things. For this exercise, use the ConnectedTractor Template that was imported from the sample file downloaded in the prior step.            4. Enter query into the filter text box then click the arrow to the right of QueryImplementingThingsWithData.                                              5. Click the Execute on Load check box, then click Done. This will cause the QueryImplementingThingsWithData Service to execute as soon as Mashup is loaded.                                          6. Expand Returned Data if you do not see All Data then click and drag All Data onto the Google Maps Widget.        7. Click Data in the Select Binding Target pop-up.          8. In the Properties panel in the lower left, scroll to see the LocationField property and select Location, the name of the Property with location information.       Test Map Operation   Click Save to save your Mashup.       2. Click View Mashup to see the Google Maps Widget displaying the locations of each Thing.     NOTE: The Google Maps Widget has built-in functionality that allows users to pan and resize the map as well as switch to satellite photo maps.     Click here to view Part 2 of this Guide.
View full tip
  Step 8: Troubleshooting   Issue                                       Resolution CSS does not seem to be applied to the Mashup. Verify your CSS is included in the runtime TWX CSS. Clear Browser cache if your CSS is not merged to the combined TWX CSS. (under debug mode: Hold refresh button->Clear Cache). TWX fails to import the extension. If the extension is already installed, but you made recent changes, you need to bump the Version number in the metadata.xml. Recent CSS changes are ignored. Clear browser cache if your CSS file has changed recently.     Step 9: Next Steps   Congratulations! You've successfully completed the Add Style to Your UI with CSS guide, and learned how to:   Create custom CSS classes using the integrated CSS editor Bind CSS classes to a Mashup and to individual Widgets Use Media queries to dynamically apply styling   Learn More   We recommend the following resources to continue your learning experience:    Capability     Guide Build Application Development Tips & Tricks Experience ThingWorx Application Development Reference   Additional Resources   If you have questions, issues, or need additional information, refer to:  Resource       Link Community Developer Community Forum Support Help Center
View full tip
    Step 12: Connect to Temperature Sensor   This step is optional. Additional instructions are provided for developers who are interested in interfacing with sensors.   The DHT11 and DHT22 digital temperature and humidity sensors are inexpensive and available from several sources: Adafruit Sparkfun SeeedStudio The Raspberry Pi does not come with any built-in analog to digital conversion capability and because these sensors are digital they can be interfaced easily with a Raspberry Pi. We will be using a Python library developed by Adafruit that simplifies interfacing with these sensors.   Install Adafruit Python Library for Sensors   We will use Git to download the Adafruit DHT11 Python from GitHub. Check if Git is already installed by opening a command window and typing the command: git If you see a "command not found" error message use this command to install Git: sudo apt-get install git-core If you get an error installing Git, run the command: sudo apt-get update then try to install Git again. Change into the EMS directory: cd microserver Download the Adafruit library with this command: git clone https://github.com/adafruit/Adafruit_Python_DHT.git Change into the directory that was just downloaded: cd Adafruit_Python_DHT Install Python build libraries: sudo apt-get install build-essential python-dev Build and install the library with this command: sudo python setup.py install   Connect Sensor to Raspberry Pi Power down the Raspberry Pi before making any wire connections. To prevent any flash memory corruption, enter the command shutdown -h now then wait a few seconds for it to complete before disconnecting the power supply. Use female-to-female jumper wires to connect the sensor as shown below. The black wire is connected to ground, the red wire is 5v or VCC, and the yellow wire carries is the digital signal. WARNING: Double check your connections before applying power. Mistakes can destroy the sensor and the Raspberry Pi!   3. Apply power and boot the Raspberry Pi. 4. Change into the EMS directory:   cd microserver 5. Test the sensor with this commmand:   ./Adafruit_Python_DHT/examples/AdafruitDHT.py 11 4   In a few a seconds the current temperature and humidity will be displayed. Change the 11 parameter to 22 if you are using the DHT22 sensor. The 4 parameter is the GPIO pin number of the Raspberry Pi that is conneCted to the sensor's signal pin. This command is the same command the luaScriptResource will use to get temperature and humidity readings.   Modify Lua template file A dozen lines need to be added to the file PiTemplate.lua file in the /microserver/etc/custom/templates directory.   After the line: properties.cpu_volt = { baseType="NUMBER", pushType="ALWAYS", value=0 } Add the two lines: properties.temp = { baseType="NUMBER", pushType="ALWAYS", value=0 } properties.humidity = { baseType="NUMBER", pushType="ALWAYS", value=0 } After the line: local voltCmd = io.popen("vcgencmd measure_volts core") Add the line: local sensorCmd = io.popen("./Adafruit_Python_DHT/examples/AdafruitDHT.py 11 4") After the line: properties.cpu_volt.value = s Add these 9 lines: -- set property temp and humidity local sensor = sensorCmd:read("*a") log.debug("[PiTemplate]",string.format("raw sensor %s", sensor)) s = string.match(sensor,"Temp=(%d+\.%d+)"); log.debug("[PiTemplate]",string.format("scaled temp %.1f", s)) properties.temp.value = s s = string.match(sensor,"Humidity=(%d+\.%d+)"); log.debug("[PiTemplate]",string.format("scaled humidity %.1f", s)) properties.humidity.value = s Stop and then restart luaScriptResource by using the following commands. ps -efl Will list all running processes, note the number in the PID column for ./lusScriptResource kill -9 PID# Replace PID# with number noted above and the process will be ended. Run LuaScriptResource by executing the following command: sudo ./luaScriptResource   Update Properties of PiThing   Log onto ThingWorx Foundation server. Click on the Home icon in Composer then broswse to Things > PiThing > Properties and click Manage Bindings button.   Click on the Remote tab, then drag and drop the temp and humidity Properties one at a time to the green plus sign next to Create new Properties. Click Done to close the binding window, then click Save. NOTE: The temp and humidity Properties will be updated every 30 seconds.     Step 13: Next Steps   Congratulations! You've successfully completed the Connect Raspberry Pi to ThingWorx guide, and learned how to:   Set up Raspberry Pi Install, configure and launch the EMS Connect a remote device to ThingWorx   Learn More   We recommend the following resources to continue your learning experience:   Capability Guide Manage Data Model Introduction Build Get Started with ThingWorx for IoT   Additional Resources   If you have questions, issues, or need additional information, refer to:   Resource Link Community Developer Community Forum Support Edge SDKs and WebSocket-based Edge MicroServer (WS EMS) Help Center External Raspberry Pi Documentation  
View full tip
  Step 8: Configure Template File (Service)   Services are implemented as Lua functions. In our Lua script, Services are divided into two pieces. The first is the Service definition which consists of a Service name, inputs and output. The second part of defining a Service is the service code. The Service code is run when you execute the service.   Create Service Definition Open the PiTemplate.lua file. Append the service definition to the file. Create a service named GetSystemProperties that gets the system properties (cpu temperature, clock frequencies, voltages) from your Raspberry Pi and updates the respective properties on the Thingworx platform. Specify your output type but not the name because the name of every output from a ThingWorx service is always result. serviceDefinitions.GetSystemProperties( output { baseType="BOOLEAN", description="" }, description { "updates properties" } ) NOTE: This service has no input parameters and an output that results in True if the properties were successfully updated on Thingworx.   Create Service code The Service code is run when you execute the Service. Functions in Lua are variables therefore to define the Service code, you will create a variable. The name of the Service has to match the name you specified in the Service definition.   Copy the service code below with comments explaining the logic and add append it to your template file, or download and unzip the full PiTemplate.zip attached here. services.GetSystemProperties = function(me, headers, query, data) log.trace("[PiTemplate]","########### in GetSystemProperties#############") queryHardware() -- if properties are successfully updated, return HTTP 200 code with a true service return value return 200, true end function queryHardware() -- use the vcgencmd shell command to get raspberry pi system values and assign to variables -- measure_temp returns value in Celsius -- measure_clock arm returns value in Hertz -- measure_volts returns balue in Volts local tempCmd = io.popen("vcgencmd measure_temp") local freqCmd = io.popen("vcgencmd measure_clock arm") local voltCmd = io.popen("vcgencmd measure_volts core") -- set property temperature local s = tempCmd:read("*a") s = string.match(s,"temp=(%d+\.%d+)"); log.debug("[PiTemplate]",string.format("temp %.1f",s)) properties.cpu_temperature.value = s -- set property frequency s = freqCmd:read("*a") log.debug("[PiTemplate]",string.format("raw freq %s",s)) s = string.match(s,"frequency%(..%)=(%d+)"); s = s/1000000 log.debug("[PiTemplate]",string.format("scaled freq %d",s)) properties.cpu_freq.value = s -- set property volts s = voltCmd:read("*a") log.debug("[PiTemplate]",string.format("raw volts %s", s)) s = string.match(s,"volt=(%d+\.%d+)"); log.debug("[PiTemplate]",string.format("scaled volts %.1f", s)) properties.cpu_volt.value = s end tasks.refreshProperties = function(me) log.trace("[PiTemplate]","~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In tasks.refreshProperties~~~~~~~~~~~~~ ") queryHardware() end Save the PiTemplate.lua file. cntrl x     Step 9: Run LSR   1. Navigate from installation directory to microserver directory. cd microserver 2. Ensure that wsems is running in a separate terminal session before you start running LuaScriptResource. 3. Ensure that you have ownership to the executable luaScriptResource and executable privileges. To check ownership: Ls -la -rwxrwxr-x 1 pi pi 769058 Jun 9 17:46 luaScriptResourc NOTE: The owner of luaScriptResource should be the user you are logged in as on the Raspberry Pi.   4. Confirm you have executable privileges by running the following command: sudo chmod 775 luaScriptResource 5. Run LuaScriptResource by executing the following command: sudo ./luaScriptResource   6. The output will show an error until we create the corresponding Thing in the next step.     Step 10: Bind Remote Thing Properties   Now we need to register a Thing so your Raspberry Pi can bind to its Properties on the Thingworx Platform.   Create a Thing named PiThing that will bind the scripts.PiThing created in config.lua . Open your Composer screen. Click Things on the left-navigation and the + symbol. Enter PiThing in the Name field and click RemoteThing in the Thing Template field.   Click Save. Ensure that the Remote Thing Property is connected. Click Properties in the left-hand navigation. Verify that the isConnected Property has a value of true. This means that your Raspberry Pi is still connected and now bound to this Thing on Thingworx Platform.   Bind the remote Thing Properties. Make sure the Properties tab is selected and click Edit at the top of the PiThing. Click Manage Bindings. Select the Remote tab at the top.   Click Add All Above Properties or drag and drop the ones you need. Click Done. Click Save. Verify that the Properties were updated with readings from the Raspberry Pi. Both the Value and Default Value for the three Properties will be set to the current reading from the Raspberry Pi. Cover the Raspberry Pi and wait about a minute, then Select the Properties tab and click Refresh. You will see the cpu_temperature value change.     NOTE: The system properties from your Raspberry Pi are now being passed to the server every 30 seconds. Wait a couple of cycles to see if the values from the Raspberry Pi change. If you are impatient, manually change the value of the property using the Set button in the Composer then click Refresh to see the updated value. The value will be temporarily updated for about 30 seconds until the Raspberry Pi reports the current live value.   Troubleshooting Tips   Tip #1 If the properties are not updating, try to stop and start both the wsems and luaScriptResource services.   quit sudo ./wsems or ./luaScriptResource Tip #2 If a wsems and/or luaScriptResource is not shut down gracefully, sometimes the service is still running which can cause issues. You can search and kill any wsems/luaScriptResource services by using the following command. Re-run the GetSystemProperties to test if this fixed the issue.   ps -efl kill -9 <id#>   Step 11: View Data from Devices   In order to demonstrate how ThingWorx can render a visualization of data from connected devices, at this point in the lesson you will import a pre-configured Mashup.   On the ThingWorx server that the EMS is connected to, start on the Home tab of Composer. Import a pre-built Mashup. Download and save the pre-built Mashup XML file attached here: Mashups_PiThingMashup-v91.xml. In Composer, click the Import/Export drop-down at the bottom-left.   Click Import. Leave all default values and click Browse to select the Mashups_PiThingMashup-v91.xml file that you just downloaded. Click Open, then Import, and once you see the success message, click Close. View Mashup displaying live data. Select the home icon in the top left side of Composer, then click Mashups on the left-navigation panel. Click Mashups_PiThingMashup-v91 and you'll see the design view of the Mashup.   Click View Mashup, and you'll see the live Mashup.    TIP: You will need to allow pop-ups in your browser for the Mashup to be displayed.     Click here to view Part 4 of this guide. 
View full tip
  Step 4: Install and Configure   Before you install the plugin, ensure that software requirements are met for proper installation of the plugin.   Open The Eclipse IDE and choose a suitable directory as a workspace. Go to the menu bar of the Eclipse window and select Help->Install New Software… After the Install window opens, click Add to add the Eclipse Plugin repository. Click Archive… and browse to the directory where the Eclipse Plugin zip file is stored and click Open. NOTE: Do not extract this zip file. Enter a name (for example, Eclipse Plugin).   Click OK. Ensure that the Group items by category checkbox is not selected. Select ThingWorx Extension Builder in the items list of the Install window. Click Next and the items to be installed are listed. Click Next and review the license agreement. Accept the license agreement and click Finish to complete the installation process. If a warning for unsigned content is displayed, click OK to complete the installation process. Restart Eclipse. When Eclipse starts again, ensure that you are in the ThingWorx Extension perspective. If not, select Window->Perspective->Open Perspective->Other->ThingWorx Extension, then click OK.     NOTE: Opening any item from File->New->Other…->ThingWorx will also change the perspective to ThingWorx Extension.   You are ready to start a ThingWorx Extension Project!   Step 5: Create Extension Project   In this tutorial, you will create a ThingWorx extension that performs authentication based on your security needs.   While in the ThingWorx Extension Perspective, go to File->New->Project. Click ThingWorx->ThingWorx Extension Project.   Click Next. Enter the Project Name (for example, AuthenticatorExample). Select Gradle or Ant as your build framework. Enter the SDK location by browsing to the directory where the Extension SDK is stored. Enter the Vendor information (for example, ThingWorx Labs). Select the JRE version to 1.8. Click Finish. Your newly created project is added to the Package Explorer tab. The information from ThingWorx Extension Properties is used to populate the metadata.xml file in your project. The metadata.xml file contains information about the extension and details for the various artifacts within the extension. The information in this file is used in the import process in ThingWorx to create and initialize the entities.   Create New Authenticator   Select your project and click New -> Authenticator to create a new Authenticator.   In the new window, enter AwesomeCustomAuthenticator for the Name.   If no Server is available, create a Server using any available option. You will not need that for this guide. This Server option might be utilized based on your later needs. Enter a description to your Authenticator, such as Sample Authenticator that validates against the Thingworx User. Select Finish. You will be able to check these settings within the metadata.xml file inside of the configfiles  directory.   You will now need to add the stubs for the authenticate, issueAuthenticationChallenge, and matchesAuthRequest methods. See below for sample code and descriptions.   Method Description Constructor Needed to instantiate new objects of type AwesomeCustomAuthenticator. Instance member data/variable values in your Authenticator will not be available across requests. initializeEntity This method is called when the Authenticator Thing is saved in ThingWorx Composer, e.g. saving configuration table updates. authenticate The logic/implementation that is used to authenticate a HTTP request. issueAuthenticationChallenge Handles logic which follows authentication failure (e.g. logging an error). matchesAuthRequest This method determines if this Authenticator is valid for the authentication request type.   Below provides more information about each of these methods and some example source code:   Constructor:   A new instance of custom Authenticator class is created to handle each new HTTP request for authentication. Upon importing a custom Authenticator extension, that Authenticator is registered into AuthenticatorManager and can be managed in the ThingWorx Composer with the other system authenticators. When that custom Authenticator is enabled, it will be used in conjunction with the other configured Authenticators to attempt to authenticate HTTP requests. Any static data for each new authentication instance should be thread safe. Best to avoid putting very much logic here, even calls to get configuration or instance data (use authenticate method instead).   initializeEntity:   Read configuration data into properties as needed for Authenticator challenges. Write the LDAP server address to some static property for use across all future instances for use in Authenticator challenges. This would be a way to ensure the LDAP server location is configurable from within ThingWorx Composer. Best to update this only once (e.g. for when the first connection is made).   authenticate:   If the authentication logic/implementation fails to authenticate the HTTP request due to error in the logic or the HTTP request contained invalid data that does not pass authentication, then this implementation should throw an exception.   Example code below:   @Override public void authenticate(HttpServletRequest request, HttpServletResponse response) throws AuthenticatorException { String username = request.getHeader("User"), password = request.getHeader("Password"); if(username.isEmpty() || password.isEmpty()) throw new AuthenticatorException("User login info is empty"); try { // This section logs the latest login time and login user to a thing called MyThing // Subscribing to these properties via DataChange event will allow this information to be stored Thing LoginHelper = (Thing) EntityUtilities.findEntity("MyThing", ThingworxRelationshipTypes.Thing); LoginHelper.setPropertyValue("LatestLoginUser", new StringPrimitive(username)); LoginHelper.setPropertyValue("LatestLoginTime", new DatetimePrimitive(DateTime.now())); _logger.warn(DateTime.now() + " -- " + username + " login attempt"); // Checks that user exists and is enabled; throws exception if can't validate // May want to create user in ThingWorx if they don't exist AuthenticationUtilities.validateEnabledThingworxUser(username); // Checks that user exists and validates credentials through all configured DirectoryServices // (one is the internal directory of ThingWorx users, one could be LDAP if configured); // throws exception if can't validate AuthenticationUtilities.validateCredentials(username, password); // REQUIRED: tells rest of ThingWorx which user is logged in for purposes of permissions, etc. this.setCredentials(username); } }   issueAuthenticationChallenge:   This may not be used at all, or it may be used for alerting or logging. May be used for constructing and sending a response to the client so the client can ask the user to enter credentials again (i.e. authentication challenge). matchesAuthRequest:   Example code below. This sample code for Authenticator to automatically login the user with default username/password when specific URI used in web browser.   @Override public boolean matchesAuthRequest(HttpServletRequest httpRequest) throws AuthenticatorException { String requestURI = httpRequest.getRequestURI(); // Must access it from this URL and not from /Thingworx/Runtime/index.html#mashup=LogoutButtonMashup as // the Request URI in the latter case is always going to show as /Thingworx/Runtime/index.html if (requestURI.equals("/Thingworx/Mashups/LogoutButtonMashup")) return true; else return false; }   Below is another example of how to implement the matchesAuthRequest method. Of course, it’s not a safe method. Nevertheless, it provides input into a different way to handle things.   @Override public boolean matchesAuthRequest(HttpServletRequest request) throws AuthenticatorException { try { // DON'T DO THIS by itself -- getHeader returns null if it can't find the header, // so this is unsafe and may block other authenticators from attempting String value1 = request.getHeader("User"); String value2 = request.getHeader("Password"); // DO ADD THIS - this is safe // Optionally add some logging statement here to inform of missing headers if(value1 == null || value2 == null) return false; return true; } catch(Exception e) { // This won't normally hit. This is really for other, more complicated validation processes throw new AuthenticatorException("Missing headers"); } }   Step 6: Build Extension   You can use either Gradle or Ant to build your ThingWorx Extension 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. This will build the project and any error will be indicated in the console window.   Your console window will display BUILD SUCCESSFUL. This means that your extension is created and stored as a zip file in your_project->build->distributions folder.   Build Extension with Ant   Go to the Package explorer -> your_project->. Right click on build-extension.xml->Run As->Ant Build.   Your console output will indicate BUILD SUCCESSFUL similar to the below text: build: [echo] Building AuthenticatorExample extension package... BUILD SUCCESSFUL Total time: 770 milliseconds   NOTE: This will build your project and create the extension zip in the AuthenticatorExample->build->distributions folder of your project.     Click here to view Part 3 of this guide.  
View full tip
    Step 4: Create Extension Project   In this tutorial, you will create a ThingWorx extension that retrieves weather information using OpenWeatherMap API. Create Account In this part of the lesson, you will create a free account in OpenWeatherMap that creates an AppKey so you can access their REST API. Sign-up for a free account. Log in to your account. Create a new API Key   NOTE: We will use this generated API key as a parameter in the REST calls.   Create New Extension Project   NOTE: Make sure that you are in the ThingWorx Extension Perspective. To verify, you should see a plus icon:   in the menu bar. If you don’t see this, you are probably in the wrong perspective. Go back to the previous step to learn how to set the perspective to ThingWorx Extension in Eclipse.   Go to File->New->Project. Click ThingWorx->ThingWorx Extension Project.  Click Next. NOTE: A New ThingWorx Extension window will appear. Enter the Project Name (for example, MyThingworxWeatherExtension). Select Gradle or Ant as your build framework. Enter the SDK location by browsing to the directory where the Extension SDK is storeed.   NOTE: The Eclipse Plugin accepts the Extension SDK version 6.6 or higher. Enter the Vendor information (for example, ThingWorx Labs). Change the default package version from 1.0.0 to support extension dependency. NOTE: The information from ThingWorx Extension Properties is used to populate the metadata.xml file in your project. The metadata.xml file contains information about the extension and details for the various artifacts within the extension. The information in this file is used in the import process in ThingWorx to create and initialize the entities. Select the JRE version to 1.8. Click Next then click Finish. Your newly created project is added to the Package Explorer tab.   Create New Entity   Select your project and click Add to create a new entity. NOTE: You can also access this from the ThingWorx menu on the menu bar. Create a Thing Template for your MyThingWorxWeatherExtension Project.   NOTE: In this guide, we are using a Template, but in a real-world scenario, you may consider using a Thing Shape to encapsulate extension functionality. By using Thing Shapes you give users of your extension the ability to easily add new functionality to existing Things. It is simple to add a new Thing Shape to an existing Thing Template, while using the properties or services defined by a Thing Template would require recreating all existing assets using the new Template. Since subscriptions cannot be created on Thing Shapes, you might choose to create Thing Templates that implement one or more subscriptions for convenience. In the pop-up window, browse to add the source folder of your project in Source Folder. NOTE: It should default to the src directory of your project. In our case it will be MyThingworxWeatherExtension/src. Browse to add the package where you want to create this new class, or simply give it a name (such as com.thingworx.weather). Enter a name and description to your Thing Template (WeatherThingTemplate).  NOTE: By default, the Base Thing Template is set to GenericThing. Select Next. NOTE: If you want to give other users of this entity permission to edit it in ThingWorx Composer, select the entity as an editable entity. Only non-editable entities can be upgraded in place; editable entities must be deleted and recreated when your extension is updated. If you need to make it possible to customize the extension, consider using a configuration table to save user customizations. Select Finish.   Verify that you have a WeatherThingTemplate class created that extends the Thing class. @ThingworxBaseTemplateDefinition(name = "GenericThing") public class WeatherThingTemplate extends Thing { public WeatherThingTemplate() { // TODO Auto-generated constructor stub } } NOTE: You might see a warning to add a serial version. You can add a default or generated serial value.   Step 5: Add Properties    In this section, you are going to add CurrentCity, Temperature and WeatherDescription properties to the WeatherThingTemplate. These properties are associated with the Thing Template and add the @ThingworxPropertyDefinitions annotation before the class definition in the code.   Right click inside the WeatherThingTemplate class or right click on the WeatherThingTemplate class from the Package Explorer. Select ThingWorx Source-> Add Property. In the popup window, create a property to store the city name. Name = CurrentCity, Base Type = STRING, Description = ‘’ Select the Has Default Value checkbox and enter a city name (eg. Boston). This will be the default value unless a specific value is passed. Select the “Persistent” checkbox. This will maintain the property value if a system restart occurs. NOTE: If you select the Logged checkbox, the property value is logged to a data store. If you select the Read Only checkbox, the data will be static. Select VALUE from the Data Change Type drop down menu       NOTE: This allows any Thing in the system to subscribe to a data change event for this property. Choose to use one of the following Data Change Types:   Data Change Type Description Always Fires the event to subscribers for any property value change Never Does not fire a change event On For most values, any change will trigger this. Off Fires the event if the new value is false Value For numbers, if the new value has changed by more than the threshold value, fire the change event. For non-numbers, this setting behaves the same as Always. Select Finish. Create another property called Temperature with a base type of NUMBER. You can keep the default values for the other parameters. Create another property called WeatherDescription with a base type of STRING. Keep the default values for the other parameters.   Step 6: Create Configuration Table   In this part of the lesson, we will create a configuration table to store the API Id that you generated from the openMapsWeather. Configuration tables are used for Thing Templates to store values similar to properties that do not change often.   Right-click inside the WeatherThingTemplate class and select ThingWorx Source->Add Configuration Table. Create a new configuration table with name OpenWeatherMapConfigurationTable. Click Add in the Data Shape Field Definitions frame. NOTE: Configuration tables require fields (columns) with a defined table structure (DataShape). Enter appid as the name with a base type STRING. Select the Required checkbox. Click OK, then Finish to add the Configuration Table To use the appid in the REST calls, you need to obtain the value from the configuration table and assign it to a field variable in the Java code. We will use the initializeThing method to obtain the appid value at runtime. NOTE: The initializeThing() method acts as an initialization hook for the Thing. Every time a Thing is created or modified, this method is executed and the value of appid is obtained from the configuration table and stored in a global field variable of the class. initializeThing() must call super.initializeThing() to ensure it performs initialization of the Thing. Create the initializeThing() method and field variable _appid with base type STRING anywhere in the WeatherThingTemplate class. private static Logger _logger = LogUtilities.getInstance().getApplicationLogger(WeatherThingTemplate.class); private String _appid; @Override public void initializeThing() throws Exception { super.initializeThing(); _appid = (String) this.getConfigurationSetting("OpenWeatherMapConfigurationTable", "appid"); } NOTE: In the code above we used ThingWorx LogUtilities to get a reference to the ThingWorx logging system, then assigned the reference to the variable _logger. In the steps below we will use this variable to log information. There are multiple kinds of loggers and log levels used in the ThingWorx Platform, but we recommend that you use the application or script loggers for logging anything from inside extension services. If prompted to import the logger, use slf4j.     Click here to view Part 3 of this guide.
View full tip
    Step 9: Create Event and Subscription   In this section, you will create a mechanism to notify the user when inclement weather occurs. For example, whenever the weather indicates storm/snow/rain, an Event should be triggered. This event is then handled by a service called a Subscription.   For this tutorial, while updating weather information inside the service UpdateWeatherInfo,we need to fire an Event: BadWeather when the weather description indicates either storm/snow/rain. This Event is handled by a Subscription: HandleWeather, which is a service that gets called whenever the BadWeather Event is fired. The subscription service HandleWeather updates a property called AlertNotification.   Create Event   In this part of the lesson, we will create an Event: BadWeather that updates weather information inside the service UpdateWeatherInfo when the weather description indicates either storm/snow/rain.   Create a property AlertNotification with a baseType STRING using the Add Property feature of the plugin we discussed before. Right click inside your java file->ThingWorx Source->Add Event.   Set the name to BadWeather and set a name for the Data Shape to Weather. NOTE: This custom Data Shape has to be created in Composer. Importing Datashapes and other custom entities created in Composer into your extension will be discussed later in the tutorial. Our DataShape Weather includes one field called WeatherDescription with a STRING base type.  Click Finish. NOTE: This will create annotation for your EventDefinition.    Create Subscription   In this part of the lesson, we will create a Subscription: HandleWeather, which is a service that gets called whenever the BadWeather Event is fired. The subscription service HandleWeather updates a property called AlertNotification. Right click inside your java file ->ThingWorx Source->Add Subscription   Set the Event Name to BadWeather and Handler Service to HandleWeather. NOTE: This means that whenever the BadWeather event is fired, the HandleWeather service will be executed. Source is left blank if the event belongs to the same template. Click Finish. This creates annotation for subscription service and also creates a new service called HandleWeather.   Modify Service   In this part of the lesson, you'll ensure that when the properties are updated, BadWeather event is triggered if the description indicates rain/snow/thunderstorm. To do this, we will modify the UpdateWeatherInfo service.   After we have called the setPropertyValue method for the properties WeatherDescription and Temperature, we can check if the weather description contains snow/rain/thunderstorm. We will create an InfoTable from the Weather Datashape. InfoTables represent data sets that take the structure of the Datashape. Each row of an InfoTable can be passed as a ValueCollection to hold data within the table. When an event is fired, we need to send data along with it. This data will be passed as an InfoTable and it is then handled by the Subscription handling the Event.We use a ValueCollection to add the weatherDescription to the InfoTable. Then, this InfoTable is set as the Event Data.   Add the code snippet to UpdateWeatherInfo section at the end of the service after setting the properties- Temperature and WeatherDescription. /* fire event BadWeather */ if (description.contains("snow") || description.contains("rain") || description.contains("thunderstorm")) { ValueCollection v = new ValueCollection(); v.put("weatherDescription", new StringPrimitive(description)); InfoTable data = InfoTableInstanceFactory.createInfoTableFromDataShape("Weather"); data.addRow(v); _logger.info("Firing event"); ThingworxEvent event = new ThingworxEvent(); event.setEventName("BadWeather"); event.setEventData(data); this.dispatchEvent(event); } Inside the HandleWeather service, set the property AlertNotification. Ensure that you have created the property AlertNotification using the eclipse plugin. Add the following code snippet to the HandleWeather service. @ThingworxServiceDefinition(name = "HandleWeather", description = "Subscription handler", category = "", isAllowOverride = false, aspects = {"isAsync:false"}) public void HandleWeather( @ThingworxServiceParameter(name = "eventData", description = "", baseType = "INFOTABLE") InfoTable eventData, @ThingworxServiceParameter(name = "eventName", description = "", baseType = "STRING") String eventName, @ThingworxServiceParameter(name = "eventTime", description = "", baseType = "DATETIME") DateTime eventTime, @ThingworxServiceParameter(name = "source", description = "", baseType = "STRING") String source, @ThingworxServiceParameter(name = "sourceProperty", description = "", baseType = "STRING") String sourceProperty) throws Exception { _logger.trace("Entering Service: HandleWeather with: Source: \"\", Event: \"BadWeather\", Property: \"\""); this.setPropertyValue("AlertNotification", new StringPrimitive("Alert:"+eventData.getFirstRow().getStringValue("weatherDescription"))); _logger.trace("Exiting Service: HandleWeather"); } Now we have an event BadWeather fired every time weather description indicates storm/snow/rain and it is handled by HandleWeather service that sets the AlertNotification property to the InfoTable data passed by the event.     Step 10: Add Composer Entities In previous parts of this tutorial, we assumed we had a datashape Weather available with field weatherDescription as the Datashape of our event: BadWeather. In this part of the lesson, we'll create a DataShape. Go to ThingWorx Composer. Click the + button. In the dropdown, select Data Shape. Enter a name, for example: Weather. Add a Field Definition weatherDescription with baseType STRING. Click check mark in the top left, then Save.   Click the More drop-down, then click Export. Export the DataShape entity from Composer, it will download in your system as an xml file. Go back to Eclipse, right-click on your project ->Import..->ThingWorx->Entities. Click Next. Browse to the directory where the xml file was downloaded. Select the xml file and Click Finish.   NOTE: This adds the xml file to the Entities folder in your project. Following the same procedure, import other entities required for this Extension stored in the Entities folder of the download we provided for this training.   NOTE: You can uncheck the box for importing DataShapes_Weather.xml, if you already loaded your Datashape in the previous steps.     Click here to view Part 5 of this guide.
View full tip
  Step 7: Add JAR Resources   You can add external JARs for use by your extension. Every third-party JAR that is not already included in either the ThingWorx Extension SDK or ThingWorx Core needs to be added to your extension project as a JAR Resource. These JAR resources are added to your metadata.xml as a tag and are used to reference the Java classes in the third-party JAR on which the extension depends. You can either use the Add button   or the ThingWorx Menu from the menu bar to add a new JAR resource. By doing so, the JAR is automatically updated in the metadata file and added to the build path. Although ThingWorx allows developers to include jar files for third-party libraries in their code, it is recommended that you avoid adding jar files for common libraries and instead use the jar files that are included with the SDK. Adding jar files to an extension could cause conflicts with jar files already used by the ThingWorx server, either when uploading an extension, or when an extension executes. Even if your extension works today, future updates to ThingWorx may require updates to your extensions. Similarly, packaging a verison of a commonly used library may mean that a customer will not be able to use your extension together with someone else’s extension.   Select the project to which you want to add the jar file to and select New Jar Resource.       Open the directory in which you have stored the training files for this tutorial. Browse to the Jars directory. Select the json-simple-1.1.1.jar file. Add a description and click Finish. NOTE: This will automatically add json-simple-1.1.1.jar to the lib folder and to your project’s build path. Add httpclient-4.5.6.jar, httpcore-4.4.10.jar and commons-logging-1.2.jar directly into the twx-lib folder in the Project folder. NOTE: These JARs are included in the group of JARs used by ThingWorx by default. In order to build your extension locally, without bundling the jars into your extension that are available on the ThingWorx server, add the above JARs to your project's build path by right-clicking on your project in the Package Explorer, right-click Your_Extension_Project (ie, MyThingWorxWeatherExtension) and select Build Path -> Configure Build Path. Verify the jars we added are in the build path. Otherwise, click Add JARs, then browse to the directory containing these JARs (lib) and add them. NOTE: twx-lib folder is a hidden folder and does not appear in the Eclipse package explorer. The twx-lib folder can be found in the WeatherExtension project inside the Eclipse workspace directory.   Step 8: Create Services   Now that you have created properties, configuration tables and added the required jars, you can begin to add services to your WeatherThingTemplate.   In this part of the lesson, we’ll add a service, UpdateWeatherInfo that will take a City parameter and update the properties of this template using the values obtained from the openWeatherMap API.   Right click inside the WeatherThingTemplate and select ThingWorx Source->Add Service. Create a new service with name UpdateWeatherInfo. Click Add in the Input Parameters frame to add City parameter with a base type STRING.   Set the name and base type of the Output Parameter based on the value that you want the service to return. For simplification, assume this service returns nothing. Set the Base Type to NOTHING. Click Finish to create the service. Copy and Paste the code for UpdateWeatherInfo as specified below. @ThingworxServiceDefinition(name = "UpdateWeatherInfo", description = "updates weather description and temperature properties", category = "", isAllowOverride = false, aspects = { "isAsync:false" }) @ThingworxServiceResult(name = "Result", description = "", baseType = "NOTHING") public void UpdateWeatherInfo( @ThingworxServiceParameter(name = "City", description = "city name", baseType = "STRING") String City) throws Exception { _logger.trace("Entering Service: UpdateWeatherInfo"); String cityProp = this.getPropertyValue("CurrentCity").getStringValue(); if (City == null){ City = cityProp; } else { this.setPropertyValue("CurrentCity", new StringPrimitive(City)); } String url = "http://api.openweathermap.org/data/2.5/weather?q=" +URLEncoder.encode(City,"UTF-8") + "&appid="+ _appid+"&units=imperial"; // create a http client HttpClient client = new DefaultHttpClient(); // create a get request with the URL HttpGet getRequest = new HttpGet(url); // add Accept header to accept json format response getRequest.addHeader("Accept", "application/json"); // send the get request and obtain a response HttpResponse response = client.execute(getRequest); // if response is successful the status code will be 200. if (response.getStatusLine().getStatusCode() == 200) { BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuilder sb = new StringBuilder(); String line = ""; while ((line = br.readLine()) != null) { sb.append(line); } JSONParser parser = new JSONParser(); JSONObject json = (JSONObject) parser.parse(sb.toString()); JSONArray weather = (JSONArray) json.get("weather"); Iterator<JSONObject> it = weather.iterator(); String description = (String) it.next().get("description"); this.setPropertyValue("WeatherDescription", new StringPrimitive(description)); double temp = (Double) ((JSONObject) json.get("main")).get("temp"); this.setPropertyValue("Temperature", new NumberPrimitive(temp)); /* fire event BadWeather */ _logger.trace("Exiting Service: UpdateWeatherInfo"); } }   Troubleshooting Issue Solution The iterator() is undefined in JSONArray Import only org.json.simple.*. Importing other JSON libraries can give this error. HttpClient/HttpGet could not be resolved to a type. Make sure you have imported the jars: httpclient-4.5.2.jar, httpcore-4.4.5.jar and commons-logging-1.2.jar, json-simple-1.1.1.jar as indicated in the previous chapter. Make sure you have imported the following packages in your template by Eclipse   Your code should be similar to the following:   package com.thingworx.weather; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URLEncoder; import java.util.Iterator; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClientBuilder; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.slf4j.Logger; import com.thingworx.logging.LogUtilities; import com.thingworx.metadata.annotations.ThingworxBaseTemplateDefinition; import com.thingworx.metadata.annotations.ThingworxConfigurationTableDefinition; import com.thingworx.metadata.annotations.ThingworxConfigurationTableDefinitions; import com.thingworx.metadata.annotations.ThingworxDataShapeDefinition; import com.thingworx.metadata.annotations.ThingworxFieldDefinition; import com.thingworx.metadata.annotations.ThingworxPropertyDefinition; import com.thingworx.metadata.annotations.ThingworxPropertyDefinitions; import com.thingworx.metadata.annotations.ThingworxServiceDefinition; import com.thingworx.metadata.annotations.ThingworxServiceParameter; import com.thingworx.metadata.annotations.ThingworxServiceResult; import com.thingworx.things.Thing; import com.thingworx.types.primitives.NumberPrimitive; import com.thingworx.types.primitives.StringPrimitive; @ThingworxBaseTemplateDefinition(name = "GenericThing") @ThingworxPropertyDefinitions(properties = { @ThingworxPropertyDefinition(name = "CurrentCity", description = "", category = "", baseType = "STRING", isLocalOnly = false, aspects = { "defaultValue:Boston", "isPersistent:true", "isLogged:true", "dataChangeType:VALUE" }), @ThingworxPropertyDefinition(name = "Temperature", description = "", category = "", baseType = "NUMBER", isLocalOnly = false, aspects = { "defaultValue:0", "isPersistent:true", "isLogged:true", "dataChangeType:VALUE" }), @ThingworxPropertyDefinition(name = "WeatherDescription", description = "", category = "", baseType = "STRING", isLocalOnly = false, aspects = { "dataChangeType:VALUE" }) }) @ThingworxConfigurationTableDefinitions(tables = { @ThingworxConfigurationTableDefinition(name = "OpenWeatherMapConfigurationTable", description = "", isMultiRow = false, ordinal = 0, dataShape = @ThingworxDataShapeDefinition(fields = { @ThingworxFieldDefinition(name = "appid", description = "", baseType = "STRING", ordinal = 0, aspects = { "isRequired:true" }) })) }) public class WeatherThingTemplate extends Thing { private static final long serialVersionUID = -5294151832877452442L; public WeatherThingTemplate() {} private static Logger _logger = LogUtilities.getInstance().getApplicationLogger(WeatherThingTemplate.class); private String _appid; @Override public void initializeThing() throws Exception {     super.initializeThing();     _appid = (String) this.getConfigurationSetting("OpenWeatherMapConfigurationTable", "appid"); } @ThingworxServiceDefinition(name = "UpdateWeatherInfo", description = "updates weather description and temperature properties", category = "", isAllowOverride = false, aspects = {     "isAsync:false" }) @ThingworxServiceResult(name = "Result", description = "", baseType = "NOTHING") public void UpdateWeatherInfo(     @ThingworxServiceParameter(name = "City", description = "city name", baseType = "STRING") String City) throws Exception {     _logger.trace("Entering Service: UpdateWeatherInfo");     String cityProp = this.getPropertyValue("CurrentCity").getStringValue();     if (City == null){         City = cityProp;     } else {         this.setPropertyValue("CurrentCity", new StringPrimitive(City));     }     String url = "http://api.openweathermap.org/data/2.5/weather?q=" +URLEncoder.encode(City,"UTF-8") + "&appid="+ _appid+"&units=imperial";     // create a http client     HttpClient client = HttpClientBuilder.create().build();     // create a get request with the URL     HttpGet request = new HttpGet(url);     // add Accept header to accept json format response     request.addHeader("Accept", "application/json");     // send the get request and obtain a response     HttpResponse response = client.execute(request);     // if response is successful the status code will be 200.     if (response.getStatusLine().getStatusCode() == 200) {         BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));         StringBuilder sb = new StringBuilder();         String line = "";         while ((line = br.readLine()) != null) {             sb.append(line);         }         JSONParser parser = new JSONParser();         JSONObject json = (JSONObject) parser.parse(sb.toString());         JSONArray weather = (JSONArray) json.get("weather");         Iterator<JSONObject> it = weather.iterator();         String description = (String) it.next().get("description");         this.setPropertyValue("WeatherDescription", new StringPrimitive(description));         Double temp = (Double) ((JSONObject) json.get("main")).get("temp");         Number number = (Number) temp;         this.setPropertyValue("Temperature", new NumberPrimitive(number));         _logger.trace("Exiting Service: UpdateWeatherInfo");     } } }     Click here to view Part 4 of this guide.
View full tip
  Build authentications extensions quickly and add to the security of your application.   GUIDE CONCEPT   Extensions enable you to quickly and easily add new functionality to an IoT solution. Extensions can be service (function/method) libraries, connector templates, functional widgets, and more.   These pointers and steps will enable you to maintain focus on development of your own application and still utilize the power of ThingWorx for other purposes at the same time.   When to Utilize:   You have your own login from outside of ThingWorx but you want to leverage ThingWorx user management You are using an identity provider other than ThingWorx You need to support passing of credentials in headers/query string parameters which ThingWorx doesn’t support out-of-the-box   Concept   Whether you would like ThingWorx to handle the security for your application, have an application you want ThingWorx to pump data into, or would just like to utilize ThingWorx features in your own application, external authentication can be a great way to integrate your application with ThingWorx. This guide will focus in on how to create an authentication middle man between a system you have already developed (or are in the middle of creating) and connect it to the ThingWorx Platform. In a provided demo website, you will login (with the provided credentials) and validate your user profile and password with ThingWorx. This setup shows the simple integration between ThingWorx and an application you would like to connect to the ThingWorx Platform.   YOU'LL LEARN HOW TO   Install the Eclipse plugin and extension SDK Create authentication application Build and import an extension   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL parts of this guide is 60 minutes.        Step 1: Completed Example   Download the completed files for this tutorial: AuthenticationExtension.zip   This tutorial will guide you 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. The download contains three directories (Source, CompletedExtension, and Demo). See below for the information about each directory.     Directory Description Source The completed project and source code to be utilized as a comparison or ready to go pre-built extension. CompletedExtension A completed and built extension that is based on the steps utilized in the latter steps. The zip file in this directory can be imported directly. Demo A demo web page that shows easy integration of an external application and ThingWorx authentication.       Step 2: Understanding Authenticators   Authentication between ThingWorx and custom outside applications begins with Authenticators.  Authenticators are the component integration point that allows for custom authentication schemes to be added into the ThingWorx platform. Authenticators can be used to retrieve content, parameters, headers, etc from HTTP requests.   The retrieved data can be verified by the authenticator using its implemented/configured verification  algorithm(s). If that data is of a username/password credential type the authenticator can choose to pass validation of that data to the configured list of Directory Services. For example, the internal ThingWorx username/password store, or delegate to an external Active Directory set of username/passwords.   ThingWorx tries to authenticate in increasing order of priority. In example, starting with  ThingworxBasicAuthenticator, unless a custom authenticator is given higher priority than that, ThingWorx will continue trying enabled authenticators by priority until one succeeds.   If an authenticator has priority 1, it will be consulted first in the chain of authenticators. If the authenticator has a priority of 101, it will be consulted after the ThingworxBasicAuthenticator (with priority of 100) fails to authenticate the HTTP request. There are several built-in authenticators   Authenticator Priority Editable ThingworxBasicAuthenticator 100 No ThingworxMobileTokenAuthenticator 150 Yes ThingworxApplicationKeyAuthenticator 200 No ThingworxSSOAuthenticator 250 Yes ThingworxFormAuthenticator 300 No ThingworxMobileAuthorizationAuthenticator 350 Yes ThingworxHttpBasicAuthenticator 400 No   When all configured and enabled authenticators fail to validate the data provided by an HTTP request, an authentication failure response is sent back to the requesting client. Custom Authenticators can be given priority such that they fit into any part of this process.   For setting the priority follow the instructions below:   Navigate to and select Security > Authenticators.   Select the Authenticator you would like to edit (ie, ThingworxSSOAuthenticator). If you do not see a specific Authenticator you would like to VIEW ONLY, check the Show System Objects checkbox in your search filter.   Update the Priority field with a new value. Click Save.       Step 3: Download Plugin and SDK   The ThingWorx Extension SDK provides supported classes and APIs to build Java-based extensions. The APIs included in this SDK allow manipulation of ThingWorx platform objects to create Java based extensions that can extend the capability of the existing ThingWorx platform.   The Eclipse Plugin assists in working with the Extension SDK to create projects, entities, and samples.   Download the Eclipse Plugin. Download Extensions SDK. Make a note of the directory where the plugin and the extension SDK are stored. The path of the directory will be required in upcoming steps. Do not extract the zip files.     Click here to view Part 2 of this guide.
View full tip
    Build extensions quickly and extend your application functionality with the Eclipse Plugin.   GUIDE CONCEPT   Extensions enable you to quickly and easily add new functionality to an IoT solution. Extensions can be service (function/method) libraries, connector templates, functional widgets, and more.   The Eclipse Plugin for ThingWorx Extension Development (Eclipse Plugin) is designed to streamline and enhance the creation of extensions for the ThingWorx Platform. The plugin makes it easier to develop and build extensions by automatically generating source files, annotations, and methods as well as updating the metadata file to ensure the extension can be imported.   These features allow you to focus on developing functionality in your extension, rather than worrying about getting the syntax and format of annotations and the metadata file correct.   YOU'LL LEARN HOW TO   Install the Eclipse Plugin and Extension SDK Create and configure an Extension project Create Services, Events and Subscriptions Add Composer entities Build and import an Extension   NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete all parts of this guide is 60 minutes.   Step 1: Completed Example    Download the attached file needed for this tutorial: ExtensionSampleFiles.zip.   The ExtensionSampleFiles.zip file provided to you contains a completed example of the scenario you will be walk through in the following steps. Utilize this file if you would like to see a finished example as a reference or if you become stuck during this guide and need some extra help.     Step 2: Download Plugin and SDK    The ThingWorx Extension SDK provides supported classes and APIs to build Java-based extensions. The APIs included in this SDK allow manipulation of ThingWorx platform objects to create Java based extensions that can extend the capability of the existing ThingWorx platform.   The Eclipse Plugin assists in working with the Extension SDK to create projects, entities, and samples. Download the Eclipse Plugin. Download the Extension SDK.. Make a note of the directory where the plugin and the extension SDK are stored. The path of the directory will be required in upcoming steps. Do not extract the zip files.     Step 3: Install and Configure   Before you install the plugin, ensure that software requirements are met for proper installation of the plugin. Open Eclipse and choose a suitable directory as a workspace. Go to the menu bar of the Eclipse window and select Help->Install New Software… After the Install window opens, click Add to add the Eclipse Plugin repository. Click Archive… and browse to the directory where the Eclipse Plugin zip file is stored and click Open. Enter a name (for example, Eclipse Plugin).     Click OK. NOTE: Do not extract this zip file. Ensure that the Group items by category checkbox is not selected. Select ThingWorx Extension Builder in the items list of the Install window. Click Next and the items to be installed are listed Click Next and review the license agreement. Accept the license agreement and click Finish to complete the installation process.   NOTE: If a warning for unsigned content is displayed, click OK to complete the installation process. Restart Eclipse. When Eclipse starts again, ensure that you are in the ThingWorx Extension perspective. If not, select Window->Perspective->Open Perspective->Other->ThingWorx Extension, then click OK.      NOTE: Opening any item from File->New->Other…->ThingWorx will also change the perspective to ThingWorx Extension.     You are ready to start a ThingWorx Extension Project!     Click here to view Part 2 of this guide.  
View full tip
Announcements