2019-02-14 04:35:12 +00:00
|
|
|
"""Support for LIRC devices."""
|
2021-03-02 08:02:04 +00:00
|
|
|
# pylint: disable=import-error
|
2019-10-21 07:58:22 +00:00
|
|
|
import logging
|
2016-05-22 21:15:09 +00:00
|
|
|
import threading
|
|
|
|
import time
|
|
|
|
|
2019-10-21 07:58:22 +00:00
|
|
|
import lirc
|
2016-10-05 05:10:31 +00:00
|
|
|
|
2019-10-21 07:58:22 +00:00
|
|
|
from homeassistant.const import EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP
|
2016-05-22 21:15:09 +00:00
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
2016-10-05 05:10:31 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
BUTTON_NAME = "button_name"
|
2016-05-22 21:15:09 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
DOMAIN = "lirc"
|
2016-10-05 05:10:31 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
EVENT_IR_COMMAND_RECEIVED = "ir_command_received"
|
2016-10-05 05:10:31 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
ICON = "mdi:remote"
|
2016-10-05 05:10:31 +00:00
|
|
|
|
2016-05-22 21:15:09 +00:00
|
|
|
|
2016-05-24 04:36:48 +00:00
|
|
|
def setup(hass, config):
|
2017-04-30 05:04:49 +00:00
|
|
|
"""Set up the LIRC capability."""
|
2016-05-23 05:19:10 +00:00
|
|
|
# blocking=True gives unexpected behavior (multiple responses for 1 press)
|
2016-05-24 04:26:49 +00:00
|
|
|
# also by not blocking, we allow hass to shut down the thread gracefully
|
|
|
|
# on exit.
|
2019-07-31 19:25:30 +00:00
|
|
|
lirc.init("home-assistant", blocking=False)
|
2016-05-24 04:26:49 +00:00
|
|
|
lirc_interface = LircInterface(hass)
|
2016-05-26 05:26:00 +00:00
|
|
|
|
|
|
|
def _start_lirc(_event):
|
|
|
|
lirc_interface.start()
|
2016-05-22 21:15:09 +00:00
|
|
|
|
2016-05-24 04:26:49 +00:00
|
|
|
def _stop_lirc(_event):
|
|
|
|
lirc_interface.stopped.set()
|
2016-05-22 21:15:09 +00:00
|
|
|
|
2016-05-26 05:26:00 +00:00
|
|
|
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, _start_lirc)
|
2016-05-24 04:26:49 +00:00
|
|
|
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, _stop_lirc)
|
2016-05-22 21:15:09 +00:00
|
|
|
|
2016-05-24 04:26:49 +00:00
|
|
|
return True
|
2016-05-22 21:15:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
"""
|
|
|
|
|
2016-05-24 04:26:49 +00:00
|
|
|
def __init__(self, hass):
|
2016-05-22 21:15:09 +00:00
|
|
|
"""Construct a LIRC interface object."""
|
|
|
|
threading.Thread.__init__(self)
|
2016-05-26 05:26:00 +00:00
|
|
|
self.daemon = True
|
2016-05-22 21:15:09 +00:00
|
|
|
self.stopped = threading.Event()
|
2016-05-24 04:26:49 +00:00
|
|
|
self.hass = hass
|
2016-05-22 21:15:09 +00:00
|
|
|
|
|
|
|
def run(self):
|
2017-04-30 05:04:49 +00:00
|
|
|
"""Run the loop of the LIRC interface thread."""
|
2016-10-05 05:10:31 +00:00
|
|
|
_LOGGER.debug("LIRC interface thread started")
|
2016-05-22 21:15:09 +00:00
|
|
|
while not self.stopped.isSet():
|
2016-06-10 03:53:41 +00:00
|
|
|
try:
|
|
|
|
code = lirc.nextcode() # list; empty if no buttons pressed
|
|
|
|
except lirc.NextCodeError:
|
2016-10-05 05:10:31 +00:00
|
|
|
_LOGGER.warning("Error reading next code from LIRC")
|
2016-06-10 03:53:41 +00:00
|
|
|
code = None
|
2016-05-22 21:15:09 +00:00
|
|
|
# interpret result from python-lirc
|
|
|
|
if code:
|
|
|
|
code = code[0]
|
2016-10-05 05:10:31 +00:00
|
|
|
_LOGGER.info("Got new LIRC code %s", code)
|
2019-07-31 19:25:30 +00:00
|
|
|
self.hass.bus.fire(EVENT_IR_COMMAND_RECEIVED, {BUTTON_NAME: code})
|
2016-05-22 21:15:09 +00:00
|
|
|
else:
|
2016-05-26 05:26:00 +00:00
|
|
|
time.sleep(0.2)
|
2016-06-15 05:42:54 +00:00
|
|
|
lirc.deinit()
|
2019-07-31 19:25:30 +00:00
|
|
|
_LOGGER.debug("LIRC interface thread stopped")
|