У меня есть eeepc с графикой Intel. Я хотел бы подключить скрипт к событию монитора, подключенного через VGA. Как это сделать?
Как создать обратный вызов для монитора, подключенного к графике Intel?
Ответы (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"
, я все еще получаю некоторые события при загрузке, поэтому вы можете каким-то образом учесть это в своем скрипте.
99
?
- person Roymunson; 22.08.2020
Этот другой ответ находится на правильном пути: вы хотите прослушивать события 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()
Смотрите также:
- Как я могу запускать код всякий раз, когда USB-устройство (не)подключено, не требуя прав суперпользователя?
- Как я могу прослушать ' USB-устройство вставлено» в Linux, в Python?
- документация pyudev – асинхронный мониторинг
У вас есть три варианта:
- Опрос определенной записи в sysfs.
- Используйте inotify для обнаружения изменений в sysfs.
- Используйте сокет netlink с NETLINK_KOBJECT_UEVENT и прослушайте
change
uevent для нужного вам устройства.
В любом из упомянутых способов вам все равно придется проводить опрос тем или иным образом, поэтому я бы выбрал первый вариант.
inotify
и netlink
позволяют использовать select()
и друзей. Вы действительно считаете это опросом?
- person Brian Cain; 30.11.2012
sudo inotifywait -e modify -m --format '%:e %f' /sys/class/drm/something
, поэтому ваш второй вариант недействителен.
- person nicholas.alipaz; 11.03.2015
inotifywait
и вместо этого попробую dbus-monitor
.
- person WinEunuuchs2Unix; 02.10.2018
Спасибо Себастьянвагнер!
С помощью этой информации я смог успешно загрузить свой медиацентр 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.