[SOLVED] Modbus Energy Meter - reading float registers

I purchased an Eastron SDM120 Modbus energy meter. I thought I understand how modbus works, but probably I am on the wrong path. I got the modbus documentation for this device: https://drive.google.com/file/d/0Bw1XOPtMPlsNZHJlU2sxZnJ6VWM/view?usp=sharing

Communication works, but I am not getting any sensible values in Openhab. I tested the device in Modbus Poll and it looked OK. On the Openhab screen I am getting some random integer values for power and current.

This is what I added to the config:
modbus:poll=500
modbus:serial.sdm120.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120.type=input
modbus.serial.sdm120.valuetype=float32
modbus:serial.sdm120.length=13
modbus:serial.sdm120.start=0
modbus:serial.sdm120.id=1

And this is how I configured the items:

Number sdm120Voltage "Voltage [%.1f]" (sdm120) {modbus="sdm120:0"}
Number sdm120Current "Current [%.1f]" (sdm120) {modbus="sdm120:1"}
Number sdm120Power "Power [%.1f]" (sdm120) {modbus="sdm120:2"}

I am not seeing any modbus errors in the log. Am I reading the registers incorrectly? I am not bothered about the holding registers if I am correct those are to update the settings of the device. As the manual states the values are sent in Modbus float format which is why I also set the valuetype to float32.

Any suggestions?

Cheers,
Csongor

See this similar thread

If you are not already using it, do switch to binding version 1.9.0

I think you should look at “endianess” - there is no Modbus Float standard, either hight or low 16-bits may be sent first. Try float32_swap datatype.

There are also debugging tips in the thread to read as integers, to be sure what is going on.

You’ve come to the right place, Rossko57 is right - reading my last few replies in that thread fumbling around should provide some good insight. But to make a long story short -

The most important thing to remember is modbus float values are actually made up of two registers, and the way your item file offsets are spaced is making it read the two registers from two different floating point pairs, which would provide crazy values.

Another thing to keep in mind is 0/1 based address offset - openhab has you provide an offset number, which counts from zero. The values in the manual you provided start from one. So long story short, the number you provide in openhab should be one less than the manual.

So to read the 0001 Voltage register, you would actually specify a start value and offset in openhab of 0. Endian-ness (which register in the pair contains the most significant bits) can also come into play, however reading that manual it seems it provides the MSB register first, which is what openhab expects, so you shouldn’t have to use the swap valuetype.

So putting this altogether, your openhab cfg should look like this, to read through the first three values.

modbus:poll=500
modbus:serial.sdm120.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120.type=input
modbus:serial.sdm120.valuetype=float32
modbus:serial.sdm120.length=14
modbus:serial.sdm120.start=0
modbus:serial.sdm120.id=1

The Active Power float register pair starts at 0013, but it’s a float pair so it’s made up of register 013 and 014, so you need to make sure you are reading both. Specifying a length of 13 will only read the first 13 registers, and you’ll miss the second half of the active power float pair. raising the read length to 14 will read up to register 14 on the device, which is good since the active power float pair is made up of register 13 and 14.


Now the items file is where the most mistakes are. You need to put in the registers the spec sheet lists, but minus one to account for the 0/1 offset difference. like this:

Number sdm120Voltage "Voltage [%.1f]" (sdm120) {modbus="sdm120:0"}
Number sdm120Current "Current [%.1f]" (sdm120) {modbus="sdm120:6"}
Number sdm120Power "Power [%.1f]" (sdm120) {modbus="sdm120:12"}

You can see why your voltage number was correct but the rest weren’t. when you had the Current offset set to 1, it was reading registers 2 and 3 on the device. register 2 on the device is the second half of the voltage float register pair, and 3 is most likely empty, so hence the weird numbers

Let me know if you need any further help, isn’t modbus fun!

Thanks for the insight Jon. I think I will have some interesting nights as I have ordered a few modbus products from Aliexpress, so I will be testing them all in the coming weeks.

Back to this topic. Today I noticed a warning right on the top of the log. I accidentally typed modbus.serial… instead of modbus:serial… in openhab.config for the valuetype line. So float was being ignored hence I was getting integer values.

Now I am getting 231.2 for voltage, but the other values are empty. Btw, I am still using 1.8.3 binding, I don’t know how to find the 1.9.0 version.

This is what I am seeing in debug:

08:55:22.840 [INFO ] [runtime.busevents             :26   ] - sdm120Voltage state updated to 231.1999969482421875
08:55:22.849 [INFO ] [.b.modbus.internal.ModbusSlave:310  ] - ModbusSlave error getting responce from slave
08:55:23.261 [DEBUG] [o.o.i.s.i.DiscoveryServiceImpl:80   ] - Unregistering service _openhab-server-ssl._tcp.local. at port 8443
08:55:23.350 [DEBUG] [b.m.internal.ModbusSerialSlave:117  ] - connection was null, going to create a new one
08:55:23.352 [TRACE] [pi.modbus.net.SerialConnection:110  ] - Got Port Identifier
08:55:23.365 [TRACE] [pi.modbus.net.SerialConnection:121  ] - Got Serial Port
08:55:23.368 [TRACE] [pi.modbus.net.SerialConnection:157  ] - i/o Streams prepared
08:55:23.370 [DEBUG] [i.modbus.io.ModbusRTUTransport:77   ] - Sent: 01 04 00 00 00 0e 71 ce
08:55:23.672 [DEBUG] [i.modbus.io.ModbusRTUTransport:141  ] - Response: 01 04 1c 43 67 19 9a 00 00 00 00 00 00 00 00 3d 50 e5 60 00 00 00 00 00 00 00 00 41 28 00 00 33 8d

There is nothing in the log for sdm120Current or sdm120Power.

There is something I don’t understand in the items config. If float is a double 16bit register, sdm120Current should be {modbus=“sdm120:4”}, shouldn’t it? I mean register 0 is the first of the voltage and the 5th register is the start of the current, therefore index should be 4. Why did you suggest 6?

Cheers,
Csongor

And one more question: this energy meter has 13 registers: voltage, current, power, apparent power, reactive power, power factor, etc. I only defined the first 3 for now. So there is 134 registers alltogether. Does it mean that modbus:serial.sdm120.length should be 134?

Float values are 2 registers, not 4. A float value is composed of two 16 bit integer registers. Your modbus device has just spaced the float pairs out quite a bit with a lot of empty registers in between for some reason. For instance the first float value is register one and register two, but the next float value doesn’t start until register 7.

The next float value, current, doesn’t start until register 7, and it’s a float value, so it takes up register 7 and register 8. these are 1-offset based numbers in the manual, so when putting them into openhab they would be one number less.

I’m not sure where you’re seeing that the 5th register is the start of the current. On page 5 of the document you linked it very clearly shows the addresses of each float value, and the registers in between are empty. the “3” in front of each address register can be ignored as it is just specifying the register type (holding, input, etc). this is automatically added over the wire by the modbus protocol and you don’t specify it in openhab, just the address number after it (minus one)

On that page it clearly shows voltage starts at register 1. in 0-based offset, that’s 0, which is what you have, which is why your voltage item is working.

Next is current, which is clearly shown as beginning at register 7 - so in openhab that would be 6. If you copy the item and open cfg text I posted you’ll see it will work as expected.

To read all the values you need, you need to set the length so it reads to the very last register you require, taking into account the two registers making up the float values, and the offset difference.

So since you just need the first three right now with the last register existing at 13 and 14, you would specify an offset of 14. If you want to read all the way down to frequency for instance, which starts at 71, you would need a length of 72.

Because of the way your device has a bunch of empty registers between each float value though that becomes very inefficient as it will be reading mostly empty registers. Another way to read multiple registers that are spaced out is defining multiple slaves in the config, instead of one with a huge read length. For instance to read the same three registers like you are now:

# read voltage registers
modbus:serial.sdm120V1.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V1.type=input
modbus:serial.sdm120V1.valuetype=float32
modbus:serial.sdm120V1.length=2
modbus:serial.sdm120V1.start=0
modbus:serial.sdm120V1.id=1

# read current registers
modbus:serial.sdm120V2.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V2.type=input
modbus:serial.sdm120V2.valuetype=float32
modbus:serial.sdm120V2.length=2
modbus:serial.sdm120V2.start=6
modbus:serial.sdm120V2.id=1

# read power registers
modbus:serial.sdm120V3.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V3.type=input
modbus:serial.sdm120V3.valuetype=float32
modbus:serial.sdm120V3.length=2
modbus:serial.sdm120V3.start=12
modbus:serial.sdm120V3.id=1

That way openhab is only reading the registers you need, and not all the empty registers in between. you just need to specify the start to be the register you want to read, and the length set to 2 so you get both registers of the float value. You also need to give each instance a unique slave name (I just added V1 V2 V3 for instance)

Then in your items file, use the unique slave names, and make the offset for each 0 since we already specified the offset with the “start” value in the cfg

Number sdm120Voltage "Voltage [%.1f]" (sdm120) {modbus="sdm120V1:0"}
Number sdm120Current "Current [%.1f]" (sdm120) {modbus="sdm120V2:0"}
Number sdm120Power "Power [%.1f]" (sdm120) {modbus="sdm120V3:0"}

WIth it done that way, you’re not reading 5 empty registers in between each actual float register pair

2 Likes

Hi Jon, thanks again. I have updated the config file to read the registers I want individually. I added Total Energy as well and all of them are working as expected.

Since you have some experience with modbus, is there any tricks I need to know? Is there any rule of thumb on number of modbus device vs. communication speed?

I also want to figure out a sensible approach to logging and reporting energy data. For example generating daily/weekly/monthly usage. But I have a feeling the rrd4j and basic chart will not be suitable for that.

Well spotted, that man! A sneaky one.

I’d view setting up the config as one block (to include unused registers) as marginally less overhead than setting up multiple virtual slaves.
There is a caveat that your device may reject access of unused registers, so the multiple slave way is more certain.
Doubt there is much in it performance wise, until you get to hundreds of Modbus slaves or want sub-100mS poll rates.

If you are going to have several Modbus serial devices, you will have to juggle baud rates+parity so they are all alike (assuming a single wired bus). Many default to 9600 no-parity these days. This is fairly modest but generally reliable enough for long wiring runs.

Now, I’m having doubts about the config ‘length’ parameter - I thought it should be smart enough to match the chosen datatype. i.e, for a contact, a length of 1 specifies 1 bit only, for a uint16 a single 16bit register, for float32 a pair of 16bit registers.
Is it not working like that? (won’t show up with single-item slaves)

The length is documented as follows in the wiki

number of data items to read. Data items here refers to registers, coils or discrete inputs depending on the slave type. For example, if the goal is to read one item with valuetype=int32, one needs to read two registers (2 * 16bit = 32bit), thus length = 2. If three coils are of interest, one should specify length = 3

So basically you need to define the number of binary values to retrieve (with discrete inputs and coils) or number of registers to retrieve (with input registers and holding registers)

Does this work as expected?

Best
Sami

Hi, it is working as expected now.

yup, works great. I think Rossko was saying it would be nice if the binding automatically calculated length based on valuetype, so if you set it to float32 it would know to read 2 registers. I don’t know if I would like that though, I like having the control to change it manually

I do see point in that, and certainly would be easier for users. However, I’m afraid changing the interpretation of the length parameter would be backwards incompatible and as such would cause issues to our users when upgrading.

This would be good improvement for openhab2 configuration however, since there we could introduce backwards incompatible changes. That’s still quite much in the air, currently one uses openhab1 version of modbus binding with openhab2

Just for the record and to ensure I understood correctly. You would prefer length to denote count of values to read, e.g. Number of float32 values, number of 16bit unsigned integers… Etc?

I do believe we need ability to control the count, otherwise one would always end up as many “slaves” (modbus requests) as there are items…

Best
Sami

On reflection, I do not think changing the nature of ‘length’ (which should/would also be reflected in ‘start’ and ‘index’ ??) is necessary or desirable.
I think for slaves with mixed datatypes it would become a nightmare keeping track of which register actually was meant at start+index

At its heart, Modbus protocol only knows binary (coil/contact) and register (16-bit) types. Anything we layer onto that, like 32-bit or even 64-bit formats, or text blocks, or image code … is just an interpretation.

Keep it simple and consistent; configuration params directly related to “native” Modbus forms. That way will always allow for any desired interpretation on top of the Modbus layer, while the opposite may not be true.

1 Like

Good point about the text and other data formats, I did not even think of those. I think keeping it simple here also means not assuming too much how the data will be used.

Ideally I would like to see the “interpretation” (valuetype) separated from the raw requests (binary data). Since you might want to just query all the registers at once, and then intrerpret some as float32, some as uint16 etc. I think good place to do this kind modification would be openhab2 migration and changes related to that. As far as I understand the new item /thing /channel configuration approach in openhab2 would make this really convenient.

What do you think?

Edit : example of one way how configuration could be structured in openhab2. The post did not comment on valuetype though…

Edit2: yes indeed start denotes the register (or coil / discrete input), so it would make sense that length has the same interpretation. However the read index defined in the item definition is different, see wiki for details. The item read index has different interpretation depending of valuetype.

Lots of elegance in separating “Modbus map” (strictly binaries and 16bit-registers, addressed in standard Modbus style) from “logical map” (bits, bytes, floats, doubles, blah, for use within OH)

In OH-1 terms, valuetype ought really be associated with the Item rather then in the binding cfg. But we got what we got, I am not suggesting any breaking change for OH1!

I have no idea how OH-2 works, but Thing seems like the place for underlying Modbus slave defining? It follows that interpretation datatype logically belongs to the Item still, yes?
I would guess there are sensible defaults that can be assumed, such as that a number-flavour-item would default interpret raw data as uint16.
Would also guess that we would need a means to declare or force the type somehow; and this is where the Channel comes in (as well as selecting from the raw block by index)?.

There is a consistency issue buried in there; when indexing into a “raw Modbus block” of 16bit-registers, should you specify index by raw registers count, or by the chosen format/type count (as we do now)? Either way has its pitfalls and requires the configuring user to have a good understanding.
Mixed types within a block presents bigger pitfalls with mixed indexing?
Yet if you stick to ‘native’ modbus single-register methods, it gets difficult to designate individual bytes - which would be useful for text handling or oddball ACBD 32-bit layouts etc.
Dunno the answer here. Gut instinct is for raw/native indexing (with a Hi/Lo option for the infrequent byte requirement)

My doubt earlier about how existing ‘length’ works was confusion with half-remembered fact of current ‘index’ being of fluid meaning, depending on type.

The old-tech approach of Modbus (a natural legacy of its history) coupled with endless manufacturer variety, is I think always going to require a reasonable level of understanding from the user.

1 Like

Well that was a good summary! I have pretty vague understanding as well when it comes to openhab2 concepts but I think you are on a right way.

Good point about indexing, that is tricky indeed… Perhaps we could solve it by making it more explicit, that you would declare if you want to pick index by bit/word/item? This certainly needs testing when developed…

Best
Sami

Sorry but i dont understand how to configure SDM120 to work with openhab2 by modbus bindig
My configuration:
modbus.cfg

modbus:poll=500
writemultipleregisters=true

modbus:serial.biuroLight.connection=/dev/ttyUSB0:19200:8:none:1:rtu
modbus:serial.biuroLight.type=holding
modbus:serial.biuroLight.id=3
modbus:serial.biuroLight.start=0
modbus:serial.biuroLight.length=1
modbus:serial.biuroLight.valuetype=uint8

modbus:serial.biuroLST.connection=/dev/ttyUSB0:19200:8:none:1:rtu
modbus:serial.biuroLST.type=holding
modbus:serial.biuroLST.id=3
modbus:serial.biuroLST.start=3
modbus:serial.biuroLST.length=2

modbus:serial.sdm120L1V.connection=/dev/ttyUSB0:9600:8:none:1:rtu
modbus:serial.sdm120L1V.type=input
modbus:serial.sdm120L1V.id=11
modbus:serial.sdm120L1V.start=0
modbus:serial.sdm120L1V.length=2
modbus:serial.sdm120L1V.valuetype=float32

item to sdm120

Number L1V "Volt [%.1f V]" (sdm120) {modbus="sdm120L1V:0"}

and a have error:

2017-02-07 12:57:51.905 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 0b 04 00 00 00 02 71 61
2017-02-07 12:57:51.907 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-02-07 12:57:51.909 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 2/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@7f9bea (unit$
2017-02-07 12:57:53.448 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 0b 04 00 00 00 02 71 61
2017-02-07 12:57:53.450 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-02-07 12:57:53.453 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 3/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@7f9bea (unit$
2017-02-07 12:57:53.455 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute reached max tries 3, throwing last error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRe$
2017-02-07 12:57:53.458 [ERROR] [.binding.modbus.internal.ModbusSlave] - ModbusSlave (sdm120L1V): Error getting modbus data for request net.wimpi.modbus.msg.ReadInputRegistersRequest@7f9bea. Error$
2017-02-07 12:57:56.307 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 0b 04 00 00 00 02 71 61
2017-02-07 12:57:56.310 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-02-07 12:57:56.314 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@223b4d (unit$
2017-02-07 12:57:57.855 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 0b 04 00 00 00 02 71 61
2017-02-07 12:57:57.858 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-02-07 12:57:57.862 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 2/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@223b4d (unit$
2017-02-07 12:57:59.404 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 0b 04 00 00 00 02 71 61
2017-02-07 12:57:59.407 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-02-07 12:57:59.411 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 3/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@223b4d (unit$
2017-02-07 12:57:59.414 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute reached max tries 3, throwing last error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRe$
2017-02-07 12:57:59.417 [ERROR] [.binding.modbus.internal.ModbusSlave] - ModbusSlave (sdm120L1V): Error getting modbus data for request net.wimpi.modbus.msg.ReadInputRegistersRequest@223b4d. Error$

i have OH2 build #777
binding-modbus1 - 1.10.0.SNAPSHOT
problem show when i add sdm120L1V slave
Anyone can help me ?

I have not working with OH2, so I don’t know if this is a OH2 issue or not.

But, you cannot have devices on the same serial network with different baud speeds. Your biuroLight and biuroLST are on 19200 baud, so you need to reconfigure SDM120 to 19200 baud as well. But the max baud rate SDM120 can work on is 9600. So you need your to bring down your other two devices to 9600 as well. Other option is to get another USB RS485 converter and run the SDM120 on a different serial line.

I hope this is the issue. I am not a modbus expert.

This is true, so that needs to be solved before even considering anything else.

Refer to this note on the wiki page for more information.

Best
Sami

Hi. I use your post to connect my sdm120 - it works, thank you :slight_smile:
I never deal with modbus, can you share your modbus.cfg with other parameters for sdm120 like apparent power, reactive power, power factor, etc?

Here it is:

# read voltage registers
modbus:serial.sdm120V1.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V1.type=input
modbus:serial.sdm120V1.valuetype=float32
modbus:serial.sdm120V1.length=2
modbus:serial.sdm120V1.start=0
modbus:serial.sdm120V1.id=1

# read current registers
modbus:serial.sdm120V2.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V2.type=input
modbus:serial.sdm120V2.valuetype=float32
modbus:serial.sdm120V2.length=2
modbus:serial.sdm120V2.start=6
modbus:serial.sdm120V2.id=1

# read power registers
modbus:serial.sdm120V3.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V3.type=input
modbus:serial.sdm120V3.valuetype=float32
modbus:serial.sdm120V3.length=2
modbus:serial.sdm120V3.start=12
modbus:serial.sdm120V3.id=1

# read Apparent power registers
modbus:serial.sdm120V4.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V4.type=input
modbus:serial.sdm120V4.valuetype=float32
modbus:serial.sdm120V4.length=2
modbus:serial.sdm120V4.start=18
modbus:serial.sdm120V4.id=1

# read Reactive power registers
modbus:serial.sdm120V5.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V5.type=input
modbus:serial.sdm120V5.valuetype=float32
modbus:serial.sdm120V5.length=2
modbus:serial.sdm120V5.start=24
modbus:serial.sdm120V5.id=1

# read Power factor registers
modbus:serial.sdm120V6.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V6.type=input
modbus:serial.sdm120V6.valuetype=float32
modbus:serial.sdm120V6.length=2
modbus:serial.sdm120V6.start=30
modbus:serial.sdm120V6.id=1

# read Power factor registers
modbus:serial.sdm120V7.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V7.type=input
modbus:serial.sdm120V7.valuetype=float32
modbus:serial.sdm120V7.length=2
modbus:serial.sdm120V7.start=70
modbus:serial.sdm120V7.id=1

# read Import active energy registers
modbus:serial.sdm120V8.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V8.type=input
modbus:serial.sdm120V8.valuetype=float32
modbus:serial.sdm120V8.length=2
modbus:serial.sdm120V8.start=72
modbus:serial.sdm120V8.id=1

# read Export active energy registers
modbus:serial.sdm120V9.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V9.type=input
modbus:serial.sdm120V9.valuetype=float32
modbus:serial.sdm120V9.length=2
modbus:serial.sdm120V9.start=74
modbus:serial.sdm120V9.id=1

# read Import reactive energy registers
modbus:serial.sdm120V10.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V10.type=input
modbus:serial.sdm120V10.valuetype=float32
modbus:serial.sdm120V10.length=2
modbus:serial.sdm120V10.start=76
modbus:serial.sdm120V10.id=1

# read Export reactive energy registers
modbus:serial.sdm120V11.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V11.type=input
modbus:serial.sdm120V11.valuetype=float32
modbus:serial.sdm120V11.length=2
modbus:serial.sdm120V11.start=78
modbus:serial.sdm120V11.id=1

# read Total active energy registers
modbus:serial.sdm120V12.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V12.type=input
modbus:serial.sdm120V12.valuetype=float32
modbus:serial.sdm120V12.length=2
modbus:serial.sdm120V12.start=342
modbus:serial.sdm120V12.id=1

# read Total reactive energy registers
modbus:serial.sdm120V13.connection=/dev/ttyUSB0:2400:8:none:1:rtu
modbus:serial.sdm120V13.type=input
modbus:serial.sdm120V13.valuetype=float32
modbus:serial.sdm120V13.length=2
modbus:serial.sdm120V13.start=344
modbus:serial.sdm120V13.id=1