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:
Every edge component that connects to the ThingWorx platform requires an Application Key.  This 'AppKey' provides both authentication and authorization control.  When an edge component connects it steps through a connection process.  The second step of that process is to send the AppKey to the platform.  The platform will inspect the key and ensure that it is valid.  It also creates a session for that edge connection and associates the AppKey with the session.  Any future requests that are sent over that AlwaysOn connection will execute under the security context configured for the user associated with the AppKey. In order for edge applications to interact with the platform they require a certain set of permissions.  It is a best practice to not associate the Administrator user with an Application Key.  Doing this would allow an edge application to invoke any and all services on the platform, and to modify the property values of any thing.  The permissions applied to an edge component's AppKey should be the minimum set required for your application to function. The AppKey associated with an edge component is typically associated with a single Thing, or a collection of Things, usually of the same ThingTemplate.  Identify the Thing(s) or ThingTemplate(s) that your application will interact with.  There are four types of interactions for edge components: property reads, property writes, service invocations, and event executions (edge components do not subscribe to events).  These four types of interactions match the runtime permissions that can be configured on a Thing, or the 'run time instance' permissions for a ThingTemplate. If an edge application will be reading or writing all properties of a particular Thing, then applying the 'read property' and 'write property' permissions is appropriate.  If only a select set of a Thing's properties will be read or written, then read and/or write permission should be disabled, and only the select properties should be enabled using overrides. Since every Thing has a number of generic services, the 'service execute' permission should be disabled, and overrides should be configured for the selected services that the edge needs access to.  In addition, overrides should be configured for the 'UpdateSubscribeProeprtyValues' service and for the 'ProcessRemoteEvents' service.  Edge components often use these service to update a collection of properties or to fire a set of events. Finally, if your edge application triggers events on a Thing, overrides should be used to provide execute permission for those events. In summary, the safest path to configuring edge permissions is to create a new user and AppKey with no permissions applied, and to then selectively apply permissions for that user only on the Thing or Things that your edge components will interact with.
View full tip
Suppose, if you have uninstalled ThingWorx Flow successfully with appropriate steps. And, tried re-installing which is failing with below error in the flow installation logs,      " FATAL: SystemCallError: windows_service[RabbitMQ] (orchestration::rabbitmq line 120) had an error: SystemCallError: The specified service does not exist as an installed service. - OpenService: The specified service does not exist as an installed service."     This is due to the registry problem. To resolve this, need to delete the registry key. Following steps are need to be performed:    Go to Start-> Search and Run 'regedit' as an Administrator Navigate to 'Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Ericsson' Delete Ericsson key and its sub key Restart your machine Install ThingWorx Flow again and it will be successful.   Here is the article link on this subject: https://www.ptc.com/en/support/article/CS328600     Thanks, Vibhuti Angne
View full tip
Remote Monitoring of Assets in Connected Factories   As stated in the previous reference benchmark, one of the missions of the IOT Enterprise Deployment Center (EDC) is to showcase how real-world IOT business problems are solved. Our goal is that these benchmarks can be used as a reference or baseline for architects working on their own implementations, showing not only a successful at-scale implementation, but also what happens when that same implementation is pushed to, or even past, it's limits.   The second in this series is attached here, this time reflecting a Connected Factory implementation. ThingWorx was deployed alongside Kepware Server, with the numbers of things, the number of properties, and the write rate for those properties being varied to once again test the capabilities of a remote monitoring use case, but this time in a Connected Factory setting. The business logic was kept simple to ensure it was not the limiting factor, as the throughput between Kepware Server and ThingWorx was pushed to the limit. See first hand the capabilities of Kepware Server and ThingWorx Foundation to handle implementations centered around real-time data reporting   More Connected Factory implementations will be added to this document in time, with multiple Kepware Server deployments and other scenarios to come. Please feel free to use this community post to ask any questions about our approach and discuss any design, deployment, and simulation factors. 
View full tip
Building More Complex Tests in JMeter Overview This is the second in a series of articles which help inform how to do user load testing in ThingWorx. This article picks up where the previous left off, continuing with the project created there. The screenshots do appear a little differently here because a new “Look and Feel” was selected for the JMeter application (switched from “Metal” to “Windows Classic”) to provide more readable screenshots. In this guide, we are going to make the very simple project more complex, working towards a better representation of a real load test. The steps below walk you through how to create and configure thread groups and parameterize the processes and procedures defined by each thread group.   Adding More Thread Groups Within JMeter, thread groups are used to organize the HTTP requests in a test into various processes or procedures, such that different mashups (and all of the HTTP requests required on each) or processes can be executed simultaneously by different thread groups throughout the test. Varying the number of threads in a group is how to vary the number of users accessing that mashup during the test, a number which increases over time in accordance with the ramp up time. The thread group name will also show up in the Summary Report tab at the end of the test, making it easier to parse through and graph the results. Start by renaming the existing thread groups so that their process or procedure names are recognizable at the end of the test: Highlight the line which reads “HTTP(S) Test Script Recorder”. (Optional) Add an Include filter to only capture the URLs relevant to your application using the Requests Filtering tab. For example, with the escape character \ necessary for ‘.’, myhost.mycompany.mydomain becomes: myhost\.mycompany\.mydomain Now record a new thread group clicking the “Start” button: Once the control box shows up in the top left corner, click to open a browser and access the ThingWorx Navigate application. Then click on “View Parts List” or some other mashup: Once the mashup loads, search using a string and/or wildcard, or click on one of the recent results if any exist: Wait for the mashup to fully load with the details on that part or assembly, and then click “Stop” in the recording controller window: All of the HTTP requests performed in the process of loading and using this mashup will be added to the JMeter project here: Next, add a new thread group manually to the project: Highlight the newly created “Thread Group” (default name) and rename it to something that relates to the nature of that process: Drag and drop the new collection of requests so that it is considered a part of the new thread group: Then drag the whole group up so that it is next to the other thread groups in the test: In more complex projects, different thread groups may be added at different times, and each time, the service calls are all assigned an index (at the end of the request URL, for example: <request>-344). These indexes may not be unique depending on how and when the thread groups were created, especially in more complex tests. The easiest way to fix this issue is save the test from the JMeter GUI, then open the JMX file in a text editor and perform a find and replace within the relevant section of text.   This is usually done using a regular expression for the number. For example, if the request name indexes are numbered -500 through -525, a regular expression to increase them to -700 through -725 would be (in Notepad++): Find: -5([0-9])([0-9]) Replace: -7\1\2 Note that if you do not use a Request Filter, sometimes the recorder will log URLs that are not part of the target application, like these “generate” samplers. These URLs are typically happening in the background of the browser to track performance, security and errors. These can be deleted: At other times, you will be repeating steps that are already part of another thread group, for example: logging in. This genidkey is a part of the login, as you can see if you look back at the login thread group. Because logging in is only necessary once, and it is assumed to be complete by the time the test starts on the second thread group, this entire section can be deleted: To see for sure if a request can be removed because it is called in a previous thread group, do a non-case-sensitive search for the name of the request: All of the requests found in this particular instance were performed in the previous thread group, so therefore this entire category can also be deleted: Another odd thing you may see (if you do not use a Request Filter with the recording feature) are “blank” requests like these: The recorder isn’t sure what to call these “non-requests”, so anything like this that isn’t an actual URL within the target application should be deleted. Static downloads should be disabled or deleted from scale testing since they are usually cached by the user browser client. In this ThingWorx example, there are static “MediaEntites” which can be deleted or disabled: Within the JMeter client there is no good way to highlight and reset them all at once, unfortunately. The easiest way to remove all of these at once is to open the JMX file in a text editor and use regex expressions for search and replace “enabled=true” with “enabled=false”. Most text editors have examples on how to use regular expressions within their Help topics. The above example is for Notepad++. Parameterize Thread Groups Parameterization is usually the part of creating a JMeter test that takes the most effort and knowledge. Some requests will require the same information for every thread, information which can therefore be defined statically within the JMeter element rather than being parameterized. Some values used within the JMeter test script can be parameterized as inputs in the top level of the test controller, for example: Duration, RampUp time, ApplicationHost, ApplicationPort.   Other values may be unique to only one thread group and could be defined in a User Defined Variables element within that group controller. The value(s) used within a request can also be determined on the fly by the results of earlier requests within a thread group. These request results typically must be post-processed and parameterized for later thread elements to function correctly.   The highest level values that are unique to each thread should be inputs from a CSV file that are passed into the threads as parameters, for example Username and Password. Data used within the test is usually parameterized in order to better emulate real world application use by multiple users. In the following example, we will parameterize the number of users for each thread group by adding a user- defined variable.   Start by selecting the new thread group and parametrizing the number of threads (i.e. the number of users accessing this mashup at a time during the test). The way to enter a variable is with syntax like this: $(searchandviewpartstructure_threads) In this case, make this a user defined variable: or a variable for the whole project, by highlighting “Test Plan” and adding the information there. Begin looking at the samplers to see what types of things need to be parameterized in your test. Consider such things as: thread count (as shown above), ramp up time (also depicted above), duration, timings, roles, URL arguments, info table information, search result information, etc.   Another example here parameterizes the search parameters for a query by adding an overall search string column to a CSV file (which can then be randomly generated by some other script): First, parameterize the body data of the request by highlighting the request, and changing the value of the desired field to something like this: $(searchString) Next, define the parameter under the Test Plan and set a default value: Now define the searchString column again as part of the CSV Data Set: Now it can be varied simply by providing different pseudo-random values with wildcards and/or known values in the CSV file.   Post Processors and Extractors Most JMeter load tests become more complex when the results of one request are sent as parameters into later requests. This is done in JMeter by using Post Processors (Extractors), tools which facilitate extracting information out of the request results so it can be assigned to JMeter parameters. There are many different types of extractors which can process the results of previous requests: CSS Selector Extractor – commonly used extractor for values returned as html attributes JSON Extractor – processes JSON objects using regular expressions BeanShell Post Processor –facilitates using code scripts to process return text when needed Regular Expression Extractor – JMeter supports use of regular expressions on request results   The JSON Extractor can be used to find and store information like the partOID number for a Windchill part as a parameter in JMeter, which can then be used to build more realistic workflows within the JMeter test. The example below steps you through setting up a JSON Post Processor.   Start by right-clicking the request that contains the results of our search. Then click “Add” > “Post Processors”> “JSON Extractor”, as shown in the image below: The extractor will now show up under that request as a sub-menu item. Select it, and name the variable something easy to reference. For the JSON Path expressions, pull the object number or some other identifying characteristic out of the search results: $.rows[0].objNumber for example. Another option would be to take information like the partOID number send that into the search string field, by defining both as properties and having one refer to the other. To pull the partOID out, use a Regular Expression Extractor: Another thing to parameterize is the summary report result file name. Adding in the number of users and ramp up time can result in files that are easier to reference later being stored on your machine. We will cover generating and reviewing Summary Reports in full in the next article in this series.     Conclusion In this article we saw how to create new thread groups, removing extraneous requests from those groups, and reduce the overall ambiguity of which thread groups are representing which processes or mashup calls. We also covered how to parameterize the individual requests as well as the summary report. Note that things like Windchill URL and hostname, search parameters and part IDs, timings, durations, offsets, anything at all that influence the results of the test, should not be hard-coded. It is better to create variables for these things to ensure that all of the various simulated activities are configured in the exact same way every time. That way, the system can be tested again and again under various strains and loads until the capabilities of the application are verified.
View full tip
Applicable Releases: ThingWorx Navigate 1.6.0 to 1.7.0     Description:   How to use InfoEngine tasks to retrieve and take actions on Windchill data to use in Navigate services The following agenda is reviewed in the session: Use case introduction Create I*E task Create service Create Mashups Execute I*E Task       The concepts of this session are still valid for newer Navigate versions, but the session was recorded using old Composer
View full tip
Applicable Releases: ThingWorx Navigate 1.8.0 to 1.9.0     Description:   New improvements of the ThingWorx Navigate Installer with the following agenda: What's new Load Balancer Multiple Windchill Systems Integration Runtime NSSM How to select files to download Installer installation steps Demo Questions         Additional information How to install PTC Navigate
View full tip
Applicable Releases: ThingWorx Navigate 1.6.0 to 8.5.0     Description:     How to use PingFederate script: Prerequisites Configuration Run the script Generated artifacts Live Demo         Associated documentation is available in PTC Single Sign On Architecture and Configuration Overview guide: PTC Single Sign-on Architecture and Configuration Overview  
View full tip
Applicable Releases: ThingWorx Navigate 1.6.0 to 8.5.0   Description:   Covers Single Sign On concepts and main items to take into account when defining SSO architecture, with the following agenda: What is Single Sign on? What is PTC Strategy for Single Sign on? How does PingFederate fits in the existing SSO Federation? What products currently can be configured for SSO? Optional SSO in Navigate 1.6 What are the key diferences in SSO over the different Navigate versions? What are we doing internally to prepare for SSO? What resources are available for SSO discussions?         Related articles for further information Related Service: Configure SSO for Navigate
View full tip
Applicable Releases: ThingWorx Platform 7.0 to 8.5   Description:   Covers how to apply patch upgrades to ThingWorx installation, with the following agenda: How to read ThingWorx version Upgrading to a major/minor version of the platform Focus on upgrading to a patch version of the platform Upgrading extensions       Always check the patch release notes for additional information and specific steps
View full tip
Applicable Releases: ThingWorx Platform 7.0 to 8.5   Description:   Covers the main topics that need to be considered when evaluating or designing a scalability strategy for the environment and applications The agenda contains the following topics: Introduction Connection Server Federation High Availability       Some of the databases mentioned in the presentation are no longer supported Please refer to the compatibility matrix to check supported databases Related Articles How to configure a Federate architecture Is high availability supported in ThingWorx  
View full tip
Applicable Releases: ThingWorx Platform 7.0 to 8.4   Description:   A practical example of how to build a data model in ThingWorx following a pre-defined design Following topics are covered: Review existing Design Plan Build all required entities in ThingWorx Composer Test the model and review scalability and reusability         The session was recorded using the old ThingWorx Composer, but the concepts are still applicable Related Success Service - Principles of Thingworx Modeling Related Service - Design your Thingworx Model
View full tip
Applicable Releases: ThingWorx Platform 7.0 to 8.4   Description:   Concepts and basic Mashup design using an use case as example Following topics are covered: Recap Scenario Requirements and review concept design Introduction to Mashup Builder Design Mashup to visualize data     Related Success Service The session was recorded using the old ThingWorx Composer, but the concepts are still applicable
View full tip
Applicable Releases: ThingWorx Platform 7.0 to 8.5   Description:   Introduction to Edge connectivity in Thingworx Foundation: Edge concept and definition Available edge products Why use Edge products What is Edge Microserver and Lua Script Resource What are the SDKs What are connection servers AlwaysOn and HTTP protocols ThingTemplates to connect remote devices     The session was recorded in an old ThingWorx version, but all the concepts are still applicable
View full tip
Applicable Releases: ThingWorx Platform 8.3 to 8.5   Description:   Installation walkthrough of ThingWorx foundation using PostgreSQL, materializing some main steps that might be difficult to read in the installation guides       Reference installation guides for each version
View full tip
Applicable Releases: ThingWorx Platform 7.0 to 8.5   Description:   Concepts and methodology to design a data model using an use case as example The following topics are covered: Real-world Product Example ThingWorx Terminology and concepts Formulate an implementation Strategy       Related Success Service
View full tip
Applicable Releases: ThingWorx Platform 7.0 to 8.4   Description:   Strategy and tools for Thingworx application backups Backup Terminology and concepts Drivers to define a backup strategy Tips for executing backup in a Thingworx instance: Tomcat, certificates, Configuration and file system data, application specific files, database     Neo4J database mentioned in the session is no longer supported For more information check Best Practices for ThingWorx Backup
View full tip
Applicable Releases: ThingWorx Platform 8.0 to 8.5; ThingWorx Navigate 1.5.0 to 8.5.0   Description:   Definition and concepts of Single Sign On (SSO), terminologies, components and architecture, as well as configuration prerequisites and high level steps to configure using PingFederation with Windchill and Navigate and main troubleshooting techniques    
View full tip
Applicable Releases: ThingWorx Platform 7.0 to 8.5   Description:   Main concepts and best practices for devops methodology such as Naming Conventions Setup and management of environments for development and testing Import/Export process and application deployment Use of Tags and Project to control your development Coding Standards Validation best practices         For project packaging and deployment, make sure to check the content about Solution Central created after this session was released
View full tip
    Hi, everyone!   In previous tech tips, I’ve introduced the ThingWorx 9.0 active-active clustering feature and provided architectural details and configurations. If you haven’t already, I recommend you check them out to learn more about how active-active clustering enables higher availability for ThingWorx: 9.0 Sneak Peek: Active-Active Clustering for ThingWorx 9.0 Sneak Peek: ThingWorx Architecture for Active-Active Clustering 9.0 Sneak Peek: Flexible Deployments of Active-Active Clustering for ThingWorx “ThingWorx on Air” Ep. 08: FAQs: ThingWorx Active-Active Clustering for Higher Availability   Today, I’ll provide more details around the load balancer in the active-active clustering architecture, some of its requirements, and a few configuration examples. Ready? Here we go! Here are the top four FAQs around the load balancer that will help you maximize your use of active-active clustering.   What do you mean by load balancing? Load balancing is the process of distributing network traffic across multiple servers. An algorithm employed by the load balancer or a proxy, determines how the traffic is distrusted. Round robin, fastest response, and least established connections are some of the most common methods of load balancing and provide different benefits, but all fundamentally ensure no single server bears too much demand. By spreading the traffic, load balancing improves application responsiveness. It also increases availability of applications and websites for users. Modern applications cannot run without load balancers. In general load balancers can run as hardware appliances or as software-defined. Hardware appliances often run proprietary software optimized to run on custom processors. As traffic increases, the vendor simply adds more load balancing appliances to handle the volume. Software defined load balancers usually run on less-expensive, standard Intel x86 hardware. Installing the software in cloud environments like Azure VMs or AWS EC2 eliminates the need for a physical appliance.   Following the seven-layer Open System Interconnection (OSI) model, load balancing occurs between layers four to seven (L4-Transport, L5-Session, L6-Presentation and L7-Application), whereas network firewalls are at levels one to three (L1-Physical Wiring, L2-Data Link and L3-Network). Load balancers have a various capabilities, which include: L4 — directs traffic based on data from network and transport layer protocols, such as IP address and TCP port. L7 — adds content switching to load balancing. This allows routing decisions based on attributes like HTTP header, uniform resource identifier, SSL session ID and HTML form data. GSLB — Global Server Load Balancing extends L4 and L7 capabilities to servers in different geographic locations. More enterprises are seeking to deploy cloud-native applications in data centers and public clouds. This is leading to significant changes in the capability of load balancers. What is a load balancer’s role in the ThingWorx Active-Active Clustering setup? As is true of any load balancer, the load balancer required in the ThingWorx Foundation active-active clustering architecture is responsible for distributing incoming traffic across the nodes within the cluster.   In the Active-Active Clustering architecture for ThingWorx, the load balancer distributes the traffic using a round-robin method. Please note that there are a several algorithms that provide load balancing techniques and this article is a good read for further understanding of it. A round-robin method rotates servers by directing traffic to the first available server and then moves that server to the bottom of the queue.   In ThingWorx clustering setup, while both WebSocket and HTTP incoming traffic are handled in a round-robin manner, they are routed differently by the load balancer.   HTTP traffic is directly distributed amongst the ThingWorx Foundation Servers within the cluster. Sticky sessions are used for the HTTP sessions—sticky via cookie, so individual users are tied directly to a single server node and see all of their changes instantaneously.   WebSocket traffic is distributed across the and is balanced via source IP to ensure each request from a device goes through the same connection server. From the ThingWorx Connection Server, the device traffic is distributed amongst the underlying ThingWorx Foundation Servers, not requiring another load balancer between the ThingWorx Connection Servers and ThingWorx Foundation Servers.   Please note that the WebSocket traffic load does not necessarily get distributed evenly nor do the incoming requests due to stickiness. For example: 2 users connect HTTP, one sends 100 requests and the other sends 2. Since they are sticky, it is not distributed evenly. 2 devices connect to a ThingWorx Connection Server. 1 is a gateway for 100 other devices, all requests fthe gateway go to the same connection server. The Connection Server does a round-robin to the underlying Foundation Servers so that the load would be better distributed across, but the load balancer is sticky to a ThingWorx Connection Server.     Which load balancer can I choose for setting ThingWorx in an Active-Active Cluster mode? ThingWorx active-active clustering is pretty much load balancer agnostic, meaning if the load balancer of your choosing that you might be using in your IT center meets the requirements, it can be utilized within the active-active clustering architecture. The load balancer is required to support the following features: Based on Layer-7 architecture Supports HTTP and WebSocket traffic Ability to support sticky sessions for  traffic and/or IP based stickiness. IP based means all traffic from a specific IP will be routed to the same server (this can be a problem with gateway type scenarios). Sticky sessions are based on a cookie, sessions are routed to same server based on cookie. Different users same IP could route to different machines. Health checking on server endpoints. (optional) It can manage SSL termination and SSL internal endpoints. Supports Path based routing. This is the ability to route to specific backends based on the URL or part of the URL. By default, all routes should go to the platform servers, but the following routes should go to the connection server: /Thingworx/WS /Thingworx/WSTunnelServer /Thingworx/WSTunnelClient /Thingworx/VWS All servers should be setup to only be part of load balancing based on their health configuration.  When configuring health check frequency, they should be run at a rate based on the tolerance for bad requests to be processed. Thingworx Foundation has a /health and /ready endpoint.   The /Thingworx/ready endpoint should be used for the load balancer.  It will return a 200 when the server is ready to receive traffic.  Connection Server checks health requests on a specific port and will return 200 when healthy. What are some of the compatible load balancers that I can use? While you can use any load balancer that satisfies the above request and meets your IT standards, below are some of the third-party load balancers that provide the features that are required of the active-active clustering architecture: HAProxy - HAProxy is a free, open source software that provides a high availability load balancer and proxy server for TCP and HTTP-based applications that spreads requests across multiple servers. It is very powerful and supports monitoring capabilities out of the box. PTC tests the clustering architecture using HA Proxy and provides a reference document for the same through the ThingWorx Foundation help center docs. Please note that it runs only on Linux environments. For a quick reference example of how to set up an HAProxy load balancer, see our Help Center here. NGINX - NGINX is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy serve. NGINX provides proxy capabilities as well as web server options. Some features like sticky sessions, advanced monitoring are not available in the opensource version and require you upgrade to NGINX Plus.  If you’re a Windows shop or already use NGINX Plus in your IT, then you may choose this load balancer offering.  However, please note that PTC doesn’t provide any official configuration steps of setting it up through our Help Center documentation. For a quick reference example of how to set up an NGNIX load balancer, see our Help Center here. AWS Application Load Balancer - Application Load Balancer (ALB) is best suited for load balancing of HTTP and HTTPS traffic and provides advanced request routing targeted at the underlying ThingWorx applications. Operating at the individual request level (Layer 7), Application Load Balancer routes traffic to targets within Amazon Virtual Private Cloud (Amazon VPC) based on the content of the request. If you’re running ThingWorx deployments on AWS, then you may choose to use AWS-offered managed load balancing services. F5: F5 Networks through its BIG-IP Local Traffic Manager solution provides advance load balancing techniques such as a full proxy where you can inspect, manage, and report on application traffic entering and exiting your network with additional features around SSL and performance optimization. Load balancers are another area where ThingWorx allows for flexibility and extensibility by enabling you to use the load balancer of your choosing that you’re most comfortable with or that best suits your needs (provided it meets the criteria above). You can also configure SSL or TLS for HAProxy when using ThingWorx HA clustering for end-to-end security. I hope this tech tip helped you develop a deeper understanding of how active-active clustering leverages load balancers to further increase your performance and thus availability and machine uptime, among many others.   If you’re not already on 9.0 and using active-active clustering, be sure to upgrade!   Stay connected, Kaya  
View full tip
Hello!   “ThingWorx on Air” Episode 9 is now available! Grab your headphones and listen to Neal, an Azure subject matter expert, and Janie, a PM focused on Azure functionality, introduce a new integration we’re working on between Kepware, Azure IoT Edge, Azure IoT Hub and ThingWorx.   Discover how you’ll be able to leverage and model OPC UA data directly in the Thing Model, how you’ll be able to connect just about any OPC UA device through the Azure stack and to the Cloud, and so much more. We can’t wait to continue to extend ThingWorx functionality to support industry standards like the OPC UA protocols.   Are you excited? Wish you could get your hands on this functionality early? You can! Reach out to Janie at jpascoe@ptc.com to learn how you can become involved in an exclusive OPC UA & ThingWorx preview program.   Enjoy the episode and let me know what you think below!   Stay connected, Kaya
View full tip
This small tutorial enables you to manage payload decoding for Adeunis Devices within ThingWorx Composer in less than 10 minutes.  Adeunis Devices communicates on LPWAN networks (LoRaWAN / Sigfox) covering sectors such as smart building, smart industry and smart city. The encoding is also possible but it will be covered in another article.   1. Get Adeunis Codec Adeunis is providing a codec enabling payload encoding and decoding.  Download here the resource file containing the codec.  Unzip the file and edit "script.txt" with your favorite text editor. Copy all text contained in the file.   2.  Create AdeunisCodec Thing Create a Thing called "AdeunisCodec" based on the GenericThing Template.   3. Create a service called "Decode" Create a Decode Service with the following setup: Inputs: type (String), payload (String) Output as JSON Past the previously copied "script.txt" content Save   4. Correct a couple of Warnings Remove all "var codec;" occurences except first one at line 1191.  Remove semi columns at lines 985,1088, 1096 and 1172   5. Remove the following section The codec relies on implementing functions on JavaScript prototypes which is not supported by ThingWorx Rhino JavaScript Engine. See the following documentation section, here.    Remove from line 1109 to 1157.   The following classes overrides will be removed: Uint8Array.prototype.readUInt16BE Uint8Array.prototype.readInt16BE Uint8Array.prototype.readUInt8 Uint8Array.prototype.readUInt32BE Uint8Array.prototype.writeUInt16BE Uint8Array.prototype.writeUInt8 Uint8Array.prototype.writeUInt32BE 6. Add new implementations of the removed functions The functions are adapted from a JavaScript framework which contains resources that helps dealing with binary data, here. Insert the  following section at the top of the "Decode" script.         function readInt16BE (payload,offset) { checkOffset(offset, 2, payload.length); var val = payload[offset + 1] | (payload[offset] << 8); return (val & 0x8000) ? val | 0xFFFF0000 : val; } function readUInt32BE (payload,offset) { checkOffset(offset, 4, payload.length); return (payload[offset] * 0x1000000) + ((payload[offset + 1] << 16) | (payload[offset + 2] << | payload[offset + 3]); } function readUInt16BE (payload,offset) { checkOffset(offset, 2, payload.length); return (payload[offset] << | payload[offset + 1]; } function readUInt8 (payload,offset) { checkOffset(offset, 1, payload.length); return payload[offset]; } function writeUInt16BE (payload,value, offset) { value = +value; offset = offset >>> 0; checkInt(payload, value, offset, 2, 0xffff, 0); if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 8); payload[offset + 1] = value; } else objectWriteUInt16(payload, value, offset, false); return offset + 2; } function writeUInt8 (payload,value, offset) { value = +value; offset = offset >>> 0; checkInt(payload, value, offset, 1, 0xff, 0); if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value); payload[offset] = value; return offset + 1; } function writeUInt32BE (payload,value, offset) { value = +value; offset = offset >>> 0; checkInt(payload, value, offset, 4, 0xffffffff, 0); if (Buffer.TYPED_ARRAY_SUPPORT) { payload[offset] = (value >>> 24); payload[offset + 1] = (value >>> 16); payload[offset + 2] = (value >>> 8); payload[offset + 3] = value; } else objectWriteUInt32(payload, value, offset, false); return offset + 4; } function objectWriteUInt16 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffff + value + 1; for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> (littleEndian ? i : 1 - i) * 8; } } function objectWriteUInt32 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffffffff + value + 1; for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * & 0xff; } }     7. Add the following function to support previous inserted functions     function checkOffset (offset, ext, length) { if ((offset % 1) !== 0 || offset < 0) throw new Error ('offset is not uint'); if (offset + ext > length) throw new Error ('Trying to access beyond buffer length'); }     8. Add the following function for casting String to Bytes     function splitInBytes(data) { var bytes = []; var bytesAsString = ''; for (var i = 0, j = 0; i < data.length; i += 2, j++) { bytes[j] = parseInt(data.substr(i, 2), 16); bytesAsString += bytes[j] + ' '; } return bytes; }     9. Remap function calls to newly inserted functions Use the built-in script editor replace feature for the following, see below:   Within the service script perform a Replace for each of the following lines. Search Replace by payload.readInt16BE( readInt16BE(payload, payload.readUInt32BE( readUInt32BE(payload, payload.readUInt16BE( readUInt16BE(payload, payload.readUInt8( readUInt8(payload, payload.writeUInt16BE( writeUInt16BE(payload, payload.writeUInt8( writeUInt8(payload, payload.writeUInt32BE( writeUInt32BE(payload,   10. At the Bottom update the following Replace : decoder.setDeviceType("temp"); By : decoder.setDeviceType(type);   11. Insert the following at the bottom var result = Decoder(splitInBytes(payload), 0);   12. Save Service and Thing   13. Create a test Service for Adeunis Temp Device Within "AdeunisCodec" Thing Create a new service called "test_decode_temp" with Output as String Insert the following code:      // result: STRING var result = me.Decode({type: "temp" /* STRING */,payload: "43400100F40200F1" /* STRING */});     Save & Execute  The expected result is:     {"temperatures":[{"unit":"°C","name":"probe 1","id":0,"value":24.4},{"unit":"°C","name":"probe 2","id":0,"value":24.1}],"type":"0x43 Temperature data","status":{"frameCounter":2,"lowBattery":false,"hardwareError":false,"probe1Alarm":false,"configurationDone":false,"probe2Alarm":false}}       Please visit the Decoder test section of Adeunis website to see the reference for the Temp device test case, here.   Spoiler (Highlight to read) The resources has been tested on ThingWorx 8.5 and with the latest and greatest ThingWorx 9...   If you are more interested in the result than in the implementation process then import the attached "Things_AdeunisCodec.xml" 😉  The resources has been tested on ThingWorx 8.5 and with the latest and greatest ThingWorx 9...  If you are more interested in the result than in the implementation process then import the attached "Things_AdeunisCodec.xml"    
View full tip
Announcements