Newsletter:7/Arduino and Zenoss

From Zenoss Wiki
Jump to: navigation, search
Community-header.jpg

Arduino and Zenoss

I’ve long been a proponent of the Arduino products, but have had a huge reservation. They’re a complete pain to monitor. How can you release a product that can take process data from dozens of analog, digital, serial, spi, and i2c data sources, and not monitor it? This reservation was solved about a year ago when Arduino released the Yun.
Arduino.jpg

Introducing the Arduino Yun

I’ve long been a proponent of the Arduino products, but have had a huge reservation. They’re a complete pain to monitor. How can you release a product that can take process data from dozens of analog, digital, serial, spi, and i2c data sources, and not monitor it? This reservation was solved about a year ago when Arduino released the Yun.

Arduino Yun

Overview

We are going to monitor the Arduino Yun. It has a Atheros CPU, and an Atmel CPU. Since the Atheros runs Linux, we will enable SNMP to monitor it. Once we have enabled SNMP, then we will utilize a simple interface called the Yun Bridge to pull even more data from the Atmel CPU. We will start small with a simple “Hello World” program and build out from there. Finally, we will make the appropriate configuration changes within Zenoss to wrap up the demonstration.

First let’s monitor the Linux Side!

As stated earlier, Yun software is built on a Linux platform, so we are able to enable SNMP via the Linux OS. So, before we start coding, let’s get SNMP working. You will see a Yun-XXXXXXXXXXXX wifi SSID, and you can connect to it without a password. Navigate to the Arduino web interface at Arduino.local, and configure networking. For more information consult the Official Arduino Yun Webpage.

Once your Yun has internet access, log in and go to the “advanced configuration panel (luci)”. Select the “Software” tab and install snmpd. Next, login to the console via ssh using a terminal window, or Putty for you Windows users, and create an appropriate /etc/snmp/snmpd.conf file, see Prepare Remote Devices. Finally, using luci, navigate back to the “Startup” tab and enable and start snmpd. After the SNMP daemon has been started, login to Zenoss and add the machine by IP to the device class /server/linux. Zenoss will throw an error on the /rom filesystem when it models the device. As you probably will immediately figure out, this is an image and it is exactly at 100% capacity. This was completely expected and it shows that we have successfully enabled SNMP on the device. Disable monitoring it. Now, let’s move on and develop a little code that will let us successfully monitor the device.

Bridge Hello World

Let’s start with making sure we know how to interface with the device by writing a simple “Hello World” program. Once we have that working, then we can begin incorporating much more sophisticated functional elements so that we can model our device. Arduino uses the ‘C’ language to program the device. The complete bridge sample code, ‘bridge.c’, can be found at:

http://arduino.cc/en/Reference/YunBridgeLibrary

This simple code snippet gives you a way to send attribute value pairs as strings across the Yun to its Linux OS that you will then be able to retrieve from a remote system via curl. To keep it simple, in the ‘loop’ function, we will call the ‘delay’ function to wait for a specified time before returning from the ‘loop’ function. For an example of how to write the ‘loop’ function that is non-blocking, reference the code found here:

http://arduino.cc/en/Tutorial/BlinkWithoutDelay.

The setup function initializes the bridge. Once the bridge is initialized, an internal process loop starts and for each iteration of the internal process loop, the ‘loop’ function is called. Again, to understand the programming libraries, please reference the Arduino tutorials.

The attribute value pair “Hello” “World” can also be obtained in a “JSON-like” structure using curl described below.

#include <Bridge.h>
void setup() {
  Serial.begin(9600);
  Bridge.begin();
}

void loop() {
  Bridge.put("Hello", "World");
  delay(500000); // slow things down so we aren't spinning
}

Compile and upload this to your Yun, and if you got everything right you can go to http://arduino.local/keystore_manager_example/, and see:

Yun Key Store Web Interface 400px

These values can also be pulled in a “JSON-like” structure. Note that while Arduino claims this is JSON, it is not quite JSON. They also pull reasonably fast, these are gathered via wifi.

$ time curl http://arduino.local/data/get
{"value":{"Hello":"World"},"response":"get"}
real    0m0.285s

You can also get a specific key’s value by:

$ time curl http://arduino.local/data/get/Hello
{"value":"World","key":"Hello","response":"get"}
real    0m0.314s

As you can see from the output listed above, the response is pretty quick. This was done on a WIFI connection, so a cabled ethernet connection would be even faster.

This was a simple demonstration to get us some experience writing code with the Yun bridge, now let’s make it a little more sophisticated and realistic.


A More Advanced Bridge

Let’s say that we have built a sensor that has several components I want to monitor, such as temperature, fans and humidity. Since nothing has changed with the “setup” function, we will reuse the one we wrote above. However, the ‘loop’ function adds several new attribute value pairs and removes the “Hello” “World” pair.

#include <Bridge.h>
void setup() {
  Serial.begin(9600);
  // Bridge startup
  Bridge.begin();
}

void loop() {
  Bridge.put("temp", "70");
  Bridge.put("humid", "40");
  Bridge.put("fan.count", "4");
  Bridge.put("fan.0", "3000");
  Bridge.put("fan.1", "3000");
  Bridge.put("fan.2", "3000");
  Bridge.put("fan.3", "1289");
  delay(50000); // Poll every 50000ms
}


Next let’s create a script that outputs data for Zenoss to use. You can look Writing Command Data Sources for more advanced examples of command data sources, here we've used a shell script to avoid some output issues caused by Tales.

#!/bin/bash
ip_address="$1"
dataset=$(curl http://${ip_address}/data/get 2>/dev/null | sed 's/{.*{//g' | sed 's/}.*//' | sed 's/\"/\ /g')
fancount=$(echo "$dataset" | sed 's/\,/\n/g' | grep fan.count | awk '{print $3}')temp=$(echo "$dataset" | sed 's/\,/\n/g' | grep temp | awk '{print $3}')
humid=$(echo "$dataset" | sed 's/\,/\n/g' | grep humid | awk '{print $3}')


while [ "${fancount}" -ge 1 ]; do
  fancount=$((fancount - 1))
  value=$(echo "$dataset" | sed 's/\,/\n/g' | grep fan.${fancount} | awk '{print $3}')
  eval fan_"$fancount"="$value"
done


echo "OK|temp=${temp} humid=${humid} fan1=${fan_0} fan2=${fan_1} fan3=${fan_2} fan4=${fan_3}"


Making it Happen in Zenoss

So next up we go to our Yun device that we modeled in Zenoss at the beginning of this paper, and add a Template and a Command Data Source. Since we are using an external script, I need to specify the monitored IP as a parameterized argument in the command line as shown in the “Command Template” section of the following dialog.

"Zenoss Yun Datasource


With your Data Source defined, save, and reopen the Data Source, and test it against the Arduino Yun device, as shown below. Pay close attention to the run time (DONE in 0 seconds), and that the output matches what you think you should be getting from the script.

You should see:

Testing the Datasource

Point out the Data!

Next we want to create graphs. In the monitoring template, add a data point using the attribute name or key in the attribute value pairs you defined in your code as the name of the data point. Set a range for the value, as illustrated below:

Adding the Temp Datapoint

When everything is complete, the template will look something like:

A List of Datapoints

Now you need to set the thresholds to alert on. These will not only generate events but affect the appearance and functionality of later RRDtool graphs.

Set your Thresholds

Now that you have the min/max values, lets create a graph for the fans by selecting the “+” UI element to add a graph definition, and naming it “fans”. Once it exists use the gear UI element to “Manage Graph Points”. Add each of your fans, and have the thresholds inherit:

You’ll also want to create similar graphs for temp/humidity. Once you're done, you'll see graphs like this:

These are the Graphs when you're done!


Suddenly Comes an Event!

Now, we will see the final effort of all the work we have put into our development. If you’ve done everything right, you should see the following. Hey! You better go fix that fan!

This is the event from your low Fan1 value

Congratulations

Without even knowing it you’ve not only learned and written the basics for thousands of really cool Yun sketches, you’ve also written an entire ZenPack in just a few hours to monitor it. It’s not perfect, doesn’t automatically model the fans, although you do have a fan count variable for that, but it does get you all the data you exported from your Arduino Yun into Zenoss allowing you to generate custom events, graphs, and monitor the Linux side of the Arduino Yun via SNMP.