Fix keyboard_remote device_descriptor when using symbolic links (#94744)

This commit is contained in:
Ian Foster 2023-06-27 11:31:41 -07:00 committed by GitHub
parent e7f29263e3
commit 286bdff8bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -203,22 +203,29 @@ class KeyboardRemote:
try:
async for event in self.inotify:
descriptor = f"{DEVINPUT}/{event.name}"
_LOGGER.debug("got events for %s: %s", descriptor, event.mask)
_LOGGER.debug(
"got event for %s: %s",
descriptor,
event.mask,
)
descriptor_active = descriptor in self.active_handlers_by_descriptor
if (event.mask & Mask.DELETE) and descriptor_active:
_LOGGER.debug("removing: %s", descriptor)
handler = self.active_handlers_by_descriptor[descriptor]
del self.active_handlers_by_descriptor[descriptor]
await handler.async_device_stop_monitoring()
elif (
(event.mask & Mask.CREATE) or (event.mask & Mask.ATTRIB)
) and not descriptor_active:
_LOGGER.debug("checking new: %s", descriptor)
dev, handler = await self.hass.async_add_executor_job(
self.get_device_handler, descriptor
)
if handler is None:
continue
_LOGGER.debug("adding: %s", descriptor)
self.active_handlers_by_descriptor[descriptor] = handler
await handler.async_device_start_monitoring(dev)
except asyncio.CancelledError:
@ -244,8 +251,10 @@ class KeyboardRemote:
self.emulate_key_hold_repeat = dev_block[EMULATE_KEY_HOLD_REPEAT]
self.monitor_task = None
self.dev = None
self.config_descriptor = dev_block.get(DEVICE_DESCRIPTOR)
self.descriptor = None
async def async_device_keyrepeat(self, path, name, code, delay, repeat):
async def async_device_keyrepeat(self, code, delay, repeat):
"""Emulate keyboard delay/repeat behaviour by sending key events on a timer."""
await asyncio.sleep(delay)
@ -255,8 +264,8 @@ class KeyboardRemote:
{
KEY_CODE: code,
TYPE: "key_hold",
DEVICE_DESCRIPTOR: path,
DEVICE_NAME: name,
DEVICE_DESCRIPTOR: self.descriptor,
DEVICE_NAME: self.dev.name,
},
)
await asyncio.sleep(repeat)
@ -266,12 +275,21 @@ class KeyboardRemote:
_LOGGER.debug("Keyboard async_device_start_monitoring, %s", dev.name)
if self.monitor_task is None:
self.dev = dev
# set the descriptor to the one provided to the config if any, falling back to the device path if not set
if self.config_descriptor:
self.descriptor = self.config_descriptor
else:
self.descriptor = self.dev.path
self.monitor_task = self.hass.async_create_task(
self.async_monitor_input(dev)
self.async_device_monitor_input()
)
self.hass.bus.async_fire(
KEYBOARD_REMOTE_CONNECTED,
{DEVICE_DESCRIPTOR: dev.path, DEVICE_NAME: dev.name},
{
DEVICE_DESCRIPTOR: self.descriptor,
DEVICE_NAME: dev.name,
},
)
_LOGGER.debug("Keyboard (re-)connected, %s", dev.name)
@ -291,12 +309,16 @@ class KeyboardRemote:
self.monitor_task = None
self.hass.bus.async_fire(
KEYBOARD_REMOTE_DISCONNECTED,
{DEVICE_DESCRIPTOR: self.dev.path, DEVICE_NAME: self.dev.name},
{
DEVICE_DESCRIPTOR: self.descriptor,
DEVICE_NAME: self.dev.name,
},
)
_LOGGER.debug("Keyboard disconnected, %s", self.dev.name)
self.dev = None
self.descriptor = self.config_descriptor
async def async_monitor_input(self, dev):
async def async_device_monitor_input(self):
"""Event monitoring loop.
Monitor one device for new events using evdev with asyncio,
@ -307,19 +329,22 @@ class KeyboardRemote:
try:
_LOGGER.debug("Start device monitoring")
await self.hass.async_add_executor_job(dev.grab)
async for event in dev.async_read_loop():
await self.hass.async_add_executor_job(self.dev.grab)
async for event in self.dev.async_read_loop():
# pylint: disable=no-member
if event.type is ecodes.EV_KEY:
if event.value in self.key_values:
_LOGGER.debug(categorize(event))
_LOGGER.debug(
"device: %s: %s", self.dev.name, categorize(event)
)
self.hass.bus.async_fire(
KEYBOARD_REMOTE_COMMAND_RECEIVED,
{
KEY_CODE: event.code,
TYPE: KEY_VALUE_NAME[event.value],
DEVICE_DESCRIPTOR: dev.path,
DEVICE_NAME: dev.name,
DEVICE_DESCRIPTOR: self.descriptor,
DEVICE_NAME: self.dev.name,
},
)
@ -329,8 +354,6 @@ class KeyboardRemote:
):
repeat_tasks[event.code] = self.hass.async_create_task(
self.async_device_keyrepeat(
dev.path,
dev.name,
event.code,
self.emulate_key_hold_delay,
self.emulate_key_hold_repeat,