Enable TCP KEEPALIVE to RFLink for dead connection detection (#46438)

RFLink compoment when used over TCP protocol suffers a major issue : it doesn't
know when connection is timeout or lost because there is no keepalive mechanism
so it can stay disconnected forever.
I wrote a small patch for the underlying 'python-rflink' library which will enable
TCP KEEPPAlive. On HASSIO side it will just add an optional argument in yml file
which will propagate to python-rflink caller.
This commit is contained in:
Christophe Painchaud 2021-02-12 15:58:59 +01:00 committed by GitHub
parent a8beae3c51
commit c3b460920e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 3 deletions

View File

@ -44,12 +44,14 @@ CONF_IGNORE_DEVICES = "ignore_devices"
CONF_RECONNECT_INTERVAL = "reconnect_interval" CONF_RECONNECT_INTERVAL = "reconnect_interval"
CONF_SIGNAL_REPETITIONS = "signal_repetitions" CONF_SIGNAL_REPETITIONS = "signal_repetitions"
CONF_WAIT_FOR_ACK = "wait_for_ack" CONF_WAIT_FOR_ACK = "wait_for_ack"
CONF_KEEPALIVE_IDLE = "tcp_keepalive_idle_timer"
DATA_DEVICE_REGISTER = "rflink_device_register" DATA_DEVICE_REGISTER = "rflink_device_register"
DATA_ENTITY_LOOKUP = "rflink_entity_lookup" DATA_ENTITY_LOOKUP = "rflink_entity_lookup"
DATA_ENTITY_GROUP_LOOKUP = "rflink_entity_group_only_lookup" DATA_ENTITY_GROUP_LOOKUP = "rflink_entity_group_only_lookup"
DEFAULT_RECONNECT_INTERVAL = 10 DEFAULT_RECONNECT_INTERVAL = 10
DEFAULT_SIGNAL_REPETITIONS = 1 DEFAULT_SIGNAL_REPETITIONS = 1
DEFAULT_TCP_KEEPALIVE_IDLE_TIMER = 3600
CONNECTION_TIMEOUT = 10 CONNECTION_TIMEOUT = 10
EVENT_BUTTON_PRESSED = "button_pressed" EVENT_BUTTON_PRESSED = "button_pressed"
@ -85,6 +87,9 @@ CONFIG_SCHEMA = vol.Schema(
vol.Required(CONF_PORT): vol.Any(cv.port, cv.string), vol.Required(CONF_PORT): vol.Any(cv.port, cv.string),
vol.Optional(CONF_HOST): cv.string, vol.Optional(CONF_HOST): cv.string,
vol.Optional(CONF_WAIT_FOR_ACK, default=True): cv.boolean, vol.Optional(CONF_WAIT_FOR_ACK, default=True): cv.boolean,
vol.Optional(
CONF_KEEPALIVE_IDLE, default=DEFAULT_TCP_KEEPALIVE_IDLE_TIMER
): int,
vol.Optional( vol.Optional(
CONF_RECONNECT_INTERVAL, default=DEFAULT_RECONNECT_INTERVAL CONF_RECONNECT_INTERVAL, default=DEFAULT_RECONNECT_INTERVAL
): int, ): int,
@ -199,6 +204,26 @@ async def async_setup(hass, config):
# TCP port when host configured, otherwise serial port # TCP port when host configured, otherwise serial port
port = config[DOMAIN][CONF_PORT] port = config[DOMAIN][CONF_PORT]
# TCP KEEPALIVE will be enabled if value > 0
keepalive_idle_timer = config[DOMAIN][CONF_KEEPALIVE_IDLE]
if keepalive_idle_timer < 0:
_LOGGER.error(
"A bogus TCP Keepalive IDLE timer was provided (%d secs), "
"default value will be used. "
"Recommended values: 60-3600 (seconds)",
keepalive_idle_timer,
)
keepalive_idle_timer = DEFAULT_TCP_KEEPALIVE_IDLE_TIMER
elif keepalive_idle_timer == 0:
keepalive_idle_timer = None
elif keepalive_idle_timer <= 30:
_LOGGER.warning(
"A very short TCP Keepalive IDLE timer was provided (%d secs), "
"and may produce unexpected disconnections from RFlink device."
" Recommended values: 60-3600 (seconds)",
keepalive_idle_timer,
)
@callback @callback
def reconnect(exc=None): def reconnect(exc=None):
"""Schedule reconnect after connection has been unexpectedly lost.""" """Schedule reconnect after connection has been unexpectedly lost."""
@ -223,6 +248,7 @@ async def async_setup(hass, config):
connection = create_rflink_connection( connection = create_rflink_connection(
port=port, port=port,
host=host, host=host,
keepalive=keepalive_idle_timer,
event_callback=event_callback, event_callback=event_callback,
disconnect_callback=reconnect, disconnect_callback=reconnect,
loop=hass.loop, loop=hass.loop,

View File

@ -2,6 +2,6 @@
"domain": "rflink", "domain": "rflink",
"name": "RFLink", "name": "RFLink",
"documentation": "https://www.home-assistant.io/integrations/rflink", "documentation": "https://www.home-assistant.io/integrations/rflink",
"requirements": ["rflink==0.0.55"], "requirements": ["rflink==0.0.58"],
"codeowners": [] "codeowners": []
} }

View File

@ -1943,7 +1943,7 @@ restrictedpython==5.1
rfk101py==0.0.1 rfk101py==0.0.1
# homeassistant.components.rflink # homeassistant.components.rflink
rflink==0.0.55 rflink==0.0.58
# homeassistant.components.ring # homeassistant.components.ring
ring_doorbell==0.6.2 ring_doorbell==0.6.2

View File

@ -989,7 +989,7 @@ regenmaschine==3.0.0
restrictedpython==5.1 restrictedpython==5.1
# homeassistant.components.rflink # homeassistant.components.rflink
rflink==0.0.55 rflink==0.0.58
# homeassistant.components.ring # homeassistant.components.ring
ring_doorbell==0.6.2 ring_doorbell==0.6.2