Автоматически регулировать яркость дисплея в зависимости от восхода и заката солнца.

Вопрос или проблема

В Ask Ubuntu есть похожие вопросы и ответы, которые указывают на следующие решения:

но они либо требуют ручного ввода времени восхода и заката, либо просто регулируют цветовой баланс и добавляют больше красного ночью.

Я ищу решение, которое автоматически получает время восхода и заката каждого дня и физически регулирует яркость дисплея. Кроме того, я хочу получить плавный переход в течение 60-120 минут, чтобы не замечать изменения дисплея.

Перенастройка в облачные дни (темнее снаружи) или когда солнце заходит между двумя трехэтажными зданиями, а не над их крышами (ярче перед закатом), должна быть быстрым и простым процессом.

Обновленный пост от 2019 года – Eyesome

Eyesome — это bash-скрипт, работающий как демон и в основном спящий 24/7. Он автоматически регулирует яркость экрана (и по желанию гамму тоже) для дисплея вашего ноутбука через аппаратный интерфейс и до двух других мониторов с использованием программного управления xrandr.

На восходе солнца (время которого автоматически получено из интернета каждый день) яркость экрана (и по желанию гамма тоже) регулируется постепенно. Плавная настройка определяется вами, но 120 минут подходят мне. Чтобы изменения были незаметными, установите интервал ожидания между регулировками. Вероятно, лучше всего выбрать от 15 до 60 секунд, и по умолчанию это 60.

Демон Eyesome спит много часов, пока не начнется закатный переход. Обратный переход восхода солнца — закатный переход постепенно снижает яркость экрана (и по желанию гамму тоже), чтобы это было незаметно. Рекомендуемо 90 минут до заката, но вы можете установить любое время, которое захотите.

Во время закатного перехода гамма может быть увеличена. Например, красная гамма может быть установлена 1.0 в дневное время и 1.2 в ночное время для уменьшения нагрузки на глаза. Синяя гамма, в свою очередь, может быть установлена 1.0 в дневное время и 0.8 в ночное время, чтобы она уменьшалась вместо этого.

Чтобы уменьшить нагрузку на ресурсы, Eyesome спит весь период между переходами восхода и заката. Есть одноразовые исключения при возобновлении после спящего режима или горячем подключении внешних мониторов. Это зависит от того, где вы живете и времени года, но среднее время сна будет 12 часов.

Вы можете скачать Eyesome с Github


Оригинальный пост от 2017 года

Введение

Это решении на bash, не требующее установки дополнительных программ. Оно требует подключения к Интернету (если вы читаете это, у вас оно есть) для автоматического получения времени восхода и заката каждого дня. Оно предоставляет удобный экран настройки. Оно автоматически запускается с cron и не требует взаимодействия с пользователем.

Этот ответ разбит на несколько частей

  • Автоматически получать время восхода и захода каждый день с помощью cron
  • Настройте яркость дисплея и время перехода
  • Основной скрипт для регулировки яркости в зависимости от времени дня
  • Автоматически запускать display-auto-brightness при каждом запуске с помощью cron
  • Мгновенное/прозрачное регулирование яркости при возврате из спящего режима
  • Резюме

Автоматически получать время восхода и захода каждый день с помощью cron

Существует множество веб-сайтов для отчета времени восхода и заката для вашего местоположения. Этот скрипт использует (https://www.timeanddate.com/), который давно является известным сайтом.

С мощностями sudo отредактируйте файл /usr/local/bin/sun-hours и вставьте это:

#!/bin/bash

# Вызывается ежедневно из /etc/cron.daily/sun-hours
while true; do

### "-q" = тихо, "-O-" вывод в pipe
echo $(wget -q -O- https://www.timeanddate.com/sun/canada/edmonton | grep -oE 'Sunrise Today.{35}' | awk -F\> '{print $3}' | tr --delete "<") > /tmp/sunrise
echo $(wget -q -O- https://www.timeanddate.com/sun/canada/edmonton | grep -oE 'Sunset Today.{35}' | awk -F\> '{print $3}' | tr --delete "<") > /tmp/sunset

## Если сеть не работает, файлы будут иметь размер в один байт
size1=$(wc -c < /tmp/sunrise)
size2=$(wc -c < /tmp/sunset)

if [ $size1 -gt 1 ] && [ $size2 -gt 1 ] ; then
    cp /tmp/sunrise /usr/local/bin/sunrise
    cp /tmp/sunset  /usr/local/bin/sunset
    chmod 666 /usr/local/bin/sunrise
    chmod 666 /usr/local/bin/sunset
    rm /tmp/sunrise
    rm /tmp/sunset
    exit 0
else
    logger "/etc/cron.daily/sun-hours: Сеть не работает. Ждем 5 минут перед повторной попыткой."
    sleep 300
fi

done

Перед сохранением скрипта замените два вхождения /canada/edmonton вашей страной и городом. Посетите сайт www.timeanddate.com, чтобы узнать точное имя или номер. Например, “Париж, США” имеет десятки имен, поэтому имена содержат номер, такой как /worldclock/@5205082 для “Париж, PA США”.

Используйте cron для запуска скрипта sun-hours каждый день

С мощностями sudo отредактируйте файл /etc/cron.daily/sun-hours и вставьте это:

#!/bin/sh
#
# Каждый день /etc/cron.daily/sun-hours получит время восхода и заката.

sleep 60 # дайте время для подключения к сети.
/usr/local/bin/sun-hours

Отметьте оба файла как исполняемые с помощью sudo chmod a+x ___/sun-hours, где “___” — это директория для каждого файла.

Используйте Conky, чтобы следить за изменениями времени рассвета / заката каждый день

Conky — популярный инструмент для мониторинга вашей системы. Вот команды для отображения времени рассвета, заката и установки яркости:

${color orange}${voffset 2}${hr 1}
${color}${goto 5}Day: ${color green}${execpi 300 cat /usr/local/bin/sunrise}  ${color}Night: ${color green}${execpi 300 cat /usr/local/bin/sunset}  ${color}Level: ${color green}${execpi 10 cat cat /sys/class/backlight/intel_backlight/brightness}
${color orange}${voffset 2}${hr 1}

Вот как это выглядит:

display-auto-brightness conky

Примечание: этот код Conky использует intel_backlight, который вам нужно изменить в зависимости от вашего адаптера дисплея, как описано в разделах ниже.

Настройка яркости дисплея и времени перехода

Вы не хотите, чтобы ваш дисплей переходит к полной яркости на восходе и к полной тусклости на закате. Нужен период перехода. Кроме того, необходимо создать файл конфигурации для записи переменных максимальной и минимальной яркости. Это экран настройки:

display-auto-brightness-config

Экран построен с использованием стандартной команды zenity, и поэтому существующие значения отображаются в метках с меткой “(значение)”, и вы вводите новые значения при необходимости. В противном случае существующие файлы сохраняются, когда новые значения пусты.

Замените intel_backlight вашим драйвером дисплея, если другой. Чтобы узнать ваше имя, используйте: ls /sys/class/backlight/*/brightness.

С мощностями sudo создайте файл /usr/local/bin/auto-brightness-config и вставьте в него этот код:

#!/bin/bash

# Чтение скрытого файла конфигурации с записями, разделенными " " в массив
IFS=' ' read -ra CfgArr < /usr/local/bin/.auto-brightness-config

# Форма Zenity с текущими значениями в метке ввода
# потому что инициализация нескольких полей ввода не поддерживается
output=$(zenity --forms --title="Конфигурация автоматической яркости дисплея" \
        --text="Введите новые настройки или оставьте поля пустыми, чтобы сохранить (существующие) настройки" \
   --add-entry="/sys/class/backlight/??????/brightness драйвер : (${CfgArr[0]})" \
   --add-entry="Максимальная яркость дисплея в дневное время : (${CfgArr[1]})" \
   --add-entry="Переходные минуты после восхода до максимума : (${CfgArr[2]})" \
   --add-entry="Минимальная яркость дисплея в ночное время : (${CfgArr[3]})" \
   --add-entry="Переходные минуты до заката : (${CfgArr[4]})")

IFS='|' read -a ZenArr <<<$output # Разделение записей zenity, разделенных "|", на элементы массива

# Обновление непустых записей массива zenity в массив конфигурации
for i in ${!ZenArr[@]}; do
    if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]} ; fi
done

# Запись скрытого файла конфигурации с использованием массива (поля автоматически разделены " ")
echo "${CfgArr[@]}" > /usr/local/bin/.auto-brightness-config

Отметьте файл как исполняемый, используя:

chmod a+x /usr/local/bin/auto-brightness-config

Основная программа display-auto-brightness

С мощностями sudo создайте файл /usr/local/bin/display-auto-brightness и вставьте в него этот код:

#!/bin/bash

# ИМЯ: display-auto-brightness
# ПУТЬ: /usr/local/bin
# ОПИСАНИЕ: Устанавливает яркость дисплея на основе мин/макс значений, времени восхода/заката и переходных минут.
# ВЫЗОВ: Вызывается из cron при запуске системы с опцией @reboot.
# ДАТА: 17 февраля 2017. Изменено: 2 декабря 2017.

# ПРИМЕЧАНИЕ: Спите только 1 минуту, чтобы изменения яркости дисплея были постепенными.
# Конфигурационный файл может измениться в любое время, поэтому переменные перечитываются при пробуждении.
# Файл поддерживается скриптом /usr/local/bin/auto-brightness-config.

# Время восхода и заката получено из www.dateandtime.com с использованием
# скрипта /usr/local/bin/sun-hours. Скрипт вызывается из cron с использованием
# /etc/cron.daily/cron-daily-sun-hours. Переменные хранятся в формате am/pm
# в /usr/local/bin/sunrise и /usr/local/bin/sunset.

# При приостановке в 6 утра может быть темно с настройкой 300. При
# возобновлении в 16:30 может быть полноценное солнце, и настройка
# должна быть 2000. Требуется от 1 до 59 секунд, чтобы отрегулировать яркость
# экрана с резким скачком яркости. Чтобы это исправить, создайте команду
# завершение спящего режима во время приостановки с помощью скрипта
# /lib/systemd/system-sleep/display-auto-brightness.

# TODO: Добавить поддержку внешних мониторов, подключенных через HDMI / DisplayPort.
# xrandr --output HDMI-0  --brightness .799
# xrandr --output DP-1-1  --brightness 1.15

if [[ $(id -u) != 0 ]]; then # требуется root полномочия для вызова этого скрипта
    echo display-auto-brightness должен быть вызван с sudo полномочиями
    exit 1
fi

# глобальная переменная
LastSetting=""

function set-and-sleep {
    if [[ "$1" != "$LastSetting" ]]; then
        sudo sh -c "echo $1 | sudo tee $backlight"
        echo "$1" > "/tmp/display-current-brightness"
        LastSetting="$1"
    fi
    sleep 60
}  

re="^[0-9]+$"   # регулярное выражение для валидных чисел

function calc-level-and-sleep {
    # Параметры: $1 = количество минут для общего перехода
    # $2 = количество секунд на переход

    secTotal=$(( $1 * 60 )) # Преобразовать общее количество минут перехода в секунды
    Adjust=$( bc <<< "scale=6; $transition_spread * ( $2 / $secTotal )" )
    Adjust=$( echo $Adjust | cut -f1 -d"." ) # Усечь число до целого

    if ! [[ $Adjust =~ $re ]] ; then
        Adjust=0   # Когда мы приближаемся к последней минуте, $Adjust может быть нечисловым
    fi

    calc_bright=$(( $min_bright + $Adjust ))
    set-and-sleep "$calc_bright"
}

while true ; do

    # Хотя переменные меняются раз в сутки, между перезагрузками могут пройти недели.
    sunrise=$(cat /usr/local/bin/sunrise)
    sunset=$(cat /usr/local/bin/sunset)

    # Прочитать скрытый файл конфигурации с записями, разделенными " " в массив
    IFS=' ' read -ra CfgArr < /usr/local/bin/.auto-brightness-config
    backlight="/sys/class/backlight/${CfgArr[0]}/brightness"
    max_bright="${CfgArr[1]}"
    after_sunrise="${CfgArr[2]}"
    min_bright="${CfgArr[3]}"
    before_sunset="${CfgArr[4]}"

    # Текущие секунды
    secNow=$(date +"%s")
    secSunrise=$(date --date="$sunrise today" +%s)
    secSunset=$(date --date="$sunset today" +%s)

    # Сейчас ночь?
    if [ "$secNow" -gt "$secSunset" ] || [ "$secNow" -lt "$secSunrise" ]; then
        # МИНИМАЛЬНОЕ: после заката или до восхода ночная настройка
        set-and-sleep "$min_bright"
        continue
    fi

    # Мы где-то между восходом и закатом
    secMaxCutoff=$(( $secSunrise + ( $after_sunrise * 60 ) ))
    secMinStart=$((  $secSunset  - ( $before_sunset * 60 ) ))

    # Сейчас полная светлая часть дня?
    if [ "$secNow" -gt "$secMaxCutoff" ] && [ "$secNow" -lt "$secMinStart" ]; then
        # МАКСИМУМ: после восхода переход И до ночного перехода
        set-and-sleep "$max_bright"
        continue
    fi

    # Дневное - ночное = переходные уровни яркости
    transition_spread=$(( $max_bright - $min_bright ))

    # Мы между восходом и полной яркостью?
    if [ "$secNow" -gt "$secSunrise" ] && [ "$secNow" -lt "$secMaxCutoff" ]; then
        # Текущее время - Восход = прогресс через переход
        secPast=$(( $secNow - $secSunrise ))
        calc-level-and-sleep $after_sunrise $secPast
        continue
    fi

    # Мы между началом затемнения и заходом солнца (полное затемнение)?
    if [ "$secNow" -gt "$secMinStart" ] && [ "$secNow" -lt "$secSunset" ]; then
        # Закат - Текущее время = прогресс через переход
        secBefore=$(( $secSunset - $secNow ))
        calc-level-and-sleep $before_sunset $secBefore
        continue
    fi

    # На этом этапе яркость была установлена вручную с помощью этой программы
    # или ровно в тестовой точке, затем она изменится в следующую минуту, так что не проблема.
    sleep 60 # сброс яркости раз в минуту.

done # Конец бесконечного цикла

Отметьте файл как исполняемый, используя:

chmod a+x /usr/local/bin/display-auto-brightness

ПРИМЕЧАНИЕ: Неудачно пересмотрено 26 августа 2017 года, чтобы исправить ошибку, когда программа останавливалась, когда последнее значение яркости было равно минимальной или максимальной яркости, и текущее значение корректировки минуты пусто (ноль). Исправлено успешно 2 декабря 2017 года, но не опубликовано до 17 февраля 2018 года. Упс!

Автоматически запускайте display-auto-brightness при каждом запуске с помощью cron

Cron используется для запуска основного приложения при каждом запуске. Создайте файл /etc/cron.d/display-auto-brightness с sudo и скопируйте в него это:

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
@reboot   root    /usr/local/bin/display-auto-brightness

#Мгновенная регулировка яркости при возобновлении из спящего режима

Вы можете поставить компьютер на паузу в 6 утра, когда оно будет до восхода солнца и ваша настройка будет на уровне 300. Вы можете возобновить в 4 часа дня, когда солнце яркое и настройка должна быть 2000, но вам придется ждать от 1 до 59 секунд, чтобы display-auto-brightness сбросил дисплей. Когда дисплей сбрасывается, изменение является резким. Для этого нужен скрипт systemd. Создайте файл /lib/systemd/system-sleep/display-auto-brightness, содержащий:

#!/bin/sh

# ИМЯ: display-auto-brightness
# ПУТЬ: /lib/systemd/system-sleep/
# ОПИСАНИЕ: Перезапуск яркости дисплея при возобновлении из спящего режима
# ВЫЗОВ: Автоматически вызывается, когда система засыпает и просыпается
# ДАТА: август 2017. Изменено: 10 июня 2018.

# ПРИМЕЧАНИЕ: Дает мгновенную регулировку яркости дисплея вместо ожидания от 1 до 59 секунд.

logger -t "logger -t "test" "\$0=$0, \$1=$1, \$2=$2" test" "\$0=$0, \$1=$1, \$2=$2"

case $1/$2 in
  pre/*)
    echo "/lib/systemd/system-sleep/display-auto-brightness: Переходим в $2..."
    ;;
  post/*)
    # 28 марта 2018 На AW17R3 этот скрипт работает слишком быстро
    sleep 2

    echo "/lib/systemd/system-sleep/display-auto-brightness: Возобновление из $2..."

    # Найдите запущенные процессы дерева, содержащие "display-auto" И "sleep"
    ProgramTree=$(pstree -g -p | grep display-auto | grep sleep)
    # echo ниже выведет в /var/log/syslog. Закомментировать с #, чтобы подавить
    echo "pstree -g -p | grep display-auto | grep sleep"
    echo "============================================="
    echo "$ProgramTree"

    # извлеките идентификатор программы sleep внутри `pstree`. например, нам нужен "16621" ниже:
    # |-cron(1198,1198)---cron(1257,1198)---sh(1308,1308)---display-auto-br(1321,1308)---sleep(16621,1308)
    pID=$(echo "$ProgramTree" | cut -f 6 -d '(' )
    pID=$(echo "$pID" | cut -f1 -d",")

    kill $pID  # убить команду сна, чтобы заставить экран яркости регулироваться немедленно
    rm /tmp/display-current-brightness
    echo "display-auto-brightness: sleep pID: '$pID' был убит."
    ;;
esac

Отметьте файл как исполняемый, используя:

chmod a+x /lib/systemd/system-sleep/display-auto-brightness

Резюме

Отображение текущего уровня яркости в системном лотке

В дополнение к примеру Conky, представленному ранее, indicator-sysmonitor вы можете отображать текущую яркость в системном лотке через bash:

display-auto-brightness systray

В этом системном лотке пример яркость установлена на 418, и остается около 20 минут до захода солнца. На закате значение будет 250, а полная дневная яркость 1200. На этом компьютере intel_backlight=4882 возможна, но, если вы находитесь в помещении с открытыми шторами, экран подобен взгляду на солнце.

Индикатор системного трея настраивается с использованием этого кода:

#!/bin/bash

# UPDT: 30 мая 2018 - Единство с новым многократным таймером и старым таймером блокировки экрана.
#       6 июля 2020 - Новый процент солнечного света eyesome.

if [ -f ~/.lock-screen-timer-remaining ]; then
    text-spinner
    Spinner=$(cat ~/.last-text-spinner) # прочитать последний использованный текстовое спиннер
    String=$(cat ~/.lock-screen-timer-remaining)
    systray="$Spinner  $String"
else
    systray=""
fi

if [ -f /usr/local/bin/.eyesome-percent ]; then
    Brightness=$(cat /usr/local/bin/.eyesome-percent)
    systray="$systray  eyesome: $Brightness"
else
    systray="$systray  eyesome: OFF"
fi

# Ниже для AU ответа: https://askubuntu.com/questions/1024866/is-it-possible-to-show-ip-address-on-top-bar-near-the-time
# default_interface=$(route -n | awk '$1 == "0.0.0.0" {print $8; exit}')
# ip_address=$(ifconfig "$default_interface" | awk 'sub(/.* inet addr:/, "") {print $1}')
# systray="$systray  $ip_address"

echo "$systray" # sysmon-indidicator выведет строку echo в системный лоток для нас.

exit 0

Этот Вопрос и Ответ (В Ubuntu Unity, могу я отобразить вывод скрипта bash в области системного лотка?) описывает, как настроить indicator-sysmonitor.

##Будущие улучшения

  • Перенос скриптов bash для этого ответа на github
  • Добавление поддержки для внешних мониторов с использованием xrandr
  • Добавление поддержки по большей красноты/меньшей синевы с использованием xrandr

Я только что написал программу, которая почти делает то, что вы ищете.
Она изменяет яркость экрана на основе изображений, снятых вашей веб-камерой для получения окружающей яркости. Вы можете самостоятельно выбрать интервал для обнаружения яркости и скорость затемнения.

https://github.com/Wandersalamander/Dimmer

Этот скрипт регулирует яркость подсветки дисплея на основании данных с изображения веб-камеры.
Возможно, это поможет вам решить вашу проблему.

https://github.com/unxed/brightness.sh/blob/master/backlight.sh

Я использую этот инструмент: https://github.com/digitaltrails/vdu_controls

Это однофайловый скрипт на Python и имеет графический интерфейс для настройки. Работает хорошо.

Если у вас нет доступа к Интернету, вы можете воспользоваться hdate:

hdate -s -l N50 -L E14 -z2

Выход:

Среда, 26 июня 2019, 23 Сиван 5779

восход: 04:55

закат: 21:17

-s закат восход

-l -L Высота и широта Праги (50°05′N 14°25′E)

-z зона SELC=+2

вы можете использовать f.lux, если вам нужен графический интерфейс

https://justgetflux.com/linux.html

Ответ или решение

Автоматическое регулирование яркости дисплея на основе времени восхода и заката солнца представляет собой интересную задачу, которая требует совмещения нескольких технологий и методов. Это позволяет пользователю минимизировать нагрузку на глаза и экономить энергию. Давайте рассмотрим теоретические аспекты, примеры реализации и их применение на практике.

Теория

Основная идея автоматического регулирования яркости дисплея заключается в динамической адаптации освещения на экране, исходя из естественного освещения окружающей среды. Это достигается путем определения времени восхода и заката солнца для конкретной геолокации и изменения яркости экрана в соответствии с этими временами.

Пример реализации

Существует несколько программных решений, которые позволяют достичь такой автоматизации:

  1. Eyesome – Это скрипт на bash, который автоматически регулирует яркость экрана в зависимости от времени восхода и заката солнца, полученного из интернета. Программа работает в фоновом режиме, используя xrandr для управления яркостью.

  2. Dimmer – Программа использует веб-камеру для определения яркости окружающей среды и автоматически регулирует яркость экрана. Пользователь может самостоятельно настроить интервалы и скорость затемнения.

  3. VDU Controls – С помощью этого скрипта на Python можно управлять настройками дисплея через GUI, что делает его удобным для пользователей, предпочитающих визуальные средства настройки.

  4. Redshift и f.lux – Эти программы значительно изменяют температуру цвета экрана, чтобы снизить нагрузку на зрение. Несмотря на их удобство, они в основном меняют цветовой баланс, а не яркость.

Для получения актуального времени восхода и заката солнца можно использовать веб-сервисы, такие как https://www.timeanddate.com/, а также альтернативные методы, такие как использование утилиты hdate, чтобы вычислять солнечные события на базе геолокации.

Применение

На практике вы можете интегрировать одно из предложенных решений в свой рабочий процесс. Например, если у вас есть базовые навыки работы с Linux и написанием скриптов, вы можете использовать уязвимости системных вызовов, как это сделано в скрипте для cron, который автоматически обновляет время восхода и заката ежедневно.

Для базовой реализации рекомендуется использовать месте инфраструктуры cron, чтобы запускать необходимые скрипты при загрузке системы или ежесуточно для обновления данных.

Во время тестирования важно учитывать не только ясность и точность изменений яркости, но и ее постепенность. Это может быть достигнуто путем настройки времени перехода между состояниями дня и ночи, чтобы глаза успевали адаптироваться к изменениям.

Заканчивая на этом анализ, следует упомянуть о ресурсоемкости решений. К примеру, скрипты, которые работают с веб-камерой, могут потреблять больше системных ресурсов, чем решения, работающие на основе данных о восходе и закате солнца.

Таким образом, вопрос автоматического регулирования яркости дисплея можно решить несколькими способами, каждый из которых имеет свои преимущества и особенности применения. Выбор метода зависит от предпочтений пользователя, уровня его технической подготовленности и специфики использования компьютера. Поддерживая оптимальные условия окружающего света, вы создаете более комфортные условия для работы и отдыха, снижая нагрузку на зрение и интерестностями в восприятии информации на экране.

Оцените материал
Добавить комментарий

Капча загружается...