Sending Veeder-Root commands using C#

Connecting to a Veeder-Root tank level sensor unit or other automatic tank gauge unit that accepts Veeder-Root commands via telnet is a pretty simple task. I’ve discussed in the past how to do that using PuTTY, and of course there’s the good old telnet.exe included with Windows that can do the same thing.

But what do you do if you want to connect to a unit programmatically using a program written in C#?

If you’re working for an employer or customer who has tens or even hundreds of Veeder-Root units, a program of this sort may be not just handy, but necessary to speed up your day and save you from boredom.

I recently tackled a project to create a program with the sole purpose of updating the clocks on all of a customer’s Omntec units. Those units do not automatically update their internal clocks when daylight saving time begins or ends, so a unit that’s recording the correct time before daylight saving time ends up an hour behind after daylight saving time goes into effect, and so forth.

It is not my intent to reproduce my entire program here since it’s very much a niche product; however, I do want to briefly explain how to send Veeder-Root commands to a TLS unit from a C# program.

MinimalisticTelnet

What I didn’t want to do was completely reinvent the wheel when it comes to connecting to the customer’s units. Since C# telnet packages do exist, I figured one of those would probably be my best bet, and I ended up using MinimalisticTelnet, which is more than adequate for my purposes.

Connecting to an Omntec unit using the sample program provided with MinimalisticTelnet was simple enough. In the TelnetInterface.cs file, I did change the default value of TimeOutMs to 2000 instead of 100. The class is written so that the timeout is set as part of the Login function, but since the units to which I am connecting don’t require a login, that wasn’t going to work for me. (An alternative would have been to modify TelnetConnection so that I could pass in a timeout value, but I just needed something quick and dirty.)

Connecting to a unit was easy enough. Sending a command and getting a response was trickier.

A word about Veeder-Root commands

When connected to a Veeder-Root or compatible TLS unit via telnet, you can issue commands ranging from setting the current time on a unit, which is what I needed to do, to querying the unit for current tank levels, and much more.

You begin each command by entering Ctrl + A. That’s easy enough on a keyboard, but how was I supposed to make it happen programmatically? The sample program provided with MinimalisticTelnet doesn’t dive into sending special keystrokes.

The solution

After quite a bit of searching, and a lot of trial and error, I stumbled across a decade-old Rebex.net blog post that mentioned using \x3 if you need to send Ctrl + C using their telnet package. Maybe \x1 would work for Ctrl + A using MinimalisticTelnet’s implementation? I gave it a try…and it worked!

For your reference, my pared down resulting code looks something like this:

TelnetConnection tc = new TelnetConnection(thisHostName, thisPort);
if (tc.IsConnected)
{
    string prompt = "\x1" + {string representing Veeder-Root command};
    tc.WriteLine(prompt);
    string response = tc.Read();
}

Hopefully this will save you some time if you’re trying to automate the process of connecting to a group of Veeder-Root, Omntec, or compatible TLS/ATG units.