Implement RFlink ping

I recently migrated from domoticz to HomeAssistant and I’ve noticed that I loose connectivity to my RFlink gateway every 5 minutes. I’m using an ESP8266 with ESP-link (https://github.com/jeelabs/esp-link) to connect to RFlink over tcp. Most likely the issue is that the gateway doesn’t receive any data for a long time and the TCP connection times out after 300 seconds. However RFlink implements a hello-protocol (see http://www.rflink.nl/blog2/protref) where the client sends “10;PING;” and RFlink replies back with “20;99;PONG;”. Domoticz implements this (pinging every 30 or 60 seconds) and my connection was very reliable.

Is there any chance this could be implemented in the RFlink component to make RFlink connections over TCP more reliable? It doesn’t seem that the python rflink package implements this natively - however it does now to discard the PONG reply, so all it would take is for the RFlink to send “10;PING;” every 30 seconds

UPDATE:

I added an entry to my crontab to send the ping command once every minute and it solves the disconnect issue - however it would be better to have it as an integrated part of HA

* * * * * echo "10;PING;" | /bin/nc -N <ip-of-rflink> 23

I find Reason for this problem … I’m beginner with HA and Linux but in my instalation of hassio ver 0.112 hassos 4.10. Is not command NC or netcat etc. Disconencting from rflink va esplink Is ugly. In log Is record (I know it can be turned off) but fór example PIR sensor in log-book Is unavailable… :frowning: Is some easy way to implement maybe ping function to my hassio instalation.

@aequitas Any chance you could implement this? Sadly it’s beyond my skills. :frowning:

I have been using your code for years and have started to see the same issue with RFlink entities going unavailable every 5 minutes, using RFLink over TCP (My Home-Assistant-RFLink-Gateway-ESP8266 setup).

I was scratching my head until I saw this post from 2019 realised that since I took away my 433Mhz home energy meter I no longer have a “heartbeat” keeping the connection alive.

Update: @aequitas, I see you seem to have added this to your python library? GitHub - aequitas/python-rflink

I have coded a quick and dirty examples in HASS IO to perform this keep-alive action, both of these work for my install (Pi 4, Home Assistant OS).

# Example configuration.yaml entry
sensor:
  - platform: command_line
    name: RFLink Keep Alive Command
    command: 'echo "10;PING;" | nc 192.168.2.22 23'
    scan_interval: 60 #seconds

or a shell command which could be called from an automation:

# Example configuration.yaml entry
shell_command:
  rflink_ping: 'echo "10;PING;" | nc 192.168.2.22 23'

Response back from the RFLink gateway, viewed from the tcp-to-serial bridge, showing the “pong” responses.

I did also try the tcp sensor, which should work for everyone regardless to their build (location of netcat) but for me at least this locks the RFLink integration out from Home Assistant :frowning:

# Example configuration.yaml entry
sensor:
  - platform: tcp
    name: rflink_ping_tcp_binary
    host: 192.168.2.22
    port: 23
    payload: '10;PING'

I have always has the issue that if I power cycle the RFLink connected Wifi serial bridge, then the RFLink integration in Home Assistant stops working, until I then restart Home Assistant.
Also the tcp sensor seems to make no way to detecting if no response is resulted / timed-out.

Seems both the RFLink integration and my ‘hack’ sensor are fighting it out!

2020-10-04 22:29:50 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.2816748752] 
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 137, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1315, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1350, in _execute_service
    await handler.func(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 459, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 655, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 490, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/light/__init__.py", line 249, in async_handle_light_on_service
    await light.async_turn_on(**params)
  File "/usr/src/homeassistant/homeassistant/components/rflink/__init__.py", line 561, in async_turn_on
    await self._async_handle_command("turn_on")
  File "/usr/src/homeassistant/homeassistant/components/rflink/__init__.py", line 498, in _async_handle_command
    await self._async_send_command(cmd, self._signal_repetitions)
  File "/usr/src/homeassistant/homeassistant/components/rflink/__init__.py", line 524, in _async_send_command
    await self._protocol.send_command_ack(self._device_id, cmd)
  File "/usr/local/lib/python3.8/site-packages/rflink/protocol.py", line 227, in send_command_ack
    yield from asyncio.wait_for(
  File "/usr/local/lib/python3.8/asyncio/tasks.py", line 490, in wait_for
    raise exceptions.TimeoutError()
asyncio.exceptions.TimeoutError

vs

2020-10-04 22:30:22 ERROR (SyncWorker_63) [homeassistant.components.tcp.sensor] Unable to connect to 192.168.2.22 on port 23: timed out

Note, I use the “TCP mode” string, I have seen others use the “Port” string but rather than set it to USB they set it to a TCP port with extra parameters for reconnect.

socat pty,link=/config/serialport-rflink,echo=0 tcp:x.x.x.x:xxxx,forever,reuseaddr,keepalive,keepidle=10,keepintvl=10,keepcnt=2

Issue raised: RFLink TCP mode does not implement ping to keep connection alive - connection times out #41251