Wia powers the future of the Internet of Things by enabling devices, servers and smartphones to communicate with one another in a simple, easy way. They take care of the messy cloud
infrastructure and expose a globally available cloud API that enables developers to build intelligent and complex applications.
In this article, we dive into a simple example of how to track and display IoT events from a real-time Angular 2 web application. As anyone running a large-scale application will attest, tracking technical and business metrics is vital to ensuring continuity of service, business health, and recovering from issues quickly. Wia IoT Messaging API is a way to track, display, and disseminate metrics quickly from devices, providing rapid insight and rapid response capabilities for your application.
So, what exactly are these IoT Messaging Services we speak of? Wia offers a number of services for integrating IoT devices, including events, logs, metrics, locations, and more. In this article, IoT Messaging refers to tracking data for specified IoT metrics over time.
You’ll first need your PubNub publish/subscribe keys. If you haven’t already, sign up for PubNub. Once you’ve done so, go to the PubNub Admin Portal to get your unique keys. The publish and subscribe keys look like UUIDs and start with “pub-c-” and “sub-c-” prefixes respectively. Keep those handy – you’ll need to plug them in when initializing the PubNub object in your HTML5 app below.
To get started with Wia services, you’ll need a Wia developer account to take advantage of their IoT APIs.
Overall, it’s a pretty quick process. And free to get started, which is a bonus!
With PubNub BLOCKS, it’s really easy to create code to run in the network. In this tutorial, we’ll use our Wia BLOCK.
Here’s how to make it happen:
That’s all it takes to create your serverless code running in the cloud!
You’ll want to grab the 20 lines of BLOCK JavaScript and save them to a file, say, pubnub_wia_block.js
. It’s available as a Gist on GitHub for your convenience.
First up, we declare our dependency on xhr (for HTTP requests) and create a function to handle incoming messages.
export default request => { let xhr = require('xhr');
Next, we set up variables for accessing the service (the API credentials based on the message payload, and base URL).
const authKey = request.message.authKey; const url = "https://api.wia.io/v1/events";
Next, we set up the HTTP params for the event tracking API call. We use a POST request for the URL. We use the JSON content of the event
message attribute as the source of most important parameters, and set the authentication headers.
const http_options = { "method": "POST", "headers": { "Content-Type": "application/json", "Authorization": "Bearer " + authKey }, body: JSON.stringify(request.message.event) };
Finally, we POST the given data and decorate the message with a wia_reply
attribute containing the results of the API call. Pretty easy!
return xhr.fetch(url, http_options).then((response) => { request.message.wia_reply = JSON.parse(response.body); return request; }); };
All in all, it doesn’t take a lot of code to add IoT metrics ingestion to our application. We like that!
OK, let’s move on to the UI!
You’ll want to grab these 98 lines of HTML & JavaScript and save them to a file, say, pubnub_wia_ui.html
.
The first thing you should do after saving the code is to replace two values in the JavaScript:
If you don’t, the UI will not be able to communicate with anything and probably clutter your console log with entirely too many errors.
For this app, you should also update this line of code with the proper device access key to simulate an IoT device:
self.wia_auth_key = 'YOUR_DEVICE_AUTH_KEY';
For your convenience, this code is also available as a Gist on GitHub, and a Codepen as well. Enjoy!
First up, we have the JavaScript code & CSS dependencies of our application.
<!DOCTYPE html> <html> <head> <title>Angular 2</title> <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script> <script src="https://unpkg.com/zone.js@0.7.2/dist/zone.js"></script> <script src="https://unpkg.com/reflect-metadata@0.1.9/Reflect.js"></script> <script src="https://unpkg.com/rxjs@5.0.1/bundles/Rx.js"></script> <script src="https://unpkg.com/@angular/core/bundles/core.umd.js"></script> <script src="https://unpkg.com/@angular/common/bundles/common.umd.js"></script> <script src="https://unpkg.com/@angular/compiler/bundles/compiler.umd.js"></script> <script src="https://unpkg.com/@angular/platform-browser/bundles/platform-browser.umd.js"></script> <script src="https://unpkg.com/@angular/forms/bundles/forms.umd.js"></script> <script src="https://unpkg.com/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js"></script> <script src="https://unpkg.com/pubnub@4.3.3/dist/web/pubnub.js"></script> <script src="https://unpkg.com/pubnub-angular2@1.0.0-beta.8/dist/pubnub-angular2.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" /> </head>
For folks who have done front-end implementation with Angular2 before, these should be the usual suspects:
In addition, we bring in the CSS features:
Overall, we were pretty pleased that we could build a nifty UI with so few dependencies. And with that… on to the UI!
Here’s what we intend the UI to look like:
The UI is pretty straightforward – everything is inside a main-component
tag that is managed by a single component that we’ll set up in the Angular2 code.
<body> <main-component> Loading... </main-component>
Let’s skip forward and show that Angular2 component template. The h3
heading should be pretty self-explanatory. We provide a select box with values and a simple button to perform the publish()
action to send an event to be processed by the BLOCK.
<div class="container"> <pre> NOTE: make sure to update the PubNub keys below with your keys, and ensure that the BLOCK settings are configured properly! </pre> <h3>MyApp IoT Messaging Integration</h3> <hr/> <p>Click the button below to send a health metric</p> <select [(ngModel)]="system_health"> <option value="healthy">healthy</option> <option value="degraded">degraded</option> <option value="disabled">disabled</option> </select> <button class="btn btn-primary btn-info" (click)="publish()">Send event!</button> <br/> <br/> <ul> <li *ngFor="let item of messages.slice()"> <div>{{item.message.event.name}} = {{item.message.event.data}}</div> </li> </ul> </div>
The component UI consists of a simple list of events (in our case, the metrics events). We iterate over the messages in the component scope using a trusty ngFor
. Each message includes the data from the Wia API.
And that’s it – a functioning real-time UI in just a handful of code (thanks, Angular2)!
Right on! Now we’re ready to dive into the Angular2 code. It’s not a ton of JavaScript, so this should hopefully be pretty straightforward.
The first lines we encounter set up our application (with a necessary dependency on the PubNub AngularJS service) and a single component (which we dub main-component
).
<script> var app = window.app = {}; app.main_component = ng.core.Component({ selector: 'main-component', template: `...see previous...`
The component has a constructor that takes care of initializing the PubNub service and configuring the channel name, auth key, and initial value. NOTE: make sure the channel matches the channel specified by your BLOCK configuration and the BLOCK itself!
}).Class({ constructor: [PubNubAngular, function(pubnubService){ var self = this; self.pubnubService = pubnubService; self.channelName = 'wia-channel'; self.wia_auth_key = 'YOUR_DEVICE_AUTH_KEY'; self.system_health = "healthy";
Early on, we initialize the pubnubService
with our credentials.
pubnubService.init({ publishKey: 'YOUR_PUB_KEY', subscribeKey: 'YOUR_SUB_KEY', ssl:true });
We subscribe to the relevant channel, create a dynamic attribute for the messages collection, and configure a blank event handler since the messages are presented unchanged from the incoming channel.
pubnubService.subscribe({channels: [self.channelName], triggerEvents: true}); self.messages = pubnubService.getMessage(this.channelName,function(msg){ // no handler necessary, dynamic collection of msg objects }); }],
We also create a publish()
event handler that performs the action of publishing the new message to the PubNub channel.
publish: function(){ var message = { event:{name:"system_health",data:this.system_health}, authKey:this.wia_auth_key }; this.pubnubService.publish({channel: this.channelName,message: message}); } });
Now that we have a new component, we can create a main module for the Angular2 app that uses it. This is pretty standard boilerplate that configures dependencies on the Browser and Forms modules and the PubNubAngular service.
app.main_module = ng.core.NgModule({ imports: [ng.platformBrowser.BrowserModule, ng.forms.FormsModule], declarations: [app.main_component], providers: [PubNubAngular], bootstrap: [app.main_component] }).Class({ constructor: function(){} });
Finally, we bind the application bootstrap initialization to the browser DOM content loaded event.
document.addEventListener('DOMContentLoaded', function(){ ng.platformBrowserDynamic.platformBrowserDynamic().bootstrapModule(app.main_module); });
We mustn’t forget close out the HTML tags accordingly.
}); </script> </body> </html>
Not too shabby for about 98 lines of HTML & JavaScript!
There are a couple other features worth mentioning in the Wia service APIs.
You can find detailed API documentation Clicking here and additional samples Clicking here.
All in all, we found it pretty easy to get started with IoT features using the API, and we look forward to using more of the deeper integration features!
Thank you so much for joining us in the IoT messaging article of our BLOCKS and web services series! Hopefully it’s been a useful experience learning about IoT-aware technologies. In future articles, we’ll dive deeper into additional web service APIs and use cases for other nifty services in real time web applications.
Stay tuned, and please reach out anytime if you feel especially inspired or need any help!
There are common underlying technologies for a dating app, and in this post, we’ll talk about the major technologies and designs...
Michael Carroll
How to use geohashing, JavaScript, Google Maps API, and BART API to build a real-time public transit schedule app.
Michael Carroll
How to track and stream real-time vehicle location on a live-updating map using EON, JavaScript, and the Mapbox API.
Michael Carroll