Custom Component: Generic SunSpec modbus TCP monitoring (inverter, meter etc)

For frequency, you can use mdi:sine-wave. You didn’t like it? :slight_smile:

Another very important thing I noticed: the sensors don’t have any prefix. I would suggest that in the configuration phase of the component, in the config_flow, you ask for a prefix, proposing a default. Because there could be more sunspec devices of different vendors, etc.

1 Like

For the various operating states: I’d suggest to put the actual value (eg 4 for my specific operating state) and in the attributes of that sensor the sunspec enumerated value (eg MPPT for value 4). This way a user could use it to customize the status (I would put the real meaning, taken from the list of my specific vendor, 4 means Running and Producing Power).

Thanks again for the feedback!

I must have missed the frequency icon, will fix in next release :slight_smile:
I’l have a look at an optional prefix config option, good suggestion.

Regarding the St field (and all enums and bitfields), i prefer having the actual symbol there for the sensor value, a text symbol says more than just a number.
Those symbols are in the spec and will always be the same, so if you want to customize that sensor you could just compare symbols instead of numbers (ie instead of check for value 4 check for the string ‘MPPT’).
I can add the number value as a state attribute though.

Also have a look at the field named “Inverter Vendor specific operating state code” (StVnd), this is supposed to be vendor specific and is always a number, perhaps that would give you what you want?

1 Like

Thanks, the prefix is really important.

I agree, if the text is meaningful though. :slight_smile:
Unfortunately the SunSpec, being a general specification, cannot be detailed on these things, that’s why I was simply asking to not lose the numeric information, so a user could eventually remap the number to a meaningful text associated to the code number. An attribute is a good idea.

unfortunately that register is not implemented for all models, mine included. :slight_smile:

Thanks again.

Version 0.0.4 is out with sensor prefix and model selection step added in setup.
Enum and bitfield raw values are also available as a sensor state attribute/

2 Likes

Great job Johan. I installed it and it works, but I have to do more in-depth testing to give you feedbacks.

Currenly I’m busy completing my custom component, but I’m struggling to solve a minor but blocking issue on config flow: Config Flow label issue

I had thought about looking at yours, if I don’t get any hint on the forum. :slight_smile:

Thanks,

Alessandro

Hi Johan,

your component is working fine. :slight_smile:

I wanted to ask you: what part of the code is used to set the info in “Device Info”? Is it the code in entity.py? Because in my component I only have the manufacturer, and I’d like to put the real model info and the fw version. Thanks for any hint on this.

As you can see (screenshot of my component), my inverter doesn’t give the real model in descriptive format, but a sort of code taken from the serial#. In my component I implemented a lookup table, with corresponding codes, to get the real model info, basically the first byte of the Options field is the index of the table. I had to access specific vendor’s docs to get it. Also for the status codes, same thing, there were 2 different tables for each status code.

image

Yes the device_info method of your entities are used for “Device info”, in my component all entities share the class defined in entity.py.

Interesting how they managed to complicate the model name on your inverter, a bit odd to use a standardized spec and make such things non-standard :wink:
There are room in the spec for vendor specific things such as your operating state (i think it’s StVnd in the bottom of that screenshot right), those are currentyly not supported in my component (will only show the number), i’m not sure if and how to handle that yet.

I don’t think you have to do anything, it’s their fault not following the specs. I still have to check with other users that have different models what comes up. Maybe it’s only for “old” inverters like mine, which is a 2013 model with the same fw of 2013.

I found the code and a device_info() for each sensor, but I don’t quite get how to modify it to add the two fields I want to the device info section. It’s my fault, I’m not a programmer…last time I developed something was 25y ago. But I’m having fun again trying to make things work…with some help by kind people like you. :slight_smile:

I don’t want to hijack your thread with my issues, maybe I’ll write you privately…thanks as always, you are very kind.

1 Like

Hi Johan,

when the inverter is off, I have a lot of these in the logs. Obviously I expect connection errors, but I think there’s some other issues. Hope it helps.

2021-06-17 01:04:39 ERROR (MainThread) [custom_components.sunspec] Socket write error: [Errno 32] Broken pipe
2021-06-17 01:04:42 ERROR (MainThread) [custom_components.sunspec] Unexpected error fetching sunspec data: Connection error: [Errno 113] Host is unreachable
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/sunspec2/modbus/modbus.py", line 515, in _read
    self.socket.sendall(req)
BrokenPipeError: [Errno 32] Broken pipe
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/config/custom_components/sunspec/__init__.py", line 118, in _async_update_data
    data[model_id] = await self.api.async_get_data(model_id)
  File "/config/custom_components/sunspec/api.py", line 88, in async_get_data
    return await self.read(model_id)
  File "/config/custom_components/sunspec/api.py", line 91, in read
    return await self._hass.async_add_executor_job(self.read_model, model_id)
  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/sunspec/api.py", line 126, in read_model
    model.read()
  File "/usr/local/lib/python3.8/site-packages/sunspec2/modbus/client.py", line 85, in read
    data = self.model.device.read(self.model.model_addr + self.offset, self.len)
  File "/usr/local/lib/python3.8/site-packages/sunspec2/modbus/client.py", line 317, in read
    return self.client.read(addr, count, op)
  File "/usr/local/lib/python3.8/site-packages/sunspec2/modbus/modbus.py", line 584, in read
    data = self._read(addr + read_offset, read_count, op=op)
  File "/usr/local/lib/python3.8/site-packages/sunspec2/modbus/modbus.py", line 517, in _read
    raise ModbusClientError('Socket write error: %s' % str(e))
sunspec2.modbus.modbus.ModbusClientError: Socket write error: [Errno 32] Broken pipe
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/sunspec2/modbus/modbus.py", line 481, in connect
    self.socket.connect((self.ipaddr, self.ipport))
OSError: [Errno 113] Host is unreachable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 187, in _async_refresh
    self.data = await self._async_update_data()
  File "/config/custom_components/sunspec/__init__.py", line 123, in _async_update_data
    self.api.reconnect()
  File "/config/custom_components/sunspec/api.py", line 108, in reconnect
    client.connect()
  File "/usr/local/lib/python3.8/site-packages/sunspec2/modbus/client.py", line 308, in connect
    self.client.connect()
  File "/usr/local/lib/python3.8/site-packages/sunspec2/modbus/modbus.py", line 483, in connect
    raise ModbusClientError('Connection error: %s' % str(e))
sunspec2.modbus.modbus.ModbusClientError: Connection error: [Errno 113] Host is unreachable

Is there any benefits over the other custom ModBus integrations already in HomeAssistant?

I have been using the SolarEdge ModBus integration to good effect, allows 5 second intervals between readings.

Not really, if the other component gives you all the data that you care about. This component aims to work with all SunSpec compliant devices and lets you choose to collect all available data that they offer. Scan interval is configurable in the UI.

Hi for all!
I have installed a smart meter (B21 112-100) on my ABB UNO Dm inverter.
I use successfully this integration on Home Assistant, but I ask if is any solution to read the smart meter registers?!

Hello Alexe!
I had a look at the spec sheet for the meter and it doesn’t look like it’s supporting SunSpec unfortunately, so this integration will not work with it. It does suport modbus over serial, so if you can hook it up to HA via a serial interface you might be able to use the generic modbus integration to read data from it.

1 Like

Thank you for the quick answer!
The smart meter is connected with serial interface rs485 to inverter and I see it’s parameters on inverter interface (web, app).
I don’t know how to link the meter to HA, without the inverter.
I was tried to get the meter with the generic modbus TCP integration, but with no response.
If any of you have an idea, I will be grateful.
Thanks again!

Sorry if I made off topic !

Aha, then it might actually be possible that the inverter makes the meter data available through it’s own modbus registers. Have you checked the available models in the configuration step? Not all are enabled by default.
Another possibility is that it makes the meter registers available on a different slave id, in that case you need to add a new SunSpec integration with that slave id.
Does the manual mention anything about the meter and modbus/sunspec?

I checked all the registers in the sunspec integration, but I did not find references to the meter parameters. I have a list of meter registers that are not in the sunspec list. ex: Active import -20480 (5000 in hex); Active export -20483 (5004 in hex) …etc.
I’m still looking!

Hello

I’m just new to HA, as i am migrating my openhab system to HA. I’ve just installed the sunspec integration, but i’ve got stuck with the connection part to my invertor.
In my previous system i used the same IP, port and Id and that worked.
In HA i get ‘Failed to connect, check hostname and port’
I’ve tried using the hostname, restarted HA, but with same result.
Does anyone has a clou?


Thanks

Hello @woutike !
Connection issues are not so easy to help with, so many things can go wrong.
Can you have a look in the logs and see if there is any error with sunspec in it?
You can find it Configuration → Logs
If you have cli access to the machine running HA, can you log in there and ping the IP?

I’ve a Fronius and a SolarEdge inverter. I’ve installed the custom SunSpec integration for both inverters. During the night I got a lot of errors every 30 seconds. I think the Fronius inverter is responsible for those errors but I’m not sure.

2021-09-01 21:07:45 ERROR (MainThread) [homeassistant.components.fronius.sensor] Failed to update: connection error
2021-09-01 21:08:22 WARNING (MainThread) [custom_components.sunspec] timed out
2021-09-01 21:08:24 ERROR (MainThread) [custom_components.sunspec] Unexpected error fetching sunspec data: Connection error: [Errno 113] Host is unreachable
Traceback (most recent call last):
File "/config/custom_components/sunspec/__init__.py", line 128, in _async_update_data
data[model_id] = await self.api.async_get_data(model_id)
File "/config/custom_components/sunspec/api.py", line 86, in async_get_data
return await self.read(model_id)
File "/config/custom_components/sunspec/api.py", line 89, in read
return await self._hass.async_add_executor_job(self.read_model, model_id)
File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/config/custom_components/sunspec/api.py", line 132, in read_model model.read()
File "/usr/local/lib/python3.9/site-packages/sunspec2/modbus/client.py", line 85, in read 
data = self.model.device.read(self.model.model_addr + self.offset, self.len)
File "/usr/local/lib/python3.9/site-packages/sunspec2/modbus/client.py", line 317, in read
return self.client.read(addr, count, op)
File "/usr/local/lib/python3.9/site-packages/sunspec2/modbus/modbus.py", line 584, in read
data = self._read(addr + read_offset, read_count, op=op)
File "/usr/local/lib/python3.9/site-packages/sunspec2/modbus/modbus.py", line 520, in _read
c = self.socket.recv(len_remaining)
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/sunspec2/modbus/modbus.py", line 481, in connect
self.socket.connect((self.ipaddr, self.ipport))
OSError: [Errno 113] Host is unreachable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 187, in _async_refresh
self.data = await self._async_update_data()
File "/config/custom_components/sunspec/__init__.py", line 133, in _async_update_data
self.api.reconnect()
File "/config/custom_components/sunspec/api.py", line 106, in reconnect
client.connect()
File "/usr/local/lib/python3.9/site-packages/sunspec2/modbus/client.py", line 308, in connect
self.client.connect()
File "/usr/local/lib/python3.9/site-packages/sunspec2/modbus/modbus.py", line 483, in connect
raise ModbusClientError('Connection error: %s' % str(e))
sunspec2.modbus.modbus.ModbusClientError: Connection error: [Errno 113] Host is unreachable
2021-09-01 21:08:54 WARNING (MainThread) [custom_components.sunspec] Socket write error: [Errno 32] Broken pipe
2021-09-01 21:08:57 ERROR (MainThread) [custom_components.sunspec] Unexpected error fetching sunspec data: Connection error: [Errno 113] Host is unreachable

What is wrong?