88 lines
3.3 KiB
Python
88 lines
3.3 KiB
Python
"""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()
|
|
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)
|