2019 年更新的帖子 - Eyesome

2019 年更新的帖子 - Eyesome

类似的问题和答案还有询问 Ubuntu指出以下解决方案:

但它们要么要求手动输入日出和日落时间,要么仅仅调整色彩平衡并在夜间添加更多的红色。

我正在寻找一种解决方案,可以自动获取每天的日出和日落时间并物理调整显示亮度。此外,我希望在 60 到 120 分钟的时间内实现过渡效果,这样我就不会注意到显示变化。

在阴天(外面较暗)或太阳恰好落在两栋三层建筑之间而不是屋顶上(日落前较亮)时重新配置应该是一个快速而简单的过程。

答案1

2019 年更新的帖子 - Eyesome

Eyesome 是一个作为守护进程运行的 bash 脚本,全天候大部分时间处于休眠状态。它通过硬件接口自动调整笔记本电脑显示屏的屏幕亮度(也可以选择调整伽玛值),并使用 xrandr 的软件控制最多调整另外两台显示器的屏幕亮度。

日出时(每天从互联网上自动获取时间),屏幕亮度(以及可选的伽玛)会逐渐调整。逐渐调整由您定义,但 120 分钟对我来说是合适的。为了使调整不引人注意,请在调整之间设置一个睡眠间隔。15 到 60 秒之间的任何值可能是最好的,默认值为 60。

Eyesome 守护进程会休眠数小时,直到日落过渡开始。与日出过渡相反,日落过渡会逐渐降低屏幕亮度(也可以选择降低伽玛值),因此不易察觉。建议在日落前 90 分钟进行,但您可以设置任何您喜欢的时间段。

在日落过渡期间,伽马值可能会被定义为增加。例如,红色伽马值在白天可能被定义为 1.0,在晚上可能被定义为 1.2,以减少眼睛疲劳。蓝色伽马值在白天可能被定义为 1.0,在晚上可能被定义为 .8,因此它会减少。

为了节省资源,eyesome 会在日落和日出之间的整个过渡期间处于休眠状态。从挂起状态恢复或热插拔外部显示器时有一次例外。这取决于您居住的地方和一年中的季节,但平均睡眠时间为 12 小时。

您可以下载Github 上的 Eyesome


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以获取确切的名称或数字。例如,“Paris, USA”有几十个名称,因此它们将包含数字,例如/worldclock/@5205082“Paris, PA USA”。

使用 cron 每天运行 sun-hours 脚本

使用 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监控每天日出/日落时间的变化

康基是一款流行的系统监控工具。以下是显示日出、日落和亮度设置的命令:

${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需要根据您的显示适配器进行更改,如以下章节所述。

配置亮度设置和过渡时间

您不希望显示器在日出时变为全亮,而在日落时变为全暗。需要一个过渡期。此外,还需要一个配置文件来记录全亮和全暗的变量。这是配置屏幕:

显示自动亮度配置

屏幕采用标准禅意命令,因此现有值显示在带有“(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

笔记:2017 年 8 月 26 日,未成功修改,以纠正当最后一个亮度级别等于最小或最大亮度且当前分钟的调整值为空白(零)时程序会停止的错误。2017 年 12 月 2 日成功修复,但直到 2018 年 2 月 17 日才发布。糟糕!

每次启动时自动开启显示自动亮度功能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

概括

显示当前亮度级别是系统托盘

除了前面介绍的 Conky 示例之外,指标-系统监视器您可以通过 bash 在系统托盘中显示当前亮度:

显示自动亮度系统托盘

在此系统托盘示例中,亮度设置为418,大约在日落前 20 分钟。日落时,亮度值为 250,白天最大亮度为 1200。在此机器上,intel_backlight=4882 是可能的,但是,如果您在室内拉开窗帘,屏幕就像盯着太阳一样。

系统托盘指示器使用此代码设置:

#!/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 可以作为应用程序指示器显示在系统托盘中吗?) 描述了如何设置指标系统监视器。

未来的增强功能

  • 将此答案的 bash 脚本迁移到 github
  • 使用添加对外部显示器的支持xrandr
  • 使用以下方法增加对红色较多/蓝色较少的支持xrandr

答案2

我刚刚写了一个程序,它几乎可以满足您的要求。它根据您的网络摄像头拍摄的图像改变屏幕亮度以获取周围的亮度。您可以自行选择检测亮度的间隔和调光速度。

https://github.com/Wandersalamander/Dimmer

答案3

此脚本根据网络摄像头图像数据调整显示器背光亮度。也许这能帮助你解决问题。

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

答案4

如果你正在寻找 GUI,你可以使用 f.lux

https://justgetflux.com/linux.html

相关内容