7

I recently migrated to 64 Bit 16.04 LTS from 32 Bit 14.04 LTS on my Toshiba L645 laptop. In 14.04 LTS system, I had a script that automatically updated the brightness level depending on the power source. Unfortunately I didn't save that script before overwriting the system. Currently, I am using the following script

#!/usr/bin/env bash
#
###########################################################
# Author: Serg Kolo , contact: 1047481448@qq.com 
# Date: February 26 2016 
# Purpose: Brightness control that polls for
#          ac adapter presence. Uses
# Dependencies: on_ac_power script, dbus, Unity/Gnome 
# Written for: http://askubuntu.com/q/739617/295286
# Tested on: Ubuntu 14.04 LTS
###########################################################
# Copyright: Serg Kolo , 2016
#    
#     Permission to use, copy, modify, and distribute this software is hereby granted
#     without fee, provided that  the copyright notice above and this permission statement
#     appear in all copies.
#
#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
#     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#     DEALINGS IN THE SOFTWARE.

# uncomment the line bellow for debugging
#set -x

ARGV0="$0"
ARGC=$#


main()
{

  # defaults
  local DISPLAY=:0
  local DECREASE=30
  local INCREASE=75
  local RCFILE="$HOME/.auto-backlightrc"
  #---

  # Check the settings
  if [ -f $RCFILE ]
  then 
       source $RCFILE 
  else
       create_rcfile $DECREASE $INCREASE
  fi
  #---

  # now actually test if we're using ac adapter
  if ! on_ac_power 
  then 
        change_brightness $DECREASE
  # The two lines bellow are optional for 
  # setting brightness if on AC. remove # 
  # if you want to use these two

  # else 
       # change_brightness $INCREASE
  fi

}

change_brightness()
{
  dbus-send --session --print-reply\
    --dest=org.gnome.SettingsDaemon.Power\
    /org/gnome/SettingsDaemon/Power \
    org.gnome.SettingsDaemon.Power.Screen.SetPercentage uint32:"$1"
}

create_rcfile()
{
  echo "DECREASE="$1 >  "$RCFILE"
  echo "INCREASE="$2 >> "$RCFILE"
}


while true
do
   main
   sleep 0.25
done

However, this script only works when power is switched from AC to Battery and does not restore the brightness level once the AC is back on. Also, once on Battery, this script consistently tries to set the brightness at the predefined level and even if I try to change that manually it resets that. I would like to be able to change the brightness level manually if I desire even in battery mode.

muru
  • 197,895
  • 55
  • 485
  • 740
thethakuri
  • 497
  • 2
  • 4
  • 13
  • Very well. I will see what i can do. If i understand correctly you want the script to also control brightness at some specific level when also on AC , right ? Also, i can try adding an option for the script to stop/start manually. That way you can stop/start it at will. Would that be acceptable ? – Sergiy Kolodyazhnyy Jun 18 '16 at 03:03
  • Not exactly. I want the script to lower the brightness when switched to Battery and restore it once back on AC. Also, currently the script persistently tries to set the brightness level. I don't want that as sometimes I want to set manually. – thethakuri Jun 18 '16 at 03:22
  • I see, so you want it to remember the brightness levels , and only make change when power-source change occurs. Otherwise , let the system behave as usual. Correct ? – Sergiy Kolodyazhnyy Jun 18 '16 at 03:43
  • Yes sir, that's it ! – thethakuri Jun 18 '16 at 03:47
  • Very well, I will begin working on it soon. I will post once the script works as expected – Sergiy Kolodyazhnyy Jun 18 '16 at 03:49
  • 1
    I've made a draft of the script. It does 90% of what is asked , remembers the brightness used on previous source, but doesn't prevent you from changing brightness while using different source. So far it's a gist on github and I intend to improve it, add a few features here and there , but mostly it's ready. Let me know what you think. Brightness initially is set to be 90 for AC and 50 for battery, so first time you start out with AC , it will jump to 50 on battery, If you boot with batter, it will jump to 90 on AC 1st time – Sergiy Kolodyazhnyy Jun 18 '16 at 07:08
  • UNPLUGGED 50 PLUGGED_IN Error: org.gtk.GDBus.UnmappedGError.Quark._gsd_2drr_2derror_2dquark.Code3 out of brightness range: 4694, has to be 4648 -> 1 – thethakuri Jun 18 '16 at 07:34
  • So its working when I unplug. But not when back to AC. According to my max_brightness file, the maximum level of brightness is 4648. But the good news is the script is responding to the events nevertheless ! – thethakuri Jun 18 '16 at 07:37
  • I see , but the script operates on percentage. The max value that is recognized by the graphics card should be determined automatically. Very odd. I've tested the script on 2 laptops , no issues there, but it might be complicated for me to test without access to the same hardware you have. I'll need to think on how to debug this – Sergiy Kolodyazhnyy Jun 18 '16 at 07:41
  • Yes I understand. The strange this is on PLUGGED_IN the brightness value is set at 4694 which is greater than max value of 4648. How was that number calculated ? Also, no matter what value I set for AC_PERCENTAGE it gives back the same number: 4694 – thethakuri Jun 18 '16 at 07:44
  • The actual value calculation is supposed to be done by the system itself. The script works only with percentage, and if you had 90% on AC, it should reset it back to 90+1 once you connect again ( because for some odd reason graphics cards set percentage 1 lower than what you tell them, so I had to set brightness to X+1 in the script , if that makes sense – Sergiy Kolodyazhnyy Jun 18 '16 at 07:47
  • Hey, its working now. I just needed to declare DISPLAY=:0 in the script. You're the trooper. Thanks a lot. Man I gotta learn shell scripting. It would be great if you could decrease the brightness level depending on the battery level as well. – thethakuri Jun 18 '16 at 08:16
  • Very well , I will clean up the script, add a few features, and post it today. As for the decrease with brightness level , that absolutely can be done as well , but it's a separate question so would need separate post. Feel free to ask it if you want :) – Sergiy Kolodyazhnyy Jun 18 '16 at 15:19

4 Answers4

3

Intro

The script below allows remembering brightness levels depending on the power source used by a laptop. It defaults to 50% on battery, 90% on AC.

Overview of options and usage

source_monitor.sh [-a INT] [-b INT] [-v] [-h]

-a set initial brightness on AC adapter
-b set initial brightness on batter
-v enable verbose output
-h prints this help text

Installation

Installation using git through terminal:

  1. Run sudo apt-get install git to install git
  2. Run mkdir $HOME/bin. Skip this step if $HOME/bin exists already
  3. cd $HOME/bin
  4. Run git clone https://github.com/SergKolo/sergrep.git
  5. The script will be in $HOME/bin/sergrep/source_monitor.sh. Make sure the script is executable with chmod +x $HOME/bin/sergrep/source_monitor.sh
  6. Add the script as a startup application. Look for Startup Applications menu in Unity Dash or Gnome search. Alternatively, run gnome-session-properties command in terminal to launch the menu. Add the full path to script as startup application so that it launches every time you log into GUI.

Alternatively, you can copy and save script source by oneself, chmod +x file, and go through the step #6 described above.

To make the script automatically start every time you log in to Gnome or Unity, use Startup Applications utility.

Script source

#!/usr/bin/env bash
#
###########################################################
# Author: Serg Kolo , contact: 1047481448@qq.com 
# Date: June 18th 2016
# Purpose: Script that remembers and sets brightness
#      depending on power sources
# 
# Written for: https://askubuntu.com/q/788383/295286
# Tested on: Ubuntu 16.04 LTS , Ubuntu Kylin 16.04 LTS
###########################################################
# Copyright: Serg Kolo , 2016
#    
#     Permission to use, copy, modify, and distribute this software is hereby granted
#     without fee, provided that  the copyright notice above and this permission statement
#     appear in all copies.
#
#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
#     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#     DEALINGS IN THE SOFTWARE.

ARGV0="$0"
ARGC=$#
wait_ac_connect()
{
  while ! on_ac_power ; do : ; sleep 0.25 ; done
  $VERBOSE && echo "<<< adapter plugged in"
}

wait_ac_disconnect()
{
  while on_ac_power ; do : ; sleep 1.25 ; done 
  $VERBOSE && echo "<<< adapter unplugged"
}

change_brightness()
{
  qdbus org.gnome.SettingsDaemon \
       /org/gnome/SettingsDaemon/Power \
      org.gnome.SettingsDaemon.Power.Screen.SetPercentage "$1"
}

get_brightness()
{
  qdbus org.gnome.SettingsDaemon \
        /org/gnome/SettingsDaemon/Power \
        org.gnome.SettingsDaemon.Power.Screen.GetPercentage
}

print_usage()
{
cat <<EOF

source_monitor.sh [-a INT] [-b INT] [-v] [-h]

-a set initial brightness on AC adapter
-b set initial brightness on batter
-v enable verbose output
-h prints this help text

Copyright Serg Kolo , 2016
EOF
}

parse_args()
{
 # boiler-pate code for reusing, options may change
 local OPTIND opt  # OPTIND must be there, 
                   # opt can be renamed to anything
 # no leading : means errors reported(which is what i want)
 # : after letter means options takes args, no :  - no args
 while getopts "a:b:vh" opt
 do
   case ${opt} in
      a)  AC_PERCENTAGE="${OPTARG}"
        ;;
      b) BAT_PERCENTAGE="${OPTARG}"
        ;;
      v) VERBOSE=true
        ;;
      h) print_usage && exit 0
        ;;
     \?)
      echo "Invalid option: -$OPTARG" >&2
      ;;
    esac
  done
  shift $((OPTIND-1))
}

main()
{

    # default values, if -a,-b, or -v options given
    # they will be changed
    local BAT_PERCENTAGE=50
    local AC_PERCENTAGE=90
    local VERBOSE=false # for debugging

    parse_args "$@"

    while true
    do

      if on_ac_power ; then
         wait_ac_disconnect
          AC_PERCENTAGE=$(($(get_brightness)+1)) # too long to explain why +1
                         # just try it for yourself
          sleep 0.25
          change_brightness "$BAT_PERCENTAGE" > /dev/null
      else
          wait_ac_connect
          BAT_PERCENTAGE=$(($(get_brightness)+1))
          sleep 0.25
          change_brightness "$AC_PERCENTAGE" > /dev/null
      fi

      sleep 0.25

    done

}

main "$@"
Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497
  • One question: What is the difference between this method, using qdbus and simply using echo 500 | sudo tee /sys/class/backlight/intel_backlight/brightness ? – thethakuri Jun 19 '16 at 05:28
  • If you want please have a look at my other issue link. – thethakuri Jun 19 '16 at 05:31
  • The big difference is that for qdbus you don't need sudo. It behaves as if you were clicking on function keys on keyboard. Second, it deals with percentages instead of actual values that graphics card understands, so I don't need to reinvent the wheel every time. I've already looked at your other issue, but so far I don't have an idea - I'm not very knowledgeable when it comes to the indicators on the top panel. – Sergiy Kolodyazhnyy Jun 19 '16 at 05:54
  • Yeah I figured it would be su access and the absolute value issues. Anyways thanks for the script ! – thethakuri Jun 19 '16 at 06:40
  • I am currently testing this script and I have encountered something else. When on login screen and I swtich on and off the power supply, the percentage calculated is 50% on AC and 25% on BAT (maybe the default max value of brightness is reset to 50%). Is there a way to hardcode the percentage of the max_brightness ? – thethakuri Jun 19 '16 at 07:48
1

Serg's script seemed to work at first. However after some time, the percentage was being evaluated incorrectly especially after coming back from hibernation. It may have been some issues with qdbus but the brightness level won't just change. So, I decided to hardcode the brightness level using the value from max_brightness file. Here's my /usr/local/bin/auto-backlight.sh :

#!/usr/bin/env bash

read MAX_BRIGHTNESS < /sys/class/backlight/intel_backlight/max_brightness

declare -i -r BATT_PERCENTAGE=45 
declare -i -r AC_PERCENTAGE=90 
declare -i -r ON_BATT=$(($MAX_BRIGHTNESS*$BATT_PERCENTAGE/100)) 
declare -i -r ON_AC=$(($MAX_BRIGHTNESS*$AC_PERCENTAGE/100))

wait_ac_connect() {   while ! on_ac_power ; do : ; sleep 0.25 ; done   echo "Adapter plugged in. Brightness level at $ON_AC" }

wait_ac_disconnect() {   while on_ac_power ; do : ; sleep 1.25 ; done  echo "Running on battery. Brightness level at $ON_BATT" }

main() {  
    while true
    do

      if on_ac_power ; then
        wait_ac_disconnect
         echo $ON_BATT > /sys/class/backlight/intel_backlight/brightness
      else
        wait_ac_connect
         echo $ON_AC > /sys/class/backlight/intel_backlight/brightness
      fi

      sleep 0.25

    done

}

main "$@"

Unlike Serg's script, this one requires a root privilege to write into brightness file. So I created a systemd service at /etc/systemd/system/auto-backlight.service:

[Unit]
Description=Change backlight on power source
ConditionFileIsExecutable=/usr/local/bin/auto-backlight.sh

[Service]
Type=simple
ExecStart=/usr/local/bin/auto-backlight.sh

[Install]
WantedBy=multi-user.target

Finally make the service load at boot with root privileges :

sudo systemctl enable auto-backlight.service
thethakuri
  • 497
  • 2
  • 4
  • 13
1

Another way could be to create rules for udev and call a simple script to change the brighness value: First, create a file named auto-backlight.sh in your home directory (or any other of your preference) with your favorite editor, like gedit, and copy and paste the next code:

#!/bin/sh
# Adjust brightness of backlights based on power source
case $1 in
    # On battery
    true)
        # Dim screen backlight
        expr `cat /sys/class/backlight/intel_backlight/max_brightness` / 10 > \
            /sys/class/backlight/intel_backlight/brightness
    ;;

    # On AC
    false)
        # Dim screen backlight
        cat /sys/class/backlight/intel_backlight/max_brightness > \
            /sys/class/backlight/intel_backlight/brightness
    ;;
esac

return 0

Please note that that /sys/class/backlight/intel_backlight/ could be something different in your system, like /sys/class/backlight/acpi_video0/. Also note that possibly you need to change the value of / 10 depending of the value of max_brightness, it could be 100, 50, 5, etc. as it is a division factor.

Give execution permissions to the new created script: chmod 771 auto-backlight.sh

Then create a file named 99auto-backlight.rules with your favorite editor and put it in the /etc/udev/rules.d/ folder: sudo gedit /etc/udev/rules.d/99auto-backlight.rules (or link it with using the "ln" command), containing the following two lines:

SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="/path/to/your/script/auto-backlight.sh true"
SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="/path/to/your/script/auto-backlight.sh false"

Replace /path/to/your/script/ with the actual path were the auto-backlight.sh script is located.

Credit to Alex Layton for his idea here: https://unix.stackexchange.com/a/110469 and to Pilot6 for his idea here: https://askubuntu.com/a/613816

0

Cuttlefish is a tool that helps automate settings changes based on events such us as plugging and unplugging the power supply

Amias
  • 5,246