Custom Component: ABB/Power-One/FIMER PV Inverters - SunSpec Modbus TCP

you are right!
The LAN Cable was “eaten” by mice, with WiFi it works without Problems!

Thanks for your great Integration and help!

1 Like

Wolfram, did you test this beta? Release v3.2.0-beta.1 - Multi MPPT changes for monophase inverters · alexdelprete/ha-abb-powerone-pvi-sunspec · GitHub

It is a PR developed by @ivanfm that I merged for monophase inverters with dual MPPTs.

Check if it solves your negative DC values. :slight_smile:

This is finally fixed in v3.3.0 just released. Try it and let me know.

Ciao @alexdelprete thank you very much for everything you’re doing for this integration.

I’ve been trying to use it for my Fimer Trio 5.8 (three phases) with the VSN300 card. I was able to connect through Qmaster (ID 247, register 0). However I receive an unknown error within HA.

Looking at the logs this is what I get:


Logger: aiohttp.server
Source: /usr/local/lib/python3.11/site-packages/aiohttp/web_protocol.py:421
First occurred: 22:22:58 (1 occurrences)
Last logged: 22:22:58

Error handling request
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/aiohttp/web_protocol.py", line 452, in _handle_request
    resp = await request_handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aiohttp/web_app.py", line 543, in _handle
    resp = await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aiohttp/web_middlewares.py", line 114, in impl
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 85, in security_filter_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 100, in forwarded_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 28, in request_context_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 80, in ban_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 233, in auth_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/headers.py", line 31, in headers_middleware
    response = await handler(request)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/view.py", line 149, in handle
    result = await handler(request, **request.match_info)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/decorators.py", line 63, in with_admin
    return await func(self, request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 177, in post
    return await super().post(request, flow_id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 72, in wrapper
    result = await method(view, request, data, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 110, in post
    result = await self._flow_mgr.async_configure(flow_id, data)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 293, in async_configure
    result = await self._async_handle_step(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 389, in _async_handle_step
    result: FlowResult = await getattr(flow, method)(user_input)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/abb_powerone_pvi_sunspec/config_flow.py", line 90, in async_step_user
    uid = await self.test_connection(name, host, port, slave_id, base_addr, scan_interval)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/abb_powerone_pvi_sunspec/config_flow.py", line 65, in test_connection
    self.hub_data = await self.hub.async_get_data()
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/abb_powerone_pvi_sunspec/api.py", line 187, in async_get_data
    self.read_sunspec_modbus_model_160()
  File "/config/custom_components/abb_powerone_pvi_sunspec/api.py", line 481, in read_sunspec_modbus_model_160
    multi_mppt_id = decoder.decode_16bit_int()
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/pymodbus/payload.py", line 405, in decode_16bit_int
    return unpack(fstring, handle)[0]
           ^^^^^^^^^^^^^^^^^^^^^^^
struct.error: unpack requires a buffer of 2 bytes

Any idea what this might be? I’m running the latest version of HA on Docker (Synology NAS). Grazie in anticipo per l’aiuto!

Synology NAS? I don’t know, but if I had to guess I’d say it’s something related to python and synology.

If you have a pc or raspberry, install HA there and test it. It’s not an issue related to the component but a system configuration problem.

Hi all,
during the last weeks I experimented some problems using @monkeypr00f Node Red flow, the cause of the problem was always correlated with compatibility betwrrn Node Red itself and the NR Companion integration in HA. This exacerbated the issues I always had related to wifi coverage with my VSN card, thus I worked a native HA configuration to gather metrics directly from VSN and so removing the “middleman” Node Red.

For those who have similar problem I share here the extract of my configuration.yaml.

Before starting You need to get the json directly from the VSN card, to do it you can use wget:

wget -v --auth-no-challenge --http-user=VSN-CARD-USERNAME --http-password=VSN-CARD-PASSWORD http://VSN-CARD-IP/v1/livedata

then open the JSON from an online parser (eg. http://json.parser.online.fr), to find the correct serial numbers for your card, you need to find these strings:

device_id":"xxxxxx-yyyy-zzzz","device_type":"meter"
device_id":"xxxxxx-yyyy-zzzz","device_type":"inverter_1phase" or device_id":"xxxxxx-yyyy-zzzz","device_type":"inverter_3phase"
device_id":"xxxxxx-yyyy-zzzz","device_type":"battery" (one device_id for every battery pack, if you have battery storage)

then place the serials collected in the pertinent sensor definition. Then restart HA and check the logs for errors, I had to do some trial to get all right.

Please be aware that the JSON structure I used, and thus the various array positions, are valid form my REACT2 inverter that should have an embedded VSN700 card, you may change the arrays indexes accordingly to your specific card. In the configuration below I commented the indexes with the clear text values names, so you can search the json to get correct indexes.

rest:
    resource: http://IP-ADDRESS-OF-VSN-CARD/v1/livedata
    username: #USERNAME, without quotes, usually "User" or "Utente", the username used to login on the web interface of the VSN
    password: #PASSWORD, without quotes, usually blank, the password used to login on the web interface of the VSN
    authentication: basic
    scan_interval: 60
    timeout: 30 #not always necessary, my VSN card has really low wifi coverage so the increased timeout helps reducing errors
    sensor:
      - name: "Home Consumption"
        value_template: "{{ value_json['METER-SN']['points'][7].value }}"
# Meter - HousePgrid_Tot
        device_class: power
        unit_of_measurement: W
      - name: "Generation Instant Consumption"
        value_template: "{{value_json['INVERTER-SN']['points'][10].value}}"
# Inverter - Pin
        device_class: power
        unit_of_measurement: W 
      - name: "Grid Instant. Input"
#Not sure, I think it's "Imported from grid Today"
        value_template: "{{value_json['METER-SN']['points'][34].value}}"
# Meter - E8_runtime
        device_class: power
        unit_of_measurement: W 
      - name: "Battery Instant. Power Flow"
        value_template: "{{value_json['INVERTER-SN']['points'][78].value}}"
# Inverter - PbaT
        device_class: power
        unit_of_measurement: W 
      - name: "Home Today"
        value_template: "{{value_json['METER-SN']['points'][31].value}}"
# Meter - E7_runtime
        device_class: power
        unit_of_measurement: W 
      - name: "Generation Today"
        value_template: "{{value_json['INVERTER-SN']['points'][55].value}}"
# Inverter - E2_runtime
        device_class: power
        unit_of_measurement: W 
      - name: "Injected Today"
        value_template: "{{value_json['METER-SN']['points'][25].value}}"
# Meter - E3_runtime
        device_class: power
        unit_of_measurement: W 
      - name: "Battery SoC"
        value_template: "{{value_json['INVERTER-SN']['points'][79].value}}"
# Inverter - TSoc
        device_class: battery
        unit_of_measurement: '%'
      - name: "Battery 1 SoH"
        value_template: "{{value_json['BATTERY-1-SN']['points'][10].value}}"
# Battery1 - Soh
        unit_of_measurement: '%'
      - name: "Battery 2 SoH"
        value_template: "{{value_json['BATTERY-2-SN']['points'][10].value}}"
# Battery2 - Soh
        unit_of_measurement: '%'
      - name: "VGrid"
        value_template: "{{value_json['INVERTER-SN']['points'][13].value}}"
# Inverter - VGrid
        device_class: voltage
        unit_of_measurement: V
      - name: "Generation to house"
#  Inverter - PbaT <  Inverter - Pin 
        value_template: >
                         {% if (value_json['INVERTER-SN']['points'][78].value | float) < (value_json['INVERTER-SN']['points'][10].value | float)  %}
                              {{ ((value_json['INVERTER-SN']['points'][78].value | float) + (value_json['INVERTER-SN']['points'][10].value | float) | float) }} 
                         {% else %}
                              {{(value_json['INVERTER-SN']['points'][10].value | float)}}
                         {% endif %}
        device_class: power
        unit_of_measurement: W
      - name: "Generation to grid"
# Meter - MeterPgrid_Tot
        value_template: >
                         {% if (value_json['METER-SN']['points'][18].value | float ) > 0 %}
                              {{ (value_json['METER-SN']['points'][18].value | float) }}
                         {% else %}
                              0
                         {% endif %}
        device_class: power
        unit_of_measurement: W
      - name: "Grid to house"
# Meter - MeterPgrid_Tot
        value_template: >
                         {% if (value_json['METER-SN']['points'][18].value | float ) > 0 %}
                              0
                         {% else %}
                              {{ ((value_json['METER-SN']['points'][18].value | float) | abs) }}
                         {% endif %}
        device_class: power
        unit_of_measurement: W
      - name: "Battery to house"
#  Inverter - PbaT
        value_template: >
                         {% if (value_json['INVERTER-SN']['points'][10].value | float ) > 0 %}
                              {{ (value_json['INVERTER-SN']['points'][10].value | float) }}
                         {% else %}
                              0
                         {% endif %}
        device_class: power
        unit_of_measurement: W
      - name: "Generation to battery"
#  Inverter - PbaT
        value_template: >
                         {% if (value_json['INVERTER-SN']['points'][10].value | float ) > 0 %}
                              0
                         {% else %}
                              {{ ((value_json['INVERTER-SN']['points'][10].value | float) | abs) }}
                         {% endif %}
        device_class: power
        unit_of_measurement: W

This work couldn’t have been possible without @monkeypr00f great job and without @alexdelprete support in finding the correct auth mechanism. Thank you both!

Could someone tell me the modbus registers for a serial connection? I can’t find anything.
I have a Huawei inverter and I managed to read the data, now I would like to connect a pvi-6000-tl-outd always in series via cable.

  1. The modbus register addresses have nothing to do with how you connect (serial or TCP), they’re always the same.

  2. You have a Huawei inverter and you write in a thread of an integration for another brand. :smiley:

  3. Do you know how to search the forum? Better, do you know what HACS (custom integration repository) is? There’s a Huawei integration: GitHub - wlcrs/huawei_solar: Home Assistant integration for Huawei Solar inverters via Modbus

Good luck.

as written in the previous post I have a huawei inverter and I managed to connect it with a serial port. now I would like to connect a second inverter to a second serial but I can’t find the modbus directors. the inverter is a pvi-6000-tl-outd which is why I wrote here, because I thought someone knew the registers or told me where to find them

You should ask first at Fumer support, they can give you the exact map for your device.

On the internet there are a lot of documents related to abb and fimer inverters but it’s hard to guess which one is applicable to the one you have…

ABB

https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://library.e.abb.com/public/c4f8b5d142a7488da678076c3ae01caf/Modbus_RTU_register_map_for_TRIO-20.0(27.6)-TL-OUTD_Revision_1.6.pdf%3Fx-sign%3DAoC3mZyQkimPiPObtpYAdNWqrldsYlHdzLWqtmuYyMlI56H2lXFUZlzi29NscOAl&ved=2ahUKEwihi6DXka6EAxVXS_EDHageC0IQFnoECDMQAQ&usg=AOvVaw1lOCPjgtOi1cih9V2sWZAb

Fimer

https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://www.fimer.com/sites/default/files/Modbus_RTU_register_map_for_TRIO-50%25200_60%25200_Revision_3.4.pdf&ved=2ahUKEwihi6DXka6EAxVXS_EDHageC0IQFnoECBUQAQ&usg=AOvVaw1uwiHO4Gtt46fZTGGQ8G28

I have an ABB Trio inverter and an ELFIN EE11A converter, which converts RS 485 to Ethernet. HA recognizes the converter, but I don’t know how to proceed. With ABB’s Aurora Lite software, I can see all the data, but I don’t know how to integrate it. Can you help me with this? Will the guide you provided work in my case as well?

TRIO 20.0

Yes, it will work. I used a converter like that too before ordering a VSN300.

You need to enable Modbus TCP on the Elfin. Then you need to find the Slave ID of the inverter, and you configure the integration with the IP of the elfin, the tcp port (502 normally) and the slave ID.

It will work fine.

I inserted this line:
modbus:

  • name: ElfinEE11
    type: tcp
    host: 192.168.1.139
    port: 502
    delay: 0
    message_wait_milliseconds: 30
    timeout: 5
    where do I find the ID of my inverter? should it be 2?
    or on Aurora I found this entry: FLASH ID is this?

please be patient, if you can help me I will be grateful.

Marino, where did you put this line? This integration is installed via config flow. There’s no line to be added anywhere. You need to follow the instructions provided in the readme.

Install the component via HACS, then add the integration from the integrations page, then configure it.

You can find the inverter id (slave id) on the inverter display, usually it’s 2 or 254 but you need to find it.

I’m redoing the procedure from scratch

First you need to understand HOW things work.

The integration needs an IP and a PORT, not a virtual com port. You only need to enable the Modbus TCP on the Elfin and check what tcp port uses, should be 502. Then you use IP:PORT of the Elfin to configure the integration.

The integration will query the elfin using modbus tcp, and the elfin will translate those commands on the serial port to the inverter and reply back.

Ensure of the Slave ID is correct.

Hi!
I’ve a Aurora Power-One inverter, but this has a Modbus RTU (RS485) interface only.
I’m using SolarView to log my inverters since years. Is there any solution to use RS485 directly?

On RS485 you can only enable the Aurora protocol to access register data, so this integration won’t work, since it only supports Sunspec standard mapping. You need to install the VSN300 card (check if it’s compatible with your inverter model), that is a datalogger that also translates Aurora protocol to Modbus TCP Sunspec.

Hello,

I have an ABB TRIO with an Ethernet Expansion Card (FIMER_ETHERNET expansion board_Quick Installation Guide_EN_RevC (1).pdf) that supports Modbus TCP. This has already been mentioned before. Unfortunately, there is no implementation according to the SunSpec.

The data from the inverter is displayed in the input registers and is probably mapped 1:1 from Modbus RTU to TCP.

The register mapping can be found here:
Modbus_RTU_registers_map_for_TRIO_8.5(5.8)_TL_OUTD (abb.com)

I have read out my data here with the Modbus Scanner:

Is there a way to modify the register mapping in your project so that I can get it to work with this Ethernet card as well?

The VSN300 is currently hard to come by, and in principle, with the right mapping, it should work with the Ethernet card as well…

I decided to stick to Sunspec because the standard register mapping could change based on the inverter model.

Nothing stops you from forking the project and modifying the code to implement custom mapping for your inverter, if you know all the register addresses of your inverter.

But if I was you, I would wait to have the VSN300 when available.