Automatycznie dostosuj jasność wyświetlacza na podstawie wschodu i zachodu słońca

10

Istnieją podobne pytania i odpowiedzi w Ask Ubuntu, które wskazują na następujące rozwiązania:

ale albo wymagają ręcznego wprowadzenia wschodu i zachodu słońca, albo po prostu dostosowują balans kolorów i dodają więcej czerwieni w nocy.

Szukam rozwiązania, które automatycznie uzyskuje godziny wschodu i zachodu słońca każdego dnia i fizycznie dostosowuje jasność wyświetlacza. Ponadto chcę efekt przejścia w okresie od 60 do 120 minut, więc nie zauważam zmiany wyświetlania.

Ponowna konfiguracja w pochmurne dni (przyciemnienie na zewnątrz) lub gdy słońce zachodzi między dwoma trzypiętrowymi budynkami zamiast ich dachów (jaśniej przed zachodem słońca) powinno być szybkim i łatwym procesem.

WinEunuuchs2Unix
źródło

Odpowiedzi:

7

Zaktualizowany post z 2019 roku - Eyesome

Eyesome to skrypt bashowy działający jako demon i śpiąc przez większość czasu 24/7. Automatycznie dostosowuje jasność ekranu (i opcjonalnie również gamma) do wyświetlacza laptopa za pośrednictwem interfejsu sprzętowego i maksymalnie dwóch innych monitorów za pomocą oprogramowania sterującego xrandr.

O wschodzie słońca (czas jest automatycznie pobierany z Internetu każdego dnia) jasność ekranu (i opcjonalnie także gamma) jest stopniowo dostosowywana. Stopniowe dostosowanie jest definiowane przez Ciebie, ale dla mnie działa 120 minut. Aby regulacje pozostały niezauważalne, ustaw odstęp uśpienia między regulacjami. Gdziekolwiek od 15 do 60 sekund jest prawdopodobnie najlepsze, a wartość domyślna to 60.

Eyesome demon śpi wiele godzin, aż rozpocznie się przejście na zachód słońca. Odwrotnie niż przejście na wschód słońca, przejście na zachód słońca stopniowo zmniejsza jasność ekranu (i opcjonalnie również gamma), więc jest niezauważalne. Zalecane jest 90 minut przed zachodem słońca, ale możesz ustawić dowolny okres.

Podczas zachodu słońca można zdefiniować gamma, aby wzrosło. Na przykład czerwony gamma można zdefiniować jako 1,0 w ciągu dnia i 1,2 w nocy, aby zmniejszyć zmęczenie oczu. Niebieska gamma z kolei może być zdefiniowana jako 1,0 w ciągu dnia i .8 w nocy, więc zamiast tego spadnie.

Aby zmniejszyć zasoby, oczy śpi przez cały okres między zachodem a wschodem słońca. Istnieją pewne wyjątki od wznowienia działania po zawieszeniu lub podłączeniu na gorąco monitorów zewnętrznych. To zależy od tego, gdzie mieszkasz i pory roku, ale średni sen wyniesie 12 godzin.

Możesz pobrać Eyesome z Github


Oryginalny post z 2017 roku

Wprowadzenie

To bashowe rozwiązanie bez potrzeby instalowania dodatkowych programów. Wymaga połączenia z Internetem (jeśli go czytasz), aby automatycznie otrzymywać wschody i zachody słońca każdego dnia. Zapewnia przyjazny dla użytkownika ekran konfiguracji. Uruchamia się automatycznie croni nie wymaga interakcji użytkownika.

Ta odpowiedź jest podzielona na wiele części

  • Automatycznie otrzymuj wschody i zachody słońca każdego dnia dzięki cron
  • Skonfiguruj ustawienia jasności i czas przejścia
  • Główny skrypt do dostosowania jasności w zależności od pory dnia
  • Automatycznie włączaj automatyczną jasność wyświetlacza przy każdym uruchomieniu cron
  • Natychmiastowa / przejrzysta regulacja jasności wznawiana od zawieszenia
  • Podsumowanie

Automatycznie otrzymuj wschody i zachody słońca każdego dnia dzięki cron

Istnieje wiele stron internetowych, które zgłaszają godziny wschodu i zachodu słońca dla Twojej lokalizacji. Ten skrypt używa ( https://www.timeanddate.com/ ), który od dawna jest dobrze znaną witryną.

Z sudo power edytuj plik /usr/local/bin/sun-hoursi wklej to:

#!/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

Przed zapisaniem skryptu zastąp dwa wystąpienia /canada/edmontonwłasnym krajem i miastem. Odwiedź witrynę, www.timeanddate.comaby uzyskać dokładną nazwę lub numer. Na przykład „Paris, USA” ma dziesiątki nazw, więc będą zawierały numery takie jak /worldclock/@5205082„Paris, PA USA”.

Używaj crona do uruchamiania skryptu godzin słonecznych każdego dnia

Z sudo power edytuj plik /etc/cron.daily/sun-hoursi wklej to:

#!/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

Oznacz oba pliki jako pliki wykonywalne, sudo chmod a+x ___/sun-hoursgdzie „___” to katalog dla każdego pliku.

Użyj Conky do monitorowania zmian wschodu / zachodu słońca każdego dnia

Conky jest popularnym narzędziem do monitorowania twojego systemu. Oto polecenia, aby wyświetlić ustawienia wschodu, zachodu i zachodu słońca:

${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}

Tak to wygląda:

conky z automatyczną jasnością wyświetlacza

Uwaga: ten kod Conky używa, intel_backlightktóre należy zmienić w zależności od karty graficznej, jak opisano w poniższych sekcjach.

Skonfiguruj ustawienia jasności i czas przejścia

Nie chcesz, aby wyświetlacz zmienił się na pełną jasność po wschodzie słońca i pełną ciemność po zachodzie słońca. Potrzebny jest okres przejściowy. Dodatkowo plik konfiguracyjny jest wymagany do rejestrowania zmiennych dla pełnej jasności i pełnego przyciemnienia. To jest ekran konfiguracji:

display-auto-jasność-config

Ekran jest zbudowany przy użyciu standardowego polecenia zenity i jako takie istniejące wartości są pokazane na etykietach ze znacznikiem „(wartość)” i w razie potrzeby wpisujesz nowe wartości. W przeciwnym razie istniejące pliki zostaną zachowane, gdy nowe wartości będą puste.

Zamień intel_backlightna sterownik ekranu, jeśli jest inny. Aby dowiedzieć się imię użycie: ls /sys/class/backlight/*/brightness.

Używając mocy sudo, utwórz plik /usr/local/bin/auto-brightness-configi wklej ten kod:

#!/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

Oznacz plik jako wykonywalny, używając:

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

Główny program display-auto-brightness

Używając mocy sudo, utwórz plik /usr/local/bin/display-auto-brightnessi wklej ten kod:

#!/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

Oznacz plik jako wykonywalny, używając:

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

UWAGA: Bezskutecznie zmieniony 26 sierpnia 2017 r. W celu usunięcia błędu, w którym program zatrzymywał się, gdy ostatni poziom jasności był równy minimalnej lub maksymalnej jasności, a wartość regulacji bieżącej minuty jest pusta (zero). Pomyślnie naprawiono 2 grudnia 2017 r., Ale nie opublikowano do 17 lutego 2018 r. Ojej!

Automatycznie włączaj automatyczną jasność wyświetlacza przy każdym uruchomieniu cron

Cron służy do uruchamiania głównej aplikacji przy każdym rozruchu. Utwórz plik /etc/cron.d/display-auto-brightnessz uprawnieniami sudo i skopiuj w tym:

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

Natychmiastowa regulacja jasności wznawiana od zawieszenia

Możesz zawiesić komputer o 6 rano, kiedy słońce wschodzi, a twoje ustawienie to 300. Możesz wznowić go o 16:00, gdy słońce jest jasne i ustawienie powinno wynosić 2000, ale musisz poczekać od 1 do 59 sekund, display-auto-brightnessaby zresetować wyświetlacz. Gdy wyświetlacz resetuje się, zmiana jest dramatyczna. Aby rozwiązać ten problem, systemdpotrzebny jest skrypt. Utwórz plik /lib/systemd/system-sleep/display-auto-brightnesszawierający:

#!/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

Oznacz plik jako wykonywalny, używając:

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

Podsumowanie

Wyświetlany poziom jasności to systray

Oprócz przedstawionego wcześniej przykładu Conky , wskaźnik-sysmonitor można wyświetlać bieżącą jasność w systray poprzez bash:

system automatycznej jasności wyświetlacza

W tej przykładowej systray ustawiono jasność na 418około 20 minut przed zachodem słońca. O zachodzie słońca wartość wyniesie 250, a dzienna pełna jasność wynosi 1200. Na tej maszynie możliwy jest intel_backlight = 4882, ale jeśli jesteś w pomieszczeniu z otwartymi zasłonami, ekran jest jak wpatrywanie się w słońce.

Wskaźnik systray jest konfigurowany przy użyciu tego kodu:

#!/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

To pytanie i odpowiedź ( czy BASH może wyświetlać się w pasku zadań jako wskaźnik aplikacji? ) Opisuje, jak skonfigurować wskaźnik-sysmonitor.

Przyszłe ulepszenia

  • Migracja skryptów bash dla tej odpowiedzi na github
  • Dodanie obsługi zewnętrznych monitorów za pomocą xrandr
  • Dodanie obsługi większej ilości czerwonych / mniej niebieskich przy użyciu xrandr
WinEunuuchs2Unix
źródło
Świetny post, ale czy możesz mi pomóc, jak wejść na ekran, aby skonfigurować przejście itp.?
Marek Urbanowicz
@MU Dziękujemy za miły komentarz. Jestem w trakcie przebudowy dokumentu za pomocą zmian Wstrzymaj / Wznów napisanych kilka miesięcy temu. Plus wkrótce napiszę kod hybrydowy WSL (Windows Subsystem for Linux). Chciałbym również zająć się twoimi obawami w nowym dokumencie. Czy masz problemy z tworzeniem /usr/local/bin/auto-brightness-configskryptu? Czy masz problemy ze zidentyfikowaniem /sys/class/backlight/??????/brightnessnazwy kierowcy? Chciałbym, aby było to świetne narzędzie, a twoje pytanie jest ważne.
WinEunuuchs2Unix
Po prostu nie mam pojęcia na podstawie Twojego posta, jak uzyskać konfigurację automatycznej Brithness Display
Marek Urbanowicz
@MU skopiuj powyższy kod /usr/local/bin/auto-brightness-configdo swojego /usr/local/binkatalogu w pliku o nazwie auto-brightness-config. Następnie z terminala zaznacz go jako wykonywalny chmod a+x /usr/local/bin/auto-brightness-config. Następnie uruchom skrypt z terminala, wpisując /usr/local/bin/auto-brightness-config. Możesz skonfigurować skrót do skryptu na pulpicie, aby uniknąć otwierania terminala i wpisywania nazwy skryptu.
WinEunuuchs2Unix
1
@dessert W końcu skonfigurowałem stronę github do eyesomenastępnego wcielenia display-auto-brightness: github.com/WinEunuuchs2Unix/eyesome. Będzie ona często aktualizowana w ciągu najbliższych kilku tygodni z dokumentacją i udoskonaleniami interfejsu.
WinEunuuchs2Unix
3

Właśnie napisałem program, który prawie robi to, czego szukasz. Zmienia jasność ekranu na podstawie zdjęć wykonanych przez kamerę internetową w celu uzyskania jasności otoczenia. Możesz samodzielnie wybrać przedział czasu, aby wykryć jasność i prędkość ściemniania.

https://github.com/Wandersalamander/Dimmer

wandersalamander
źródło
1
Brzmi jak świetny pomysł dla większości ludzi - z wyjątkiem tych z nas z taśmą maskującą do kamery internetowej ...
WinEunuuchs2Unix
1
@ WinEunuuchs2Unix Nawet dla „zainteresowanych” taśmą nad kamerą może być świetnie! Nie musisz przykrywać kamery internetowej czarną taśmą, aby uczynić zdjęcia bezużytecznymi - kawałek białego papieru osiąga prawie taki sam efekt anonimowości i nadal zachowuje zdolność aparatu do pomiaru jasności pomieszczenia. W rzeczywistości arkusz papieru mógłby go poprawić, ponieważ mierzyłby bardziej równomiernie ilość światła, które faktycznie pada na aparat, a dźwięk jest mniej więcej taki sam, jak ilość, która pada na ekran monitora, jeśli kamera znajduje się tuż nad nim. =)
Vinícius M
0

Jeśli nie masz dostępu do Internetu, możesz skorzystać z hdate:

hdate -s -l N50 -L E14 -z2

Wynik:

Wednesday, 26 June 2019, 23 Sivan 5779

sunrise: 04:55

sunset: 21:17

-s zachód słońca wschód słońca

-l -L Wysokość i szerokość geograficzna Pragi (50 ° 05′N 14 ° 25′E)

-z strefa SELC = + 2

kserostomus
źródło