OpenVND Software

This project started with the rumor that some vending machines supported a protocol that enabled one to monitor inventory. Lots of searching led me to a site in Switzerland that had some information on UCS/DEX. Actually, they were about the only site that had anything useful on the protocol, including a Windows application with source code. While I can’t find a copyright or license notice anywhere, I am very happy that they were kind enough to include this application, because it would have been extremely difficult to do without them.

Being open source kinda folks, I installed Debian on the eBox as the base operating system. I am familiar with Debian and I wanted something small for the operating system. I eneded up having to install “wheezy” (Debian testing) in order to get the proper firmware for the wireless card in the eBox.

Not being big on Windows software, we started to port the Bonusdata DEX.EXE program to perl, but ran out of time. DEX is not a simple protocol, so we decided to punt and just use wine.

Once wine was installed, we set up a cron job to run:

wine DEX.exe /M:COINCO /D:OUTPUT.DEX

The “COINCO” option is what is required for the CB500 drink machine we purchased.

This results in the output that you see on the bottom half of this example. Unfortunately, there is not an easy guide to DEX, but after spending several days searching I was able to interpret the important part – namely, the drink inventory.

The CB500 has ten slots, and these are numbered 010 through 019 (you enter in two digits from 10 to 19 in order to dispense a drink). Here is the output for slot 010:

PA1*010*50*****
PA2*6*350*6*350*0*0*0*0*0*0*0*0
PA3*2*150*2*150
PA4*0*0*0*0
PA5*20120301*125320*0

This section is repeated for each slot.

The PA1 line identifies the slot and the current price.

The PA2 line (the important one) show how many drinks have been sold. In this case, “*6*350*” means six drinks have been sold for a total revenue of $3.50 (it was set to $1.00 the first time I tested the machine). I believe the second set of numbers is lifetime sales in the slot, but I haven’t reset it to test this out.

I am not sure what the PA3 and PA4 lines mean, but the PA5 line is a timestamp for the last sale, in this case, March 1st, 2012 at 12:53:20 pm.

In order to get this information into OpenNMS, it was a simple matter of placing this file in the webroot of the apache server on the eBox, and then using the HTTP Data Collector to parse it.

This solved half my problem. I could now tell when a drink was sold. But I wanted to get a notification when the number of drinks was low. I solved this by simply creating a static text file with the slot, drink name and total cans stocked. The cron job was modified to add it to the output of drinks.txt.

Slot 010: Sprite: 25
Slot 011: Sprite Zero: 48
Slot 012: Diet Pepsi: 71
Slot 013: Diet Cheerwine: 24
Slot 014: Diet Dr Pepper: 60
Slot 015: Coke Zero: 59
Slot 016: Diet Coke: 49
Slot 017: RC Cola: 49
Slot 018: Coke: 48
Slot 019: Ginger Ale: 94

Now there was a way to identify the slot, drink name, total stocked and total sold. All the rest was done in OpenNMS.

The steps to get it into OpenNMS:

  1. Create a service called “HTTP-Drinks”. This can be done in capsd by adding a plugin or provisiond by adding a detector.
  2. Provision a node in OpenNMS to represent the drink machine. Since all of our machines in the office are named after South Park characters, I chose “ike”.
  3. Add the HTTP-Drinks service to ike.
  4. Modify http-data-collection.xml to parse the drinks.txt file into values OpenNMS can use (see this file for the configuration). It will grab the name of the drink in each slot, the total stocked in each slot and the total sold in each slot.
  5. Add this collection to collectd-configuration.xml.
  6. Create reports in snmp-graph.properties for each slot.
  7. Add an absolute threshold and a low threshold for each slot (see image below – click to embiggen)
  8. Add notifications for the three threshold events.

And there you have it.

To-Do

There are a number of things yet to be completed.

  1. SNMP Support: With a proper OID table, it would be much easier to configure OpenNMS to collect this information from machines with any number of slots using generic resources. The Net-SNMP agent supports the “pass” directive which could call a program to return the proper values via OIDs. We just ran out of time to do this rather low priority project, even though it is a lot of fun.
  2. Migrate DEX.EXE to perl: I hate having to rely on wine, but hey, it works, so the return on investment is very high to just keep using it.
  3. Configure the temperature probe access under Linux: the probe I bought has some software available but it, too, is Windows only. It was a rather late addition to this project, so getting it working has been a low priority.
  4. Create a small webapp to update the static portion of the drinks.txt file (currently, this is just hand edited).

In closing, we hope this experiment demonstrates how useful OpenNMS is in odd, yet real-world situations. Getting those thresholds generated was the easy part.