home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
72.65k stars 30.41k forks source link

remote_rpi_gpio does not recover from lost connection #116007

Open rfspereira opened 5 months ago

rfspereira commented 5 months ago

The problem

Environment: a) Remote PI is a RPI 3B+ with raspberrypi desktop OS latest version available. Enabled the GPIO. b) Configured Home Assistant with remote_rpi_gpio (as shown on documentation examples). Home Assistant is running on a RPI 4 with the default HA image for RPI 4 and latest version.

All works fine until the moment the remote device is turned off and back on.

After rebooting the only way to get the connection back is to restart home assistant.

What version of Home Assistant Core has the issue?

core-2024.4.3

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant OS

Integration causing the issue

No response

Link to integration documentation on our website

No response

Diagnostics information

No response

Example YAML snippet

# Example configuration.yaml entry
switch:
  - platform: remote_rpi_gpio
    host: 192.168.20.202
    invert_logic: true
    ports:
      5: O0

Anything in the logs that might be useful for us?

Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/commands.py:239
integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 9:48:18 PM (5 occurrences)
Last logged: 9:48:25 PM

[547738448832] [Errno 104] Connection reset by peer
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 239, in handle_call_service
    response = await hass.services.async_call(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2543, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2580, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 971, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 1043, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1655, in async_turn_on
    await self.hass.async_add_executor_job(ft.partial(self.turn_on, **kwargs))
  File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/remote_rpi_gpio/switch.py", line 83, in turn_on
    remote_rpi_gpio.write_output(self._switch, 1)
  File "/usr/src/homeassistant/homeassistant/components/remote_rpi_gpio/__init__.py", line 50, in write_output
    switch.on()
  File "/usr/local/lib/python3.12/site-packages/gpiozero/output_devices.py", line 219, in on
    self._write(True)
  File "/usr/local/lib/python3.12/site-packages/gpiozero/output_devices.py", line 96, in _write
    self.pin.state = self._value_to_state(value)
    ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/gpiozero/pins/__init__.py", line 285, in <lambda>
    lambda self, value: self._set_state(value),
                        ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/gpiozero/pins/pigpio.py", line 249, in _set_state
    elif self.function == 'input':
         ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/gpiozero/pins/__init__.py", line 262, in <lambda>
    lambda self: self._get_function(),
                 ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/gpiozero/pins/pigpio.py", line 222, in _get_function
    return self.GPIO_FUNCTION_NAMES[self.factory.connection.get_mode(self.number)]
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pigpio.py", line 1402, in get_mode
    return _u2i(_pigpio_command(self.sl, _PI_CMD_MODEG, gpio, 0))
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pigpio.py", line 1026, in _pigpio_command
    dummy, res = struct.unpack('12sI', sl.s.recv(_SOCK_CMD_LEN))
                                       ^^^^^^^^^^^^^^^^^^^^^^^^
ConnectionResetError: [Errno 104] Connection reset by peer

and

Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/commands.py:239
integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 9:48:25 PM (6 occurrences)
Last logged: 9:48:25 PM

[547738448832] [Errno 32] Broken pipe
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 239, in handle_call_service
    response = await hass.services.async_call(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2543, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2580, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 971, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 1043, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1655, in async_turn_on
    await self.hass.async_add_executor_job(ft.partial(self.turn_on, **kwargs))
  File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/remote_rpi_gpio/switch.py", line 83, in turn_on
    remote_rpi_gpio.write_output(self._switch, 1)
  File "/usr/src/homeassistant/homeassistant/components/remote_rpi_gpio/__init__.py", line 50, in write_output
    switch.on()
  File "/usr/local/lib/python3.12/site-packages/gpiozero/output_devices.py", line 219, in on
    self._write(True)
  File "/usr/local/lib/python3.12/site-packages/gpiozero/output_devices.py", line 96, in _write
    self.pin.state = self._value_to_state(value)
    ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/gpiozero/pins/__init__.py", line 285, in <lambda>
    lambda self, value: self._set_state(value),
                        ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/gpiozero/pins/pigpio.py", line 249, in _set_state
    elif self.function == 'input':
         ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/gpiozero/pins/__init__.py", line 262, in <lambda>
    lambda self: self._get_function(),
                 ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/gpiozero/pins/pigpio.py", line 222, in _get_function
    return self.GPIO_FUNCTION_NAMES[self.factory.connection.get_mode(self.number)]
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pigpio.py", line 1402, in get_mode
    return _u2i(_pigpio_command(self.sl, _PI_CMD_MODEG, gpio, 0))
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pigpio.py", line 1025, in _pigpio_command
    sl.s.send(struct.pack('IIII', cmd, p1, p2, 0))
BrokenPipeError: [Errno 32] Broken pipe

Additional information

No response

home-assistant[bot] commented 5 months ago

remote_rpi_gpio documentation remote_rpi_gpio source

cz-unit commented 3 months ago

Yep, I have the same problem, and this has been going on since end of 2023. The problem is that the service does not do an attempt at a re-connection if the network is interrupted after HomeAssistant is launched. Thus you launch HA, it connects to the remote listener on the remote PI, then fails if anything happens to that TCP connection.

A simple retry subroutine should fix this issue, currently the only thing you can do is re-load HA which is a pain in the tail and not something that you can count on for an automation.

ThemeIT commented 2 months ago

i am having the same issue. I have a program in place to turn on/off my rpi and after one power-cycle HA wont reconnect, because it drops the entity after one connection loss. As previously mentioned: it needs a reconnection subroutine.

mtotah commented 1 month ago

workaround:

write a small script on the PI to monitor changes, and publish them to MQTT. define your sensors as MQTT sensors in HA.

I am a newbie in python, here's my first take and its working nicely:

from gpiozero import Button from signal import pause import paho.mqtt.publish as publish

def sendout(pin, value):

print('sendout ' , pin, value)

publish.single("poolRpi/in/" + str(pin), value, hostname="your.mqtt.broker.ip")

buttons = {}

def setup(pin): button = Button(pin, bounce_time = 0.2) button.when_pressed = lambda: sendout(pin, 'ON') button.when_released = lambda: sendout(pin, 'OFF') buttons[pin] = button sendout(pin, 'ON' if button.is_pressed else 'OFF')

pins = [17,22,27] for pin in pins: setup(pin) pause()