Stefan Bruda
2014-May-19 23:12 UTC
[Nut-upsuser] Tripp Lite SMART3000RM2U (protocol 3003) running time and charge?
Hello, First of all thank you so much for the information. At 22:43 -0400 on 2014-5-15 Charles Lepple wrote: > > On May 15, 2014, at 9:39 PM, Stefan Bruda wrote: > > > What bugs be though is that I cannot seem to be able to read the > > remaining run time on battery. The battery charge is also widely > > inaccurate (it drops to zero really fast and stays there). I read > > somewhere that the usb.debug numbers may hold the key to this (at > > least to the running time that is), but I don't know what to do with > > them (and I can no longer find that piece of information...). > > Here's where the battery.charge variable is calculated: > > https://github.com/networkupstools/nut/blob/master/drivers/tripplite_usb.c#L1099 > > battery_charge = (unsigned)(s_value[5]); > > (In that file, the 3003 protocol is denoted by "tl_model == TRIPP_LITE_SMARTPRO".) > > Due to the command prefix characters in the protocol, the > ups.debug.S hex values are actually indexed from 1 as follows: > > 1 2 3 4 5 6 7 > > ups.debug.S: 31 30 30 00 28 30 0d '100..0.' > > Hence, your s_value[5] yields 0x28 == 40%. Thank you. I do not remember the exact number but the battery level was nowhere near 40% at the time (more like 80%). Furthermore the above line was obtained while charging; when on battery s_value[5] falls to 0 almost immediately and stays there. Therefore as far as my UPS is concerned s_value[5] is wildly incorrect. > That said, a lot of information was either observed empirically, or > taken from this email: > > http://lists.alioth.debian.org/pipermail/nut-upsuser/2005-September/000218.html > > You will note that neither battery charge nor runtime is listed > there. > > It is possible that a better value for the state-of-chage could be > calculated, similar to the other protocols: > > https://github.com/networkupstools/nut/blob/master/drivers/tripplite_usb.c#L1129 Many thanks for the pointer. I tried something like the above but the "B" message is not answered (errors are spit by libusb too). However, I did notice that the battery voltage is available in the 3003 protocol (as a response to the "D" message), so I computed the battery charge percentage starting from that, along the following line: ------ begin patch ------ --- tripplite_usb.c.original 2014-05-19 16:20:58.251634449 -0400 +++ tripplite_usb.c 2014-05-19 16:53:54.806609602 -0400 @@ -1098,8 +1098,8 @@ - /* This may not be right... */ - if(tl_model == TRIPP_LITE_SMARTPRO) { - battery_charge = (unsigned)(s_value[5]); - dstate_setinfo("battery.charge", "%u", battery_charge); - } } @@ -1167,9 +1167,22 @@ hex2d(d_value+1, 2) * input_voltage_scaled / 120); bv = hex2d(d_value+3, 2) * battery_voltage_nominal / 120.0 ; - + // bv is 48V nominal rather than 12V + dstate_setinfo("battery.voltage", "%.2f", bv); + if(tl_model == TRIPP_LITE_SMARTPRO) { + if (bv / 4 >= V_interval[1]) + bp = 100; + else if (bv / 4 <= V_interval[0]) + bp = 10; + else + bp = (int)(100*sqrt((bv / 4 - V_interval[0]) + / (V_interval[1] - V_interval[0]))); + dstate_setinfo("battery.charge", "%3d", bp); + } + /* - * - * - * - * - * - * - * - * - * - * - * - * - * - * - */ ret = send_cmd(m_msg, sizeof(m_msg), m_value, sizeof(m_value)); ------ end patch ------ This is against NUT 2.7.1 and so will probably not apply cleanly on the current latest and greatest. I would not apply it as is anyway since it is quick and dirty and I am sure that it may be simplified (the conditional in particular is probably not needed...). The result seems to be quite a bit off compared with the output of Poweralert, as follows: 90% Poweralert = 50V = 79% as reported by the modified NUT. A bit afterward the voltage falls to 49.2V (= 73% in the modified NUT) but Poweralert still reports 90%. Later still (but not much later) Poweralert gets down to 80% = 48.4V = 67% as per the modified NUT. I have not tested anything lower than this. In related matter: 1. The voltage as read by NUT is precisely the voltage read by Poweralert. So if the voltage is in direct relationship with the remaining charge (which it should, however roughly) then all is needed is some computation to figure it out. 1. The nominal voltage of the battery pack is 48V rather than 12V (hence the division of bv to 4), but I am assuming that the relationship between the voltage and the charge still holds (since these are the same batteries, just that they are connected in series). 2. The UPS I am experimenting on has an external battery pack connected to it (BP48V24-2U, which contains no less than 8 batteries!) so overall I seem to have three parallel packs each consisting in four batteries in series. This may (or may not) be the reason of the calculations being off. 3. In any case the calculations are nonetheless a way better estimate than s_value[5]. Please let me know if more information is needed. I know that everything is largely a guess, but if anybody has any better idea on how to calculate the remaining capacity I would be more than happy to hear it and try it out. Any pointer is much appreciated. > However, calculating runtime usually requires the UPS to do a > battery test, and observe the voltage while under load. This unit > might not be capable of doing that. Understood. Many thanks. Best regards, Stefan -- If it was so, it might be; and if it were so, it would be; but as it isn't, it ain't. That's logic. --Lewis Carroll, Through the Looking-Glass No HTML emails and proprietary attachments please <http://bruda.ca/ascii>
Charles Lepple
2014-May-20 02:19 UTC
[Nut-upsuser] Tripp Lite SMART3000RM2U (protocol 3003) running time and charge?
On May 19, 2014, at 7:12 PM, Stefan Bruda wrote:> Hello, > > First of all thank you so much for the information.No problem, glad it is useful.> [...] > Therefore as far as my UPS is concerned s_value[5] is wildly > incorrect.So it turns out that the RM15002U also does not report anything useful for s_value[5]: http://lists.alioth.debian.org/pipermail/nut-upsuser/2007-January/002076.html We really should ask the author of tripplite_usb what he was thinking :-)> Many thanks for the pointer. I tried something like the above but the > "B" message is not answered (errors are spit by libusb too). However, > I did notice that the battery voltage is available in the 3003 > protocol (as a response to the "D" message), so I computed the battery > charge percentage starting from that, along the following line: > > ------ begin patch ------ > --- tripplite_usb.c.original 2014-05-19 16:20:58.251634449 -0400 > +++ tripplite_usb.c 2014-05-19 16:53:54.806609602 -0400 > @@ -1098,8 +1098,8 @@ > > - /* This may not be right... */ > - if(tl_model == TRIPP_LITE_SMARTPRO) { > - battery_charge = (unsigned)(s_value[5]); > - dstate_setinfo("battery.charge", "%u", battery_charge); > - } > } > > @@ -1167,9 +1167,22 @@ > hex2d(d_value+1, 2) * input_voltage_scaled / 120); > > bv = hex2d(d_value+3, 2) * battery_voltage_nominal / 120.0 ;Does battery_voltage_nominal get set correctly? Theoretically, it should be 48, since the 2nd and 3rd digits of ups.debug.V are 08, and that gets multiplied by 6. Might be useful to have an intermediate value that doesn't scale to actual battery voltage for the charge calculation, since bv seems to be some sort of ratio relative to a 12V battery.> - > + // bv is 48V nominal rather than 12V > + > dstate_setinfo("battery.voltage", "%.2f", bv); > > + if(tl_model == TRIPP_LITE_SMARTPRO) { > + if (bv / 4 >= V_interval[1]) > + bp = 100; > + else if (bv / 4 <= V_interval[0]) > + bp = 10; > + else > + bp = (int)(100*sqrt((bv / 4 - V_interval[0]) > + / (V_interval[1] - V_interval[0]))); > + dstate_setinfo("battery.charge", "%3d", bp); > + } > + > /* - * - * - * - * - * - * - * - * - * - * - * - * - * - * - */ > > ret = send_cmd(m_msg, sizeof(m_msg), m_value, sizeof(m_value)); > ------ end patch ------ > > This is against NUT 2.7.1 and so will probably not apply cleanly on > the current latest and greatest. I would not apply it as is anyway > since it is quick and dirty and I am sure that it may be simplified > (the conditional in particular is probably not needed...).Not much has changed between 2.7.1 and 2.7.2+git, so it might not be that bad.> The result seems to be quite a bit off compared with the output of > Poweralert, as follows: 90% Poweralert = 50V = 79% as reported by the > modified NUT. A bit afterward the voltage falls to 49.2V (= 73% in > the modified NUT) but Poweralert still reports 90%. Later still (but > not much later) Poweralert gets down to 80% = 48.4V = 67% as per the > modified NUT. I have not tested anything lower than this. > > In related matter: > > 1. The voltage as read by NUT is precisely the voltage read by > Poweralert. So if the voltage is in direct relationship with the > remaining charge (which it should, however roughly) then all is needed > is some computation to figure it out.It's going to be a rough estimate for sure, since it depends on the load, plus whatever internal resistance the battery has built up over time. The UPS self test usually skips a lot of this complication when trying to calibrate for a low battery signal.> 1. The nominal voltage of the battery pack is 48V rather than 12V > (hence the division of bv to 4), but I am assuming that the > relationship between the voltage and the charge still holds (since > these are the same batteries, just that they are connected in series).Agreed.> 2. The UPS I am experimenting on has an external battery pack > connected to it (BP48V24-2U, which contains no less than 8 batteries!) > so overall I seem to have three parallel packs each consisting in four > batteries in series. This may (or may not) be the reason of the > calculations being off.See above, but I think the current code is taking this into account.> 3. In any case the calculations are nonetheless a way better estimate > than s_value[5]. > > Please let me know if more information is needed. > > I know that everything is largely a guess, but if anybody has any > better idea on how to calculate the remaining capacity I would be more > than happy to hear it and try it out. Any pointer is much > appreciated.Maybe what we do is expose the V_interval[] entries as options in ups.conf (or even upsrw variables), and use those in lieu of s_value[5] if they are set. Given how long this code has been this way, either nobody else has run into this (and s_value[5] has a different meaning) or nobody trusts battery.charge, and your code will be an improvement. While you're in there, can you check to see if everything still works if you comment out the "usb_set_altinterface(udev, 0)" line from drivers/libusb.c? (You might need to unplug and re-plug the UPS to be certain.) I ran across an old patch which removed that line to make a TrippLite OMNIVS1000 work on OS X, but I'm not sure if that line is needed on other OSes. -- Charles Lepple clepple at gmail
Stefan Bruda
2014-May-22 14:03 UTC
[Nut-upsuser] Tripp Lite SMART3000RM2U (protocol 3003) running time and charge?
Hello, At 22:19 -0400 on 2014-5-19 Charles Lepple wrote: > > On May 19, 2014, at 7:12 PM, Stefan Bruda wrote: > > > Therefore as far as my UPS is concerned s_value[5] is wildly > > incorrect. > > So it turns out that the RM15002U also does not report anything useful for s_value[5]: > > http://lists.alioth.debian.org/pipermail/nut-upsuser/2007-January/002076.html > > We really should ask the author of tripplite_usb what he was thinking :-) Well, it does produce a number between 0 and 100, which might even mean the battery charge for some UPSes... > > ------ begin patch ------ > > --- tripplite_usb.c.original 2014-05-19 16:20:58.251634449 -0400 > > +++ tripplite_usb.c 2014-05-19 16:53:54.806609602 -0400 > > @@ -1098,8 +1098,8 @@ > > > > - /* This may not be right... */ > > - if(tl_model == TRIPP_LITE_SMARTPRO) { > > - battery_charge = (unsigned)(s_value[5]); > > - dstate_setinfo("battery.charge", "%u", battery_charge); > > - } > > } > > > > @@ -1167,9 +1167,22 @@ > > hex2d(d_value+1, 2) * input_voltage_scaled / 120); > > > > bv = hex2d(d_value+3, 2) * battery_voltage_nominal / 120.0 ; > > Does battery_voltage_nominal get set correctly? Theoretically, it > should be 48, since the 2nd and 3rd digits of ups.debug.V are 08, > and that gets multiplied by 6. Yes, as it appear as 48V in the output of upsc. > Might be useful to have an intermediate value that doesn't scale to > actual battery voltage for the charge calculation, since bv seems > to be some sort of ratio relative to a 12V battery. I am game, but what would a more appropriate value be? I am new to the intricacies of reverse engineering Tripp Lite UPSes so I don't really know how to proceed... ;-) I am not even terribly familiar with the properties of lead-acid batteries (such as the variance of the internal resistance and the such). > > - > > + // bv is 48V nominal rather than 12V > > + > > dstate_setinfo("battery.voltage", "%.2f", bv); > > > > + if(tl_model == TRIPP_LITE_SMARTPRO) { > > + if (bv / 4 >= V_interval[1]) > > + bp = 100; > > + else if (bv / 4 <= V_interval[0]) > > + bp = 10; > > + else > > + bp = (int)(100*sqrt((bv / 4 - V_interval[0]) > > + / (V_interval[1] - V_interval[0]))); > > + dstate_setinfo("battery.charge", "%3d", bp); > > + } > > + > > /* - * - * - * - * - * - * - * - * - * - * - * - * - * - * - */ > > > > ret = send_cmd(m_msg, sizeof(m_msg), m_value, sizeof(m_value)); > > ------ end patch ------ > > > > This is against NUT 2.7.1 and so will probably not apply cleanly on > > the current latest and greatest. I would not apply it as is anyway > > since it is quick and dirty and I am sure that it may be simplified > > (the conditional in particular is probably not needed...). > > Not much has changed between 2.7.1 and 2.7.2+git, so it might not > be that bad. It should apply, but somebody more familiar with the thing should verify the code. For instance is this only applicable to tl_model =TRIPP_LITE_SMARTPRO (as in my code)? How about tl_model =TRIPP_LITE_SMART_0004? This one supposedly also responds to a "D" message with (again supposedly) the same kind of response, but maybe s_value[5] is better in this case. In my patch I simply did not care about it and I would not know whether to care or not since I don't have access to this kind of UPS. Any modification would be a matter of wild guesses for me (though I am not sure whether others have better foundations for their guesses either ;-) ). I believe that the other type is left in the dark anyway when it comes to the battery charge (so this code will at least not do any harm for TRIPP_LITE_SMART_0004), but I might be wrong (I did not cover more than 10% of the code really). > > The result seems to be quite a bit off compared with the output of > > Poweralert, as follows: 90% Poweralert = 50V = 79% as reported by the > > modified NUT. A bit afterward the voltage falls to 49.2V (= 73% in > > the modified NUT) but Poweralert still reports 90%. Later still (but > > not much later) Poweralert gets down to 80% = 48.4V = 67% as per the > > modified NUT. I have not tested anything lower than this. > > > > In related matter: > > > > 1. The voltage as read by NUT is precisely the voltage read by > > Poweralert. So if the voltage is in direct relationship with the > > remaining charge (which it should, however roughly) then all is needed > > is some computation to figure it out. > > It's going to be a rough estimate for sure, since it depends on the > load, plus whatever internal resistance the battery has built up > over time. Agreed. Moreover a precise value seems to be available from the UPS which is tantalizing (this, or Poweralert performs the same kind of calculations, but in a smarter way). Problem is, I have no idea where to get it from... > Maybe what we do is expose the V_interval[] entries as options in > ups.conf (or even upsrw variables), and use those in lieu of > s_value[5] if they are set.>From what I see in the code V_interval[] is hard coded rather thanbeing read from the UPS. Oh, I see, you mean that various users will set this to whatever works for their UPS, right? Yes, I believe this to be a very good idea, so that people can effectively modify the parameters without recompiling the code. > Given how long this code has been this way, either nobody else has > run into this (and s_value[5] has a different meaning) or nobody > trusts battery.charge, and your code will be an improvement. Well, I seem to recall that it is mentioned in the documentation that the value is not to be trusted (I am not sure whether it is this value or overall the output of the driver which is labelled as experimental). I have been running NUT for several years with this UPS without caring about that value -- as long as a battery critical event turned my machines off I was happy. :-) The reason I started investigating this is that I wanted to see whether the mentioned external battery pack is taken into consideration by the UPS and I discovered that I have no means of seeing if it is so. This all being said, I cannot vouch whether my code is useful or not -- please keep in mind that I only have one UPS to play with so the result is not necessarily portable. > While you're in there, can you check to see if everything still > works if you comment out the "usb_set_altinterface(udev, 0)" line > from drivers/libusb.c? (You might need to unplug and re-plug the > UPS to be certain.) I have commented out the line and upsc seems to behave as before. I have not performed any other test but this should be enough to show that the line is not useful, right? In case it matters by the way this is all happening on a box running kernel version 3.12.13 with Gentoo patches. The NUT I am playing with is the stock Gentoo unstable variety, meaning version 2.7.1 with some Gentoo patching on top. Best regards, Stefan -- If it was so, it might be; and if it were so, it would be; but as it isn't, it ain't. That's logic. --Lewis Carroll, Through the Looking-Glass No HTML emails and proprietary attachments please <http://bruda.ca/ascii>
Possibly Parallel Threads
- Tripp Lite SMART3000RM2U (protocol 3003) running time and charge?
- Tripp Lite SMART3000RM2U (protocol 3003) running time and charge?
- Tripp Lite SMART3000RM2U (protocol 3003) running time and charge?
- Tripp Lite SMART3000RM2U (protocol 3003) running time and charge?
- Tripp Lite SMART3000RM2U (protocol 3003) running time and charge?