How do I get correct values from Carlo Gavazzi EM340 Modbus

I have this setup now in my configuration.yaml, and it works (mostly)

mqtt:
  sensor:
    -  name: "EM340_in"
       state_topic: "EM340/kWh_in"
       value_template: "{{ value | float  | round (2) }}"
       unit_of_measurement: "kWh"
       device_class: energy
       state_class: total_increasing       
    -  name: "EM340_out"
       state_topic: "EM340/kWh_out"
       value_template: "{{ value | float  | round (2) }}"
       unit_of_measurement: "kWh"
       device_class: energy
       state_class: total_increasing    
    -  name: "EM340_A1"
       state_topic: "EM340/A1"
       value_template: "{{ value | float  | round (2) }}"
       unit_of_measurement: "A"
       device_class: current
       state_class: measurement
    -  name: "EM340_A2"
       state_topic: "EM340/A2"
       value_template: "{{ value | float  | round (2) }}"
       unit_of_measurement: "A"
       device_class: current
       state_class: measurement
    -  name: "EM340_A3"
       state_topic: "EM340/A3"
       value_template: "{{ value | float  | round (2) }}"
       unit_of_measurement: "A"
       device_class: current
       state_class: measurement

I am publishing to mqqt with a python script on a raspberry pi that has a RS485-CAN-hat attached to it. I intend to swap out the rpi for an esp8266 later in the week. The python code :

from pymodbus.client.sync import ModbusSerialClient
from pymodbus.pdu import ExceptionResponse
from pymodbus.exceptions import ModbusIOException
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian
import struct
import time

import paho.mqtt.client as mqtt #import the client1
broker_address='192.168.1.90'
port=1883

class ModbusException(Exception):
  def __init__(self, resp):
    self.msg = str(result)

  def __str__(self):
    return self.msg

class ModbusRequestDefinition(object):
  def __init__(self, kind, unit, address, count, converter, label, decimals, topic):
    self.kind = kind
    self.unit = unit
    self.address = address
    self.count = count
    self.converter = converter
    self.label = label
    self.decimals = decimals
    self.topic = topic

reqs = [
 #ModbusRequestDefinition('H', 1, 0x0002, 2, '', 'V1'),
 #ModbusRequestDefinition('H', 1, 0x0002, 2, '', 'V2'),
 #ModbusRequestDefinition('H', 1, 0x0004, 2, '', 'V3'),
 ModbusRequestDefinition('H', 1, 0x000C, 2, '', 'A1', 1000,'EM340/A1'),
 ModbusRequestDefinition('H', 1, 0x000E, 2, '', 'A2', 1000,'EM340/A2'),
 ModbusRequestDefinition('H', 1, 0x0010, 2, '', 'A3', 1000,'EM340/A3'),
 ModbusRequestDefinition('H', 1, 0x0034, 2, '', 'kWh+', 10,'EM340/kWh_in'),
 ModbusRequestDefinition('H', 1, 0x004E, 2, '', 'kWh-', 10,'EM340/kWh_out')
]

client = ModbusSerialClient(method='rtu', port='/dev/ttyAMA0', baudrate=9600, stopbits=1, timeout=1)
client.connect()

delay = 0.05
#period = 0.5
period = 5

mqttclient = mqtt.Client("P1") #create new instance
mqttclient.username_pw_set("your mqqt user", "your mqtt password") # !! insert your own credentials here !!
mqttclient.connect(broker_address) #connect to broker

while True:
  for req in reqs:
    try:
      time.sleep(delay)
      if req.kind == 'H':
        result = client.read_holding_registers(address=req.address,
                                               count=req.count,
                                               unit=req.unit)

        if type(result) in [ExceptionResponse, ModbusIOException]:
          raise ModbusException(result)
        # print(req.label,  end ="\t" )
        # print(req.topic,  end ="\t" )
        decoder = BinaryPayloadDecoder.fromRegisters(result.registers, byteorder=Endian.Big, wordorder=Endian.Little)
        val = decoder.decode_32bit_int()/req.decimals
        # print(val)
        mqttclient.publish(req.topic,val)

    except ModbusException as e:
      print("ERROR when querying '{0}': {1!s}".format(req.label, e))
      if client.socket is None:
        print("renew socket")
        #client.socket = getSerial()

  #print("-------------")
  time.sleep(period)

client.close()

this is old pymodbus v2.5 as I couldnt yet port to the new release v3. Anyone have a working example there that I could start from then I would be happy to adapt.

Then submit the EM340_in and EM340_out sensors to the energy wizard and after a few hours of running you can see the stats generating a nice energy graph.

Now I have to mimic the same RS485 > ESP8266 > MQTT > HA for my inverter

Sounds good and well. Go for it!
Just wanted to quickly mention that I am a very happy user of the Protoss RS485 product family, specifically the PE11-H. Ethernet or Wifi, 230V or 5V, Plug and play for 10-30€

Anyone willing to help here with a very basic question for me to get things started.

I do have a Gavazzi EM330 with ModBus interface connected to a Wallbox Pulsar EV charger. I believe that the Wallbox acting as a host and EM330 client. Could I just plug i.e. this in parallel to the EM330 data ports to steal the readings to HA?

Here is my configuration.

modbus.yaml

# in configuration.yaml insert the following row which includes this file
# modbus: !include modbus.yaml

  - name: modbus_serial1
    delay: 5
    timeout: 5
    message_wait_milliseconds: 1000
    type: serial
    method: rtu
    baudrate: 9600
    bytesize: 8
    stopbits: 1
    parity: N
    # To find the path to the port, login using SSH and use "ls -al /dev/serial/by-id/" to 
    # find the path to the USB-interface (ttyUSB<x> where x is a number)
    port: /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_B002EGCF-if00-port0
   
    # Template for Carlo Gavazzi EM340-S1 Modbus MID RS-485  
    # Valid for Home Assistant v2024.7.4
    # Register documentation for sensors: https://gavazzi.se/app/uploads/2020/11/em330_wr_et330_et340_cp.pdf
    # Feel free to improve
    
    sensors:
      - name: WR_V_L1-N
        unique_id: wr_v_l1-n
        unit_of_measurement: V
        state_class: measurement
        device_class: voltage
        slave: 1
        address: 0x0000
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_V_L2-N
        unique_id: wr_v_l2-n
        unit_of_measurement: V
        state_class: measurement
        device_class: voltage
        slave: 1
        address: 0x0002
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_V_L3-N
        unique_id: wr_v_l3-n
        unit_of_measurement: V
        state_class: measurement
        device_class: voltage
        slave: 1
        address: 0x0004
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_V_L1-L2
        unique_id: wr_v_l1-l2
        unit_of_measurement: V
        state_class: measurement
        device_class: voltage
        slave: 1
        address: 0x0006
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_V_L2-L3
        unique_id: wr_v_l2-l3
        unit_of_measurement: V
        state_class: measurement
        device_class: voltage
        slave: 1
        address: 0x0008
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_V_L3-L1
        unique_id: wr_v_l3-l1
        unit_of_measurement: V
        state_class: measurement
        device_class: voltage
        slave: 1
        address: 0x000A
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_A_L1
        unique_id: wr_a_l1
        unit_of_measurement: A
        state_class: measurement
        device_class: current
        slave: 1
        address: 0x000C
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.001
        scan_interval: 15
        swap: word

      - name: WR_A_L2
        unique_id: wr_a_l2
        unit_of_measurement: A
        state_class: measurement
        device_class: current
        slave: 1
        address: 0x000E
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.001
        scan_interval: 15
        swap: word

      - name: WR_A_L3
        unique_id: wr_a_l3
        unit_of_measurement: A
        state_class: measurement
        device_class: current
        slave: 1
        address: 0x0010
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.001
        scan_interval: 15
        swap: word

      - name: WR_W_L1
        unique_id: wr_w_l1
        unit_of_measurement: W
        state_class: measurement
        device_class: power
        slave: 1
        address: 0x0012
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_W_L2
        unique_id: wr_w_l2
        unit_of_measurement: W
        state_class: measurement
        device_class: power
        slave: 1
        address: 0x0014
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_W_L3
        unique_id: wr_w_l3
        unit_of_measurement: W
        state_class: measurement
        device_class: power
        slave: 1
        address: 0x0016
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_VA_L1
        unique_id: wr_va_l1
        unit_of_measurement: VA
        state_class: measurement
        device_class: reactive_power
        slave: 1
        address: 0x0018
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_VA_L2
        unique_id: wr_va_l2
        unit_of_measurement: VA
        state_class: measurement
        device_class: reactive_power
        slave: 1
        address: 0x001A
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_VA_L3
        unique_id: wr_va_l3
        unit_of_measurement: VA
        state_class: measurement
        device_class: reactive_power
        slave: 1
        address: 0x001C
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_VAR_L1
        unique_id: wr_var_l1
        unit_of_measurement: VA
        state_class: measurement
        device_class: reactive_power
        slave: 1
        address: 0x001E
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_VAR_L2
        unique_id: wr_var_l2
        unit_of_measurement: VA
        state_class: measurement
        device_class: reactive_power
        slave: 1
        address: 0x0020
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_VAR_L3
        unique_id: wr_var_l3
        unit_of_measurement: VA
        state_class: measurement
        device_class: reactive_power
        slave: 1
        address: 0x0022
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_V_L-N
        unique_id: wr_v_l-n
        unit_of_measurement: V
        state_class: measurement
        device_class: voltage
        slave: 1
        address: 0x0024
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_V_L-L
        unique_id: wr_v_l-L
        unit_of_measurement: V
        state_class: measurement
        device_class: voltage
        slave: 1
        address: 0x0026
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_W
        unique_id: wr_w
        unit_of_measurement: W
        state_class: measurement
        device_class: Power
        slave: 1
        address: 0x0028
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_VA
        unique_id: wr_va
        unit_of_measurement: VA
        state_class: measurement
        device_class: reactive_power
        slave: 1
        address: 0x002A
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_VAR
        unique_id: wr_var
        unit_of_measurement: VA
        state_class: measurement
        device_class: reactive_power
        slave: 1
        address: 0x002C
        data_type: int32
        input_type: input
        precision: 0
        scale: 0.1
        scan_interval: 15
        swap: word

      - name: WR_PF_L1
        unique_id: wr_pf_l1
        state_class: measurement
        device_class: power_factor
        slave: 1
        address: 0x002E
        data_type: int16
        input_type: input
        precision: 3
        scale: 0.001
        scan_interval: 15

      - name: WR_PF_L2
        unique_id: wr_pf_l2
        state_class: measurement
        device_class: power_factor
        slave: 1
        address: 0x002F
        data_type: int16
        input_type: input
        precision: 3
        scale: 0.001
        scan_interval: 15

      - name: WR_PF_L3
        unique_id: wr_pf_l3
        state_class: measurement
        device_class: power_factor
        slave: 1
        address: 0x0030
        data_type: int16
        input_type: input
        precision: 3
        scale: 0.001
        scan_interval: 15

      - name: WR_PF
        unique_id: wr_pf
        state_class: measurement
        device_class: power_factor
        slave: 1
        address: 0x0031
        data_type: int16
        input_type: input
        precision: 2
        scale: 0.001
        scan_interval: 15

      - name: WR_Phase_sequence
        unique_id: wr_phase_sequence
        state_class: measurement
        slave: 1
        address: 0x010E
        data_type: int32
        input_type: input
        scan_interval: 60

      - name: WR_HZ
        unique_id: wr_hz
        unit_of_measurement: Hz
        state_class: measurement
        device_class: frequency
        slave: 1
        address: 0x0033
        data_type: int16
        input_type: input
        precision: 2
        scale: 0.1
        scan_interval: 15

      - name: WR_kWh_Positive_Total
        unique_id: wr_wh_positive_total
        unit_of_measurement: kWh
        state_class: total_increasing
        device_class: energy
        slave: 1
        address: 0x0034
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.000001
        scan_interval: 60

      - name: WR_kVARh_Positive_Total
        unique_id: wr_kvarh_positive_total
        unit_of_measurement: kWh
        state_class: total_increasing
        device_class: energy
        slave: 1
        address: 0x0036
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.000001
        scan_interval: 60

      - name: WR_kW_DMD
        unique_id: wr_kw_dmd
        unit_of_measurement: kW
        device_class: power
        slave: 1
        address: 0x0038
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.00001
        scan_interval: 15

      - name: WR_kW_DMD_Peak
        unique_id: wr_kw_dmd_peak
        unit_of_measurement: kW
        device_class: power
        slave: 1
        address: 0x003A
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.00001
        scan_interval: 15

      - name: WR_kWh_Positive_Partial
        unique_id: wr_kwh_positive_partial
        unit_of_measurement: kWh
        state_class: total_increasing
        device_class: energy
        slave: 1
        address: 0x003C
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.000001
        scan_interval: 60

      - name: WR_kVARh_Positive_Partial
        unique_id: wr_kvarh_positive_partial
        unit_of_measurement: kWh
        state_class: total_increasing
        device_class: energy
        slave: 1
        address: 0x003E
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.00001
        scan_interval: 60

      - name: WR_kWh_L1
        unique_id: wr_kwh_l1
        unit_of_measurement: kWh
        state_class: total_increasing
        device_class: energy
        slave: 1
        address: 0x0040
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.000001
        scan_interval: 60

      - name: WR_kWh_L2
        unique_id: wr_kwh_l2
        unit_of_measurement: kWh
        state_class: total_increasing
        device_class: energy
        slave: 1
        address: 0x0042
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.000001
        scan_interval: 60

      - name: WR_kWh_L3
        unique_id: wr_kwh_l3
        unit_of_measurement: kWh
        state_class: total_increasing
        device_class: energy
        slave: 1
        address: 0x0044
        data_type: int32
        input_type: input
        precision: 1
        scale: 0.000001
        scan_interval: 60
1 Like