Willcox David
2023-May-22 16:31 UTC
[Nut-upsuser] Synthesize low batt (LB) fron SNMP UPS which does not support this?
Hmm. Is there maybe something there already that will do this? Maybe kind of back-handed. In drivers/dstate.c, I see: In status_init(), if ?driver.flag.ignorelb? is set in the driver state, the ?ignorelb? flag is set. In status_set(), if ignorelb is set, and the status being set (presumably from the UPS) is LB, it?s ignored. In other words, LB reported by the UPS is ignored. In status_commit(), if ignorelb is set, there?s code to compare battery.charge against battery.charge.low and battery.runtime against battery.runtime.low. If either is below the ?low? setting, ? LB? is added to the status. (So ?OL? would become ?OL LB? and ?OB" would become ?OB LB?. And note that the two ?.low? settings can be overridden in the config. So, I surmise that of the UPS config in ups.conf included: driver.flag.ignorelb = 1 override.battery.charge.low = 50 would not that cause status to be returned as ?OB LB? when charge dropped below 50%? (I?d tried doing the override a while ago, but didn?t know about the ?ignorelb? thing.) Am I missing something? (I tried setting this but it didn?t seem to work. But then, I?m not sure how the NUT I installed from a package on my RPI compares with the source I downloaded.) (I surmise from the way that code works that there must be a seperate process for each driver. Otherwise all of those static variables are scary.)> On May 22, 2023, at 6:12 AM, Greg Troxel <gdt at lexort.com> wrote: > > Carsten Aulbert <carsten.aulbert at aei.mpg.de> writes: > >> Hi all, >> >> On 5/19/23 15:11, Greg Troxel wrote: >>> LB is baked in to nut behavior. So if a UPS doesn't report LB, then >>> it makes sense to synthesize it. Synthetic LB is the cleanest fix at >>> the earlier processing point. >> >> I fully agree and thus this ought to be done in/near uspd IMHO. I >> glanced over the server/ directory and was not sure where even to >> begin hooking this in. Should this be directly in upsd (upsd.c) or >> rather in/near the driver level (driver/main.c)? > > I think it belongs in upsd someplace, as what I want is a way to make LB > appear based on a rule instead of (or in addition) to the LB reported by > the device. The 50% vs 10% example captures the need for %-LB on > devices that actually do report LB perfectly, and I think it's a desire > many will have. > >>> Yes, this could be in upsmon, but that's not synthetic LB, it's >>> choosing to shutdown if battery is below X. >> >> Yeah, this should be independent and fully on the client side (and >> thus upsmon) where each client can choose how to react to a UPS on >> battery. > > It could also make sense to make upsmon smarter, but if we are really > talking about defining "this UPS's battery is now low", that's what LB > is supposed to mean and we should make it work that way. > >>> We should be clear on "critical" vs "LB" and clean up the language to >>> be consistent. >> >> For upsmon, I would stay with critical as this is already mentioned in >> upsmon(8) and I guess "LB" could stay for the server part as each user >> could decide whether she wants to rely on LB from the UPS itself or on >> the self-defined override. > > I think the difference is: > > LB is a state reported by a UPS (perhaps synthetic in upsd) that says > that the battery is nearing empty and remaining runtime is limited > > critical is an opinion by upsmon that the UPS has reached a state > where it is prudent to do an immediate shutdown. Typically LB implies > critical but it could be more complicated. > >>> Beware that I'm a bit fuzzy on details beyond my comments and even >>> some on things I commented on, so take them as such. >> >> Same here, quite at a loss what is handled where on the server and >> always low on time due to other projects/tasks. >> >> Cheers and any pointers appreciated! > > I would look where input from drivers is processed, and basically add > > if (battery% <= 50 && ! set?(LB)) { > log that we are doing synthetic LB > set!(LB) > } > > to mix C and scheme :) Then of course make it configurable. But it > probably is that easy to just make it hard-coded 50. > > _______________________________________________ > Nut-upsuser mailing list > Nut-upsuser at alioth-lists.debian.net > https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://alioth-lists.debian.net/pipermail/nut-upsuser/attachments/20230522/58b8580a/attachment-0001.htm>
Carsten Aulbert
2023-May-24 09:26 UTC
[Nut-upsuser] Synthesize low batt (LB) fron SNMP UPS which does not support this?
Hi again, On 5/22/23 18:31, Willcox David via Nut-upsuser wrote:> Hmm. Is there maybe something there already that will do this? Maybe > kind of back-handed. > > In drivers/dstate.c, I see: > > 1. In status_init(), if ?driver.flag.ignorelb? is set in the driver > state, the ?ignorelb? flag is set. > 2. In status_set(), if ignorelb is set, and the status being set > (presumably from the UPS) is LB, it?s ignored. In other words, LB > reported by the UPS is ignored. > 3. In status_commit(), if ignorelb is set, there?s code to compare > battery.charge against battery.charge.low and battery.runtime > against battery.runtime.low. If either is below the ?low? setting, ? > LB? is added to the status. (So ?OL? would become ?OL LB? and ?OB" > would become ?OB LB?. And note that the two ?.low? settings can be > overridden in the config.this looks exactly like the right place and functionality I would like to have, BUT> > Am I missing something?yes, probably the same trap I fell into, status_commit does not seem to be not called (at least from the dummy driver I use for testing) upon changing charge/runtime. I can only force a call by flipping OL/OB. I sprinkled a bit of debug information [1] into status_commit and journald looks like initial upsrw call to set dummy OL: May 24 08:23:24 gateway dummy-ups[284580]: [D2] entering setvar(ups.status, OL) May 24 08:23:24 gateway dummy-ups[284580]: [D2] status_commit: Entering (1) May 24 08:23:24 gateway dummy-ups[284580]: [D2] status_commit: charge val/low 33/30'] May 24 08:23:24 gateway dummy-ups[284580]: [D2] status_commit: runtime val/low 200/180'] May 24 08:23:27 gateway dummy-ups[284580]: [D1] upsdrv_updateinfo... setting it OB May 24 08:23:38 gateway dummy-ups[284580]: [D2] entering setvar(ups.status, OB) May 24 08:23:38 gateway dummy-ups[284580]: [D2] status_commit: Entering (1) May 24 08:23:38 gateway dummy-ups[284580]: [D2] status_commit: charge val/low 33/30'] May 24 08:23:38 gateway dummy-ups[284580]: [D2] status_commit: runtime val/low 200/180'] May 24 08:23:42 gateway dummy-ups[284580]: [D1] upsdrv_updateinfo... changing run-time May 24 08:23:48 gateway dummy-ups[284580]: [D2] upsdrv_updateinfo: NO-OP: input file was already read once to the end May 24 08:23:49 gateway dummy-ups[284580]: [D2] entering setvar(battery.runtime, 100) May 24 08:23:52 gateway dummy-ups[284580]: [D1] upsdrv_updateinfo... later changing charge May 24 08:37:28 gateway dummy-ups[284580]: [D2] send_to_one: sending PONG May 24 08:37:32 gateway dummy-ups[284580]: [D1] upsdrv_updateinfo... May 24 08:37:33 gateway dummy-ups[284580]: [D2] upsdrv_updateinfo: NO-OP: input file was already read once to the end May 24 08:37:33 gateway dummy-ups[284580]: [D2] entering setvar(battery.charge, 5) May 24 08:37:37 gateway dummy-ups[284580]: [D1] upsdrv_updateinfo... May 24 08:37:38 gateway dummy-ups[284580]: [D2] upsdrv_updateinfo: NO-OP: input file was already read once to the end and still no LB. But going back "OL", suddenly LB is added: May 24 09:21:48 gateway dummy-ups[284580]: [D2] entering setvar(ups.status, OL) May 24 09:21:48 gateway dummy-ups[284580]: [D2] status_commit: Entering (1) May 24 09:21:48 gateway dummy-ups[284580]: [D2] status_commit: charge val/low 5/30'] May 24 09:21:48 gateway dummy-ups[284580]: [D2] status_commit: appending LB flag [charge '5' below '30'] Thus it seems somewhere in the state logic there ought to be a possibility to trigger this automatically (on changing charge/runtime while OB) but there is not. Hopefully, someone with more knowledge than I have can chime in here :) Cheers Carsten [1] Please don't judge me by this, I still use printf and friends a lot for debugging (sorry for breaking lines, it's just for illustration): @@ -1113,12 +1116,13 @@ /* write the status_buf into the externally visible dstate storage */ void status_commit(void) { + upsdebugx(2, "%s: Entering (%d)", __func__, ignorelb); while (ignorelb) { const char *val, *low; val = dstate_getinfo("battery.charge"); low = dstate_getinfo("battery.charge.low"); - + upsdebugx(2, "%s: charge val/low %s/%s']", __func__, val, low); if (val && low && (strtol(val, NULL, 10) < strtol(low, NULL, 10))) { snprintfcat(status_buf, sizeof(status_buf), " LB"); upsdebugx(2, "%s: appending LB flag [charge '%s' below '%s']", __func__, val, low); @@ -1127,6 +1131,7 @@ val = dstate_getinfo("battery.runtime"); low = dstate_getinfo("battery.runtime.low"); + upsdebugx(2, "%s: runtime val/low %s/%s']", __func__, val, low); if (val && low && (strtol(val, NULL, 10) < strtol(low, NULL, 10))) { snprintfcat(status_buf, sizeof(status_buf), " LB"); -- Dr. Carsten Aulbert, Max Planck Institute for Gravitational Physics, Callinstra?e 38, 30167 Hannover, Germany, Phone +49 511 762 17185 -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4827 bytes Desc: S/MIME Cryptographic Signature URL: <http://alioth-lists.debian.net/pipermail/nut-upsuser/attachments/20230524/86647a74/attachment.bin>
Greg Troxel
2023-May-26 12:36 UTC
[Nut-upsuser] Synthesize low batt (LB) fron SNMP UPS which does not support this?
Willcox David via Nut-upsuser <nut-upsuser at alioth-lists.debian.net> writes:> In status_init(), if ?driver.flag.ignorelb? is set in the driver state, the ?ignorelb? flag is set. > In status_set(), if ignorelb is set, and the status being set > (presumably from the UPS) is LB, it?s ignored. In other words, LB > reported by the UPS is ignored. > In status_commit(), if ignorelb is set, there?s code to compare > battery.charge against battery.charge.low and battery.runtime against > battery.runtime.low. If either is below the ?low? setting, ? LB? is > added to the status. (So ?OL? would become ?OL LB? and ?OB" would > become ?OB LB?. And note that the two ?.low? settings can be > overridden in the config.Interesting. Perhaps the runtime check to set LB should be in status_set also. However I think it's more subtle than that. Read https://networkupstools.org/docs/developer-guide.chunked/ar01s04.html and also look at some other drivers. I think there's an assumption baked in that changing values like battery% and line voltage is a different thing from changing flags, but "set LB if battery <= X" crosses those. So it may be necessary to understand how this init/set interacts with everything else. Perhaps we need a "update cycle done" call that is made every time regardless of if the drive thinks it changed flags. Or perhaps a driver is supposed to call status_commit when it is done no matter what. Some code reading is in order!> (I tried setting this but it didn?t seem to work. But then, I?m not > sure how the NUT I installed from a package on my RPI compares with > the source I downloaded.)If you are trying to debug or to develop new things, you really have to build from source and run that, rather than running old code from a packaging system. Nobody should run 2.7.4, pretty much for any reason.> (I surmise from the way that code works that there must be a seperate > process for each driver. Otherwise all of those static variables are > scary.)Yes, each driver runs as a process, as ps will show you, and this is essentially the driver library from which a device-specific driver is constructed.
Seemingly Similar Threads
- Synthesize low batt (LB) fron SNMP UPS which does not support this?
- Synthesize low batt (LB) fron SNMP UPS which does not support this?
- Synthesize low batt (LB) fron SNMP UPS which does not support this?
- [PATCH/RFC v2 0/3] Updates to ACP smart driver
- Synthesize low batt (LB) fron SNMP UPS which does not support this?