Azure Event Hub to Adafruit Bridge

Ok, this might be a round about way to do something, but I really wanted to experiment with MQTT and Azure Event Hubs.  I wrote a bridge that would bridge data between several MQTT brokers and then queue that data up on an Azure Event Hub.  These MQTT brokers are fed by data from several ESP8266 boards reporting different environmental conditions (temperature, etc).

After I got the MQTT to Azure Event Hub bridge done, I then found Adafruit’s io.adafruit.com dashboarding service (http://io.adafruit.com).  It is pretty cool.  So, what I then wanted to do is write a bridge between my Azure Event Hub to Adafruit to show data on a dashboard.

1. Creating my MQTT listener to bridge data to Azure

I created my MQTT listener using th M2Mqtt library.  You can get this as a nuget package by:

PM> Install-Package M2Mqtt

Or, you can grab it here: 
I then set the client up to subscribe the root of topics on the MQTT server.  I have a specific format in the topic that allows me to then route if I want to.

public void SetupMQTT()

{

// create client instance

uPLibrary.Networking.M2Mqtt.MqttClient client = newuPLibrary.Networking.M2Mqtt.MqttClient(BrokerIP);

// register to message received

client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

string clientId = Guid.NewGuid().ToString();

client.Connect(clientId);

// subscribe to the topic “#”.  Or basically grabbing every message comnig through.

client.Subscribe(new string[] { “#” }, new byte[] {MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });  

}

After I have this setup, whenever something is published to my MQTT broker, my client code calls:  client_MqttMsgPublishReceived
In this method, I have some routing rules, and depending on the rules, I then route certain messages to the Event Hub on Azure.

// this is an object that I will serialize. this has both the topic and the message so that I can deserialize it on the other side.

Models.MQTTPacket mqttPacket = new Models.MQTTPacket

{

MQTTTopic = topic,

Message = message,

};

// create some eventData for the event hub to consume

var eventData = newEventData(Encoding.Default.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(new Models.LogMessageEvent()

{

InstanceId = this.InstanceID,

MachineName = Environment.MachineName,

SiteName = this.SiteName,

Value = Newtonsoft.Json.JsonConvert.SerializeObject(mqttPacket)

})));

eventData.PartitionKey = this.InstanceID;

// send the message off to the event hub

_client.SendAsync(eventData);

So far, so good. I have now pushed certain MQTT messages off to my Azure queue based on some rules that I am not showing here for brevity.

2. Bridging from Azure Event Hub to IO.Adafruit.com

Now that I have the data up on Azure, I now want to put some of it out to Adafruit.  I did this by writing a simple bridge.  I found a great bit of code here on how to process a log stream.
http://fabriccontroller.net/getting-started-azure-service-bus-event-hubs-building-a-real-time-log-stream/
If you look at his example of the simple code for reading the Service Bus, you can easily adapt this to what you want.
the main thing that I did is after I received the message from the event hub, I then pushed it over to adafruit.

var messages = receiver.Receive(10);

foreach (var message in messages)

{

// get the message coming back from the Azure Event Hub

var logMessage = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.LogMessageEvent>(Encoding.Default.GetString(message.GetBytes()));

// lets deserialize what is coming back from the Event Hub value. This value contains an JSON object that has both the MQTT topic as well as the message.

// at this point, I could then apply routing and rules to determine which adafruit feed, etc I would want to send the data to.

ctMQTTLib.Models.MQTTPacket oPacket = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.MQTTPacket>(logMessage.Value);

Console.WriteLine(“{0} [{6}] {2}/{3}: {5}”, DateTime.Now, message.PartitionKey, logMessage.MachineName, logMessage.SiteName, logMessage.InstanceId, logMessage.Value, state);

Console.WriteLine(” > Instance/PartitionKey: {0}”, message.PartitionKey);

 

 

// setup the headers. in this case, I am going to send the x-aio-key containing the appropriate key for my feed.

List<ctLib.Helpers.JsonHelper.NameValue> parms = newList<ctLib.Helpers.JsonHelper.NameValue>();

parms.Add(new ctLib.Helpers.JsonHelper.NameValue

{

Name = “x-aio-key”,

Value = AdafruitKey,

});

 

// create the payload to send to adafruit. I only care about the value that is going out to a particular feed.

Models.IOAdafruitFeedItem adafruitItem = new Models.IOAdafruitFeedItem

{

value = oPacket.Message,

};

// serialize the object to send as the body

string adafruitPayload = Newtonsoft.Json.JsonConvert.SerializeObject(adafruitItem);

// call my helper app to send the data to adafruit for a particular feed

ctLib.Helpers.JsonHelper.SendToServer(“https://io.adafruit.com/api/feeds/” + AdafruitFeed + “/data”, adafruitPayload, parms, “POST”);

}

}

Once the Adafruit API receives the data (using a RESTful API call), it is immediately shown on the dashboard.  Very slick!

io.Adafruit.dashboard1.PNG

here is a flow of what it might look like (the architecture)
Catalina API for Dynamics SL Videos
Testing PH/Temperature sensor