Skip to content

remote_rpi_gpio broken pipe after remote machine rebooted or temporarily disconnected #64441

@scarre

Description

@scarre

The problem

remote_rpi_gpio is working fine until the remote machine is temporarily unavailable/disconnected from the network or rebooted.
Trying to interact with the remote gpio (e.g. switch on/off) results in error: Failed to call service switch/turn_on (/turn_off) [Errno 32] Broken pipe.
Functional connection to remote machine can only be recovered by restarting Home Assistant core.
Already reported as #45770 and closed, but apparently not solved.
#45770

What version of Home Assistant Core has the issue?

core-2021.12.9

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

remote_rpi_gpio

Link to integration documentation on our website

https://www.home-assistant.io/integrations/remote_rpi_gpio/

Example YAML snippet

switch:
  - platform: remote_rpi_gpio
    host: 192.168.xxx.xxx
    invert_logic: true
    ports:
      17: relay1
      18: relay2
      26: relay3

Anything in the logs that might be useful for us?

Logger: homeassistant.components.websocket_api.http.connection
Source: components/remote_rpi_gpio/__init__.py:54
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 14:29:54 (1 occurrences)
Last logged: 14:29:54

[2779057864] [Errno 32] Broken pipe
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 185, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1495, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1530, in _execute_service
    await handler.job.target(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 209, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 663, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 896, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 700, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 948, in async_turn_on
    await self.hass.async_add_executor_job(ft.partial(self.turn_on, **kwargs))
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/remote_rpi_gpio/switch.py", line 73, in turn_on
    remote_rpi_gpio.write_output(self._switch, 1)
  File "/usr/src/homeassistant/homeassistant/components/remote_rpi_gpio/__init__.py", line 54, in write_output
    switch.on()
  File "/usr/local/lib/python3.9/site-packages/gpiozero/output_devices.py", line 229, in on
    self._write(True)
  File "/usr/local/lib/python3.9/site-packages/gpiozero/output_devices.py", line 106, in _write
    self.pin.state = self._value_to_state(value)
  File "/usr/local/lib/python3.9/site-packages/gpiozero/pins/__init__.py", line 305, in <lambda>
    lambda self, value: self._set_state(value),
  File "/usr/local/lib/python3.9/site-packages/gpiozero/pins/pigpio.py", line 267, in _set_state
    elif self.function == 'input':
  File "/usr/local/lib/python3.9/site-packages/gpiozero/pins/__init__.py", line 283, in <lambda>
    lambda self: self._get_function(),
  File "/usr/local/lib/python3.9/site-packages/gpiozero/pins/pigpio.py", line 240, in _get_function
    return self.GPIO_FUNCTION_NAMES[self.factory.connection.get_mode(self.number)]
  File "/usr/local/lib/python3.9/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.9/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

It would probably be good to try recovering the connection ( at least a few times - 2 or 3) after a broken pipe error ,before abandoning. I think that trying to recover upon error is better than continuously monitoring the connection: it is less "invasive" and not so costly.
There are many situations where a remote machine can be temporarily disconnected from the network or rebooted, and it shouldn't require a reboot of the core to recover.
With other integrations (e.g. deconz with a remote hub), temporarily disconnecting the remote hub or rebooting it will not affect home assistant core. I understand that accessing a deconz remote hub via a web service is not exactly comparable to maintaining a TCP connection with a remote rapsberry pi; however not trying to re-establish a TCP connection when we know it is broken seems a bit "incomplete".

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions