I would probably study and wrap NUT, making what is essentially a bridge to translate NUT messages to DCE messages.
This would be a device that could handle whatever drivers NUT supports.
It would do whatever it needed to do, to get messages from NUT, and act upon them using DCE stuff...
This is a pattern used by many parts of LinuxMCE, for example, for MythTV, they expose a telnet port that our DCE device MythTV_Player connects a socket to. The MythTV_Player has code that talks to this socket, and sends commands. It also listens on the socket, and when messages are recieved, it emits events (such as when a screen has changed.) that it reacts to.
How this is implemented is an exercise for the reader, it's open ended.
Devices can have child devices. Mostly these child devices do not have device drivers themselves, they are merely end points, where the router can send a message to. You would have a child device for each UPS, which would probably at the very least, contain device data for which driver to use, and what information the driver would need to connect. There is a method in C++ and GSD drivers called "Received Command for Child" so that the big parent device can get the command and act upon it.
This is the pattern, LinuxMCE is a messaging system.