"""Integration of lirc network service""" 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 EVENT_IR_COMMAND_RECEIVED = "ir_command_received" BUTTON_NAME = "button_name" _LOGGER = logging.getLogger(__name__) DOMAIN = 'lirc_network' REMOTE_NAME = 'remote' 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, vol.Optional(CONF_PORT, default=8765): cv.port, }])) }, extra=vol.ALLOW_EXTRA) async def async_setup(hass, config): hass.data[DATA_LIRC_NETWORK] = [] for config_element in config[DOMAIN]: connection = LircConnection(hass, config_element) hass.data[DATA_LIRC_NETWORK].append(connection) await connection.start() _LOGGER.warning("About to return true in async_setup") return True 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, 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 async def _process_line(self, line): # Example msg: # 0000000000001795 00 Down Hauppauge_350 # 0000000000001795 01 Down Hauppauge_350 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: 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)