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


10

У Ask Ubuntu є подібні запитання та відповіді, які вказують на ці рішення:

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

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

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

Відповіді:


7

Оновлений пост від 2019 року - Eyesome

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

На сході сонця (час автоматично отримується з Інтернету щодня), яскравість екрана (і, можливо, також гамма) регулюється поступово. Поступова настройка визначена вами, але для мене працює 120 хвилин. Щоб налаштування залишалися непомітними, встановіть інтервал сну між налаштуваннями. Десь між 15 і 60 секундами, мабуть, найкраще, а за замовчуванням - 60.

Окулярний демон демон спить багато годин, поки не починається захід переходу. Навпаки до переходу до сходу сонця, захід заходу поступово зменшує яскравість екрана (і, можливо, гамма), тому він непомітний. Рекомендується за 90 хвилин до заходу сонця, але ви можете встановити будь-який період, який вам подобається.

Під час переходу на захід сонця гамма може визначатися для збільшення. Наприклад, червону гаму можна визначити як 1,0 вдень та 1,2 вночі для зменшення напруги очей. Блакитна гамма в свою чергу може бути визначена як 1,0 вдень і .8 вночі, тому вона замість цього зменшиться.

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

Ви можете завантажити Eyesome з Github


Оригінальна публікація від 2017 року

Вступ

Це баш-рішення без необхідності встановлювати додаткові програми. Потрібен підключення до Інтернету (якщо ви це читаєте, у вас є таке), щоб автоматично отримувати час сходу і заходу кожного дня. Він забезпечує зручний екран налаштування. Він запускається автоматично з 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

Примітка. Цей код Conky використовує intel_backlightнеобхідні зміни, залежно від адаптера дисплея, як описано в розділах нижче.

Налаштуйте параметри яскравості та час переходу

Ви не хочете, щоб ваш дисплей перейшов на повну яскравість на сході сонця і повну тьмяність на заході сонця. Потрібен перехідний період. Додатково потрібен файл конфігурації для запису змінних для повної яскравості та повного затемнення. Це екран конфігурації:

display-auto-яскравість-config

Екран побудований за допомогою стандартної команди zenity і як такі існуючі значення відображаються на мітках з тегом "(value)" і ви вводите нові значення, якщо потрібно. Інакше наявні файли зберігаються, коли нові значення порожні.

Замініть 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. Ви можете відновити його о 16:00, коли сонце яскраве, а налаштування має бути 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 через bash:

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

У цьому прикладі яскравості встановлено яскравість 418і це приблизно за 20 хвилин до заходу сонця. На заході ця величина становитиме 250, а денна повна яскравість - 1200. На цій машині можливий інтелектуальний підсвічування = 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-скриптів для цієї відповіді на github
  • Додавання підтримки для використання зовнішніх моніторів xrandr
  • Додавання підтримки для більш червоного / менш синього використання xrandr

Чудовий пост, але чи можете ви допомогти мені, як потрапити на екран, щоб налаштувати перехід тощо?
Марек Урбанович

@MU Дякую за добрий коментар. Я перебуваю в процесі оновлення документа із змінами призупинення / відновлення, написаними пару місяців тому. Крім того, я скоро напишу гібридний код WSL (підсистема Windows для Linux). Я також хотів би вирішити ваші проблеми в новому документі. У вас є проблеми зі створенням /usr/local/bin/auto-brightness-configсценарію? У вас виникають проблеми з ідентифікацією імені /sys/class/backlight/??????/brightnessдрайвера? Я хотів би зробити це чудовою корисністю, і ваше питання важливе.
WinEunuuchs2Unix

Я просто не маю уявлення на основі вашої публікації, як отримати конфігурацію автоматичної Brithness Display
Marek Urbanowicz

@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


1
Здається чудовою ідеєю для більшості людей - крім тих, хто з нас маскує стрічку над веб-камерою ...
WinEunuuchs2Unix

1
@ WinEunuuchs2Unix Навіть для 'заінтересованих' із стрічкою над кулачком це може бути чудово! Вам не потрібно накривати веб-камеру чорною стрічкою, щоб зробити знімки марними - аркуш білого паперу досягає майже такого ж ефекту анонімності, а ще зберігає здатність камери вимірювати яскравість кімнати. Насправді аркуш паперу насправді міг би покращити його, оскільки він би вимірював рівномірно кількість світла, яке насправді потрапляє на камеру, звук якого буде приблизно таким же, як і кількість, що потрапляє на екран монітора, якщо камера знаходиться прямо над нею. =)
Вініцій М


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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.