[Nut-upsdev] Designing a Raspberry Pi "UPS"

Charles Lepple clepple at gmail.com
Tue Apr 9 00:17:10 UTC 2013

On Apr 8, 2013, at 12:15 PM, Gary Marsh wrote:

> I'm designing a power management card for a Raspberry Pi, for an embedded application. Basically, here's the bits and pieces that would be on the card:
> - A 12V SLA battery charger, which can be powered from a wall wart or solar panel.
> - A pair of 12V->5V switching regulators, one powering the Pi and the other powering a built-in 4-port USB hub.
> - A USB capable microcontroller which manages the card and reports the battery/charge status to the Pi over USB.


> I'm envisioning the card acting like a UPS or a laptop battery. If local mains/solar electricity is available, the battery charges. If not, the Pi and its peripherals run off the battery. My application is data acquisition in places where power isn't easily available or isn't reliable, but there might be lots of other uses - I plan to release the design under a Creative Commons license when I'm done, so other people can build and mess with the design.
> Anyway the hardware design is no problem for me, and I've got a bit of experience implementing USB HID and CDC, but as far as making something that's reasonably "plug and play" with Linux/NUT I don't really know where to start.

The HID part should be relatively straightforward. NUT can use both EP0-based requests as well as interrupt pipe updates.

I would say that in general, NUT is at least one step removed from a plug-and-play power management system. We do have a nut-scanner tool that can create configuration files for auto-discovered devices  (I think), but that initial step is still manual. (I personally haven't used nut-scanner.)

It is a bit of a design decision. The sweet spot for NUT is a more complex power network, such as an equipment rack where a single UPS powers several computers in the rack (and where a network monitoring tool can gather statistics from each NUT server). For this, it is hard to automatically set up the non-master systems (as there is no way to tell which UPS they are plugged into).

That said, if support for your device was added to NUT, it would get picked up by nut-scanner.

> I'm hoping I can create a generic HID UPS or battery class, and have everything "just work", but I'm not sure if this is the case. Anyone mind giving me a few pointers in the right direction?

What we have found with the HID PDC spec is that everyone implements the report descriptors slightly differently. In the best scenario, we simply map HID "Usage paths" (since a Usage ID by itself can be ambiguous if the collection is not specified) to NUT names, and everything just works. This mapping is selected by USB VID/PID. In other cases, vendors have not debugged their HID report descriptors with other software, and we end up having to apply scaling factors to adjust for improper units, or mapping voltage measurements to their correct names. In your case, we could certainly work with you to debug the firmware.

It looks like UPower (the tool that gnome-power-manager talks to) has a similar set of tables to identify an UPS, but the code appears to be able to handle a generic PDC HID device by matching the HID Usage Page for the top-level collection[1]. I haven't gone any further down that rabbit hole, but for basic plug-and-play integration, if that works, that might be the best solution for your use case.

What NUT brings to the table on top of UPower is the networked aspect (multiple systems can monitor a single UPS for power information), and a good degree of scriptability for monitoring variables other than just on-line/on-battery/low-battery status.

Since MGE (now Eaton) contributed to the original HID PDC spec, you might want to model your UPS after their report descriptor layout. The mapping to NUT variable names is in drivers/mge-hid.c[2]. There are several other drivers/*-hid.c files which showcase some of the other special cases (not that MGE is completely blameless).

[1] http://cgit.freedesktop.org/upower/tree/src/linux/up-device-hid.c#n100

[2] https://github.com/networkupstools/nut/blob/master/drivers/mge-hid.c#L850

Charles Lepple
clepple at gmail

More information about the Nut-upsdev mailing list