influxdata / telegraf

Agent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.
https://influxdata.com/telegraf
MIT License
14.61k stars 5.57k forks source link

Modbus feature request: scaling and offset #9725

Closed wz2b closed 1 year ago

wz2b commented 3 years ago

This feature request expands on #9279 to add one additional feature: scale/offset of registers.

I would like to propose adding optional 'scale' (default 1.0) and 'offset' (default 0.0). The use case for this is devices that report in integers but with some scaling, usually a power of 10. An example of this is the main power factor register set on a PowerLogic PM800 which is an integer register that reports a value of 0-2000. This value corresponds to the power factor of 0 to 2, so to get that number you have to multiply by 0.001. A second use case is unit conversion - for example reading a register that is in celsius but outputting it as Fahrenheit.

The output of any scaled value has to be either a double or a float. Ideally we would store these internally as doubles to minimize the ULPS of a float being misleading (you want to report 12 but because of floating point error it comes out as 11.99998).

When converting:

  1. Read the register in the register format specified by the user, then convert it to a double
  2. Multiply by the scale (may be a fraction)
  3. Add the offset (may be negative)
  4. Output the result as a double

In this example register 2000 is a floating point number in degrees C and I want to convert it to degrees F. In the second example, the power factor is a number from 0 to 2000 that needs to be converted to a power factor which means 0 to 2 with 1 being unity power.

  fields = [
    { address=2000, name = "degreesF", type = "FLOAT32", scale = 1.8, offset = 32 },
    { address=2004, name = "power_factor", type = "UINT", scale =0.001, offset = 0}
  ]

image

In this example, register 1190 (read as a 16-bit signed integer) has to be divided by 1000 to yield a result (the power factor) between -1 and +1.

Note that this is not at all specific to the PM800. That was just the first device I had access to. Three are quite a few devices that operate this way, in part because floats weren't supported in many early Modbus devices.

Playing devil's advocate, you could do this transmogrification in a processor but this behavior is so common across modbus devices that it really becomes cumbersome. Most off the shelf devices you can use for this kind of conversion - for example the CCS Babel Buster - allow you to specify scale/offset conversions in the manner I describe, so I think it should be part of the Modbus plugin itself.

srebhan commented 3 years ago

@wz2b: Just for your information, a scale factor already exists doing exactly what you describe. However, currently we do not support an offset but I can see that this might be a reasonable feature.

TimurDela commented 2 years ago

Another use case for an offset is when I am reading analogue signals for which the offset and scale can be tuned in the device. For instance, I have a power meter that outputs 4 analogue signals via Modbus RTU. I have set Channel 1 to give the voltage (V) but the signal Telegraf receives is an intensity (I) in mA. The conversion is V = a × I +b where 'a' and 'b' can be set in the settings of my power meter. If I am to do the conversion in the queries, this means I have to log 'a' and 'b' as well which is not convenient at all. Having them as tags is not very convenient are they are numerical values. I'd rather directly log via Telegraf the quantity I am interested in rather than 3 numbers that are meaningless if taken separately.

The 'scale' feature is great, please also add 'offset'.

srebhan commented 2 years ago

@TimurDela the question is a bit where to stop. You can currently do the computations using the starlark plugin. But maybe should probably do the offset thing... Are you willing to cook up a PR please?

TimurDela commented 2 years ago

@srebhan I now see that indeed the starlark plugin can be used for this. Can I suggest writing a more explicit description for that plugin so people looking for mathematics, operation, offset, scale, gain etc get a chance to understand that this plugin is for them? I was not able to identify this plugin was for me by searching for some keywords in the processor plugin catalogue.

srebhan commented 2 years ago

@TimurDela can you please submit a PR for the starlark processor with improved docs? I already check your PR, comments there...