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
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 });
}
// 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);
2. Bridging from Azure Event Hub to IO.Adafruit.com
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!