Skip to content

Commit

Permalink
Fix keyboard_remote device_descriptor when using symbolic links (#94744)
Browse files Browse the repository at this point in the history
  • Loading branch information
lanrat authored Jun 27, 2023
1 parent e7f2926 commit 286bdff
Showing 1 changed file with 38 additions and 15 deletions.
53 changes: 38 additions & 15 deletions homeassistant/components/keyboard_remote/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,22 +203,29 @@ async def async_monitor_devices(self):
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:
Expand All @@ -244,8 +251,10 @@ def __init__(self, hass: HomeAssistant, dev_block: dict[str, Any]) -> None:
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)
Expand All @@ -255,8 +264,8 @@ async def async_device_keyrepeat(self, path, name, code, delay, repeat):
{
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)
Expand All @@ -266,12 +275,21 @@ async def async_device_start_monitoring(self, dev):
_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)

Expand All @@ -291,12 +309,16 @@ async def async_device_stop_monitoring(self):
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,
Expand All @@ -307,19 +329,22 @@ async def async_monitor_input(self, dev):

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,
},
)

Expand All @@ -329,8 +354,6 @@ async def async_monitor_input(self, dev):
):
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,
Expand Down

0 comments on commit 286bdff

Please sign in to comment.