Smart meter integration via RS485-USB

Because of the radical cost increase of energy, I am now 1 week into my HomeAssistant project.
So I am quite new to HomeAssistant :smiley:

I basically want to break down my power consumption, as my household is fully powered by electrical power, i.e. Solar PV array, heat pump and electric car.
I live in Denmark and already had a few smart meters installed to monitor my solar production and total power consumption trough a commercial product (SolarLog).
I now want to integrate the existing meters into HomeAssistant via RS485, but have had NO succes communicating with them. Please help me out resolving it :slight_smile:

I have done the following:
Installed HomeAssistant via Raspberry Pi Imager giving me version: Home Assistant 2022.8.4
Bought a USB->RS485 USB-stick with an CH340G chip
Ensured my modbus cable is terminated with an 120Ohm resistance.
Defined a modbus hub as follows:

modbus:
  - name: hub1
    type: serial
    baudrate: 9600
    bytesize: 8
    method: rtu
    parity: E
    port: /dev/ttyUSB0
    stopbits: 1
    sensors:
      - name: Pro380_1a
        slave: 2
        address: 2
        input_type: input
        #count: 2
        precision: 2
        data_type: float16
        unit_of_measurement: kW
        device_class: power
        state_class: total_increasing

Upon restart the sensor is created, but appears as “unavailable”.

When I study my log I can see a few error mesages, such as:

2022-08-14 15:15:48.154 DEBUG (SyncWorker_0) [pymodbus.transaction] Current transaction state - TRANSACTION_COMPLETE
2022-08-14 15:15:48.155 DEBUG (SyncWorker_0) [pymodbus.transaction] Running transaction 14
2022-08-14 15:15:48.156 DEBUG (SyncWorker_0) [pymodbus.transaction] SEND: 0x2 0x4 0x0 0x2 0x0 0x1 0x90 0x39
2022-08-14 15:15:48.156 DEBUG (SyncWorker_0) [pymodbus.framer.rtu_framer] Changing state to IDLE - Last Frame End - None, Current Time stamp - 1660482948.156671
2022-08-14 15:15:48.162 DEBUG (SyncWorker_0) [pymodbus.client.sync] New Transaction state 'SENDING'
2022-08-14 15:15:48.165 DEBUG (SyncWorker_0) [pymodbus.transaction] Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2022-08-14 15:15:48.325 DEBUG (SyncWorker_0) [pymodbus.transaction] Transaction failed. (device reports readiness to read but returned no data (device disconnected or multiple access on port?)) 
2022-08-14 15:15:48.326 DEBUG (SyncWorker_0) [pymodbus.framer.rtu_framer] Frame - [b''] not ready
2022-08-14 15:15:48.326 DEBUG (SyncWorker_0) [pymodbus.transaction] Getting transaction 2
2022-08-14 15:15:48.327 DEBUG (SyncWorker_0) [pymodbus.transaction] Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'

Regarding the modbus settings I have double checked the meter settings. It has address 002, Even parity, 9600 baud, 1 stopbit and a bytesize of 8. It is branded as a SolarLog pro380-mod, but I am quite sure it is identical to an inepro(R) pro380-mod.

I have succesfully integrated a Shelly 3EM, Netatmo and a Tesla wall connector and am confident I can build a “powerfull” monitoring tool once I get the “RS485-sensors” connected and would hate to have to buy new sensors to get it to work :slight_smile:

Please help me out!

Best regards
Kasper

1 Like

This is ok:

SEND: 0x2 0x4 0x0 0x2 0x0 0x1 0x90 0x39

But meter don’t replay

Does the vendor have an application that works using the USB setup?

@PeteRage
Not to my knowledge. The meter was communication along with my Kaco Inverter via RS485 to a SolarLog200 - a commercial product for monitoring solar production. The inverter having address 001, and the meter on address 002.

I therefore bought this USB to RS485 adapter:
https://www.bifelectronic.com/measuring-devices/3642-sbc-ttl-rs485-4250236819587.html

It appears others have had success with it, but not me.

@nikito7 Yes, apart from the branding this meter looks exactly like mine, but no connection. I have however changed the address of the meter to 2, as my inverter was already on 1. Right now I have disconnected the inverter and focussing my trouble shooting on the meter.

This is more a question about Modbus I think. I am not a Modbus expert, but hope the following helps you.

I have never heard of your SolarLog Pro380 device before. However, I am suspicious of your register address settings as ‘2’. I am certain that you are using the wrong register address, and possibly the wrong function code (should be ‘holding’), and you probably need to be reading 2 registers as float32 for the power value as it is likely to be double-size for ‘total power’. Also worth noting that as the value is power (kW) then the state_class should be measurement.

As this is Modbus over serial I would also add that you appear to already have one master (the SolarLog200 ?) on the bus reading both inverter (slave ID 1) and meter (slave ID2) and you cannot (should not) add another master to the same physical bus (your HA via USB adaptor is a master). Sorry to be a damp squib but I don’t think you can do what it is you are trying to do, if you already have something else reading this device.

Anyway…

The ‘slave’ address in the sensor is for the physical slave ID of the device on the Modbus. Usually this is ‘1’, and in the short time I have spent looking at the on-line SolarLog manuals, the default seems to be ‘1’, so I would want to double check, however you say you have set this to ‘2’ for the power meter.

The ‘address’ field is the register address within the device you are trying to talk to.
A quick poke around the good old internet found a Modbus register list (search for PRO380-Modbus-registers-V1.18) which, if it actually does apply to the device you are talking about, suggests that the correct address (for total active power) is 2080 (hex), as 2 data blocks Big-endian (Hex float).

As cross reference, I found this…
https://manualzz.com/doc/11609514/pro1-pro380-modbus-user

which seems very clear, informative, and useful. Reading through the above, the register table for V1.18 has two entries, apparently one is for reading a single register, the other for reading multiple registers in one read. You probably need to read the bit about the various software versions and identify if you have V1.18 or not. Pre V1.18 the register addresses are probably different.

I am certainly no expert in this, so I may be very wrong, but how about trying…? Sorry I can’t test this as I don’t have your device / setup, but this may give you some ideas on how to go forward.

modbus:
  - name: hub1
    type: serial
    baudrate: 9600
    bytesize: 8
    method: rtu
    parity: E
    port: /dev/ttyUSB0
    stopbits: 1
    sensors:
      - name: Pro380_1a
        slave: 2
        address: 8320
        input_type: holding
        precision: 2
        data_type: float32
        unit_of_measurement: kW
        device_class: power
        state_class: measurement

@Biscuit Thank you for your input. I appreciate the support, as I am certainly not a Modbus expert either :slight_smile:

You are probably right that I am using the wrong registry address. Will correct that in accordance with your recommendations.

As for the master-slave input, the previous master (SolarLog200) has been removed from the bus, so that should not be the issue.

I have tested your proposed config, and unfortunately it was not successfull. The meter simply does not reply.

The meter should reply with something even if you are reading the wrong register.

If it’s isn’t then

  • the baud rate, parity, etc, may be wrong
  • the device address is wrong

Or its no modbus.

There are two versions:

  • Modbus
  • MBus

Maybe you need set something in screen.

Or usb device it’s not working correctly.

1 Like

Well, it was a good first stab…

A Modbus setup has so many variables, and everything has to be correct otherwise it will not work. As we say in English, you need all your ducks lined up.

Here is a link to what I hope is the manual for your device - a reference point to work from!

PRO380 user manual download

So the ‘ducks’ are:

USB converter:
These are noted for being unreliable, and some just don’t work. Chipset has something to do with this, but sometimes it is just a broken device. If all else fails then you might have to replace it and try another.

Wires:
Modbus uses wires labelled A and B, which must be connected A-A and B-B. For short runs the earth is not required, though using twisted pair is recommended. Any earth shield or a spare pair can be connected to earth, but only at one end (not both). Check the connections. Try swapping them over. I don’t know your device, but sometimes the terminal for coms wires (unlike the terminals for the power wires) can be small and short, and with the electrical screw bit at only the front. I have known wires to clamp on the insulation and thus not actually connect inside the terminal…
Maximum bus length on the meter is 60 1000 metres with up to 60 devices (meters), but I assume that you are using less than 1 metre and only the one device for testing.

The terminating resistor (120 ohm) is again not always essential for short cable runs of a metre or two. Where it is used it is really only there to stop reflections at the each end of the bus, and reflections generally only cause odd readings not a failure. Many devices have this built in (some with dip switches so they can be cut in or out). I note the device manual says you must add it, but I would try without anyway. You never know, the resister may be faulty and providing a short across the terminals.

Of course the wires have to be OK too (yes, I know, grandma and eggs, but it does happen).

Meter:
We are assuming this is the PRO380 MOD, which is the Modbus version (not the serial version or the Mbus version). Clearly must be if you have been using it successfully with the solar logging device.

Default is for
Modbus over RS485 RTU
9600 baud, 1 stop, Even parity
so that all looks good, and I assume you have already checked this more than once! (worth checking the device though - some of these settings are programmable over Modbus and the solar log device may have changed them).
And you have checked the address is ‘2’, so we will go with that. If this is not correct then the meter will certainly not respond!

Computer:
The USB is plugged into something (your Raspberry Pi) and that TTY port details have to be correct. I do my Modbus work over TCP to an ethernet to RS485 adaptor so I can’t help with the USB settings, but I did try one USB serial adaptor on my PC to my inverter and that was OK. Sometimes drivers are needed, so it may be worth just plugging your adaptor into a PC if you can manage the cable run. PCs are a bit more forgiving for setting up USB and drivers, and there are a few Modbus testers out there that are great for debugging use.
I am assuming that the /dev/ttyUSB0 bit is good and operational.
HA is working on the Pi, and you can see the connection in the logs.

So we now have a fully working Modbus compliant physical connection. It would be great to be able to do a ‘loop back’ test, but not possible easy to do on RS485.

Modbus:
The manual (see above) has a full Modbus register table, for version 2-18, and references the older version 1-14 as being different. I believe you can go through the meter setting screens to find the version, and this is worth checking to ensure that we use the correct register table. Addresses are different between them. Wrong address - not going to work.

Assuming you are on V2.18, I would try a very simple, single register read. How about ‘meter amps’?
So address is 400B, which must be hex.
Single register, function code 3
A (Amps) and signed.

modbus:
  - name: hub1
    type: serial
    baudrate: 9600
    bytesize: 8
    method: rtu
    parity: E
    port: /dev/ttyUSB0
    stopbits: 1
    sensors:
      - name: test1
        slave: 2
        address: 16395

If I ignore all the extra settings, these are the only settings actually required - the default is to read register type ‘holding’ which is function code 3, so that should work. This will read 1 register as 16 bit integer. Being signed just means we will probably end up with the bit-compliment, so a bigger number, and this can be sorted out later.
Just to show if it works, this should get the meter amp reading (assuming you have it connected). Otherwise you could try register 16388 which should be the baud rate (ie 9600, again with the sign-bit set).
If this works - then you can sort out the other settings for data_type, class and so on.

If it does not work, then I would lean towards suspecting the USB adaptor. Otherwise I am running out of ideas. Fingers crossed!

More thoughts…

I’m a manual reader - so I found the SolarLog200 manual online. Very enlightening.

First thing is, I think the A/B terminals for the PRO380 are the other way about. The SolarLog200 must usually connect to the meter, and the manual suggests terminal 1 (B) to terminal 22 (A), which I personally think is the wrong way about, but hey - try changing the wires over, you never know.

Second thing is, the SolarLog200 certainly appears to find and re-programme the meter (it changes the slave ID for a start) so I wonder what gets changed, and if this affects your ability to connect and read to it? Possibly. I would only suggest a reboot back to factory settings if you intend to stop using the SolarLog200 altogether, so try other options first.

Third thing is, as the SolarLog200 is a great bit of kit, and it connects to both your meter and your inverter, why not use the internal Modbus over TCP server within the SolarLog200 to get to the accumulated data you require? I am not sure that the unit exposes much by way of information - the register address list looks very short, but it is set up to run Modbus over TCP on port 502, slave address 1, and supports (only) Modbus function code 4.

For example, power consumption, W, 32 bit unsigned, register address 3518. You would not need an adaptor provided your SolarLog200 is connected to your LAN.

@Biscuit Thank you for your feedback.

I was really happy with the SolarLog but 10months ago it stopped working. I cannot help being suspicious that SolarLog bricked it from remote to get me to buy a new one and into their SaaS business model - but that is another discussion.

As for the modbus settings, I have verified several of the directly on the meter, that has a small screen where I can browse through output as well as most of the configurations. On the meter I have positively confirmed the two following settings:
Baudrate: 9600
Address (slave ID): 002 (I remember changing this config myself, to get it to work together with the inverter, which is slave 1, but currently not in bus). I have now changed the slave address back to default 001 through the meter interface.
Bytesize, method, parity and stopbits I have gotten from the manual.
The port I have identified by listing the dev folder before and after plugging in the USB device.

Right now I am suspicious of the USB itself even though I bought two and none of them work.
I will now try mirroring the wires, and if that do not work I will move to a pc for testing.
If you have suggestions for another way to read the meter, I am open to that. I just thought this usb device would be simple :slight_smile:

Good news, partial success. The device appears to be finally responding. :smiley:

I get the following from the log:

2022-08-16 22:21:24.993 DEBUG (SyncWorker_3) [pymodbus.transaction] Incomplete message received, Expected 9 bytes Recieved 8 bytes !!!!
2022-08-16 22:21:24.993 DEBUG (SyncWorker_3) [pymodbus.transaction] Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2022-08-16 22:21:24.994 DEBUG (SyncWorker_3) [pymodbus.transaction] RECV: 0x1 0x20 0x10 0xbd 0x6c 0xb1 0xb 0xff
2022-08-16 22:21:24.995 DEBUG (SyncWorker_3) [pymodbus.framer.rtu_framer] Frame check failed, ignoring!!
2022-08-16 22:21:24.995 DEBUG (SyncWorker_3) [pymodbus.framer.rtu_framer] Resetting frame - Current Frame in buffer - 0x1 0x20 0x10 0xbd 0x6c 0xb1 0xb 0xff
2022-08-16 22:21:24.995 DEBUG (SyncWorker_3) [pymodbus.transaction] Getting transaction 1
2022-08-16 22:21:24.999 DEBUG (SyncWorker_3) [pymodbus.transaction] Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
2022-08-16 22:21:24.999 DEBUG (SyncWorker_3) [homeassistant.components.modbus.modbus] Pymodbus: hub1: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

Sometimes it only receives 7 bytes. Any suggestions on how to proceed?

And what made the meter respond?
I am embarrassed to admit I apparently created a loose connection when I terminated with the 120ohm resistor. After ensuring good connection of the wires, the meter is now responding. I believe it was correcting the register address that made that happen.

I can understand your frustration with the SolarLog. I have a Solis inverter, and a Solis data stick, and that has been very unreliable for quite some time. All this failure and messing about forces otherwise happy customers to go and do their own thing!

There is just so much that has to be just right for Modbus to work. A lose connection is certain failure, and not getting the right registers will not work either! I guess your device must be the later version. Worth checking that out, then you will know for certain which register address map to use.

Well, we now know the physical serial connection is probably working, and we have a response. Incomplete message is not uncommon, but I now think some debugging will be required.

As your SolarLog has died a death, if it were me (and it is not me doing this) I would look to see if I could ‘factory reset’ the power meter - I would want to start with known default settings, and then go through the setting table to double check. The SolarLog does ‘take control’ and I believe it changes settings when it first finds the devices on the bus. This, of course, may require effort just getting back to the state you are currently in, so you may decide to stay as you are!

I do get ‘incomplete messages’ myself. I went down the path of using an ethernet to serial adaptor and thus Modbus over TPC between HA and the adaptor. Modbus over TCP is easier, and I have a LAN connection to my inverter / battery in the garage. Sometimes Modbus devices go to sleep, and need time or a bit of a kick to wake them up.

We do have a received frame. I need to go away and decode this, and find out what ‘frame check failed means’ but things seem to be much further forward, so there is still hope.

Yes, Modbus should be simple but it is full of traps. We will continue…

Continuing…

We have a connection and the meter is responding - a good step forwards.

Going back to the V2-18 register map, the register for ‘Baud Rate’ is 4004 (hex) which is signed. If we set up to try and read just this, we expect to get ‘9600’ into our HA sensor. This number will not change, so any issues with the read/return will be down to other problems. For example, if the HA sensor result changes randomly from time to time I would suspect noise on the bus as a possible reason.

Noting the register number, and that you have moved the meter slave address to ‘1’, I think the no-frills yaml for this is:

modbus:
  - name: hub1
    type: serial
    baudrate: 9600
    bytesize: 8
    method: rtu
    parity: E
    port: /dev/ttyUSB0
    stopbits: 1
    sensors:
      - name: test1
        slave: 1
        address: 16388

We can leave everything else as default, so this should return a data type of int16. Although the manual says ‘signed’ I expect 9600 to be returned as it is.

Using the other guide I found, the Modbus message to and from the meter should therefore be:
SEND: 01 03 40 04 00 01 CRC
this is the slave id, read holding register function code (03), register address, data length (00 01) and the CRC of 2 bytes. = 8 bytes in total

RETURN: 01 03 02 25 80 A3 74
this is the slave id, the read function code, the return data length, the return (2580) and the CRC (which I have checked but this may be the other way around - some devices are Big endian other Little endian, so it could be 74 A3…)

The return should be 7 bytes, as far as I can tell.

If you care to test this, it should hopefully work.
If it works most/some of the time, the sensor should hold 9600 (the Baud rate).

If it works, but there are errors and/or the value changes from 9600, I would assume that there is noise on the bus wires. That suggest

  • add in the terminating resistor to the meter (if not there)
  • add in another terminating resistor to the adaptor (if the wire length is over, say, 6 metres). Does the adaptor have its own terminating resistor built in?
  • use twisted pair wire, and add in some form of grounding

I assume that all of this is surrounded by lots of mains electricity (did wonder if you have three phase or just one phase supply) so using twisted pair for the AB circuit is advised/necessary. Also connecting one (and only one) end of either a screening shield or another spare pair of wires to ground helps. In my setup I have used standard LAN cable, one pair for the AB pair, and I have tied another pair to the GRND at the adaptor end. I can’t see a grounding point on the meter, and many of the USB adaptors don’t have one either. If noise is the issue, then a better adaptor with a Modbus GRND terminal, shielded cable, or a lower Baud rate might help.

Once we have the Slave ID and the Register Address sorted, this seems to be hardware issues. Once those are sorted, you should be able to move forwards. Good luck!

@Biscuit once again thank you for the elaborate feedback. I am starting to pull my hair here. The meter is no longer responding, and I have double checked the termination. I will investigate further in the weekend and follow your latest suggestions. I will let you know how it turns out :slight_smile:

Hi Kasper,

any progress about your smartmeter? I’m in a similar situation. I have an original Inepro PRO380 MOD (and also a solarlog and a Kaco Inverter), but it’s an old version with different modbus register. I also don’t get a reply from the meter.
The old manual can be found here: https://vallin.lv/wp-content/uploads/2017/10/PRO380-user-manual-V1-03.pdf

Best, Tom

Allright, after a lot of digging and reading, I have finally found a solution. :grinning:

I have found the solution here (only available in german, but only the schematic is important).
https://wiki.volkszaehler.org/hardware/channels/meters/power/pqplus_cmd68-52?s[]=inepro

The secret was adding pull up and pull down resistors to the data lines and adding termination resistors at the meter and the converter. I have modified my USB RS485 converter and added a 5V line to the sub D plug. I have just opened the case and soldered an additional wire from 5V USB to one of the sub D pins. Since I had no 820 Ohm resistors at home, I tried it with 650 and a 1000 Ohm resistor and both were working fine.

That’s how I lined all my ducks up! :wink:

Best, Tom

1 Like

I think if you use something like this RS485 USB converter you could have skipped some soldering