Monitoring the UPS status from VB6

The mission:  Our software needs to monitor the state of the UPS unit for our equipment.  If a power failure occurs and the UPS switches to battery power, the software needs to finish the devices being processed on the equipment and come to a graceful halt. 

The options: 

  • I wanted to have a signal from the UPS unit wired as a standard sensor input to our equipment.  Pros:  Consistent way of providing an input.  Doesn’t require a software change.  Cons:  Requires $150 relay board option for the UPS, plus additional wiring.  Our EEs hated this idea.
  • Connect the UPS to the PC via a serial port input.  Pros:  This is the standard way of handling a UPS device for PCs.  Doesn’t require additional wiring.  Needless to say, the EEs love this option.  Cons:  Not a standard input to our equipment.  Requires a software change.  I don’t mind making a software change – after all, that’s what I’m here for – but it has to be a reasonable amount of effort for what we are getting out of it. 

If we get the status from the UPS from the serial port, how does our software read it?

  • SNMP Manager – I don’t think so.
  • Request copy of custom protocol from APC – We could, but now we are talking a lot more code and customization for one little device.
  • Read status written by Windows UPS service to the registry.  Bingo!  This was a suggestion from our system administrator.  This was simple to implement.  Has some issues, but on the whole, works well.  How fortuitous that the UPS service does this.

Setting up the UPS: 

  • Plug the serial cable from the UPS into the PC.  In the Windows Control Panel, select Power Options.  In the UPS tab, select the UPS device and comm port.

In the software (VB6):

  • Use RegOpenKeyEx/RegQueryValueEx/RegCloseKey API calls to read the status values from registry key “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UPS\Status”.  Look in MSDN for “Windows Driver Kit:  Battery Devices”.  I read the “CommStatus” key to know if the PC was communicating with the UPS and “UtilityPowerStatus” to determine if the UPS was on AC power or battery. 
  • I realized pretty quickly that I also need to know if the UPS service is even running.  If it isn’t, those values in the registry are meaningless.  Use the OpenSCManager/OpenService/CloseServiceHandle API calls to monitor the “UPS” service.  Don’t forget to close the handles for both the OpenSCManager and the OpenService calls. 
  • It is so much prettier to check the service status in .Net – use the ServiceController class from the System.ServiceProcess namespace:  ServiceController service = new ServiceController(“UPS”);


  • This works fine on Windows XP.  I’d be surprised if it works for Windows Vista.  I suspect we will be revisiting this issue again in a few months.
  • There is no way to determine if the UPS unit is turned off or on.  If the unit is off, the communication status is fine, but the registry values are not updating.  Doh!
  • You can’t install the APC PowerChute software – it disables the Windows UPS service.

Post a Comment

Required fields are marked *

%d bloggers like this: