Friday, August 12, 2011

Power Monitoring for DC Insight - Operation (InterMapper) - Developing the Modbus Probe

IDC Solutions from Australia was generous in providing us with a prototype of their pMon power monitoring hardware. The solution has Modbus TCP communication protocol and I am glad to say I have successfully integrate their solution into our DC Insight offering.

Since InterMapper does not support Modbus TCP out-of-the-box, I have to venture into using a command-line base probe to integrate the two.

The intention of this blog post is to summarize the development process and list out the resource I used (which I can later reference again if needed :)

First off, it is studying the Modbus protocol.  The Modbus Organization host the document - Modbus Application Protocl Specification v1.1b. After reviewing the specification to understand the low-level workings of the protocol, it is time to test and make sure the Modbus TCP functionality is indeed working on the device.  It appears there were not as many open-source/free tools available to do this test compare to SNMP.  In the end I found a free command-line tool, modpoll, and a simple GUI test client Simply Modbus (not free, but only US$60 for a single license).  I must confess, I didn't buy Simply Modbus TCP, since I am comfortable with using the command-line. But for those who like a GUI, give Simply Modbus a try!

I also looked into other open-source projects such as jamod and openscada. I was unable to get jamod to work, and openscada is really an over-kill for what I am trying to achieve.

This should all be relative straight forward except the documentation from IDC for the base register was incorrect!  The documentation claim the starting address is 401000, but in fact, it was just 1000. For those who know Modbus protocol, they should know right away something is wrong, since 401000 is greater than 65535, the 16-bit limitation on Modbus addressable space, but I was new and didn't know better.

With some trial and error, and some luck, I manage to find that the starting address is 1000.

In hindsight, it is now pretty clear why the writer of the document/manual might have thought it is 401000, because when you look at a typical modbus request, it will look something like this:

00 04 00 00 00 06 01 03 04 8A 00 02

"8A 00" highlighted is the starting address, but if you are not careful and including the byte before, you may actually think it starts with 4xxxxx!

After I sorted that out, it is time to pick the right method to integrate with InterMapper. At first, I thought a simple TCP probe might do the job, but after looking into the manipulation required, a command-line based probe is definitely the way to go.

I first thought of using Java to write a small program, but with my previous experience in building the RF Code  probes based on Java, I learned my lesson. To learn more about my lesson-learned and what is the disadvantage of using Java in this probe based application, I have wrote back to a question on the InterMapper-talk forum.  It just so happened someone requested for Groovy support to write InterMapper probes, I wrote back and gave my 2 cents.

The next logical choice would be to use InterMapper's support for python. I am pretty new to python, with some limited toying around in the past. I wrote a broken and primitive message board on Google App Engine when it first came, and later in my short dabbling with HomeTasty, which is also based on python.

Since I was doing some pretty low-level network programming, I studied the python socket api at the official python documentation. The write-up and examples there was sufficient for me to get the python integration going. After the python script was completed, the integration with InterMapper was pretty straight forward.

One last thing I want to share is the swapping of the higher-order and lower-order byte of a 32-bit value. Since modbus is a big-endian protocol and Windows/Linux is a little endian system, I have to do some bit flipping (shifting to be exactly, but I like the analogy to burger flipping in McDee). 

I haven't been flipping bits since my university days, so it took me a while to understanding the code suggested here and here after some googling.

The following code will swap a 32-bit value from "AA BB CC DD" to "BB AA DD CC".

swapped = (((swapme<<8)&0xFF00FF00) | ((swapme>>8)&0x00FF00FF))

And here is a screenshot of the InterMapper status window with power readings from pMon monitoring one of the feeds powering our centralized air-conditioner.

That's it for my little geeky adventure.  Now is time to iron out the details of the solution and prepare for the up and coming data center exhibition - Data Center Strategic 2011 in Hong Kong.

P.S. Here are some photos of the deployment.
Here is a picture of the pMon monitoring unit

Here is a picture of our fuse box.  There are 3 rows in this fuse box.  The open section shows a row of fuse for a single phase.   There is one more row above and below for the other phases.  The air conditioner is a 3-phase unit with a power feed from each phase.  I have clamp 3 feeds of the air conditioner to monitor our A/C power usage.

Here is a close up of the current transformer clamp on to a live power feed.