Re "DIY-NAS", that was a typo. I did mean "DIY-UPS" as you suspected.
Re: Using custom vid:pid while specifying the arduino subdriver, I didn't know that! So if someone finds a particular board that doesn't match, they could still move forward without needing to patch NUT. Nice! On Fri, May 17, 2024 at 5:42 AM Jim Klimov <jimklimov+...@gmail.com> wrote: > Looks very great, thanks for writing this! I gather you'd port this to the > Wiki page you've started, too? > > A couple of comments: > > > So I run a NUT server on a Raspberry PI which is connected via USB to my > DIY-NAS Arduino. > > DIY-UPS? > > > See drivers/arduino-hid.c for the list of supported IDs... > > Since NUT v2.8.1 [PR #1369], the `usbhid-ups` driver allows the user to > specify a `subdriver` in config - to use the specific mapping for the > specified vendorid:productid (and/or other matching options involved), > allowing for IDs not yet known to NUT (built into any driver) or to use a > different subdriver than the one associated with those IDs (some vendors > historically have same IDs used for significantly different products). > Either way, while it is ideally preferable to test and post PRs with > correct out-of-the-box detection of devices handled by this or that code, > the specimens seen roaming in the wild keep eluding any pre-created > matchers that are set in stone for the particular build of (packaged) NUT. > This feature allows for at least some more tweaks and experiments in the > field. > > Hope this helps, > Jim Kl.imov > > > > On Fri, May 17, 2024 at 1:05 PM Kelly Byrd <kb...@memcpy.com> wrote: > >> Ha! I got several on and off list requests for details, so I'll give a >> bunch of details here and then maybe I can move this to a wiki page others >> can help edit. >> >> WARNING! WARNING! WARNING! >> Be careful! My implementation required opening up high power components, >> and dealing with 120VAC mains power and high currents on 12VDC. If you >> decide to tackle any of this yourself, you need to understand how to do >> this safely, size components appropriately, etc. >> >> My goal is to keep a home Internet connection available during a power >> outage. This doesn't happen that often, but it bugged me when it did and I >> like playing with power-related things, so this became a fun project to >> tackle. I guess I should mention that my home network gear is in a rack in >> the garage. "modem", router, switch, wifi APs powered over PoE from the >> switch, NAS, and typically a Raspberry Pi or two doing whatever "always on" >> things I want. I also previously built a substantial portable battery box >> that will power other appliances like TVs and computers, but the networking >> gear is all in the garage and I can't power both at once without some very >> long extension cables snaking through the house. >> >> I noticed a few years ago that my Internet connection stayed up during a >> couple of different neighborhood power outages, assuming I could power the >> gear on my side. I guess the equipment on the ISP side is far enough away >> that it isn't affected? For a few years, I did this with a 12V inverter >> connected to an EV (an electric car). It turns out the 12V system in many >> EVs will provide 12V power through a DC step-down from the main traction >> battery. I really only need like 15A and previous testing made me confident >> I could safely do this as long as the main battery had capacity left. So, I >> did that for a while, but earlier this year we sold the EV and became a >> one-car household. So...what do I do? I had an inverter, if I could get >> batteries and a way to charge them, I should be most of my way toward a DIY >> UPS, right? >> >> Specs/Requirements >> * AC power needed is typically about 150W, I typically use 300W as a >> value for max surge. If I turn off my NAS, the load is only about 50-55W >> AC. I was aiming for 2-3 days of power for this load, and can live without >> the NAS during an outage, so I need 2.8-4.3kWh of capacity with the NAS off. >> >> * While I do want this to work, this is a fun personal project. Mucking >> with it is part of the goal. I had some hobby money to spend, but not >> infinite. I wanted to reuse things I had on hand or could get easily for >> v1. I also get to decide how reliable it needs to be. >> >> The system is: >> * AIMS Pure Sine 12V 600W Inverter. I had it already. Having this >> inverter on hand drove the decision for 12V vs 24/48V. Also, power needs >> are relatively low so 12V doesn't lead to more than 55A of current, and >> that's only when charging from a deep discharge. >> >> * RV Converter/Charger: PowerMax PM4 55A 12V. This is a lead acid battery >> charger that will also provide power after batteries are charged. Many >> battery chargers are not designed to be run 24/7, this one is. >> >> * Two 12V 200Ah Renology AGM deep cycle batteries wired in parallel. Got >> a deal on these. I decided I was ok with 75%-80% DoD even though these are >> lead acid. This gives me about 3.5kWh of usable AC capacity. >> >> * Batteries and charger are wired up with 4AWG, the inverter is something >> smaller, I think 6AWG? >> >> >> What I have built is a double conversion online system. The inverter is >> powering the AC load all the time. There's no transfer switch. There's >> lower efficiency when power is on because the normal power path is always >> AC->DC->AC. I did this because I wasn't confident in my ability to find a >> transfer switch that would transfer fast enough and it was one more thing >> to figure out and buy. In my head, this online architecture is simpler, but >> I may change it in the next version. I worry a bit about the inverter being >> ok running full time, but since it is rated for 600W and I use only 150W >> all the time, I decided it's ok. When it fails, I'll figure out something >> else. >> >> I chose lead acid deep-cycle batteries because if you're willing to >> discharge them to 70-80% they're very cost effective vs LiFePO4 or other >> lithium types. I know this will shorten the number of cycles I get from >> them. I'm ok with that. In this application, they sit at 100% for all but >> maybe a few hours to a few days a year. They may see one or two deep >> discharges a year. If I get five years out of them, that's great! >> >> I calculated roughly 3.5kWh of usable capacity for these two wired in >> parallel. Running with the NAS off is maybe 5A from the DC side of things, >> which is a really low load for a 400Ah battery bank. They are very heavy, >> but I already had a heavy duty storage rack next to the load, so that's not >> a problem in this case. Also, the voltage range for 12V lead acid batteries >> is still better supported than LiFePO4. Right now, there are still more >> (and lower cost) chargers and inverters that assume a lead acid voltage >> range. As an example, my inverter will shut down if it sees over about >> 14.6V. >> >> So, how does this fit into NUT? One key aspect of my capacity planning >> was: "normal load is ~150W, but if the NAS turns off, I can make that >> 50-60W.". My NAS is a QNAP, it has NUT installed. Before this DIY UPS, I >> was using an APC consumer UPS connected to the NAS via USB so it would turn >> off 5 min after mains power went off. That's the behavior I wanted for my >> DIY UPS. >> >> So how did I do this? >> >> Gear: >> * Arduino Pro Micro clone. It has a micro USB port built in and is >> commonly used for "make an Arduino appear to be some USB device" projects. >> It can be powered over USB, or by 5VDC directly to pins. >> >> * AC detection module: https://www.amazon.com/gp/product/B082PWV586. >> Gives me an opto-isolated "is the mains AC present" signal the Arduino can >> read. >> >> * Raspberry Pi running NUT. I wish I didn't need this, but I do for now. >> While building and debugging the Arduino code, I needed to modify the NUT >> code. Those patches made it in v2.8.1 and v2.8.2 NUT releases, but I still >> don't think my QNAP NAS has v2.8.2 available. I eventually plan to remove >> this. >> >> I put the AC detection module and the Arduino inside the PowerMax >> converter/charger enclosure, on a little 3D printed mount. The AC module >> connect to the AC input terminals inside the PowerMax and then the signal >> side connects to a pin on the Arduino and pulls it high (or low, I forget) >> when the AC is gone. I run a USB cable out of the PowerMax case which >> connects to the RPi running NUT. The RPi is powered by the inverter, and it >> powers the Arduino over USB. The RPi stays on during a power outage. >> >> So now I can write some Arduino code that loops and checks the status of >> a digital pin. How do I pretend to be a UPS in a way NUT will recognize? >> >> Some googling led me to the HIDPowerDevice project. >> https://github.com/abratchik/HIDPowerDevice. That is a library for >> Arduino MCUs that does all the protocol for getting an Arduino device to be >> recognized as a HID compliant UPS device over USB. You use it by >> periodically calling a `sendReport` function with various flags set. Ex: >> PowerDevice.sendReport(HID_PD_REMAININGCAPACITY, &iRemaining, >> sizeof(iRemaining)); >> PowerDevice.sendReport(HID_PD_PRESENTSTATUS, &iPresentStatus, >> sizeof(iPresentStatus)); >> >> `iPresentStatus` is a bit field with a ton of info in it, like: >> PRESENTSTATUS_ACPRESENT, PRESENTSTATUS_DISCHARGING, >> PRESENTSTATUS_CHARGING, etc. See the project for full details. >> >> So, now my Arduino code loop does this: >> Check status of AC on/off pin. >> Set/clear PRESENTSTATUS_ACPRESENT and set >> PRESENTSTATUS_CHARGING/PRESENTSTATUS_DISCHARGING accordingly. >> Call `sendReport` from the HIDPowerDevice library. >> Sleep a second, loop. >> >> In reality, my loop does a little bit more than this. It loops every >> second, but only sends a report if some status changed but waits no more >> than every 5 seconds between reports in any case. NUT (and Windows, and >> MacOS) seem to expect this. >> >> So, assuming I can get NUT to recognize the Arduino Micro as a UPS, this >> should work. I had two problems getting NUT to recognize the Arduino: >> 1) Will NUT recognize the default Arduino vendor and product id >> (vid:pid)? The answer is YES! There is an Arduino subdriver for usbhid in >> NUT. It looks like the HIDPowerDevice project author added this originally >> a few years ago! See drivers/arduino-hid.c for the list of supported IDs. >> If you end up with an Arduino device that has another vid/pid combo, it >> would need to be added there. >> >> 2) When using the HIDPowerDevice library, the Arduino Micro presents as a >> composite HID device, so it is more than one HID type at once. AFAICT, real >> world examples of composite devices are rare, but it is in the HID spec. In >> this exact case the Arduino presents as both serial/comm interface >> (typically used for debug output when running code from the Arduino IDE) >> and as a HID Power Device (the HID term for UPS status over USB). This all >> works now as of NUT 2.8.2. >> >> Note that the Arduino subdriver is not as full featured as something like >> the APC subdriver. I don't think it allows for NUT to set values on the >> Arduino HID device. I don't know if the Arduino HIDPowerDevice library >> supports this either. I have only tested the send-a-report-periodically >> code path. >> >> NUT config >> What I really wanted was for my NAS to shut down when mains power goes >> away. My QNAP NAS runs NUT, but I needed 2.8.2 and getting a new version on >> there was more than I wanted to tackle, especially since my PRs weren't in >> a release version of NUT at that time. So I run a NUT server on a Raspberry >> PI which is connected via USB to my DIY-NAS Arduino. The RPi does not react >> to changes in the UPS at all. It makes them available over the network to >> the NUT instance running on the QNAP NAS. The QNAP NAS is then configured >> to poll the RPi NUT instance for UPS status and set to shut down if AC >> power is out for 5 min. I would rather not deal with this extra RPi in the >> setup, but it was the easiest way forward for me. Once NUT 2.8.2 is >> available for my QNAP NAS. I'll get rid of it. >> >> >> Optional Upgrade >> DC voltage sensing to give an idea of remaining runtime or remaining >> capacity. Since this is too long already, I'll try to be brief. One thing I >> did a month or so after the initial install was add DC voltage detection to >> the Arduino side of things: >> >> Gear: >> * 0-25VDC voltage sensor (https://www.amazon.com/gp/product/B01HTC4XKY). >> It's a voltage divider, let's my code sense the DC voltage. >> >> * External ADC: ADS1115 board. I wanted higher resolution DC voltage >> detection. >> >> My code then changed to take readings from the ADS1115 and convert that >> into a rough "50-100% capacity remaining" that I can report to NUT. It took >> a while to get right and it's only "accurate enough", not "trust this to a >> millivolt level of accuracy". For now it's just nice to have and I enjoyed >> having to learn about ADC measuring on Arduino enough to get this accurate >> enough to report with 1% differences in capacity. >> >> Future >> I've been researching designing a PCB and doing an "all-in-one" UPS. I'll >> talk more about that on the wiki page as well. >> >> I guess I should share my Arduino code on GitHub too. >> >> On Thu, May 16, 2024 at 10:59 AM gene heskett via Nut-upsuser < >> nut-upsuser@alioth-lists.debian.net> wrote: >> >>> On 5/16/24 08:59, Jim Klimov via Nut-upsuser wrote: >>> > I agree with earlier posters, such documentation can help future >>> > tinkerers. There is probably more than just one to hold the hand and >>> > walk through the ordeals :) >>> > >>> > Perhaps a new page at https://github.com/networkupstools/nut/wiki >>> > <https://github.com/networkupstools/nut/wiki> can be a good >>> location... >>> > >>> > Jim >>> > >>> Great Idea Jim. >>> > >>> > On Thu, May 16, 2024 at 1:29 PM Bill Gee <b...@campercaver.net >>> > <mailto:b...@campercaver.net>> wrote: >>> > >>> > Hi Kelly - >>> > >>> > As an Arduino nerd, I am interested in this! I am sure others on >>> the >>> > list would be interested. If nothing else, it would be nice to >>> have >>> > some documentation in the archives. >>> > >>> > I assume you set it up as an online system rather than a standby >>> > system. >>> > Right? If true, then the choice of inverter is fairly >>> critical. It >>> > has to be bomb-proof reliable. >>> > >>> > What did you choose for battery voltage? What is the power >>> capacity of >>> > the inverter? >>> > >>> > Which Arduino did you use? All of my Arduino projects use the Pro >>> > Mini, >>> > though it would be quite easy to get some other model for this. >>> > >>> > Thanks - >>> > =============== >>> > Bill Gee >>> > >>> > On 5/15/24 20:11, Kelly Byrd wrote: >>> > > I put together my own DIY UPS, it's a RV charger/converter, an >>> > > inverter, and some batteries. I use an Arduino and the >>> > HIDPowerDevice >>> > > library (https://github.com/abratchik/HIDPowerDevice >>> > <https://github.com/abratchik/HIDPowerDevice> >>> > > <https://github.com/abratchik/HIDPowerDevice >>> > <https://github.com/abratchik/HIDPowerDevice>>) to get it to talk >>> to >>> > NUT. >>> > > Been working great for months! >>> > > >>> > > The Arduino is connected to two modules: >>> > > * AC detection circuit to measure mains power on/off >>> > > * Voltage divider and an external ADC to get a reasonably good >>> DC >>> > > voltage level for the battery which I turn into the a charge >>> > percentage. >>> > > >>> > > This uses the USBHID driver in NUT and "just works" as long as >>> > you're >>> > > using NUT 2.8.2 or later. I used the example code in the >>> > HIDPowerDevice >>> > > library as a starting point for running on my Arduino. >>> > > >>> > > I can share more specifics about the Arduino side of things off >>> > list if >>> > > you want, the NUT side of things is pretty boring and normal. >>> > > >>> > > On Wed, May 15, 2024 at 3:27 PM Kiril Zyapkov via Nut-upsuser >>> > > <nut-upsuser@alioth-lists.debian.net >>> > <mailto:nut-upsuser@alioth-lists.debian.net> >>> > > <mailto:nut-upsuser@alioth-lists.debian.net >>> > <mailto:nut-upsuser@alioth-lists.debian.net>>> wrote: >>> > > >>> > > Hello, >>> > > >>> > > I found out about NUT just days ago while searching for a >>> > solution >>> > > for my home setup. After some digging through the interwebs, >>> > I come >>> > > to you with questions. >>> > > >>> > > I'm putting together a DIY 12V UPS, very similar to what >>> this >>> > guy did: >>> > > >>> > > [1] >>> > > >>> > >>> https://baldpenguin.blogspot.com/2015/10/diy-12v-ups-for-home-network-equipment.html >>> < >>> https://baldpenguin.blogspot.com/2015/10/diy-12v-ups-for-home-network-equipment.html> >>> < >>> https://baldpenguin.blogspot.com/2015/10/diy-12v-ups-for-home-network-equipment.html >>> < >>> https://baldpenguin.blogspot.com/2015/10/diy-12v-ups-for-home-network-equipment.html >>> >> >>> > > >>> > > The objective is to keep a bunch of mini PCs and network >>> gear >>> > online >>> > > for as long as the battery lasts and then provide a >>> mechanism >>> > for a >>> > > graceful shutdown of my NAS and other appliances for which >>> > cutting >>> > > power would not be healthy. The project above is missing the >>> > > "connected" part. I want to get mine to play with NUT >>> nicely. >>> > Other >>> > > prior art is this project: >>> > > >>> > > [2] https://github.com/xm381/Raspberry-Pi-UPS >>> > <https://github.com/xm381/Raspberry-Pi-UPS> >>> > > <https://github.com/xm381/Raspberry-Pi-UPS >>> > <https://github.com/xm381/Raspberry-Pi-UPS>> >>> > > >>> > > Mentioned in a previous thread here: >>> > > >>> > > [3] >>> > > >>> > >>> https://alioth-lists.debian.net/pipermail/nut-upsuser/2018-August/011198.html >>> < >>> https://alioth-lists.debian.net/pipermail/nut-upsuser/2018-August/011198.html> >>> < >>> https://alioth-lists.debian.net/pipermail/nut-upsuser/2018-August/011198.html >>> < >>> https://alioth-lists.debian.net/pipermail/nut-upsuser/2018-August/011198.html >>> >> >>> > > >>> > > A valid approach -- emulates an existing protocol on an >>> arduino. >>> > > >>> > > Are there other similar projects that you know of? I found >>> > plenty of >>> > > "DIY UPS" projects, but none were "smart". >>> > > >>> > > I am able to put together firmware for some micro which >>> will take >>> > > care of measuring voltages, currents, possibly also turn >>> on/off >>> > > loads, serial or USB or IP are options. Not sure yet what >>> > hardware >>> > > features I'll put together, but this depends somewhat on the >>> > > approach for getting this thing integrated with NUT. PSUs >>> and >>> > > batteries are already on the way, and my junk drawers have >>> most >>> > > other parts I may need. >>> > > >>> > > So, options found so far: >>> > > >>> > > * Use genericups. Least favorite option, very limited >>> features >>> > > >>> > > * Use the same approach as [2]. If I were to go that route >>> -- >>> > which >>> > > is the best protocol to pick for emulation? I'm looking for >>> > > something simple, extensible/flexible and well-documented. >>> > > >>> > > But what I really wish was possible was the ability to >>> > describe my >>> > > device in some format, feed it to a generic driver in NUT >>> and >>> > > profit. I see some efforts have been made in this >>> direction, most >>> > > notably: >>> > > >>> > > [4] >>> > > >>> > >>> https://github.com/networkupstools/nut/wiki/Data-Mapping-File-(DMF) >>> > < >>> https://github.com/networkupstools/nut/wiki/Data-Mapping-File-(DMF)> >>> > > >>> > < >>> https://github.com/networkupstools/nut/wiki/Data-Mapping-File-(DMF) < >>> https://github.com/networkupstools/nut/wiki/Data-Mapping-File-(DMF)>> >>> > > >>> > > What is the state there? Is it usable for USB HID? Or, how >>> hard >>> > > would it be to make it usable? Even a modbus description >>> will >>> > do -- >>> > > implementing the modbus server (yes, server, I'm being >>> > > politically-correct) over serial or even TCP is easy, if >>> only >>> > there >>> > > was a way to dump a CSV with register descriptions in some >>> > magical >>> > > driver... >>> > > >>> > > And yet another approach which comes to mind is to >>> implement my >>> > > driver as an external executable. This may be completely >>> > unfeasible >>> > > and stupid, and please let me know if it is. But, from what >>> I >>> > > gather, drivers run in their own process and talk to the >>> > daemon via >>> > > a UNIX socket. Why not make it possible for the driver to >>> be just >>> > > any executable, built/deployed outside of the NUT codebase? >>> The >>> > > socket protocol seems simple enough, and this will allow >>> for ... >>> > > creativity. It could be implemented in any language >>> (including >>> > > scripting languages) and need not depend on anything >>> > NUT-specific, >>> > > other than maybe some common CLI interface and/or >>> configuration. >>> > > >>> > > I'm hoping the NUT masters will have some insight. Thanks >>> for >>> > > working on this! >>> > > >>> > > Cheers, >>> > > Kiril >>> > > _______________________________________________ >>> > > Nut-upsuser mailing list >>> > > Nut-upsuser@alioth-lists.debian.net >>> > <mailto:Nut-upsuser@alioth-lists.debian.net> >>> > > <mailto:Nut-upsuser@alioth-lists.debian.net >>> > <mailto:Nut-upsuser@alioth-lists.debian.net>> >>> > > >>> > >>> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser >>> > < >>> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser> >>> > > >>> > < >>> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser < >>> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser>> >>> > > >>> > > >>> > > _______________________________________________ >>> > > Nut-upsuser mailing list >>> > > Nut-upsuser@alioth-lists.debian.net >>> > <mailto:Nut-upsuser@alioth-lists.debian.net> >>> > > >>> > >>> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser >>> > < >>> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser> >>> > >>> > _______________________________________________ >>> > Nut-upsuser mailing list >>> > Nut-upsuser@alioth-lists.debian.net >>> > <mailto:Nut-upsuser@alioth-lists.debian.net> >>> > >>> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser >>> > < >>> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser> >>> > >>> > >>> > _______________________________________________ >>> > Nut-upsuser mailing list >>> > Nut-upsuser@alioth-lists.debian.net >>> > https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser >>> >>> Cheers, Gene Heskett, CET. >>> -- >>> "There are four boxes to be used in defense of liberty: >>> soap, ballot, jury, and ammo. Please use in that order." >>> -Ed Howdershelt (Author, 1940) >>> If we desire respect for the law, we must first make the law respectable. >>> - Louis D. Brandeis >>> >>> >>> _______________________________________________ >>> Nut-upsuser mailing list >>> Nut-upsuser@alioth-lists.debian.net >>> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser >>> >> _______________________________________________ >> Nut-upsuser mailing list >> Nut-upsuser@alioth-lists.debian.net >> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser >> >
_______________________________________________ Nut-upsuser mailing list Nut-upsuser@alioth-lists.debian.net https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser