Monitoring MQTT Services in an Angular Web Application

I’m going to show you how to use the Paho MQTT JavaScript implementation in an Angular application to subscribe to a topic and display the message content in a web browser.

I’ve built this as part of my ongoing project to build a custom Weather Station for my home. 

Prerequisites:

  • An Angular CLI project
  • A working MQTT Broker to access with accessible topics that are receiving messages

MQTT Packages for Angular

There’s a few MQTT related packages for Angular integration on npm. I’ve chosen to use ng2-mqtt. It works for me at this point. I did consider using ngx-mqtt, but as it’s build was marked as failing at the time of writing(13/11/2018) I decided to use the simpler ng2-mqtt.

Procedure

First, set up an Angular CLI Project. I’m using Angular 7.0.3. 

Install ng2-mqtt using npm:

npm install --save ng2-mqtt

For simplicity of testing and demonstration, I’m using ng2-mqtt in my AppComponent. As I further develop my weather station display app, I’ll probably move it to a specific service for managing weather data.

Import Paho at the top of your app.component.ts:

import {Paho} from 'ng2-mqtt/mqttws31';

Add some properties for variables to the class AppComponent for storing the incoming data. Change these to match your needs:

windSpeed: Number;
windDirection: Number;

Also add a private member for the MQTT client. I’ve also put in a variable for storing the IP address or hostname of my MQTT broker. In a real world implementation you’d put this in some sort of configuration management.

private client;

mqttbroker = 'localhost';

Your AppComponent should implement OnInit:

export class AppComponent implements OnInit {

Then add a ngOnInit implementation:

ngOnInit() {
  this.client = new Paho.MQTT.Client(this.mqttbroker, Number(9001), 'wxview');
  this.client.onMessageArrived = this.onMessageArrived.bind(this);
  this.client.onConnectionLost = this.onConnectionLost.bind(this);
  this.client.connect({onSuccess: this.onConnect.bind(this)});
}

In this code we create a client object and tell it the address of the MQTT Broker and the port number we’re using. I’ve given my client the name ‘wxview’. We then specify callbacks that will be used for when a message is received, a connection is lost, and a connection is established.

Note when setting references to member functions that handle each event, we call the .bind(this) function. This ensures that “this” in the callback function refers to the AppComponent class, not the MQTT Client. For more information, see the Function.prototype.bind() article on Mozilla Developer Network.

Now we can set up the onConnect function:

onConnect() {
  console.log('onConnect');
  this.client.subscribe('wxstation/wind_speed');
  this.client.subscribe('wxstation/wind_direction');
}

This function tells the client to subscribe to specified topics. In my case I’ve used topics that are specific to my weather station project. You can change the topics to be subscribed to for your project specific requirements.

We set up onConnectionLost as per the documentation:

onConnectionLost(responseObject) {
  if (responseObject.errorCode !== 0) {
    console.log('onConnectionLost:' + responseObject.errorMessage);
  }
}

This will just log the error to the browser console if the connection is lost.

Then we build our function to handle any messages received:

onMessageArrived(message) {
  console.log('onMessageArrived: ' + message.destinationName + ': ' + message.payloadString);

  if (message.destinationName.indexOf('wind_speed') !== -1) {
    this.windSpeed = Number(message.payloadString);
  }

  if (message.destinationName.indexOf('wind_direction') !== -1) {
    this.windDirection = Number(message.payloadString);
  }

}

In this function I first log the message topic(message.destinationName) and message(message.payloadString) to the web browser console. 

I then check the topic of the message received and update the appropriate member variable.

To finally put this all together, build a template that binds to these variables:

<div class="container-fluid">
  Wind Speed: {{windSpeed}}<br />
  Wind Direction: {{windDirection}}
</div>

Now when you open your app in the browser, you’ll see the web page continually update as new MQTT messages are received by the broker. 

The Full Code

Check it out on Stackblitz.