Implementation of SmartGateway for IoT Demo

This is part 5 of my IoT series of blogs. So far we did look at the following topic

This post will take a closer look of the content of the Smart Gateway and will give more information on the what and how.

From a building block perspective, the Smart Gateway consists of the following elements

Gateway

  • Raspbian as the OS running on the Raspberry Pi
  • Docker to contain and separate the various functionalities running on the Gateway
  • Red Hat JBoss Fuse as the “smart” part of the Gateway, being responsible for
    • providing the MQTT Broker for the sensors
    • transforming messages from native to a generic XML format
    • content based routing of messages to their designated targets

As the previous blogs explained how to setup the Smart Gateway, this one will look into the implementation details, being

  • receiving a CSV based message via MQTT
  • transforming the CVS to XML and enhancing it with Meta-Data from the MQTT Topic
  • forwarding the transformed message via JMS to the “Datacenter” for further processing

Overview

The logic of the Smart Gateway is build using a Apache Camel route in Spring XML.

camel

There are many ways of doing this, like

  • running the Camel route in a standalone Java application
  • deploying the Camel route as a feature/bundle on JBoss Fuse
  • deploying the Camel route as a bundle on JBoss EAP

I have decided to use the JBoss Fuse based option, as I needed the Message-Broker from JBoss Fuse anyhow and also wanted to make use of the management and monitoring capabilities of JBoss Fuse.

The complete sourcecode of the Smart Gateway can be copied from my Github repository.

The Route

The Camel route is, based on the things our Gateway needs to do, rather simple

<route>
    <from uri="mqtt:mqtt.temp.receiver?host=tcp://localhost:1883&amp;amp;subscribeTopicNames=iotdemo/#/#&amp;amp;userName=admin&amp;amp;password=change12_me"/>
    <bean ref="myHelper" method="enhanceMessage" beanType="com.redhat.demo.smart_gateway.MyHelper"/>
    <unmarshal ref="bindyDataFormat"/>
    <convertBodyTo type="java.lang.String"/>
    <to uri="activemqDatacener:queue:message.to.rules_cep"/>
</route>

Let’s analyse the relevant lines of this fragment, starting with the receiving part

    <from uri="mqtt:mqtt.temp.receiver?host=tcp://localhost:1883&amp;amp;subscribeTopicNames=iotdemo/#/#&amp;amp;userName=admin&amp;amp;password=change12_me"/>

This code uses the mqtt component of Apache Camel and listens on the topic ‘iotdemo/#/#’ for incoming messages. The ‘#’ are wildcards, enabling the Gateway to receive messages on any topics conforming to this naming convention.

In our case the first ‘#’ stands for the type of sensor ( e.g. temperature, humidity ) and the second one for the unique id of the sensor/device.

    <bean ref="myHelper" method="enhanceMessage" beanType="com.redhat.demo.smart_gateway.MyHelper">

The received message and all it’s Meta-Data is forwarded to a custom Java Bean for processing. In this case it will take the CSV value from the payload of the MQTT-Message and extend it with details from the name of the MQTT-Topic on which it was received.

We will take a look at this bean later on in this post.

    <unmarshal ref="bindyDataFormat"/>

Now that our helper bean has extended the CVS value with all relevant information, we can use the  Apache Camel bindy component to unmarshal the CSV value to XML.

    <convertBodyTo type="java.lang.String"/>

To be on the safe/flexible side for further receipients of the message, I found it the most simple way to transform the XML based message to a String.

    <to uri="activemqDatacener:queue:message.to.rules_cep"/>

In the last step of the Camel route, we forward the message to a Messagebroker on a remote system.

The Helper Java Bean

As always with creating code, there are many ways to implement the same results.

For the task to extend the payload of an Apache Camel message with information from it’s meta data, I decided to create a Java Bean and use it in my Camel route. The reasons for this where

  • I knew how to do that
  • demonstrate how to use custom beans in Apache Camel

The relevant part of the Java Bean is

public class MyHelper {
	
	@Handler
	public String enhanceMessage( String body,  Exchange exchange  ) {
		String res = null;
		
		res = addDeviceID(body, exchange);
		res = addDeviceType(res, exchange);
		res = appendTimestamp(res, exchange);

		return res;
	}

All member functions of any class annotated with ‘@Handler’ can be used within a Camel Route.

Camel will call those Handler and hand over the ‘body’ of the message and the ‘Exchange‘ , holding the information during the entire routing of a Message.

Within the custom function you can do whatever Java permits you to do with the message, it’s meta data, etc.

Summary

I’m well aware that this is a rather simple setup, but it very neatly shows the idea and concept of how one could implement a Smart Gateway.

For the full documentation of how to build and run the Smart Gateway, please take a look at the other postings of this series

 

, , ,
2 comments on “Implementation of SmartGateway for IoT Demo
  1. Pingback: Building an IoT Sensor with Node-RED on Intel Edison - Open Sourcerers

  2. Pingback: IoT - Smart Gateway with Intel Edison & TI Sensortag - Part 1 - Open Sourcerers

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: