[Nut-upsdev] zero-prepended values - why oh why?

Peter Selinger selinger at mathstat.dal.ca
Tue Feb 28 13:31:37 UTC 2006


Niklas Edmundsson wrote:
> 
> > with decimal precision, I'd prefer not to add a decimal. On the other
> > hand, if it can measure a value more precisely I don't see what value
> > there is in truncating it.
> 
> I seriously doubt that there are any UPS devices that can do accurate 
> voltage/current measurements with two decimals.
> 
> A Fluke 87 multimeter (which is a rather expensive one) has an 
> accuracy of +/- 0.7% plus 2 digits when measuring AC voltage, +/- 1.0% 
> plus 2 digits when measuring AC current.
> 
> 0.7% of 120V is 0.84V, so showing a second decimal makes little sense.
> 
> As a reference, cheap multimeters usually have +/- 2% +/- 2 digits. 
> This is probably more like what you'll find in a UPS.
> 
> Given this, it's probably no use to display a second decimal for the 
> current either (yes, I assume that a small/cheap UPS has less exact 
> measurement capability ;).
> 
> Frequency measurements are easier to get more exact, so two decimals 
> there probably makes sense.
> 
> In general, the trend seems to be that expensive devices (like our 
> 120kW APC Silcon UPS) tend to be rather honest with the accuracy of 
> the measurement capabilities and provides voltage like integers and 
> frequency with one decimal. Some cheap devices however spits out 
> measurements with two decimals but the minimum step seems to be 
> multiple-integer... So there's a big difference in what the ups 
> outputs and the actual accuracy. I find it better to be rather 
> conservative.
> 
> So, to be really honest, voltage measurements should probably have no 
> decimals at all ;)

I think we should not worry about that. If a device announces that its
voltage measurements are in units of 0.1V, then that is what we should
use. I do have devices that do this, and yes, they do fluctuate by as
little as 0.1V. I suspect that the accuracy is higher than you
predict, because the device only has to measure voltages accurately in
a very small range (typically between 110 and 130 volts). 

> So yes, I agree with integers are integers. Ie, use %d or %.0f as 
> format string depending on what you use for internal driver storage.

I apologize if I am about to state the obvious, but when changing %f
to %d, you will get garbage output unless you also insert an (int)
typecast (except in the few cases where the compiler might do this
automatically).  The reason this is relevant is that certain drivers,
such as newhidups and mge-shut, keep the format strings in a big
lookup table, and the driver makes certain assumptions about the types
of the variables being formatted. I was a bit surprised when I saw
changes such as the following in Arnaud's latest commit:

-       { "battery.runtime", 0, 0, "UPS.PowerSummary.RunTimeToEmpty", "%05d", NULL, SHUT_FLAG_OK, NULL },
+       { "battery.runtime", 0, 0, "UPS.PowerSummary.RunTimeToEmpty", "%.0f", NULL, SHUT_FLAG_OK, NULL },

This doesn't seem like the kind of thing that will work. Note how this
is being used (item->fmt is the format string from the above table,
item->hid2info is the last table entry, which is NULL in this
example):

mge-shut.c:206:
            if (item->hid2info != NULL)
              {
               nutvalue = hu_find_infoval(item->hid2info, (long)hData.Value);
               if (nutvalue != NULL)
                 dstate_setinfo(item->type, "%s", nutvalue);
               else
                 dstate_setinfo(item->type, item->fmt, hData.Value);
              }
            else
              dstate_setinfo(item->type, item->fmt, hData.Value);

Also observe that hData.Value is of type "long" (hidtypes.h:102).
Applying dstate_setinfo with format "%.0f" to a value of type "long"
should produce garbage, as there is no way the compiler can figure out
to do a typecast in this situation.

Arnaud, did you test this, and did it work? I think it shouldn't.

In newhidups, the semantics of the value formatting strings is even
more woundrous, as the format string assumes the value is a float,
*unless* item->hid2info is non-NULL, in which case it assumes it is a
string. I have been meaning to document and/or simplify this
behaviour, when I have time some time. 

The upshot is, for drivers that use lookup tables, better know what
you are doing before you change format strings.

-- Peter






More information about the Nut-upsdev mailing list