Reconnecting client: optional keep-alive & timeout

- lirc timeout, to reliably detect disconnect
This commit is contained in:
Martin Bauer
2020-07-13 11:32:38 +00:00
parent feeefbe987
commit 349861ad7c
3 changed files with 66 additions and 31 deletions

View File

@@ -2,7 +2,9 @@
import logging
import voluptuous as vol
from datetime import timedelta
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.const import CONF_HOST, CONF_PORT
from ..reconnecting_client import ReconnectingClient
@@ -16,6 +18,8 @@ REPEAT_COUNTER = 'repeat_counter'
LIRC_HOST = 'host'
DATA_LIRC_NETWORK = 'data_lirc_network'
LIRC_TIMEOUT = 40 # in seconds
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema(vol.All([{
vol.Required(CONF_HOST): cv.string,
@@ -39,7 +43,17 @@ class LircConnection(ReconnectingClient):
def __init__(self, hass, config):
super().__init__(hass, config[CONF_HOST], config[CONF_PORT], "lirc_network",
receive_line_callback=self._process_line,
connection_status_changed_callback=self._connection_state_changed)
connection_status_changed_callback=self._connection_state_changed,
timeout=LIRC_TIMEOUT)
self._multiline_response_in_progress = False
self._multiline_response = ""
async def keep_alive_callback(*args, **kwargs):
if self._writer and self.connected:
self._writer.write("VERSION\n".encode())
await self._writer.drain()
async_track_time_interval(hass, keep_alive_callback, timedelta(seconds=LIRC_TIMEOUT / 2))
async def _connection_state_changed(self, _):
pass
@@ -48,17 +62,27 @@ class LircConnection(ReconnectingClient):
# Example msg:
# 0000000000001795 00 Down Hauppauge_350
# 0000000000001795 01 Down Hauppauge_350
splitted_line = line.split()
if len(splitted_line) != 4:
_LOGGER.warning(f'Ignoring LIRC message from host {self._host}: "{line}"')
return
if line.startswith("Unknown LIRC Command received: VERSION"):
pass # response of irserver to VERSION query
elif line.strip() == "BEGIN":
self._multiline_response_in_progress = True
elif self._multiline_response_in_progress and line.strip() == "END":
self._multiline_response_in_progress = False
self._multiline_response = ""
elif self._multiline_response_in_progress:
self._multiline_response += line
else:
code, repeat_counter, key_name, remote_name = splitted_line
repeat_counter = int(repeat_counter, 16) # repeat code is hexadecimal
key_name = key_name.lower()
data = {BUTTON_NAME: key_name,
REMOTE_NAME: remote_name,
REPEAT_COUNTER: repeat_counter,
LIRC_HOST: self._host}
_LOGGER.info(f"Got new LIRC network code {data}")
self.hass.bus.fire(EVENT_IR_COMMAND_RECEIVED, data)
splitted_line = line.split()
if len(splitted_line) != 4:
_LOGGER.warning(f'Ignoring LIRC message from host {self._host}: "{line}"')
return
else:
code, repeat_counter, key_name, remote_name = splitted_line
repeat_counter = int(repeat_counter, 16) # repeat code is hexadecimal
key_name = key_name.lower()
data = {BUTTON_NAME: key_name,
REMOTE_NAME: remote_name,
REPEAT_COUNTER: repeat_counter,
LIRC_HOST: self._host}
_LOGGER.info(f"Got new LIRC network code {data}")
self.hass.bus.fire(EVENT_IR_COMMAND_RECEIVED, data)