Как создать обратный вызов для "монитора подключен" на графике Intel?
У меня есть компьютер с графикой Intel. Я бы хотел подключить скрипт к событию монитора, подключенного через VGA. Как это сделать?
5 ответов
Как грубое решение, вы можете опросить sysfs. На моем ноутбуке у меня есть:
$ cat /sys/class/drm/card0-LVDS-1/status
connected
$ cat /sys/class/drm/card0-VGA-1/status
disconnected
Я предполагаю, что для этого требуется ядро DRM и, возможно, KMS.
Чтобы увидеть, если вы можете запустить что-то автоматически, вы можете запустить udevadm monitor --property
и наблюдайте, пока вы (не) подключаете монитор, чтобы увидеть, поступают ли сообщения о событиях.
С моим Radeon я получаю событие при первом подключении монитора VGA, но при последующих отключениях и повторных подключениях событий нет. Событие должно выглядеть примерно так (используя ваш пример):
KERNEL[1303765357.560848] change /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV_LOG=0
ACTION=change
DEVPATH=/devices/pci0000:00/0000:00:02.0/drm/card0
SUBSYSTEM=drm
HOTPLUG=1
DEVNAME=dri/card0
DEVTYPE=drm_minor
SEQNUM=2943
MAJOR=226
MINOR=0
К сожалению, сравнивать не с чем, но пока на картинке только одна видеокарта, что не так уж важно. Найдите, откуда udev получает правила в вашей системе (возможно, /etc/udev/rules.d/
) и создать 99-monitor-hotplug.rules
файл с:
ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/root/hotplug.sh"
udev
затем будет работать hotplug.sh
когда дисплей подключен. В качестве теста я положил следующее в /root/hotplug.sh
(не забудьте сделать этот скрипт исполняемым):
#!/bin/sh
for output in DVI-I-1 LVDS-1 VGA-1; do
echo $output >> /root/hotplug.log
cat /sys/class/drm/card0-$output/status >> /root/hotplug.log
done
С этим я получил запись в hotplug.log
после того как я подключил внешний дисплей. Даже фильтрация для ACTION=="change"
У меня все еще есть некоторые события при загрузке, так что вы можете учесть это как-то в своем скрипте.
Этот другой ответ находится на правильном пути: вы хотите слушать события DRM от udev
,
Я реализовал скрипт Python, который запускает некоторый код, когда USB-устройства или внешние дисплеи (не) подключены. Я включаю ниже минимальную версию этого скрипта (не проверено):
#!/usr/bin/env python3
import pyudev
def udev_event_received(device):
... # Your code here!
context = pyudev.Context()
monitor_drm = pyudev.Monitor.from_netlink(context)
monitor_drm.filter_by(subsystem='drm')
observer_drm = pyudev.MonitorObserver(monitor_drm, callback=udev_event_received, daemon=False)
observer_drm.start()
# This will prevent the program from finishing:
observer_drm.join()
Смотрите также:
У вас есть три варианта:
- Опрос по конкретной записи в sysfs.
- Используйте inotify для обнаружения изменений в sysfs.
- Используйте сокет netlink с NETLINK_KOBJECT_UEVENT и слушайте
change
событие для устройства, которое вы хотите.
В любом из упомянутых способов вам все равно придется опрашивать тем или иным способом, поэтому я бы просто выбрал первый вариант.
Спасибо Себастьян Вагнер!
Благодаря этой информации я смог успешно загрузить свой медиацентр Kodi с выключенным телевизором. Действительно, когда телевизор выключен, драйвер Intel не хочет устанавливать режим, и я получил пустой экран, когда позже включил телевизор.
Журнал Kodi показал следующую строку:
WARNING: CXRandR::Query - output HDMI1 has no current mode, assuming disconnected
Поэтому я создал следующую строку в /etc/udev/rules.d/99-monitor-hotplug.rules:
ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/usr/sbin/hotplugtv.sh"
Содержимое файла /usr/sbin/hotplugtv.sh (мой X-сервер работает от имени пользователя root):
#!/bin/bash
export DISPLAY=:0
export XAUTHORITY=/root/.Xauthority
/bin/date 2>&1 >> /var/log/hotplugtv.log;
if [[ $(cat /sys/class/drm/card0-HDMI-A-1/status | grep -Ec "^connected") -eq 1 ]]; then
echo "TV connected!" >> /var/log/hotplugtv.log;
/bin/sleep 2s;
/usr/bin/xrandr --verbose --output HDMI1 --auto 2>&1 >> /var/log/hotplugtv.log;
else
echo "TV disconnected!" >> /var/log/hotplugtv.log;
fi
Не забывайте перезагружать правила udev, когда вы вносите какие-либо изменения в свой скрипт (это сводило меня с ума!):
udevadm control --reload-rules
Будьте осторожны, чтобы отключить все заставки в Kodi, потому что они остаются активными навсегда, когда вы наконец включите телевизор. С другой стороны, энергосбережение / DPMS работает нормально.
Предполагая, что вы используете X, сценарий может проанализировать вывод xrandr, чтобы увидеть, какие мониторы подключены. Это должно работать с любой видеокартой. Это тот же инструмент, который вы, вероятно, будете использовать, чтобы использовать изменения в вашем скрипте.
Это не решает проблему с уведомлениями для автоматического запуска скрипта. Хотя у меня нет отличного общего решения, распространенным случаем является обнаружение внешнего монитора, поскольку ноутбук подключен к док-станции. В этом случае ваш скрипт может отключить что-то еще, что срабатывает при подключении к док-станции, например, при добавлении или удалении USB-клавиатуры или Ethernet.