goodwe icon indicating copy to clipboard operation
goodwe copied to clipboard

Permission denied by using search_inverters()

Open samuixx opened this issue 10 months ago • 1 comments

Hi, I have changed the line for the IP address in the example as follows: ip_address = await goodwe.search_inverters() and now I receive the following error message:

python3 /etc/openhab/scripts/solargo_test.py Traceback (most recent call last): File "/etc/openhab/scripts/solargo_test.py", line 33, in asyncio.run(get_runtime_data()) File "/usr/lib/python3.11/asyncio/runners.py", line 190, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "/etc/openhab/scripts/solargo_test.py", line 7, in get_runtime_data ip_address = await goodwe.search_inverters() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/goodwe/init.py", line 127, in search_inverters result = await command.execute(UdpInverterProtocol("255.255.255.255", 48899, 1, 0)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/goodwe/protocol.py", line 456, in execute response_future = await protocol.send_request(self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/goodwe/protocol.py", line 182, in send_request await self._connect() File "/usr/local/lib/python3.11/dist-packages/goodwe/protocol.py", line 124, in _connect self._transport, self.protocol = await asyncio.get_running_loop().create_datagram_endpoint( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/asyncio/base_events.py", line 1386, in create_datagram_endpoint raise exceptions[0] File "/usr/lib/python3.11/asyncio/base_events.py", line 1373, in create_datagram_endpoint await self.sock_connect(sock, remote_address) File "/usr/lib/python3.11/asyncio/selector_events.py", line 634, in sock_connect return await fut ^^^^^^^^^ File "/usr/lib/python3.11/asyncio/selector_events.py", line 642, in _sock_connect sock.connect(address) PermissionError: [Errno 13] Permission denied

What can I do to search and use the IP address of the inverter. Thank you very much

samuixx avatar Feb 21 '25 15:02 samuixx

I encountered the same issue, but only on linux operating Systems (Ubuntu and Mint) not on Windows (10 and 11).

The Issue for this lies in the goodwe Module.

The reason for this is broadcasting on a socket is different. To broadcast on a linux socket, either the socket has to be configured to broadcast or the process needs root privilege.

Here the Broadcast is created:

File "/usr/local/lib/python3.11/dist-packages/goodwe/init.py", line 127, in search_inverters result = await command.execute(UdpInverterProtocol("255.255.255.255", 48899, 1, 0))

But later on in the Stack this information is not transmitted to the method, during a switch from the goodwe module to the asyncio module

This is visible in this error Message

File "/usr/local/lib/python3.11/dist-packages/goodwe/protocol.py", line 124, in _connect self._transport, self.protocol = await asyncio.get_running_loop().create_datagram_endpoint( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This being the full method call:

self._transport, self.protocol = await asyncio.get_running_loop().create_datagram_endpoint(
                lambda: self,
                remote_addr=(self._host, self._port),
            )

Leads to:

A Permission error during the connection, since the socket is not of the type broadcast and needs root privilege.

File "/usr/lib/python3.11/asyncio/selector_events.py", line 642, in _sock_connect sock.connect(address) PermissionError: [Errno 13] Permission denied

To Fix

The method call needs an additional argument, to enable broadcast on the socket.

File "/usr/local/lib/python3.11/dist-packages/goodwe/protocol.py", line 124,

self._transport, self.protocol = await asyncio.get_running_loop().create_datagram_endpoint(
                lambda: self,
                remote_addr=(self._host, self._port),
                allow_broadcast=True,
            )

Vitog-Coding avatar May 26 '25 10:05 Vitog-Coding

I've ran into the same thing and submitted a PR to fix it https://github.com/marcelblijleven/goodwe/pull/122

singe avatar Nov 26 '25 05:11 singe