Tom
2023-Feb-19 13:18 UTC
[Nut-upsuser] Using 'dummy.ups' for a real application, not just testing...
Good Morning, I am working on setting up a 12V DC UPS that will power a NAS and a router for a few hours. It contains some lithium-ion batteries, and a BMS to control charging. Since it is just a dumb box with batteries, it has no intelligence to inform the NAS of its status. This is where NUT comes in... I would like to incorporate a Raspberry Pi NUT server into this scheme. The Rpi can measure input voltage, and output voltage & current to determine the status of this simple UPS. With some of the excellent documentation online, I have gotten a NUT server running on the Rpi, and my NAS (a Qnap) has been able to read the status. I used the 'dummy-ups' driver for testing this and it worked great. Now, for the real business - Since this is entirely homebrew, there is not an appropriate driver available. I read about creating my own driver using 'skel.c' as a template. But, nobody else would have any interest in my very specialized driver. Plus - it seems overwhelming to me when I attempt to understand how to build NUT and I fear getting totally bogged down in all the minutiae of that. But, it occurred to me - Why can't I just use 'dummy-ups' for this as-is? I can have a simple 'c' or Python program to read my values (to determine status) and then just write a few relevant lines into a '.dev' file to be served out to the LAN with the factory NUT server tools? My file would contain something like this: ups.mfr: Tom ups.model: My Contraption battery.charge: 100 ups.status: OL input.voltage: 1.02 battery.voltage: 11.5 output.voltage: 11.2 output.current: 3.4 battery.runtime: 1000 I write this file periodically (maybe every 15-60 seconds) and the Rpi NUT server would be none the wiser and just keep supplying the constantly updated contents of this file to the NAS. Am I overlooking something with this approach? I am completely new to NUT and would appreciate any feedback from more seasoned users... -Thanks Tom -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://alioth-lists.debian.net/pipermail/nut-upsuser/attachments/20230219/d3246b1e/attachment.htm>
Greg Troxel
2023-Feb-19 14:29 UTC
[Nut-upsuser] Using 'dummy.ups' for a real application, not just testing...
Tom via Nut-upsuser <nut-upsuser at alioth-lists.debian.net> writes:> I am working on setting up a 12V DC UPS that will power a NAS and a router > for a few hours. It contains some lithium-ion batteries, and a BMS to > control charging. Since it is just a dumb box with batteries, it has no > intelligence to inform the NAS of its status. This is where NUT comes in...I don't follow. "no status" but you are reading voltages. Are you using an ADC wired up to e.g. i2c, so you have added monitoring ability? How are you measuring current?> I would like to incorporate a Raspberry Pi NUT server into this scheme. > The Rpi can measure input voltage, and output voltage & current to > determine the status of this simple UPS. > > With some of the excellent documentation online, I have gotten a NUT server > running on the Rpi, and my NAS (a Qnap) has been able to read the status. > I used the 'dummy-ups' driver for testing this and it worked great.I am not sure you are really missing anything, but I would suggest: You are doing two things. One is finishing the job of building a UPS that report status from the battery system you have. The second is making an interface from that to NUT. Think about it in two parts. Build and debug it in two parts. dummy doesn't feel right because this is a real UPS, not a test setup. I wonder if any of the existing drivers has a generic UPS protocol that is written to be simple. By that I mean a protocol designed to be written and read with minimal code, rather than NUT authors having to cope with what the hardware people thought was good. json comes to mind. I don't think the NUT RFC specifies this part at all. Having thought this far I can see why you ended up at dummy as writing a file with variables and values is exactly what the generic protocol ought to do. You definitely want logging of values to a db/etc. so that you can understand the relationships among voltage, current, runtime, SOC. But that's not really about NUT. As for> Now, for the real business - Since this is entirely homebrew, there is > not an appropriate driver available. I read about creating my own > driver using 'skel.c' as a template. But, nobody else would have any > interest in my very specialized driver.I don't follow. Surely others might want to buy the battery thing, and use the ADC etc., and replicate this.> ups.mfr: Tom > ups.model: My Contraption > battery.charge: 100 > ups.status: OL > input.voltage: 1.02 > battery.voltage: 11.5 > output.voltage: 11.2 > output.current: 3.4 > battery.runtime: 1000> I write this file periodically (maybe every 15-60 seconds) and the Rpi NUT > server would be none the wiser and just keep supplying the > constantly updated contents of this file to the NAS.I don't follow how much of this you think is real. Battery.charge is tough to estimate and your input.voltage does not make sense. And the output current seems high for what you described, but maybe your NAS uses a lot. I have 37W output from a UPS (AC) powering a router, a RPI3, a POE ethernet switch, and an access point on the switch. I guess that's the equivalent of 3A at 12V, assuming 100% efficiency so 3.4 with a NAS with disks is not implausible. I would urge you to only write actual data and just leave out things you don't know. I suspect after a test run you will have a good curve *for the load you actually have* mapping battery voltage to runtime. Also to charge. So you can have some actual data and some synthetic data, just like a real UPS :-) I don't know how often dummy does stat(2) to check if the file has changed but I would expect often and maybe it's the usual pollinterval. As an example, I get a notification within seconds if my input voltage drops below 100V (vs 125 nominal and 122-127 almost always). Usually it has gone to 0V. There's a 1s poll interval, and then a python program watching NUT sends this over MQTT, and then Home Assistant sends xmpp. I have two concerns: one is that I want to know about even brief outages and the second is that I want to know about them as they happen, not a minute later. If in a ramdisk (which seems necessary anyway) you could just write it every second, and you could also write it once a minute OR if anything has changed in an interesting way. Interesting is at least any ups.status change and any transition from input voltage being in the ok range to being not in the ok range or back.
Charles Lepple
2023-Feb-20 02:05 UTC
[Nut-upsuser] Using 'dummy.ups' for a real application, not just testing...
> On Feb 19, 2023, at 8:18 AM, Tom via Nut-upsuser <nut-upsuser at alioth-lists.debian.net> wrote: > > Good Morning, > > I am working on setting up a 12V DC UPS that will power a NAS and a router for a few hours. It contains some lithium-ion batteries, and a BMS to control charging. Since it is just a dumb box with batteries, it has no intelligence to inform the NAS of its status. This is where NUT comes in... > > I would like to incorporate a Raspberry Pi NUT server into this scheme. The Rpi can measure input voltage, and output voltage & current to determine the status of this simple UPS. > > With some of the excellent documentation online, I have gotten a NUT server running on the Rpi, and my NAS (a Qnap) has been able to read the status. I used the 'dummy-ups' driver for testing this and it worked great. > > Now, for the real business - Since this is entirely homebrew, there is not an appropriate driver available. I read about creating my own driver using 'skel.c' as a template. But, nobody else would have any interest in my very specialized driver.You'd be surprised, especially if you are using a more common battery management chip.> Plus - it seems overwhelming to me when I attempt to understand how to build NUT and I fear getting totally bogged down in all the minutiae of that.While it looks somewhat intimidating at first glance, we do have instructions for building a version of NUT from source that matches a lot of the paths that are in the Raspbian (Debian) package: https://github.com/networkupstools/nut/wiki/Building-NUT-on-Debian,-Raspbian-and-Ubuntu> But, it occurred to me - Why can't I just use 'dummy-ups' for this as-is? I can have a simple 'c' or Python program to read my values (to determine status) and then just write a few relevant lines into a '.dev' file to be served out to the LAN with the factory NUT server tools? My file would contain something like this:For what it's worth, I think using dummy-ups for prototyping is a good idea, especially if you put the .dev file on a RAM-based filesystem (as Greg suggested), like /run or /dev/shm. (I forget whether Raspbian usually puts /tmp on the SD card.) There are also a few i2c-based drivers in the NUT tree, such as https://github.com/networkupstools/nut/blob/master/drivers/pijuice.c and https://github.com/networkupstools/nut/blob/master/drivers/asem.c I have some notes on interfacing to an i2c-based battery pack from a few years ago: https://www.ghz.cc/charles/NUT/OpenElectrons_SmartUPS.html The code is pretty old, and the rest of NUT has been updated since then, but it's probably helpful for estimating the scope of converting a standalone C-based i2c program into a NUT driver. (I ended up not merging that driver into NUT.)> > ups.mfr: Tom > ups.model: My Contraption > battery.charge: 100 > ups.status: OL > input.voltage: 1.02 > battery.voltage: 11.5 > output.voltage: 11.2 > output.current: 3.4 > battery.runtime: 1000 > > I write this file periodically (maybe every 15-60 seconds) and the Rpi NUT server would be none the wiser and just keep supplying the constantly updated contents of this file to the NAS.I think the NAS is probably only looking at ups.status (OL/OB/LB) to trigger shutdown (barring any custom "shut down when variable X gets below a threshold), but it certainly can't hurt to publish the other values if you have something to log them. -- Charles Lepple clepple at gmail