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

ThingWorx Navigate is now Windchill Navigate Learn More

IoT & Connectivity Tips

Sort by:
In this video you would see how to start to use your already created Virtual Image of ThingWorx Analytics using Oracle Virtual Box. This Video is Part-1 of the Series Getting Started with ThingWorx Analytics.   Updated Link for access to this video:  Getting Started with ThingWorx Analytics: Part 1 of 2
View full tip
Sometimes M2M Assets should poll the platform on demand, such as in the case of avoiding excessive data charges from chatty assets.  A mechanism was developed that instructs the Asset to contact (poll) the platform for actions that the Asset needs to act on such as File Uploads, Set DataItem, etc. The Shoulder Tap SMS message is the platform’s way of contacting the Asset – tapping it on the shoulder to let it know there’s a message waiting for it.  The Asset responds by polling for the waiting message.  This implementation in the platform provides a way to configure the Model Profile that is responsible for sending an SMS Shoulder Tap message to an M2M Asset.  The Model Profile contains model-wide instructions for how and when a Shoulder Tap message should be sent. How does it work? The M2M asset is set not to poll the Axeda Platform for a long period, but the Enterprise user has some actions that the Asset needs to act upon such as FOTA (Firmware Over-the-Air).       Software package deployed to M2M Asset from Axeda Platform and put into Egress queue.       The Shoulder Tap mechanism executes a Custom Object that then sends a message to the Asset through a delivery method like SMS, UDP, etc.       The Asset’s SMS, etc. handler receives the message and the Asset then sends a POLL to the Platform and acts upon the action in the egress queue How do you make Shoulder Tap work for your M2M Assets? The first step is to create a Model Profile, the model profile will tell Asset of this model, how to communicate. For Example, if the Model Profile is Shoulder Tap, then the mechanism used to communicate to the Asset will imply Shoulder Tap.  Execute the attached custom object, createSMSModelProfile.groovy, and it will create a Model Profile named "SMSModelProfile". When you create a new Model, you will see  “SMSModelProfile“ appear in the Communication Profile dropdown list as follows: The next step is to create the Custom Object Transport script which is responsible for sending out the SMS or other method of communication to the Asset.  In this example the custom object is be named SMSCustomObject​.  The contents of this custom object are outside the scope of this article, but could be REST API calls to Twilio, Jasper or to a wireless provider's REST APIs to communicate with the remote device using an SMS message.   This could also be used with the IntegrationPublisher API to send a JMS message to a server the customer controls which could then be used to talk directly with custom libraries that are not directly compatible with the Axeda Platform. Once the Shoulder Tap scripting has been tested and is working correctly, you can now directly send a Shoulder Tap to the Asset from an action or through an ExtendedUI Module, such as shown below: import com.axeda.platform.sdk.v1.services.ServiceFactory; final ServiceFactory sFact = new ServiceFactory() def assetId = (Long)parameters.get("assetId") def stapService = ServiceFactory.getShoulderTapService() stapService.sendShoulderTap( assetId ) See Extending the Axeda Platform UI - Custom Tabs and Modules for more about creating and configuring Extended UI Modules. What about Retries? maxRetryCount  - This built in attribute’s value defines the number of times the platform will retry to send the Shoulder Tap message before it gives up. retryInterval -The retry interval that can be used if the any message delivery needs to be retried. Retry Count and Interval are configured in the Model Profile Custom Object like so: final DeliveryMethodDescriptor dmd = new DeliveryMethodDescriptor(); fdmd.setMaxRetryCount(2); fdmd.setRetryInterval(60);
View full tip
Introduction In the dynamic landscape of IoT and industrial applications, development teams often face challenges such as limited visibility into application behavior, fragmented tooling, and time-consuming troubleshooting processes. To address these pain points, PTC has launched a DevOps initiative aimed at strengthening the ThingWorx low-code platform. This initiative delivers key enhancements in debugging, source control, monitoring, alerting, logging, and AI-driven development support. As ThingWorx continues to evolve, our commitment remains centered on improving the day-to-day experience for both developers and administrators. We've been listening closely to your feedback—this new project reflects our response, focusing on smoother DevOps integration and empowering users with deeper control and visibility into their applications. While many enterprises already rely on IT-recommended tools to manage the application lifecycle and Day-2 operations, PTC is committed to complementing these investments by delivering additional capabilities and guidance tailored to the ThingWorx platform. Key features of the new devOps project initiative include real-time debugging and version control, the ability to roll back to previous versions, hot-fix deployments, and distributed team development through seamless integration with repositories like GitHub. Furthermore, streamlined application packaging and deployment significantly simplify the management of ThingWorx-based applications. These enhancements go beyond routine updates and reflect a meaningful evolution in how teams develop, troubleshoot, and optimize IoT applications in production environments.  Debugging : Preview in ThingWorx 10.0   The first major feature introduced under DevOps is the debugging capability, currently available in a private preview (alpha version). Debugging has long been a challenge in ThingWorx applications, where troubleshooting JavaScript code within the platform was often cumbersome and time-consuming. With the new JavaScript Debugger, developers can now debug their scripts directly within ThingWorx Composer, reducing the time spent identifying and fixing issues. This feature brings real-time issue resolution, allowing developers to pinpoint errors efficiently without needing external tools.   Security and seamless integration into the existing ThingWorx environment were critical design considerations for this feature. The debugging actions are logged securely for audit and compliance, ensuring that sensitive information remains protected. Furthermore, support for major browsers such as Chrome, Firefox, Edge, and Safari enhances the accessibility of this feature across different development environments. The debugging capability is expected to significantly improve developer productivity by offering better visibility into JavaScript execution and real-time error tracking, reducing the trial-and-error approach that developers previously relied upon. Here is a brief video offering a preview of upcoming features included in the ThingWorx 10.0 release, with general availability planned for the 10.1 release later this year.   Debugger Capability (Preview) Logging and Monitoring : Continuous improvement   In addition to the new debugging capabilities, we’ve delivered several enhancements focused on monitoring and alerting—specifically designed to support the needs of IT administrators responsible for maintaining the uptime and reliability of ThingWorx environments in the last major release. The integration of OpenTelemetry has transformed logging and performance monitoring, allowing better observability of system operations. This enhancement enables third-party integrations with monitoring tools such as Sumo Logic, Datadog, and Splunk, providing developers and administrators with deeper insights into system performance. These improvements have made ThingWorx more resilient and responsive, allowing teams to proactively detect and address issues before they impact operations. Mashup Builder : Continuous improvement   We have been continuously enhancing Mashup development capabilities, starting with the introduction of Read-Only Mashups in ThingWorx 9.6 and extending through to the latest improvements in recent releases. Also, a new Export Function replaces the legacy Data Export Widget, offering a more secure and efficient data export process. Binding Verification & Debugging introduces a powerful capability to detect and resolve broken bindings after mashup migrations, reducing errors and improving reliability. Improved UI Management features, such as widget highlighting and container zooming, make mashup creation and debugging more intuitive. Additionally, developers can now customize Tab Titles & Favicons, enabling better branding and a more polished user experience for ThingWorx applications. Mash up improvements in ThingWorx 9.7 The Road Ahead: AI-Powered Development and Version Control   The next phase of the DevOps initiative is set to deliver major advancements in source control and AI-driven development. One key enhancement is the addition of IDE-like features for source code management, enabling developers to better track, iterate, and roll back changes. Planned integrations with GitHub and other repositories will support seamless collaboration in distributed teams.   We welcome your feedback as you explore the new Debugger Feature Preview included in the ThingWorx 10.0 release. In parallel, we are actively working with customers and partners to enhance key capabilities such as source code version control and application lifecycle management within the ThingWorx platform. If you're interested in contributing to the future of low-code development, we encourage you to share your thoughts in the comments below—our team will be in touch to connect.   Vineet Khokhar Principal Product Manager, IoT Security Stay tuned for more updates as we approach the release of ThingWorx 10.0, and as always, in case of issues, feel free to reach out to <support.ptc.com>  
View full tip
A while back, when I was learning about the ThingWorx platform, I could not find any good description of how InfoTables worked so I reverse engineered everything I could about them from a javascript perspective and wrote a short paper that I think is still of use today so I posted a copy here. It discusses what role InfoTables have as a ThingWorx primitive for passing data to and from ThingWorx and some of the lesser known capabilities that the data structure itself has built in. Here is a link to it Getting to Know InfoTables.pdf .
View full tip
When using the Auto-bind section of an EMS configuration it is very important to note the difference between "gateway":true and "gateway":false. Using either gateway value, when used with a valid "name" field, will result in the EMS attempting to bind the Thing with the ThingWorx platform, and will allow the EMS to respond to file transfer and tunnel services related to the auto-bound things, but this is around where the similarities end. Non-Gateway: This type of auto-bound thing can be thought of as a placeholder because the EMS will still require a LuaScriptResource to be bound in order to respond to property/service/event related messages. There must be a corresponding Thing based on the RemoteThing template (or any RemoteThing derived template e.g. RemoteThingWithFileTransfer) on the ThingWorx server in order for the bind to succeed. There are many reasons to use this type of auto-bound thing, but the most common is to bind a simple thing that can facilitate file transfer and tunnel services but does not need any custom services, properties, or events that would be provided by custom lua scripts within the LuaScriptResource. Gateway: An auto-bound gateway can be bound to the ThingWorx platform ephemerally if there is no Thing present to bind with on the platform. To clarify, if no Things exist with the matching Thing Name on the platform, and the EMS is attempting to bind a Gateway, a Thing will be automatically created on the platform to bind with the auto-bound gateway. This newly created ephemeral thing will only be accessible through the ThingWorx REST API, and once the EMS unbinds the gateway the ephemeral thing will be deleted If there is a pre-existing Thing on the ThingWorx server, then it must be based off of the EMSGateway template in order for the bind to succeed. The EMSGateway template, used both normally and ephemerally, will provide some gateway specific services that would otherwise be inaccessible to a normal remote thing. See EMSGateway Class Documentation for more details.
View full tip
Hi,   I have just been playing around with the Edge MicroServer on a couple of Raspberry Pi's.  I obviously want them connected to ThingWorx, however they stop when the SSH session closes which isn't ideal.  I thought about doing something really quick and dirty using 'nohup', but this could have lead to many running processes, and wouldn't still not have started automatically when the Pi booted.  So, I did it right instead using init.d daemon configurations.   There are two files; one for the EMS and one for the Lua Script Resource.  You need to put these in /etc/init.d, then make sure they are owned by root.   sudo chown root /etc/init.d/thingworx* sudo chgrp root /etc/init.d/thingworx*   You'll need to modify the paths in the first lines of these files to match where you have your microserver folder.  Then you need to update the init.d daemon configs and enable the services.   sudo update-rc.d thingworx-ems defaults sudo update-rc.d thingworx-ems enable sudo update-rc.d thingworx-lsr defaults sudo update-rc.d thingworx-lsr enable   You can then start (stop, etc.) like this:   sudo service thingworx-ems start sudo service thingworx-lsr start   They should both also start automatically after a reboot.   Regards,   Greg
View full tip
In this video we show the setup for anomaly detection (ThingWatcher) in release 8.4. We also show how to create an anomaly alert.  
View full tip
Race to the finish line of IoT app development with ThingWorx Edge!     Hi everyone,   Today’s post comes fully packed with an intro to our ThingWorx Edge strategy. Learn how to connect your machine data to ThingWorx, how our SDKs work, why you’d want to use them and how you can deploy agents.   To learn more about the Edge with ThingWorx, I spoke with Shravan. When Shravan’s not following Formula 1, learning about the latest trends in AI or playing cricket, he’s leading our development teams as the PM for the Edge. Check out what he had to say:   Kaya: How can I connect my machine data to ThingWorx through a protocol that the platform does not natively support?  Shravan: If you’re looking to connect your machine data to ThingWorx through a proprietary protocol and you require a 1:1 connection with the platform, we have two paths you can take. You can either: Utilize PTC’s Edge MicroServer (EMS) out-of-the-box solution. This is a stand-alone application that you can configure to send property updates, files, etc. to your instance of the ThingWorx Platform. It’s almost like a little mailman. Or, if you want to build connectivity into your own Edge devices, you can take advantage of PTC’s Edge Software Development Kits (SDKs). We offer three SDKs—C, .NET and Java—to enable you to build connectivity into your own custom application.   Kaya: And how can I connect my machine data to ThingWorx if my protocol is known? Shravan: Alternatively, if you’re a customer that communicates over a known protocol, then we’d recommend using our ThingWorx Industrial Connectivity product, also known as KEPServerEX or ThingWorx Kepware Edge.   For more background, I’ll go into a little more depth: KEPServerEX works in a Windows environment. It leverages OPC and IT-centric communication protocols (SNMP, ODBC and web services). It has more than 150+ drivers that help to establish stable and secure communication channels to devices, PLCs, Gateways, etc. ThingWorx Kepware Edge, launched during LiveWorx 2019, provides the most valuable features of KEPServerEX to be deployed in Linux-based gateways, starting with three key drivers: Modbus Ethernet, Allen-Bradley ControlLogix Ethernet and Siemens TCP/IP.   Kaya: Okay, great. Let’s cover SDKs first. In one sentence, can you explain how our SDKs work?   Shravan: The SDKs provide services for establishing a secure WebSocket connection (AlwaysON) to the ThingWorx Platform so that you can perform functions such as property updates, file transfers, tunneling, software content management (SCM), etc.   Kaya: At a high level, why do SDKs leverage AlwaysON? Shravan: Typically, transferring data to a server in IoT would require leveraging either REST web services, which has high connection overhead, works over HTTP or using MQTT, which requires a server and additional open ports.   So, an ideal connection should have three key features as a minimum: Stays continuously on. Is always ready to receive data and execute commands. Should also use existing open ports on firewall.   ThingWorx Edge SDKs provide this ideal connection though “Always On” protocol, which is based on WebSockets.   Kaya: What are the top three things a developer can do with the SDKs?  Shravan: Here are my top three. Thing property updates: Events can subscribe to changes in property values and in aspects of properties. File transfer: Browse remote directories and files on an instance of ThingWorx platform and enable bidirectional file transfer between an edge device and an instance of the platform. Tunneling: Allows users to establish secure, firewall-friendly application tunnels for applications that use TCP, such as VNC or SSH.   Kaya: How can you deploy SDK-based agents to devices? Shravan: You can deploy the agent in two main ways. One where the agent lives adjacent to the control and monitoring application of the machine and the other where the agent is directly integrated to the control and monitoring app of the machine.   Kaya: Anything else you want to mention?  Shravan: The Edge SDKs support a framework for adding additional functionality to the SDKs. This is known as the Edge Extension Framework. This allows additional functionality to be provided as installable services, which allows them to be extended in a manageable way while keeping the core SDK as compact and efficient as possible. Software Content Management (SCM) was the first commercially available Edge Extension.   - - -   This concludes the first installment of our series on Edge. Be on the lookout for deeper dives into KEPServerEX, SDKs, ThingWorx Kepware Edge and AlwaysOn.   Reach out if you have any questions.   Stay connected, Kaya                     P.S. For everyone who’s followed me for the past year, I’d just like to extend a huge thanks, as “Ask Kaya” has just turned one! It’s been a great first year and I’m excited for year two!
View full tip
Design Your Data Model Guide Part 2   Step 4: Data Sources – Component Breakout   Component Breakout     Once you have a full list of Things in your system (as well as requirements for each user), the next step is to identify the information needed from each Thing (based on the user's requirements). This involves evaluating the available data and functionality for each Thing. You then align the data and functionality with the user's requirements to determine exactly what you need, while eliminating that which you do not. This is important, as there can be cost and security benefits to only collecting data you need, and leaving what you don't. NOTE: Remember from the Data Model Introduction that a Thing's Components include Properties, Services, Events, and Subscriptions.   Factory Example   Using the Smart Factory example, let’s go through the different Things and break down each Thing's components that are needed for each of our users.   Conveyor Belts   The conveyor belt is simple in operation but could potentially have a lot of available data. Maintenance Engineer - needs to know granular data for the belt and if it has any alerts emergency shutdown (service) machine state (on/off) (property) serial number (property) last maintenance date (property) next scheduled maintenance date(property) power consumption (property) belt speed (property) belt motor temp (property) belt motor rpm (property) error notification (event) auto-generated maintenance requests (subscription) Operator - needs to know if the belt is working as intended belt speed (property) alert status (event) Production Manager - wants access to the data the Operator can see but otherwise has no new requirements   Robotic Arm   The robotic arm has 3 axes of rotation as well as a clamp hand. Maintenance Engineer - needs to know granular data for the arm and if it has any alerts time since last pickup (property): how long it has been since the last part was picked up by this hand? product count (property): how many products the hand has completed emergency shutdown (service) machine state (on/off) (property) serial number (property) last maintenance date (property) next scheduled maintenance date (property) power consumption (property) arm rotation axis 1 (property) arm rotation axis 2 (property) arm rotation axis 3 (property) clamp pressure (property) clamp status (open/closed) (property) error notification (event) 15.auto-generated maintenance requests (subscription) Operator - needs to know if the robotic arm is working as intended clamp status (open/closed) (property) error notification (event) product count (property): How many products has the hand completed? Production Manager - wants access to the data the Operator can see but otherwise has no new requirements   Pneumatic Gate   The pneumatic gate has two states, open and closed. Maintenance Engineer - needs to know granular data for the gate and if it has any alerts emergency shutdown (service) machine state (on/off) (property) serial number (property) last maintenance date (property) next scheduled maintenance date (property) power consumption (property) gate status (open/closed) (property) error notification (event) auto-generated maintenance requests (subscription) Operator - needs to know if the pneumatic gate is working as intended. gate status (open/closed) (property) error notification (event) The Production Manager wants access to the data the Operator can see but otherwise has no new requirements   Quality Control Camera   The QC camera uses visual checks to make sure a product has been constructed properly. Maintenance Engineer - needs to know granular data for the camera and if it has any alerts machine state (property): on/off serial number (property) last maintenance date (property) next scheduled maintenance date (property) power consumption (property) current product quality reading (property) images being read (property) settings for production quality assessment (property) error notification (event) auto-generated maintenance requests (subscription) product count (property): how many products the camera has seen Operator - needs to keep track of the quality check results and if there are any problems with the camera setup settings for production quality assessment (property) error notification (event) bad quality flag (event) product count (property): how many products the camera has seen Production Manager - wants access to the data the Operator can see but otherwise has no new requirements   Maintenance Request System Connector   Determining the data needed from the Maintenance Request System is more complex than from the physical components, as it will be much more actively used by all of our users. It is important to note that the required functionality already exists in our system as is, but it needs bridges created to connect it to a centralized system. Maintenance Engineer - needs to receive and update maintenance requests maintenance engineer credentials (property): authentication with the maintenance system endpoint configuration for connecting to the system (property) get unfiltered list of maintenance requests (service) update description of maintenance request (service) close maintenance request (service) Operator - needs to create and track maintenance requests operator credentials (property): authentication with the maintenance system endpoint configuration for connecting to the system (property) create maintenance request (service) get filtered list of maintenance requests for this operator (service) Production Manager - needs to monitor the entire system - both the creation and tracking of maintenance requests; needs to prioritize maintenance requests to keep operations flowing smoothly production manager credentials (property): authentication with the maintenance system endpoint configuration for connecting to the system (property) create maintenance request (service) get unfiltered list of maintenance requests (service) update priority of maintenance request (service)   Production Order System Connector   Working with the Production Order System is also more complex than the physical components of the lines, as it will be more actively used by two of the three users. It is important to note that the required functionality already exists in our existing production order system as is, but it needs bridges created to connect to a centralized system. Maintenance Engineer - will not need to know anything about production orders, as it is outside the scope of their job needs Operator - needs to know which production orders have been set up for the line, and needs to mark orders as started or completed operator credentials (property): authentication with the production order system endpoint configuration for connecting to the system (property) mark themselves as working a specific production line (service) get a list of filtered production orders for their line (service) update production orders as started/completed (service) Production Manager - needs to view the status of all production orders and who is working on which line production manager credentials (property): authentication with the production order system endpoint configuration for connecting to the system (property) get a list of production lines with who is working them (service) get the list of production orders with filtering options (service) create new production orders (service) update existing production orders for quantity, and priority (service) assign a production order to a production line (service) delete production orders (service)   Step 5: Data Sources – Thing-Component Matrix     Now that you have identified the Components necessary to build your solution (as well as the Things involved in enabling said Components), you are almost ready to create your Data Model design. Before moving onto the design, however, it is very helpful to get a good picture of how these Components interact with different parts of your solution. To do that, we recommend using a Thing-Component Matrix. A Thing-Component Matrix is a grid in which you will list Things in rows and Components in columns. This allows you to identify where there are overlaps between Components. From there, you can break those Components down into reusable Groups. Really, all you're doing in this step is taking the list of individual Things and their corresponding Components and organizing them. Instead of thinking of each item's individually-required functionality, you are now thinking of how those Components might interact and/or be reused across multiple Things.   Sample Thing-Component Matrix   As a generic example, look at the chart presented here.   You have a series of Things down the rows, while there are a series of Components (i.e. Properties, Services, Events, and Subscriptions) in the columns. This allows you to logically visually identify how some of those Components are common across multiple Things (which is very important in determining our recommendations for when to use Thing Templates vs. Thing Shapes vs. directly-instantiated Things). If we were to apply this idea to our Smart Factory example, we would create two sections of our Thing-Component Matrix, i.e. the Overlapping versus Unique Components. NOTE: It is not necessary to divide your Thing Component Matrix between Overlapping vs Unique if you don't wish to do so. It is done here largely for the sake of readability.   Overlapping Matrix   This matrix represents all the overlapping Components that are shared by multiple types of Things in our system:   Unique Matrix   This matrix represents the Components unique to each type of Thing:     Step 6: Model Breakdown         Breaking down your use case into a Data Model is the most important part of the design process for ThingWorx. It creates the basis for which every other aspect of your solution is overlaid. To do it effectively, we will use a multi-step approach. This will allow us to identify parts we can group and separate, leading to a more modular design.   Entity Relationship Diagram   To standardize the represention of Data Models, it is important to have a unified view of what a representation might look like. For this example, we have developed an Entity Relationship Diagram schematic used for Data Model representation. We will use this representation to examine how to build a Data Model.   Breakdown Process   ThingWorx recommends following an orderly system when building the specifics of your Data Model. You've examined your users and their needs. You've determined the real-world objects and systems you want to model. You've broken down those real-world items by their Component functionality. Now, you will follow these steps to build a specific Data Model for your application. Step Description 1 Prioritize the Groups of Components from your Thing-Component Matrix by each Group's Component quantity. 2 Create a base Thing Template for the largest group. 3 Iterate over each Group deciding which entity type to create. 4 Validate the design through instantiation. In the next several pages, we'll examine each of these steps in-depth.   Click here to view Part 3 of this guide.   
View full tip
New to ThingWorx and looking to get up to speed on using the platform?  The new Developer eSupport Portal is here to help! This guide will walk you through the process of gaining access to the Developer eSupport Portal, and will also provide a quick overview of the various content that you will be able to leverage.  Before you know it, you will have all the tools and knowledge needed to begin creating simple applications within the platform and begin establishing connections to a wide array of devices, industrial systems, enterprise applications, cloud services, etc. Creating an Account For users that have already created an account through the PTC eSupport website, you should be all set. Simply use your existing account credentials to access the Developer eSupport Portal.  For those who do not yet have an account, you can create one by using one of the following links: For customers with an active maintenance agreement, follow the link to create a Customer Account For users who do not yet have a maintenance agreement with PTC, follow the link to create a Basic Account Your account level will determine what you will have access to within the Developer eSupport Portal. Through the remainder of the guide, we will take note of areas where access rights may vary. Getting Acquainted with the Develop eSupport Portal Now that you have an account, you will have access to our Developer eSupport Portal.   There are three main areas to focus on in the portal: the Search Area, the various Content Category buttons, and the Learning Path. Search Area At the top of the page, you will find a search text box that will allow you to quickly sift through all of our available content, including various support articles, reference documents, training content, and post from our ThingWorx Community forum.  Simply type in any topic revolving around the ThingWorx platform that you are interested in learning about and initiate the search.  Looking for information on how to make better use of our search engine? Click on the Advanced Search link beneath the search text box to learn how to find that exact document or support article you are looking for. Content Categories Beneath the search area, you will find various content category buttons that will help direct you to commonly-accessed areas of the eSupport website.  As you click on each content category, a pop-up window will appear with additional popular links related to that category.  Here is a quick summary of each category: Getting Started This category will direct you to links related to setting up your own instance of the ThingWorx platform.  It also contains links to various getting started documents related to the ThingWorx Platform and the world of IoT. Courses and Tutorials This category will provide information on various learning resources related to the ThingWorx platform. ThingWorx Community This category will provide links to our ThingWorx Community site, a forum where developers can interact with one another.  You can also find various documents and blogs written by our expert staff that revolve around using the platform and provide information on recommended field practices. Recommended Readings This category provides links to popular reference documentation and supporting articles related to the ThingWorx Platform. Support This category provides links to various support outlets, like our Knowledge Base articles and the ThingWorx Community.  There is also information on contacting our expert Application Support Engineers for those with customer-level accounts. Marketplace This category provides information on the ThingWorx Marketplace, a website where developers can build and publish innovative applications, add-ons, and extensions for the ThingWorx Platform and share them with the ThingWorx Community. By utilizing these pre-built components, you can expand upon the out-of-the box functionality and develop your own applications more quickly using these components. Learning Path To the right of the search area, you will find your personalized path to success.  This path has been put together by our educational team to help you get up to speed on using the ThingWorx platform as quickly as possible.  You can keep track of your progress as you work through the learning path by checking off each completed item.  Let’s quickly discuss the various elements of the path. Explore MOOCs This link will take you to all of our available massive open online courses, or MOOCs. These are short courses intended to introduce you to the concepts of the technology involved in the Internet of Things. Not all of the courses in this area will feature the ThingWorx Platform front and center, but will introduce you to various skills and concepts that will be used as you dive deeper into the platform and the world of IoT. Access the ThingWorx Community Now that you have created an account, you will have access to the ThingWorx Community, a forum where you can interact with other ThingWorx developers and members of the ThingWorx support team.  This is a great place to discover how other users are developing applications within the ThingWorx platform.  You will also have access to various documents and blog posts written by our expert staff that will introduce you to new product features, or introduced you to various field practices that you may find useful when writing your own applications. Finally, this is also a great area to ask questions if you are looking for some assistance as you develop your own applications. Complete a Quick Start This link will direct you to our quick start areas.  Here, you will be given access to a temporary ThingWorx instance and guided through various examples centered on building applications and connecting devices to the platform.  The Application QuickStarts will show you just how rapidly you can design functional applications within the platform, while the Device QuickStarts will demonstrate just how easy it is to connect your devices to the platform, collect data from them, and display them within your applications.  You will also have access to a general tour of the ThingWorx platform in this area, which will walk you through the basic elements of our developer environment, the ThingWorx Composer. Download & Install the ThingWorx Platform The next step in this process will be to install and configure your own local instance of the ThingWorx platform.  For customers with an active maintenance agreement, you can obtain the ThingWorx platform install files from the eSupport Downloads page.  For users with basic accounts, we will be providing access to an evaluation version of the platform. View Learning Resources This link will take you to the PTC Learning Connector.  Here you will discover IoT-based case studies and talks, gain access to short learning tutorial videos centered on key platform functionality and concepts, gain access to a wide array of knowledge base articles written by our expert application support engineers, and access ThingWorx Reference documentation. Explore the Help Center The PTC Help center provides access to all PTC product documentation.  With regards to ThingWorx, this includes access to ThingWorx Utilities, Converge, and Edge Connectivity documentation, in addition to the ThingWorx Platform documentation itself.  Links are provided for both the current release and supported legacy release versions of the platform. Create an Application After going through the previous steps in the learning path, you should now have all the necessary information to begin designing your own ThingWorx application. Try creating an application that takes full advantage of the various IoT concepts used so far that will help you meet your business needs.  And of course, feel free to go back and reference any of the provided material in the previous steps to help you accomplish this task. Get Certified This link provides information on the PTC certification plans for the ThingWorx platform. Various levels of certification are available for application developers, connectivity developers, platform developers, system engineers, and architects intending to develop professional-level applications.  Becoming certified is a great way to showcase your skills and talents in the emerging world of IoT that top employers are seeking. Feedback We hope that you find the Developer eSupport Portal helpful in getting up-to-speed on the world of IoT and the ThingWorx platform!  We are also very interested in hearing more about your own experience with the portal. If you would like to let us know, please click on the Feedback link beneath the search area to send your comments directly to us.  We look forward to hearing from you, and will always strive to make the portal as helpful and efficient as possible.
View full tip
    Modernize your Mashups with CSS to enhance the presentation of your application.   GUIDE CONCEPT   This project will introduce using CSS to create a customized, consistent look and feel for your IoT application.   Following the steps in this guide, you will create a custom CSS class definitions and bind these classes to Mashup features.   We will teach you how to present a professional-looking user interface and ensure consistency of style treatments within your application by implementing Cascading Style Sheets (CSS) in Mashups.     You'll learn 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     Step 1: Custom CSS Benefits   You now have more flexibility to customize your application’s UI and improve the user experience using industry-standard web techniques. You can implement CSS in ThingWorx to control the visualization of your Mashup.   Feature                   Benefit Text Treatments Optimize text with shadow, color, font, and border Responsive UI Customize layout based on user actions and the data being displayed Media Queries Accommodate many screen sizes with flexboxes and other standard containers Animations Implement standard CSS key frames Customizations Modify application appearance without changing source Mashup Linting Expedite development with code auto-completion and design-time syntax warnings       Step 2: Access Sample Files   We created sample entities you can use to complete the steps in this guide. Download the attached Mashups_CustomCssTutorialMashup.xml From the Home page of Composer, click the Import/Export icon, then choose Import   Keep the default options and click Browse. Locate and select the CustomCssTutorialMashup.xml file you downloaded and extracted, click Open then Import.   Click Close after the Import successful message is displayed. Click the Browse tab in the left navigation panel, then click Mashups.                     6. Select the CustomCssTutorialMashup.                 7. Click View Mashup to view the Mashup.     NOTE: This is a simple Mashup designed to demonstrate how the UI changes when CSS is applied.       Step 3: Create CSS Rule Block   In this step, you will use the built-in editor to create a custom CSS class that will be used in the next step to modify the appearance of three buttons grouped by the Fieldset Widget.   Open the CustomCssTutorialMashup in Edit and Design view.     Click Custom CSS.     Copy the CSS class below and paste it into the Custom CSS editor: .myMashupClass .widget-fieldset .widget-ptcsbutton { box-shadow: 5px 5px 5px #888888; } NOTE: This class will create a shadow around all of the buttons that are in a Fieldset container  only after it is bound to a Mashup,   4. Click Save.     Tips   Press Ctrl -> Space to use the Auto-complete feature and see code snippets, which can expedite your development time.     The Linting feature will warn you if there are errors in your code, so you can fix them at design time.       Step 4: Apply Custom Class to Mashup   In this step we will demonstrate how to modify the look and feel of a Mashup without changing the Mashup itself. The myMashupClass we just created chains two selectors: the widget-fieldset and the widget-button. Only Widgets that are in both selector categories will be modified.   Click Design and select the Explorer tab, then select the top-level Mashup.     In the property panel in the lower left, locate the CustomClass property and type myMashupClass as the value. Press Tab to save the value change.     WARNING: You must press Tab after every property change in order for the new value to be saved.   4. Click Save then View Mashup to see that the buttons in the Field Set have shadow borders.       Step 5: Apply Custom Class to Widget   In addition to the Mashup level, you can apply style treatments directly to a Widget in your Mashup. In ThingWorx, the following Widgets have a CustomClass property you can modify:     For this example, we will make the text on one of the buttons all caps.   In the CustomCssTutorialMashup, click Custom CSS. Add the following css code: .myButtonClass .widget-ptcsbutton { text-transform: uppercase; }     Return to the Design view, and In the Explorer tab, click the button-3.     In the Property panel, enter myMashupClass to the CustomClass field, then press tab     Save then View Mashup the Mashup to see that the button text is now all caps.       Step 6: Bind Custom Class   The UI of a Mashup can be dynamically updated at runtime by binding the value of the CustomClass property to a dynamic data source such as: Services Mashup parameters Widgets (expression widgets for example)   In this portion of the guide, we will demonstrate modifying a Mashup in response to user actions:   Return to the Design view for the CustomCssTutorialMashup. In the Mashup Builder, click the Functions tab in the lower right, then expand Event Routers and expand eventsrouter-6     Click Output property and drag it onto the bottom button of the group of three buttons.     Select the CustomClass property from the pop-up to bind it to Button-4   In Mashup Builder click Custom CSS tab. Add the following css code: .myBoundButtonClass1 .widget-ptcsbutton { text-transform: lowercase; } .myBoundButtonClass2 .widget-ptcsbutton { text-transform: uppercase; }           7. Click Save and then View Mashup.           8. Click on each of the Apply buttons to see the results of a CSS class applied to in response to user actions.     Step 7: Use Media Queries   You can use Media queries to apply styling based on the characteristics of the device being used to access the application. For this example, we will use a CSS Class to hide three elements when the browser’s width is less than 600 pixels wide.   1. Open the CustomCssTutorialMashup in Edit and Design view, then click Custom CSS.     2. Copy the CSS class below and use the Custom CSS editor to add it to the top of the existing  CSS, then click Save. @media screen and (max-width: 1000px) { #root_ptcslabel-10-bounding-box { visibility: hidden; } #root_ptcstextfield-7-bounding-box{ visibility: hidden; } #root_ptcstextfield-12-bounding-box { visibility: hidden; } }   NOTE: The ID selector in your CSS must add root_ to the beginning, and -bounding-box to the end of the element’s ID shown in Mashup Builder.   3. Click View Mashup, then click and drag the edge of the browser window to reduce the width below 600 pixels.     NOTE: The three Widgets selected in the media class added in the last step will disappear as soon as the browser is less than 600 pixels wide.       Click here to view Part 2 of this guide.
View full tip
Preface   In this blog post, we will discuss how to Start and Stop ThingWorx Analytics, as well as some other useful triaging/troubleshooting commands. This applies to all flavors of the native Linux installation of the Application.   In order to perform these steps, you will have to have sudo or ROOT access on the host machine; as you will have to execute a shell script and be able to view the outputs.   The example screenshots below were taken on a virtual CentOS 7 Server with a GUI as ROOT user.     Checking ThingWorx Analytics Server Application Status   1. Change directory to the installation destination of the ThingWorx Analytics (TWA) Application. In the screenshot below, the application is installed to the /opt/ThingWorxAnalyticsServer directory   2. In the install directory, there are a series of folders and files. You can use the ​ls​ command to see a list of files and folders in the installation directory.     a. You will need to go navigate one more level down into the ./ThingWorxAnalyticsServer/bin​ ​directory by using command ​cd ./bin​     b. As you can see above, we used the ​pwd​ command to verify that we are in the correct directory.   3. In the ./ThingWorxAnalyticsServer/bin directory, there should be three shell files: configure-apirouter.sh, configure-user.sh, and twas.sh     a. To run a status check of the application, use the command ./twas.sh status           i. This will provide a list of outputs, and a few warning messages. This is normal, see screenshot below:      b. You will have a series of services, which will have a green active (running) or red not active (stopped).           i. List of services: twas-results-ms.service - ThingWorx Analytics - Results Microservice twas-data-ms.service - ThingWorx Analytics - Data Microservice twas-analytics-ms.service - ThingWorx Analytics - Analytics Microservice twas-profiling-ms.service - ThingWorx Analytics - Profiling Microservice twas-clustering-ms.service - ThingWorx Analytics - Clustering Microservice twas-prediction-ms.service - ThingWorx Analytics - PredictionMicroservice twas-training-ms.service - ThingWorx Analytics - Training Microservice twas-validation-ms.service - ThingWorx Analytics - Validation Microservice twas-apirouter.service - ThingWorx Analytics - API Router twas-edge-ms.service - ThingWorx Analytics - Edge Microservice   Starting and Stopping ThingWorx Analytics   If you encounter any errors or stopped services in the above, a good solution would be to restart the TWA Server application.   There are two methods to restart the application, one being the restart ​command, the other would be using the stop​ and ​start​ commands.   Method 1 - Restart Command:   1. In the same ./ThingWorxAnalyticsServer/bin​ ​directory, run the following command: ./twas.sh restart     a. The output of a successful restart will look like the following: 2. The restart should only take a few seconds to complete   Method 2 - Stop / Start Commands:   1. In the same ./ThingWorxAnalyticsServer/bin​ ​directory, run the following command: ./twas.sh stop 2. After the application stops, run the following command: ./twas.sh start   Note: You can confirm the status of the TWA Server application by following the steps in the "Checking ThingWorx Analytics Server Application Status" section above.
View full tip
Build an Equipment Dashboard Guide Part 1   Overview   This project will introduce you to the principles of ThingWorx Foundation by creating an eqipment dashboard. Following the steps in this guide, you will create the building blocks of your first IoT application, including Things and Streams. We introduce the basics for creating an IoT application. NOTE: This guide's content aligns with ThingWorx 9.3. The estimated time to complete ALL 2 parts of this guide is 30 minutes.    Step 1: Learning Path Overview   This guide explains the steps to create an Industrial Eqipment Dashboard, and is part of the Connect and Monitor Industrial Plant Equipment Learning Path. You can use this guide independently from the full Learning Path. If you want to learn the basics of creating an eqipment dashboard with ThingWorx, this guide will be useful to you.When used as part of the Industrial Plant Learning Path, you should already have ThingWorx Kepware Server installed, and it should be sending data to ThingWorx Foundation. You also need to have previously created the Thing Shape and Thing Template used for this dashboard. We hope you enjoy this Learning Path.   Step 2: Create Thing   A Thing is used to digitally represent a specific component of your application in ThingWorx. In Java programming terms, a Thing is similar to an instance of a class. In this step, you will create a Thing that represents an individual Pump using the Thing Template we created in the previous guide. Using a Thing Template allows you to increase development velocity by creating multiple Things without re-entering the same information each time. In ThingWorx Foundation, navigate to Browse > Modeling > Things. Click + New. In the Name field, type MyPump. NOTE: This name, with matching capitalization, is required for the data display created in a later step.       4. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject.       5. In the Base Thing Template field, search for and select the previously-created PumpTemplate.       6. At the top, click Save.          Manage Property Bindings At the top, click Properties and Alerts. At the top, click Manage Bindings. In the top-left Local > Search Things field, search for and select IndConn_Tag1. Drag-and-drop Simulation_Examples_Functions_Random3's + symbol onto the watts Property on the right. At the bottom-right of the pop-up, click Done. Note how the Tag from ThingWorx Kepware Server is now bound to the the watts Property. Click Save. Click Refresh repeatedly to confirm the watts Property value is changing.     Step 3: Store Data in Value Stream   Now that you have created the MyPump Thing to model your application in ThingWorx, you need a storage Entity to record changing Property values. This step shows how to save time-series data in a Value Stream already created in a previous guide. To learn more, refer to the Methods for Data Storage guide. Navigate to Browse > Modeling > Thing Templates. Click the previously-created PumpTemplate Thing Template to open it. Confirm you are on the General Information tab. If necessary, click Edit to allow changes. In the Value Stream field, search for and select IndConn_ValueStream. Click Save.   Step 4: Create Application UI   ThingWorx Foundation is used to create customized web applications that can display and interact with data from multiple sources. These web applications are called Mashups and are created using the Mashup Builder. The Mashup Builder is where you create your web application by dragging and dropping Widgets such as Grids, Charts, Maps, and Buttons onto a Canvas. All of the user interface elements in your application are Widgets. We will build a web application with three Widgets: Image showing a picture of the pump Value Display showing the pump serial number Line Chart showing the value of watts Property trend over time.   Create New Mashup   Navigate to Browse > Visualization > Mashups.   Click + New.   Keep the defaults and click OK.   In the Name field, type pump-dashboard. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. Click Save.   At the top, click Design.   Define Mashup Areas   At the top-left, ensure the Layout tab is selected. Click Add Bottom to split your UI into two halves.   Click the newly-created bottom-half to select it. Click Add Left.   Click the bottom-left container to select it. In the top-left Layout section, scroll down and select Fixed Size.   Type 200 in the Width text box that appeared, then press your keyboard’s Tab key to record your entry.   Add Widgets   In the top-left, click the Widgets tab.   In the Filter field, type image.   Drag-and-drop an Image Widget onto the lower-left area of the central Canvas. This Widget will show an image of the pump in use. 4. In a similar manner to what was just done with the Image Widget, drag-and-drop a Value Display Widget onto the top area. 5. Likewise, drag-and-drop a Line Chart Widget onto the lower-right area.   6. Click Save.          Click here to view Part 2 of this guide. 
View full tip
    Learn how to connect, query, insert, and handle data from an external database.   GUIDE CONCEPT   This project will introduce how to utilize and incorporate an external database with the ThingWorx Platform.   Following the steps in this guide, you will connect the ThingWorx Platform to a database, insert data, execute stored procedures, and query data.      YOU'LL LEARN HOW TO   Connect ThingWorx to external databases Query databases and and handling results Insert data and running stored procedures   NOTE: The estimated time to complete this guide is 60 minutes.     Step 1: Completed Example   Download the attached DatabaseApplication.zip and import it into ThingWorx Composer. This download will provide examples that can be used as a reference or as a final copy as you walk through this guide.   In this tutorial, you will learn how to query data and write data to live external databases. The zip file provided contains the following files and entities as a completed version of the scenario to be covered. Import the .twx files into ThingWorx in any order. Run the SQL Server table scripts in a database you have setup followed by the stored procedures.      Name                                                 Description                                                                      Type SQLServerDatabaseController A connected entity for use with an SQL Server database ThingWorx Entity OracleDatabaseController A connected entity for use with an Oracle database ThingWorx Entity AddStudentToCourse.sql Stored procedure to add students to a course in a SQL Server database Database Stored Procedure GetStudentInCourse.sql Stored procedure to information about students in a course in SQL Server database Database Stored Procedure Course.sql SQL Server table representing Courses Database Stored Procedure Person.sql SQL Server table representing Students Database Stored Procedure PersonCourses.sql SQL Server table representing the connection between Students and Courses Database Stored Procedure     This guide will use connections to a SQL Server database, however you can use ANY database that can be used with the Java programming language. Based on the database you will be using, please perform the installation process for that database and create a user with READ, WRITE, and EXECUTE permissions. Ensure the password is set for this user and keep in mind that a UI for the database connection is not needed, but it can make things a bit simpler.      Database Download                       Installation Documentation           Jar File Download SQL Server Download SQL Server Installation SQL Server Jar File Oracle Download Oracle Installation Oracle Jar File     Please follow the below steps to enable a connection between ThingWorx and your database of choice: Ensure the user you created has read, write, and execute permissions. If you would rather split roles, you can create multiple users to handle each aspect. The execute permission for stored procedures is not necessary. Download the database driver/.jar file and move it to the lib directory of the Tomcat installation (ie, /lib). Restart the Tomcat server to load the JDBC driver to make it available for the ThingWorx web application.   Step 2: Connect to External Database   ThingWorx is based on java programming language and can make connections to any database that supports a java-based connection. All that is needed is to add the .jar file for the database to the lib folder of Tomcat folder and setup the connection in the ThingWorx Platform. Follow the below steps to get started creating the connection.   Create Connection   To create a connection and begin working with an external database, you will need to create a database Thing and set up the connection string and credentials. (To see the final version of this entity, you can look at SQLServerDatabaseController.)   In ThingWorx Composer, click the + New at the top of the screen.   Select Thing in the dropdown.   Name the Thing DatabaseController and select Database as the base type. Set the Project field (ie, PTCDefaultProject).   Click Save and go to the Configurations tab. In this tab, you will enter the class name of your driver, the connection string for that database connection, and the credentials to access the database. Keep in mind, the JDBC Driver Class Name, JDBC Connection String, and the connectionValidationString values are all database type specific. For example, to connect to a SQL Server database, the below configuration can be used.      Title                                              Description                    Example JDBC Driver Class Name The specific class name of the driver being used for the connection. net.sourceforge.jtds.jdbc.Driver (SQL Server) or oracle.jdbc.driver.OracleDriver (Oracle) JDBC Connection String The connection string to locate the database by host/port/database name. jdbc:jtds:sqlserver://server:port/databaseName (SQL Server) or jdbc:oracle:thin:@hostname:port:databaseName (Oracle) connectionValidationString A simple query that should always work in a database. SELECT GetDate() (SQL Server) or SELECT SYSDATE FROM DUAL (Oracle) After entering credentials, click Save. Go the Properties and Alerts tab. You'll see properties showing the connection validation similar to the image below. If you don't have a connection as yet, work on your configuration information and validate the credentials being used. If you're still having troubles after that, see the examples section below or use the next section for help to try a query of the database.   Help and Troubleshooting For help finding the correct configuration for you, check out these JDBC Configuration Examples or try out this Connection String Reference for help with your connection string.   You've just created your first database connected Thing! Now jump to the next section and let's begin to query the database for information. Step 3: Query Data from External Database Now that you're connected to the database, you can begin querying the database for information and the flow of data. The queries and data shown below are based on the table scripts provided in the download. Examples of how the ThingWorx entity should look can be seen in the SQLServerDatabaseController and OracleDatabaseController entities. Running a Query As you may have noticed by working in ThingWorx and developing applications, an InfoTable is often used to work with large sets of data. An InfoTable is also how data is returned from a database query. If you're expecting only 1 value in the result set, the data will be held in the first index of the InfoTable. If you're expecting rows of data coming back, expect there to be rows of information inside of the InfoTable. Follow the steps below to set up a helper service to perform queries for the database. While other services might generate the query to be used, this helper service will be a shared execution service. In the DatabaseController entity, go to the Services tab. Create a new service of type SQL (Query) called RunDatabaseQuery.   3. Set the Output as InfoTable, but do not set the DataShape for the InfoTable. 4. Add the following parameter:  Name            Base Type   Required query String True 5. Add the following code to the new service: <<query>> 6. Click Save and Continue. Your service signature should look like the below example.   You now have a service that can run queries to the database. This is also a simple method to test/troubleshoot the database connection or a quick query. Run your service with a simple query. You might notice that no matter the fields in the result set, the InfoTable will match it based on field type and field name. There are two ways you can go from here. You can either query the database using services that call this service, or you can create more SQL command services that query the database directly. Let's go over each method next, starting with a service to call our helper. In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service JavaScriptQuery_PersonsTable. Set the Output as InfoTable, but do not set the DataShape for the InfoTable. Add the following code to your new service: try { var query = "SELECT * FROM Persons"; logger.debug("DatabaseController.JavaScriptQuery_PersonsTable(): Query - " + query); var result = me.RunDatabaseQuery({query:query}); } catch(error) { logger.error("DatabaseController.JavaScriptQuery_PersonsTable(): Error - " + error.message); }   5. Click Save and Continue. Any parameter, especially those that were entered by users, that is being passed into an SQL Statement using the Database Connectors should be fully validated and sanitized before executing the statement! Failure to do so could result in the service becoming an SQL Injection vector. This is a simple way to query the database since much of your development inside of ThingWorx was already based in JavaScript. Now, let's utilize the second method to create a query directly to the database. You can use open and close brackets to create parameters for your query. You can also use <> as a method to mark a value that will need to be replaced. As you build your query, use [[Parameter Name]] for parameters/variables substitution and <> for string substitution. In the Services tab of the DatabaseController entity, create a new service of type JavaScript. Name the service SQLQuery_GetPersonByEmail. Ensure the Output is InfoTable. Add the following code to your new service: SELECT * FROM Persons WHERE person_email = [[email]]; 5. Add the following parameter:  Name          Base Type    Required email String True 6. Click Save and Continue. An example of using the string replacement is as follows:         DELETE FROM <> WHERE (FieldName = '[[MatchName]]'); DELETE FROM << TableName >> WHERE ( FieldName = [[MatchNumber]]);             Click here to view Part 2 of this guide.
View full tip
    Step 5: Log to Value Stream   Now that you have explored the Properties of IndConn_Tag1, you’ve seen how ThingWorx Kepware Server feeds information to ThingWorx Foundation. To get an even better indication of changes and confirm continued connectivity, we will log the changes to a Value Stream in order to record the values with a TimeStamp.   Create Value Stream   Return to the ThingWorx Foundation New Composer browser. Click Browse. Click Data Storage -> Value Streams. Click + New. In the Choose Template pop-up, select ValueStream. Click OK. Type IndConn_ValueStream in the Name field. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. In the Description field, enter an appropriate description, such as Value Stream to record changes from ThingWorx Kepware Server. Click Save.   Bind Value Stream   Open the IndConn_Tag1 either by clicking on the tab at the top, or by clicking on PTCDefaultProject on the left At the top, select General Information. In the Value Stream field, enter indconn. Select IndConn_ValueStream from the sorted list. At the top, select Properties and Alerts. Click Simulation_Examples_Functions_Random3. A new set of options will expand from the right. Check the box for Persistent. Check the box for Logged. Click the Check button to close the expanded options. Click Save. All changes to the Random3 Tag, fed from ThingWorx Kepware Server, are now stored and TimeStamped in the Simulation_Examples_Functions_Random3 Property.   Step 6: Visualize the Data   We'll now create a Mashup to visualize the record of information from ThingWorx Kepware Server. In ThingWorx Foundation's Browse, click Visualization -> Mashups. Click +New. In the New Mashup pop-up, leave the default selections. Click OK. In the Name field, enter IndConn_Mashup. If Project is not already set, click the + in the Project text box and select the PTCDefaultProject. At the top, click Save. At the top, click Design. In the Filter Widgets field at the top-left, enter chart. Drag-and-drop a Line Chart onto the central canvas area. Add Data   On the right-side of the Mashup Builder, click the Data tab. Click the + button on the Data tab.        3. In the Add Data pop-up, enter indconn in the Entity field, overwriting Filter. 4. Select IndConn_Tag1 from the sorted list. 5. In the Filter field below Services, enter queryprop. 6. Click the right arrow button beside QueryPropertyHistory. The QueryPropertyHistory Service of the IndConn_Tag1 Thing will appear on the right in the Selected Services field. 7. Check the box under Execute on Load in the Selected Services field.' 8. Click Done. Note that the QueryPropertyHistory Service now appears on the right side Data tab. 9. Click the arrow to expand QueryPropertyHistory, then click to expand Returned Data. 10. Drag-and-drop All Data from the QueryPropertyHistory Service from the right onto the Time Series Chart in the center. 11. In the Select Binding Target pop-up, select Data.        Configure Chart Properties   In the bottom-left Properties of timeserieschart-1, enter xaxisfield in the Filter Properties field. Expand the drop-down for XAxisField. Select timestamp. Click Save. Click View Mashup. (You may have to enable pop-ups to view the mashup.) The IndConn_Mashup will show you the recorded history of property changes that came from ThingWorx Kepware Server. NOTE: If the Mashup visualization is blank, confirm your connection to IndConn. Return to the Test Connection section of the Bind Industrial Tag step.   Step 7: Next Steps   Congratulations! You've successfully completed the Connect Kepware Server to ThingWorx Foundation guide. You've learned how to: Connect ThingWorx Foundation to ThingWorx Kepware Server Map Tags to Properties     The next guide in the Connect and Monitor Industrial Plant Equipment learning path is Create Industrial Equipment Model. 
View full tip
  Implement reusable Mashup Templates and Shapes in your IoT application.     Guide Concept   This guide will introduce you to creating your own advanced responsive ThingWorx user interface templace. You’ll learn some best practices and tips for creating a UI for your IoT application. With Mashup templates, you’re able to quickly and easily build pages that will look alike and have some of the same functionality already programmed.   Following the steps in this guide, you will create reusable content and develop scalable user interfaces.   We will teach you how to make UI development easier and more efficient for all of your IoT application needs.     You'll learn how to   Utilize ThingWorx using best practices for UI design Create Entities to make development faster and scalable    NOTE: The estimated time to complete this guide is 30 minutes     Step 1: Completed Example Files   Download and import GiftedReusability.xml attached to this case. Within the file you imported, 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: Create Reusable Mashup   A reusable Mashup can be embedded in another Mashup in order to enable common components. Follow the steps below to create a reusable Mashup.   In the ThingWorx Composer, click the + New at the top of the screen.   Select Mashup Template in the dropdown.   Select Responsive for the layout option. Click Ok.   Enter a name for the Mashup Template, such as MashupTemplateExample. Set the Project field (ie, PTCDefaultProject). Click Save then click Design to get to the Mashup canvas.   You've now created a Mashup template that can be utilized to create other Mashups faster and easier. After saving, you will have the regular Mashup design window as shown below.     Play around and have some fun with this new Mashup. With the Workspace view in the Default option, you can see how simple it is to add sections and layout configurations within the page. You can also see that there is functionality for adding Widgets and data to the template. Let's add containers.   Let's add some containers to our UI. This will allow for easier grouping of UI components or to allow users an easy comparison of charts and graphs.   Select the Main layout and click Add Left. Do this a second time. Select the left most container and select Add Bottom. Select the right most container and select Add Top. Select the top section that was just added and click Add Right.   You should have something like the image above. Now that you have formulated these sections, you can use the standard methods to add Widgets, styles, and data. In the Nested Container section, you can decide on how these containers should be sized as your add new sections to your page.   If you make any changes to this Mashup Template, you are then able to create new Mashups based off of this Mashup after select Responsive as the layout option. We will be making some of these changes in the next steps.       Step 3: Configure Mashup   There are two Thing Templates provided. AirHandler is a top level template with several direct implementations (FanA, FanB, FanC, etc.). There is also a HeatHandler Thing Template. This template inherits from the AirHandler Thing Template and has 2 direct implementations.   The AirHandlerTemplate Mashup can be used with either direct AirHandler implementations, or indirect implementations such as implementations of the HeatHandler Thing Template. This Mashup can also be reused further with implementations of another Thing Template.   Open the AirHandlerTemplate Mashup, which contains the layout that will be used in this example. Drag and drop a Property Display Widget onto the left column in the layout on the canvas.   Drag and drop an Image Widget onto the bottom right space of the canvas.   Drag and drop a Checkbox Widget onto the top part space of the of the canvas.   Click the + button in the Data panel.   Check the Dynamic checkbox. Select the AirHandler in the Select Entity text box. Filter for and find the GetPropertyValues service, then click the arrow.   Check the Execute on Load checkbox. Click Done.   You've just created a Mashup Template that will utilize the AirHandler entity for data and property values. This will allow you to continuously create new Mashups with a head start. In the next steps, we will connect the data values of the AirHandler template to the Widgets in the screen.         Step 4: Define Entity Parameter   Mashups come with a parameter named Entity. This parameter is a BaseType of ThingName and often used in dynamic Mashups as an input to Services or outlets of information. In our example, the Entity parameter is used to tell the Mashup which implementation of the AirHandler we should present.   With the updated AirHandlerTemplate Mashup still open, follow the directions below:   Select the Mashup in the Explorer pane. Select the Settings icon in the Widget properties panel.   The Configure Mashup Parameters pop-up will appead. Add a parameter named Entity with a Base Type of Thing Name. Select Done.   In the Mashup Property panel, drag the Entity parameter to the EntityName field of the DynamicThingTemplates_AirHandler data source.   Select All Data from the GetPropertyValues Service and drag it to the Property Display Widget. When prompted, select Data from the Select Binding Target pop-up.   Expand the All Data section of the GetPropertyValues service. Drag the FanStatus field to the Checkbox Widget. When prompted, select State from the Select Binding Target pop-up.   Drag the HandlerImage field from AllData section to the Image Widget. When prompted, select SourceURL.    With the Mashup selected in the Workspace pane. Drag the EntityChanged event from the Widget Properties panel to drop GetPropertyValues service. This ensures that the GetPropertyValues service will be called at runtime when the Mashup shows a new Entity.    Click Save.   NOTE: You can configure the Property Display Widget to display only certain properties. To do this, select the Property Display Widget in the Workspace pane, click the dropdown arrow and select Configure Widget. Uncheck the fields you do not want to see (for example, name, description, tags, and HandlerImage) and click Done.   You have just created a reusable Mashup to display information based on the particular incoming AirHandler. At this point, clicking View Mashup will not display any data. Proceed through the remainder of this exercise to connect it as a Contained Mashup.       Step 5: Use Mashup Template as Component   This HandlerExample Mashup is not a Mashup Template. It will be used later to contain a Mashup Template. It already contains the layout that will be used in the example.   Adding Service   The below steps are based on the HandlerExample Mashup. This completed version can be found in the provided download.   Create a new Mashup named Handler and add a column. Drag and drop a List Widget onto the left column of the Mashup layout.    Drag and drop a Contained Mashup Widget onto the right column of the Mashup layout. In the Name property for the Contained Mashup Widget, filter and select the AirHandlerTemplate Mashup.    Click the + button in the Data pane. Select AirHandler in the Select Entity search box. Filter for and find the GetImplementingThings service, then click the blue arrow.   Check the Execute on Load checkbox. Click Done.   Configuring Data Input   Select All Data from the GetImplementingThings service and drag it to the List Widget. When prompted, select Data.    Expand the Selected Row(s) section of the GetImplementingThings service. Drag the name field to the Contained Mashup Widget. When prompted, select Name.    Select the List Widget in the Workspace pane. In the Properties section, set the DisplayField and ValueField properties to name.    With the List Widget still selected, check the AutoSelectFirstRow property. Click Save, then View Mashup.    You will see Fans and Heaters in the list because they are both implementations for the AirHandler template. The Mashup can be used for both scenarios and will show the property fields for both. The AirHandlerTemplate can be used with other templates because it is only a Mashup Template.   Based on the properties of the other Thing Templates used with this particular template, determines whether an image will be shown in the right layout.   The FinishedExample Mashup is a finished example of this exercise.       Step 6: Next Steps   Congratulations on completing the guide!   The next guide in the Customize UI and Display Options to Deploy Applications learning path is Deploy an Application.    If you have questions, issues, or need additional information, refer to:    Resource       Link Build Application Development Tips & Tricks Community Developer Community Forum Support Help Center  
View full tip
Wanting to build a simple environment with ThingWorx, using a Raspbery Pi mini-computer and an Edge MicroServer (EMS), one has to bear in mind some apparently insignificant tips, that can make a huge difference in a well-connected platform.    The Raspbery Pi can have either a few sensors attached on it and/or a Sense HAT integrated with it. A Sense HAT is an add-on board for Raspbery Pi that has an 8x8 LED matrix, a five-button joystick and a sensor, gyroscope. Tips: The ThingWorx guide "Connecting ThingWorx EMS with Rasberry Pi Quickstart" can be expanded to read Sense HAT specific sensor information A Sense HAT integrated with Raspberry Pi can be accessed from anywhere, using the existing APIs to read/write Getting location information while using the Pi board (because The Sense HAT doesn't have this feature): The Raspberry Pi has several USB ports, therefore inserting a USB GPS can be used as a workaround for connecting and reading location information (or the GPIO pins could be used to connect a GPS board) To include services and properties to read Sense HAT sensors data, start from the existing LUA example.lua template and built a Pi specific one. The EMS is a pre-built application that can be installed on Windows or Linux and it provides a bridge between the remote device and the ThingWorx platform, using the REST API AlwaysOn protocol. Tips: To read data from a sensor, it is important to use the corresponding library for that sensor; if LUA scripting is used, then this library has to be easily integrated with LUA (LSR is optional with EMS; EMS can be used standalone). Using the correct library, the EMS will be able to gather the data and push it to ThingWorx. The LSR sends properties to the EMS over the HTTP(s) protocol, which converts it to the AlwaysOn Protocol, and sends it to the Platform LUA is a process manager useful if having to integrate devices from different vendors using different modes to interact To test if the LSR is working: go to Composer -> Properties tab of the remote thing, click "Manage Bindings", select the "Remote" tab, next to "Local" - here can be seen all the remote properties added to the thing by the LSR. For creating and biding more things: create the remote thing in ThingWorx and then add them to the config.lua file in the same way you have the gateway Listing any "Remote Things" that are ready to be connected, and are not associated with any Thing, yet: Monitoring; one method to try to bind them: type the name of the thing in the Identifier section of General Information of the Thing To request a local REST API call to the default EMS port 8000, from a LSR, make sure that the GET works fine (i.e for a property update:  localhost:8000/Thingworx/Things/MyThing/Properties/myString It should return you something like this: {"rows":[{"myString":""}],"fieldDefinitions":{"myString":{"name":"myString","description":"","type":"STRING","aspects":{}}}}
View full tip
Requirements: 6.1.2+ Geofences are geometric shapes drawn virtually on a geographical area that represents a fence that can be crossed by a device.  The Axeda Platform has built-in support for mobile locations and geofences, which can be linked to the rules engine to enable notifications based on geofence crossing. What this tutorial covers This tutorial demonstrates the workflow of creating a geofence through to creating the expression rules with notifications, then how the mobile location can trigger the rules. 1) Creating the Geofence 2) Creating the Expression Rule There is currently no user interface built into the Axeda Applications Console which interacts with geofences.  For a sample application with a geofence user interface, see Sample Project: Traxeda​ (TODO).  For a single Custom Object that includes all of the functionality described below, see the end of  this document. The properties of a geofence are a name, a description, and a series of coordinates based on Well-Known Text (WKT) syntax (see the OpenGIS Simple Features Specification). def addGeofence(CONTEXT, map){     Geofence myGeofence = new Geofence(CONTEXT)        myGeofence.name = map.name     if(map.type != "polygon" && map.type != "circle")     {         throw new Exception("Invalid type: need 'polygon' or 'circle', not '$map.type'")     }     else if(map.type == "polygon")     {         def geo = map.locs.loc.inject( "POLYGON (("){ str, item ->             def lng = item.lng             def lat = item.lat             str += "$lng $lat,"         str         }         //the first location also has to be the last location         myGeofence.geometry = geo + map.locs.loc[0].lng + " " + map.locs.loc[0].lat + "))"         //Something like this is built:         //POLYGON ((-71.082118 42.383892,-70.867198 42.540923,-71.203654 42.495374,-71.284678 42.349394,-71.163829 42.221382,-71.003154 42.266114,-71.082118 42.383892))     }     else if(map.type == "circle")     {         def lng = map.locs.loc[0].lng         def lat = map.locs.loc[0].lat         myGeofence.geometry = "POINT ($lng $lat)"         //POINT (-71.082118 42.383892)         myGeofence.buffer = map.radius.toDouble()     }     myGeofence.description = "ALERT:::$map.alertType:::$map.alert"     try {          myGeofence.store()     }     catch (e){         logger.info e.localizedMessage             return null     }     myGeofence } The geofence itself does not interact with devices in any way.  Rather it is the Expression Rule that is applied to models and devices and that invokes the geofence when a mobile location is passed in. Creating the Expression Rule The Expression Rule for the Geofence is built as follows: TYPE: MobileLocation IF:  Expression set to "InNamedGeofence" for entering and "!InNamedGeofence" for exiting. The following function creates this expression rule: /* Sample call createGeofenceExpressionRule(CONTEXT, "My Geofence", "rule_MyGeofence", "in", "You entered the geofence!", "SDK Generated Geofence Rule", 100) */ def createGeofenceExpressionRule(com.axeda.drm.sdk.Context CONTEXT, String geofencename, String rulename, String alertType, String alertMessage, String ruledescription, int severity){     ExpressionRuleFinder erf = new ExpressionRuleFinder(CONTEXT)     erf.setName(rulename)     ExpressionRule expressionRule1 = erf.findOne()     expressionRule1?.delete()        def expressionRule = new ExpressionRule(CONTEXT)     expressionRule.setName(rulename)     expressionRule.setDescription(ruledescription)     expressionRule.setTriggerName("MobileLocation")     def ifExpStr = "InNamedGeofence(\"$geofencename\", Location.location)"     if(alertType == "out"){         ifExpStr = "!" + ifExpStr     }     expressionRule.setIfExpression(new Expression(ifExpStr))     expressionRule.setThenExpression(new Expression("CreateAlarm(\"$alertMessage\", severity)"))     expressionRule.setEnabled(true)     expressionRule.setConsecutive(false)     expressionRule.store()     expressionRule } Then the rule associations must be created to apply the rule to a model or device. /* Sample call findOrCreateRuleAssociations(CONTEXT, myModel, expressionRule, "EXPRESSION_RULE", "MODEL") Where expressionRule is the rule created in the above example */ def findOrCreateRuleAssociations(Context CONTEXT, Object entity, Object rule, String ruleType, String entityType){     // rule type is whether this is an expression rule     ruleType = ruleType ?: "EXPRESSION_RULE"     entityType = entityType ?: "DEVICE_INCLUDE"     RuleAssociationFinder ruleAssociationFinder = new RuleAssociationFinder(CONTEXT)     ruleAssociationFinder.setRuleId(rule.id.value)     ruleAssociationFinder.setRuleType(RuleType.valueOf(ruleType))     ruleAssociationFinder.setEntityId(entity.id.value)     ruleAssociationFinder.setEntityType(EntityType.valueOf(entityType))     def ruleAssociations = ruleAssociationFinder.findAll()     if (!ruleAssociations || ruleAssociations?.size() == 0){         def ruleAssociation = new RuleAssociation(CONTEXT)         ruleAssociation.entityId = entity.id.value         ruleAssociation.entityType = EntityType.valueOf(entityType)         ruleAssociation.ruleType = RuleType.valueOf(ruleType)         ruleAssociation.setRuleId(rule.id.value)         ruleAssociation.store()         ruleAssociations = [ruleAssociation]     }     return ruleAssociations } The rule will now be triggered when any device of the applied model sends a mobile location within the geofence, which in turn will create an alarm. Here is a custom object with the complete geofence functionality: import com.axeda.drm.sdk.Context import com.axeda.drm.sdk.geofence.Geofence import com.axeda.drm.sdk.geofence.GeofenceFinder import com.axeda.drm.sdk.rules.engine.Expression import com.axeda.drm.sdk.rules.engine.ExpressionRule import com.axeda.drm.sdk.rules.engine.ExpressionRuleFinder import com.axeda.drm.sdk.rules.engine.RuleAssociation import com.axeda.drm.sdk.rules.engine.RuleAssociationFinder import com.axeda.drm.sdk.rules.engine.RuleType import com.axeda.drm.sdk.common.EntityType import com.axeda.drm.sdk.device.Model import com.axeda.drm.sdk.device.ModelFinder try {     def Context CONTEXT = Context.getSDKContext()     def model = findOrCreateModel(CONTEXT, "FooModel")     def sampleCircle = [         "name": "My Circle",         "alert": "My Geofence Alert Text",         "type": "circle",         "alertType": "in",         "radius": "65.76",         "locs": [             [                 "loc": [   "lat": "42.60970621339408",   "lng": "-73.201904296875"   ]             ]         ]     ]     def samplePolygon = [         "name": "My Polygon",         "alert": "My Geofence Alert Text",         "type": "polygon",         "alertType": "out",         "locs": [             ["loc": [  "lng": -71.2604999542236,  "lat": 42.3384903145478  ]],             ["loc": [  "lng": -71.4218616485596,  "lat": 42.3242772020001  ]],             ["loc": [  "lng": -71.5585041046143,  "lat": 42.2653600946699  ]],             ["loc": [  "lng": -71.5413379669189,  "lat": 42.1885837119108  ]],             ["loc": [  "lng": -71.4719867706299,  "lat": 42.1137514551207  ]],             ["loc": [  "lng": -71.3737964630127,  "lat": 42.0398506628541  ]],             ["loc": [  "lng": -71.2508869171143,  "lat": 42.0311807962068  ]],             ["loc": [  "lng": -71.1355304718018,  "lat": 42.2084223174036  ]],             ["loc": [  "lng": -71.2604999542236,  "lat": 42.3384903145478  ]]         ]     ]     // find geofence if it exists     def circle = findGeofenceByName(CONTEXT, sampleCircle.name)     // create circular geofence     if (!circle){         circle = addGeofence(CONTEXT, sampleCircle)     }     // create rule for circular geofence     def circleRule = createGeofenceExpressionRule(CONTEXT, circle.name, "${circle.name}__Rule",                                                                            sampleCircle.alertType, sampleCircle.alert, "SDK Generated Geofence Rule", 100)     // apply rule to new Model     findOrCreateRuleAssociations(CONTEXT, model, circleRule, "EXPRESSION_RULE", "MODEL")     def polygon = findGeofenceByName(CONTEXT, samplePolygon.name)     if (!polygon){         polygon = addGeofence(CONTEXT, samplePolygon)     }     def polygonRule = createGeofenceExpressionRule(CONTEXT, polygon.name, "${polygon.name}__Rule",                                                                               samplePolygon.alertType, samplePolygon.alert, "SDK Generated Geofence Rule", 100)     // apply rule to new Model     findOrCreateRuleAssociations(CONTEXT, model, polygonRule, "EXPRESSION_RULE", "MODEL") } catch (Exception e) {     logger.info(e.localizedMessage) } return true def findGeofenceByName(CONTEXT, name){     GeofenceFinder geofenceFinder = new GeofenceFinder(CONTEXT)     geofenceFinder.setName(name)     def geofence = geofenceFinder.find()     geofence } def addGeofence(CONTEXT, map){     Geofence myGeofence = new Geofence(CONTEXT)     myGeofence.name = map.name     if(map.type != "polygon" && map.type != "circle") {         throw new Exception("Invalid type: need 'polygon' or 'circle', not '$map.type'")     } else if(map.type == "polygon") {         def geo = map.locs.loc.inject( "POLYGON (("){ str, item ->             def lng = item.lng             def lat = item.lat             str += "$lng $lat,"             str         }         //the first location also has to be the last location         myGeofence.geometry = geo + map.locs.loc[0].lng + " " + map.locs.loc[0].lat + "))"         //Something like this is built:         //POLYGON ((-71.082118 42.383892,-70.867198 42.540923,-71.203654 42.495374,-71.284678 42.349394,-71.163829 42.221382,-71.003154  42.266114,-71.082118 42.383892))     } else if(map.type == "circle") {         def lng = map.locs.loc[0].lng         def lat = map.locs.loc[0].lat         myGeofence.geometry = "POINT ($lng $lat)"         //POINT (-71.082118 42.383892)         myGeofence.buffer = map.radius.toDouble()     }     myGeofence.description = "ALERT:::$map.alertType:::$map.alert"     try {         myGeofence.store()     }  catch (e) {         logger.info e.localizedMessage         return null     }     myGeofence } def createGeofenceExpressionRule(com.axeda.drm.sdk.Context CONTEXT, String geofencename, String rulename,                                                      String alertType, String alertMessage, String ruledescription, int severity) {     ExpressionRuleFinder erf = new ExpressionRuleFinder(CONTEXT)     erf.setName(rulename)     ExpressionRule expressionRule1 = erf.findOne()     expressionRule1?.delete()     def expressionRule = new ExpressionRule(CONTEXT)     expressionRule.setName(rulename)     expressionRule.setDescription(ruledescription)     expressionRule.setTriggerName("MobileLocation")     def ifExpStr = "InNamedGeofence(\"$geofencename\", Location.location)"     if(alertType == "out"){         ifExpStr = "!" + ifExpStr     }     expressionRule.setIfExpression(new Expression(ifExpStr))     expressionRule.setThenExpression(new Expression("CreateAlarm(\"$alertMessage\", severity)"))     expressionRule.setEnabled(true)     expressionRule.setConsecutive(false)     expressionRule.store()     expressionRule } def findOrCreateRuleAssociations(Context CONTEXT, Object entity, Object rule, String ruleType, String entityType) {     // rule type is whether this is an expression rule     ruleType = ruleType ?: "EXPRESSION_RULE"     entityType = entityType ?: "DEVICE_INCLUDE"     RuleAssociationFinder ruleAssociationFinder = new RuleAssociationFinder(CONTEXT)     ruleAssociationFinder.setRuleId(rule.id.value)     ruleAssociationFinder.setRuleType(RuleType.valueOf(ruleType))     ruleAssociationFinder.setEntityId(entity.id.value)     ruleAssociationFinder.setEntityType(EntityType.valueOf(entityType))     def ruleAssociations = ruleAssociationFinder.findAll()     if (!ruleAssociations || ruleAssociations?.size() == 0){         def ruleAssociation = new RuleAssociation(CONTEXT)         ruleAssociation.entityId = entity.id.value         ruleAssociation.entityType = EntityType.valueOf(entityType)         ruleAssociation.ruleType = RuleType.valueOf(ruleType)         ruleAssociation.setRuleId(rule.id.value)         ruleAssociation.store()         ruleAssociations = [ruleAssociation]     }     return ruleAssociations } def findOrCreateModel(Context CONTEXT, String modelName) {     ModelFinder modelFinder = new ModelFinder(CONTEXT)     modelFinder.setName(modelName)     def model = modelFinder.find()     if (!model){         model = new Model(CONTEXT, modelName);         model.store();     }     return model } https://gist.github.com/axeda/6529288/raw/5ffca58c3c48256b81287d6a6f2d2db63cd5cd2b/AddGeofence.groovy
View full tip
  If you’ve ever wished you could see into the future, you’ve come to the right place! Put your reflective suits and sunglasses on to prepare for a glimpse into the future of our upcoming ThingWorx 8.4 release! Here are sneak peeks of the top three features you may not have known are coming in ThingWorx 8.4.   1. Thing Presence While it sounds like something from an episode of Ghost Hunters, Thing Presence provides insight into the communication state of polling or duty cycle Things (those that check in and out on a periodic basis). We’re introducing a new IsReporting state, which would be set to true when polling assets check in on time and are considered “present in the network.” This helps to bridge the gap where the traditional ThingWorx IsConnected state reports offline and does not coincide with the actual network presence of the device.   Thing Presence: New "IsReporting" State2. Data Helpers You may not know what Data Helpers are, but if you’re a longstanding ThingWorx developer you likely know about Expression and Validator widgets. These widgets were handy because they allowed you to write conditional logic or input validation to drive behaviors in the UI, but were super frustrating to use. They took up lots of room on the visual layout canvas and only had a very little textbox to edit them. In the 8.4 release, we are happy to announce that these two widgets will no longer be placed on the layout canvas. Instead, they will have a dedicated editor to work from with plenty of room for code development, parameter configuration and event definition and binding. We’re wrapping all of this functionality into a nice little feature called…Data Helpers. Data Helpers: Expression and Validator Widgets No Longer in Layout Canvas3. ThingWorx Flow In case Thing Presence and Data Helpers aren’t exciting enough, we’re also introducing ThingWorx Flow, a neat new feature set that dramatically speeds development of connected applications through integrations with business systems like Salesforce and SAP. Imagine that, when a certain alert triggers, you want to automatically create a Salesforce service ticket and even send an emergency text to an operator to prevent damage to a device. A large set of out-of-the-box system connectors (PTC Windchill, Office 365, Google Docs, Slack, Jira and more) are included, which you can drag and drop onto a canvas to visually define a workflow. In the example below, a ThingWorx-connected device element, a Salesforce “create case” action and a Twilio text message connector were dropped into the canvas to create a visual workflow. Orchestration: Example Workflow that Creates Salesforce Cases and Alerts OperatorsThing Presence, Data Helpers & Flow—get ready for these and more in ThingWorx 8.4!   Stay tuned for future posts that go into greater depth about each of these features and comment your thoughts below!   Stay connected, Kaya
View full tip
Signals indicate the predictive strength or weakness of specific features on the goal variable. Use Signals to explore which features are important to predicting outcomes, and which are not. Note: Please be aware that the video states that a model has to be created before Signals can run, but this is no longer the case for version 8.1.   Updated Link for access to this video:  Create Signals In ThingWorx Analytics Builder
View full tip
Procedure to configure a secure connection between Windchill and Thingworx server. Assuming Windchill and Thingworx are already configured with SSL, this video consists of detailed steps for setting up Thingworx and Windchill to trust each other.     For full-sized viewing, click on the YouTube link in the player controls.   Visit the Online Success Guide to access our Expert Session videos at any time as well as additional information about ThingWorx training and services.
View full tip
Announcements