Improving vertical scale for LuCI statistics' collectd-mod-nut plugin

My router is collecting UPS statistics through a modified 22.03.3, RRDtool 1.0.50, and collect-mod-xyz 5.12.0-33.

For the AC voltage graph, the default autoscale subroutine set max value starting at 125V, but my (supposedly 117V) mains has been close to that value, so when eventually needed an update, it jumped to 200V. The min has stayed at 100V for as loong as I have been observing. From my viewpoint, 100V it could be a little high, 125V is a little low, and 200V is too much. (I mean, the line is never vertically centered). Here some examples:

So, How can the autoscale be improved? or at least, where can I manually set the vertical scale limits?

Since this is not an OpenWrt specific problem: Have you already checked the rrdtool documentation where autoscaling is explained?

Well, maybe the autscale issue is upstream, but since OpenWrt uses it, I don't know whether is there a configuration file we could tweak or improve, or on the contrary is embedded in the code and therfore hidden to all of us.

I read the rrdtool graph documentation, but again, unless knowing which configuration/file to check, I don't know where to look for applying the options stated there.

It is the nut.js javascript that jow already modifed for you (and linked the pr in the other discussion)

Jow has done most of the LucI graph definitions, and I have modifed quite a few of them for better scaling etc.. But I haven't touched nut graphs as I have no data for it.

You might test modifying the javascript file (each graph definition separately) and try either minimum values, max values and/or autoscale parameters.

You can't set those in the LuCI uci config, but you have to edit the graph definitions in the source code. (Supported LuCI source code definitions will get converted to rrdgraph commands when the graphs are created. The rules are in but that is rather cryptic)

see examples e.g.


Yep. My first though was to look at the already improved nut.js, but I didn't find any range references, only number format, colors and placement of the graph/legend (I suppose noarea and overlay means that).

For the other .js you quote is totally clear where we could make the changes, but for the nut pluggin is not.

Regarding the data samples for assisting you or Jow to figure this out, each .rrd I'm working with is 12.8KB. There are three options: a)I could share it to you by other method, or b)you could generate it locally with an spreadsheet following an initial dump data I could provide here, you filling-up the rest of the 287 values with ramdom data in 30s increments and then converting that to binary (I don't know how). Or c)if you know how to edit or fill a real .rrd you could generate it a blank one with the following command, and filling it in binary:

rrdtool create voltage-input.rrd --step 30 \
  DS:value:GAUGE:60:NaN:NaN \
  RRA:AVERAGE:0.1:1:288 \
  RRA:AVERAGE:0.1:10:288 \
  RRA:AVERAGE:0.1:70:288 \
  RRA:AVERAGE:0.1:310:288 \

The real one looks like this:

rrdtool dump voltage-input.rrd 
<!-- Round Robin Database Dump -->
        <version> 0001 </version>
        <step> 30 </step> <!-- Seconds -->
        <lastupdate> 1680706661 </lastupdate> <!-- 2023-04-05 10:57:41 -04 -->

                <name> value </name>
                <type> GAUGE </type>
                <minimal_heartbeat> 60 </minimal_heartbeat>
                <min> NaN </min>
                <max> NaN </max>

                <!-- PDP Status -->
                <last_ds> UNKN </last_ds>
                <value> 1.3310000000e+03 </value>
                <unknown_sec> 0 </unknown_sec>

<!-- Round Robin Archives -->
                <cf> AVERAGE </cf>
                <pdp_per_row> 1 </pdp_per_row> <!-- 30 seconds -->
                <xff> 1.0000000000e-01 </xff>

                        <ds><value> NaN </value>  <unknown_datapoints> 0 </unknown_datapoints></ds>
                        <!-- 2023-04-05 08:34:00 -04 / 1680698040 --> <row><v> 1.2400000000e+02 </v></row>
                        <!-- 2023-04-05 08:34:30 -04 / 1680698070 --> <row><v> 1.2273333333e+02 </v></row>
#meaning the first 30s average = 124V and 122.7V 30s later, etc.

If any of these seems feasible to you, let me know.

EDIT: A real .rrd is 12.8KB if plotting 5 timeframes. If plotting only one of 288 samples (2+ hours) it would be 2.9KB.

Following hnyman advise, I've been mimicking pieces of other graphs definitions to nut.js. The key part is to incorporate to the section definitions.push the directive alt_autoscale_max: true, that alternate autoscale algortithm does a real zoom of the data:

However, if you think the range is too narrow (or jerky) on some cases and/or you prefer an static range, you can suit your preferences with something like:

y_min: "90",
y_max: "140",
alt_autoscale_max: true,

(Knowing that for an American APC UPS, the "medium" sensitivity switchs to battery below 92V or above 139V).

It doesn't follow exactly your settings, but renders something close:


  • The changes are not seen right away. You need to wait some seconds
  • It seems collectd-mod-apcupsd and other plugins have the alt_autoscale_max on by default, whereas collectd-mod-nut plugin relays on the basic autoscale (that would be good to improve)
  • If the alt_autoscale_max is not set, the y_min render a lower value than specified, and y_max doesn't do anything
  • Of course there are different voltages for different countries, so to release a solution with fixed min and max would have to take that into consideration
  • You can extrapolate this to the battery voltage