Pull to refresh

Выключаем монитор с клавиатуры

Reading time3 min
Views25K
Предыдущий топик про ddccontrol, открыл для меня, что по DDC можно мониторы выключать. Не вгонять в сон, не включать энергосберегающий режим, а реально выключать. Так, чтобы гасла (и совсем не мигала!) лампочка питания на морде. Как от нажатия выкл на той же самой морде. Разумеется, можно не только выключать, но и включать. Программно!

1) Это можно сделать программно (ddccontrol)
2) Это можно прописать в скрипт
3) Скрипт можно повесить на хоткей

5) PROFIT??

В список профитов можно записать возможность включения/выключения ОДНОЙ кнопкой на клавиатуре ВСЕХ мониторов (у меня их сейчас два, и я планирую больше в будущем). Кнопка на клавиатуре куда приятнее для нажатия, чем кнопка монитора (по которой её целиться надо, да и монитор от нажатия может слегка поворачиваться, что раздражает).


Задача состоит из трёх этапов:
0) Настроить ddccontrol
1) написать скрипт, который будет адекватно отрабатывать включение/выключение мониторов в любой комбинации включенных выключенных мониторов.
2) Найти неиспользуемую кнопку на клавиатуре (и её код).
3) Назначить на этот код запуск скрипта.

Настройка ddccontrol


Настройка проста: нужно прописать i2c-dev модуль в /etc/modules (модули, которые грузятся автоматом при загрузке) Для первого запуска можете обойтись командой modprobe i2c-dev, которая пробует загрузить модуль здесь-и-сейчас.

Далее нам нужно проверить, что код выключения монитор выключает, а код включения — включает.

Я ранее рассказывал, как работать с ddccontrol, так что не буду всё пересказывать. Для моих самсунгов (обоих) регистр 0xe1 включает/выключает монитор:

ddccontrol -r 0xe1 -w 1 dev:/dev/i2c-2 — вкл; -w 0 — выкл.
Аналогично и для dev:/dev/i2c-1.

Мы так же можем получить это значение: ddccontrol -r 0xe1 dev:/dev/i2c-1

Опуская всё лишнее, нужная строка выглядит так:

Управление 0xe1: +/0/1 [???] (выкл)
Управление 0xe1: +/1/1 [???] (вкл)

Нам нужно настроить простенький греп для этого:
ddccontrol -r 0xe1 dev:/dev/i2c-1|grep -o +/./1|cut -b 3
Помимо мусора на stderr (нас он не волнует) мы получаем на выходе число: 1 — вкл, 0 — выкл. Ситуацию «пустая строка» мы обработаем некрасивым, но работающим суммированием с нулём. (пусто + ноль = ноль).

Скрипт


ТЗ для скрипта: если включен хотя бы один монитор — выключить все мониторы. Если включенных мониторов нет, попытаться включить все мониторы. В силу специфики работы ddcontrol нам придётся либо разрешить себе делать sudo ddccontrol без пароля (можете сами дописать скрипт), либо поменять права на доступ для файлов /dev/i2c-* (я просто поменял им группу на свою, этого хватило). На всякий случай напоминаю, что SUID-биты для шелл-скриптов не работают. Поменять группу файлов устройств для ddccontrol можно командой sudo chgrp `id -gn` /dev/i2c-*.

Текст скрипта (я его назвал /usr/local/bin/ddc-powerswitch):

#!/bin/sh
reg=0xe1
begin=1
end=2
seq=`seq -f "dev:/dev/i2c-%.0f" $begin $end`
for dev in $seq
do
        state=$(( ($state+0) | (`ddccontrol -r $reg $dev|grep -o +/./1 |cut -b 3` + 0) ))
done
echo state=$state
for dev in $seq
do
        ddccontrol -r $reg -w $(( ! $state )) $dev &
done



Комментарии к коду: begin/end — настраиваемо. На первое время можете прописать 0 и 6.
Если убрать амперсанд — будет легче отлаживать, но скрипт будет медленнее работать.
Параллелить опрос мониторов не рекомендую, будет race condition.

Поиск кнопки


Я решил использовать не использующуюся мультимедиа-кнопку на клавиатуре. Для этого была использована программа xev (запускать из шелла). Нажимаете нужную кнопку, смотрите код. В моём случае это была кнопка «мой компьютер» (код 198) с иконкой системника с монитором (иконка монитора — что может лучше подойти для вкл/выкл мониторов, тем паче, что она с самого края и попасть по ней случайно сложно?)

Назначение скрипта на хоткей


Я использовал следующий метод (гуру будут пинать за кривизну, просьба к пинку до востребования прилагать более прямые решения, с биндингом на общесистемном уровне):

Отредактируем (создадим) файл ~/.xbindkeysrc
"ddc-powerswitch"
 F31

(внимание: кавычки, пробел перед F31)

Теперь пропишем запус всего, что нужно в скрипт автозапуска. Для KDE это ~/.kde/Autostart/ddc-hotkeys (не забудте сделать его +x), для gnome ~/.config/autostart (для старых версий гнома сложнее, вот).

xmodmap -e 'keycode 198=F31'
xbindkeys



Вместо 198 нужно указать код клавиши, которая вам приглянулась при общении с xev.

Собственно, всё. Мы зарегистрировали хоткей, прописали его куда нужно. Теперь по нажатию кнопки, если есть хотя бы один включенный монитор, все мониторы выключаются. Если все мониторы выключены — включаются.
Tags:
Hubs:
+81
Comments47

Articles