""" LIRC interface to receive signals from a infrared remote control. This sensor will momentarily set state to various values as defined in the .lintrc file which can be interpreted in home-assistant to trigger various actions. Sending signals to other IR receivers can be accomplished with the shell_command component and the irsend command for now. """ # pylint: disable=import-error import threading import time import logging from homeassistant.const import EVENT_HOMEASSISTANT_STOP DOMAIN = "lirc" REQUIREMENTS = ['python-lirc>=1.2.1'] _LOGGER = logging.getLogger(__name__) ICON = 'mdi:remote' EVENT_BUTTON_PRESSED = 'button_pressed' BUTTON_NAME = 'button_name' def setup(hass, config): """Setup LIRC capability.""" # Perform safe import of third-party python-lirc module try: import lirc except ImportError: _LOGGER.error("You are missing a required dependency: python-lirc.") return False # blocking=True gives unexpected behavior (multiple responses for 1 press) # also by not blocking, we allow hass to shut down the thread gracefully # on exit. lirc.init('home-assistant', blocking=False) lirc_interface = LircInterface(hass) lirc_interface.start() def _stop_lirc(_event): lirc_interface.stopped.set() hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, _stop_lirc) return True class LircInterface(threading.Thread): """ This interfaces with the lirc daemon to read IR commands. When using lirc in blocking mode, sometimes repeated commands get produced in the next read of a command so we use a thread here to just wait around until a non-empty response is obtained from lirc. """ def __init__(self, hass): """Construct a LIRC interface object.""" threading.Thread.__init__(self) self.stopped = threading.Event() self.hass = hass def run(self): """Main loop of LIRC interface thread.""" import lirc while not self.stopped.isSet(): code = lirc.nextcode() # list; empty if no buttons pressed # interpret result from python-lirc if code: code = code[0] _LOGGER.info('Got new LIRC code %s', code) self.hass.bus.fire(EVENT_BUTTON_PRESSED, {BUTTON_NAME: code}) else: time.sleep(0.1) # avoid high CPU in this thread _LOGGER.info('LIRC interface thread stopped')