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

10

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

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

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

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

WinEunuuchs2Unix
источник

Ответы:

7

Обновлено сообщение от 2019 - Eyesome

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

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

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

Во время заката можно определить увеличение гаммы. Например, красная гамма может быть определена как 1,0 в течение дня и 1,2 в течение ночи, чтобы уменьшить нагрузку на глаза. Синяя гамма, в свою очередь, может быть определена как 1,0 в течение дня и 0,8 в ночное время, поэтому она будет уменьшаться.

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

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


Оригинальное сообщение от 2017 года

Вступление

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

Этот ответ делится на несколько частей

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

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

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

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

#!/bin/bash

# Called daily from /etc/cron.daily/sun-hours
while true; do

### "-q"= quiet, "-O-" pipe output
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

## If network is down files will have one byte size
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: Network is down. Waiting 5 minutes to try again."
    sleep 300
fi

done

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

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

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

#!/bin/sh
#
# Each day /etc/cron.daily/sun-hours will get sunrise and sunset times.

sleep 60 # give time for network to come up.
/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}

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

автоматическая яркость дисплея

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

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

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

дисплей-авто-яркость-конфигурация

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

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

Используя полномочия sudo, создайте файл /usr/local/bin/auto-brightness-configи вставьте этот код:

#!/bin/bash

# Read hidden configuration file with entries separated by " " into array
IFS=' ' read -ra CfgArr < /usr/local/bin/.auto-brightness-config

# Zenity form with current values in entry label
# because initializing multiple entry data fields not supported
output=$(zenity --forms --title="Display Auto Brightness Configuration" \
        --text="Enter new settings or leave entries blank to keep (existing) settings" \
   --add-entry="/sys/class/backlight/??????/brightness driver : (${CfgArr[0]})" \
   --add-entry="Day time maximum display brightness : (${CfgArr[1]})" \
   --add-entry="Transition minutes after sunrise to maximum : (${CfgArr[2]})" \
   --add-entry="Night time minimum display brightness : (${CfgArr[3]})" \
   --add-entry="Transition minutes before sunset to minimum : (${CfgArr[4]})")

IFS='|' read -a ZenArr <<<$output # Split zenity entries separated by "|" into array elements

# Update non-blank zenity array entries into configuration array
for i in ${!ZenArr[@]}; do
    if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]} ; fi
done

# write hidden configuration file using array (fields automatically separated by " ")
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

# NAME: display-auto-brightness
# PATH: /usr/local/bin
# DESC: Set display brightness based on min/max values, sun rise/set time
#       and transition minutes.
# CALL: Called from cron on system startup with @reboot option.
# DATE: Feb 17, 2017. Modified: Dec 2, 2017.

# NOTE: Only sleep for 1 minute to make display brightness changes gradual.
#       Configuration file can change any time so variables reread when waking.
#       The file is maintained by /usr/local/bin/auto-brightness-config script.

#       Sunrise and sunset time obtained from www.dateandtime.com using
#       /usr/local/bin/sun-hours script. The script is called from cron using
#       /etc/cron.daily/cron-daily-sun-hours. Variables stored in am/pm format
#       in /usr/local/bin/sunrise and /usr/local/bin/sunset.

#       When suspending at 6 am it might be dark with setting at 300. When 
#       resuming at 4:30pm it might be full sun and setting needs to be 2000.
#       It will take between 1 and 59 seconds to adjust screen brightness with
#       sudden jump in brightness. To correct this create kill sleep command
#       during suspend with /lib/systemd/system-sleep/display-auto-brightness
#       script.

# TODO: Add support for external monitors connected via HDMI / DisplayPort.
#       xrandr --output HDMI-0  --brightness .799
#       xrandr --output DP-1-1  --brightness 1.15

if [[ $(id -u) != 0 ]]; then # root powers needed to call this script
    echo display-auto-brightness must be called with sudo powers
    exit 1
fi

# global variable
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]+$'   # regex for valid numbers

function calc-level-and-sleep {
    # Parms $1 = number of minutes for total transition
    #       $2 = number of seconds into transition

    secTotal=$(( $1 * 60 )) # Convert total transition minutes to seconds
    Adjust=$( bc <<< "scale=6; $transition_spread * ( $2 / $secTotal )" )
    Adjust=$( echo $Adjust | cut -f1 -d"." ) # Truncate number to integer

    if ! [[ $Adjust =~ $re ]] ; then
        Adjust=0   # When we get to last minute $Adjust can be non-numeric
    fi

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


while true ; do

    # Although variables change once a day it could be weeks between reboots.
    sunrise=$(cat /usr/local/bin/sunrise)
    sunset=$(cat /usr/local/bin/sunset)

    # Read hidden configuration file with entries separated by " " into array
    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]}"

    # Current seconds
    secNow=$(date +"%s")
    secSunrise=$(date --date="$sunrise today" +%s)
    secSunset=$(date --date="$sunset today" +%s)

    # Is it night time?
    if [ "$secNow" -gt "$secSunset" ] || [ "$secNow" -lt "$secSunrise" ]; then
        # MINIMUN: after sunset or before sunrise nightime setting
        set-and-sleep "$min_bright"
        continue
    fi

    # We're somewhere between sunrise and sunset
    secMaxCutoff=$(( $secSunrise + ( $after_sunrise * 60 ) ))
    secMinStart=$((  $secSunset  - ( $before_sunset * 60 ) ))

    # Is it full bright day time?
    if [ "$secNow" -gt "$secMaxCutoff" ] && [ "$secNow" -lt "$secMinStart" ]; then
        # MAXIMUN: after sunrise transition AND before nightime transition
        set-and-sleep "$max_bright"
        continue
    fi

    # Daytime - nightime = transition brightness levels
    transition_spread=$(( $max_bright - $min_bright ))

    # Are we between sunrise and full brightness?
    if [ "$secNow" -gt "$secSunrise" ] && [ "$secNow" -lt "$secMaxCutoff" ]; then
        # Current time - Sunrise = progress through transition
        secPast=$(( $secNow - $secSunrise ))
        calc-level-and-sleep $after_sunrise $secPast
        continue
    fi

    # Are we between beginning to dim and sunset (full dim)?
    if [ "$secNow" -gt "$secMinStart" ] && [ "$secNow" -lt "$secSunset" ]; then
        # Sunset - Current time = progress through transition
        secBefore=$(( $secSunset - $secNow ))
        calc-level-and-sleep $before_sunset $secBefore
        continue
    fi

    # At this stage brightness was set with manual override outside this program
    # or exactly at a testpoint, then it will change next minute so no big deal.
    sleep 60 # reset brightness once / minute.

done # End of forever loop

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

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

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

Запускать авто-яркость дисплея автоматически при каждой загрузке с 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

# NAME: display-auto-brightness
# PATH: /lib/systemd/system-sleep/
# DESC: Restart display brightness when resuming from suspend
# CALL: Automatically called when system goes to sleep and wakes up
# DATE: August 2017. Modified: June 10, 2018.

# NOTE: Gives instant display brightness adjustment instead of waiting 1 to 59 seconds.

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: Going to $2..."
    ;;
  post/*)
    # March 28, 2018 On AW17R3 this script runs too fast
    sleep 2

    echo "/lib/systemd/system-sleep/display-auto-brightness: Resuming from $2..."

    # Find running tree processes containing "display-auto" AND "sleep"
    ProgramTree=$(pstree -g -p | grep display-auto | grep sleep)
    # echo's below will print in /var/log/syslog. Comment out with # to suppress
    echo "pstree -g -p | grep display-auto | grep sleep"
    echo "============================================="
    echo "$ProgramTree"

    # extract sleep program ID within `pstree`. eg we would want "16621" below:
    # |-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  # kill sleep command forcing screen brightness to adjust immediately
    rm /tmp/display-current-brightness
    echo "display-auto-brightness: sleep pID: '$pID' has been killed."
    ;;
esac

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

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

Резюме

Текущий уровень яркости дисплея - systray

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

Авто-яркость дисплея

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

Индикатор systray настраивается с помощью этого кода:

#!/bin/bash

if [ -f ~/.lock-screen-timer-remaining ]; then
    text-spinner
    Spinner=$(cat ~/.last-text-spinner) # read last text spinner used
    Minutes=$(cat ~/.lock-screen-timer-remaining)
    systray=" $Spinner Lock screen in: $Minutes"
else
    systray=" Lock screen: OFF"
fi

if [ -f /tmp/display-current-brightness ]; then
    Brightness=$(cat /tmp/display-current-brightness)
    systray="$systray Brightness: $Brightness"
else
    systray="$systray Brightness: OFF"
fi

echo "$systray" # sysmon-indidicator will put echo string into systray for us.

exit 0

В этом разделе « Вопросы и ответы» ( Может ли BASH отображаться в systray в качестве индикатора приложения? ) Описывается, как настроить индикатор-sysmonitor.

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

  • Перенос сценариев bash для этого ответа на github
  • Добавление поддержки для внешних мониторов с помощью xrandr
  • Добавлена ​​поддержка более красного / менее синего с помощью xrandr
WinEunuuchs2Unix
источник
Отличный пост, но не могли бы вы помочь мне, как попасть в экран, чтобы настроить переход и т.д.?
Марек Урбанович
@MU Спасибо за ваш добрый комментарий. Я нахожусь в процессе обновления документа с изменениями Suspend / Resume, написанными пару месяцев назад. Кроме того, я скоро напишу гибридный код WSL (Windows Subsystem для Linux). Я бы тоже хотел обсудить ваши проблемы с новым документом. У вас проблемы с созданием /usr/local/bin/auto-brightness-configсценария? У вас проблемы с определением имени /sys/class/backlight/??????/brightnessводителя? Я хотел бы сделать это отличной утилитой, и ваш вопрос важен.
WinEunuuchs2Unix
Я просто не знаю, основываясь на вашем посте, как получить конфигурацию автоматического отображения на экране
Marek
@MU скопируйте приведенный выше код /usr/local/bin/auto-brightness-configв ваш /usr/local/binкаталог в файле с именем auto-brightness-config. Затем из терминала отметьте его как исполняемый chmod a+x /usr/local/bin/auto-brightness-config. Затем запустите скрипт из терминала, набрав /usr/local/bin/auto-brightness-config. Вы можете настроить ярлык на рабочем столе для скрипта, чтобы не открывать терминал и не вводить имя скрипта.
WinEunuuchs2Unix
1
@dessert Я наконец-то настроил страницу github для eyesomeследующего воплощения display-auto-brightness: github.com/WinEunuuchs2Unix/eyesome. В течение следующих нескольких недель он будет часто обновляться с документацией и доработками интерфейса.
WinEunuuchs2Unix
3

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

https://github.com/Wandersalamander/Dimmer

wandersalamander
источник
1
Звучит как отличная идея для большинства людей - за исключением тех из нас, у
кого есть
1
@ WinEunuuchs2Unix Даже для «заинтересованных» людей, которые держат ленту над камерой, это может быть здорово! Вам не нужно покрывать веб-камеру черной лентой, чтобы сделать снимки бесполезными - лист белой бумаги обеспечивает почти такой же эффект анонимности и при этом сохраняет способность камеры измерять яркость комнаты. Фактически, лист бумаги может реально улучшить его, поскольку он будет измерять более равномерное количество света, попадающего на камеру, и звук будет примерно таким же, как и количество, попадающее на экран монитора, если камера находится прямо над ним. =)
Vinícius M
0

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

hdate -s -l N50 -L E14 -z2

Вывод:

Wednesday, 26 June 2019, 23 Sivan 5779

sunrise: 04:55

sunset: 21:17

закат

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

-z зона SELC = + 2

xerostomus
источник