summaryrefslogtreecommitdiff
path: root/brightness.py
blob: a88e2f8a268d616c3605ce7bde9bae20e31f2833 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/env python3

'''
brightness.py
Usage:
    brightness.py [show]
    brightness.py set [--] <value>
'''

import re

import docopt

backlight_prefix_path = '/sys/class/backlight/intel_backlight'


def read_brightness():
    '''
    Return the current brightness value as reported by the driver.
    '''
    # We can use either the `brightness' file or `actual_brightness'.
    # The differences are documented in the linux kernel tree at
    # Documentation/sysfs-class-backlight.txt
    # Briefly speaking, reading the `brigthness' file returns the
    # brightness as reported by the driver whereas reading
    # `actual_brigthess` returns the value queried directly from the
    # hardware.
    with open(backlight_prefix_path + '/brightness') as fd:
        return int(fd.read())


def read_max_brightness():
    '''
    Return the maximum brightness value that is supported.
    '''
    with open(backlight_prefix_path + '/max_brightness') as fd:
        return int(fd.read())


def print_current_brightness():
    '''
    Output the current brightness first as a value over the maximum
    value, then as a percentage.
    '''

    max_brightness = read_max_brightness()
    cur_brightness = read_brightness()

    percentage_brightness = cur_brightness * 100 / max_brightness

    output = 'Current brightness: {cur}/{max} ({percentage:.2f}%)'.format(
        cur=cur_brightness, max=max_brightness,
        percentage=percentage_brightness)

    print(output)


def set_current_brightness(value):
    '''
    Set the current brightness value according to the parameter.
    The parameter can take multiple forms:
    1) a number (e.g. 650);
    2) a number followed by the '%' sign (e.g. 70%);
    3) a number preceded by a '+' or '-' sign (e.g. +30);
    4) a number number preceded by a '+' or '-' sign and followed by a '%' sign
      (e.g. +10%).
    '''

    matches = re.fullmatch('([+-])?(\d+)(%)?', value)

    if matches is None:
        raise ValueError()

    groups = matches.groups()
    # The first group is either '+', '-' or None.
    # The second group is a number.
    # The third group is either '%' or None.
    max_brightness = None
    cur_brightness = None
    new_brightness = None

    # If we are going to increment / decrement the the value, we need to know
    # what the current value is.
    if groups[0] is not None:
        cur_brightness = read_brightness()
    # If we want to play around with percentage values, we need to know what
    # the maximum value is.
    if groups[2] is not None:
        max_brightness = read_max_brightness()

    # option 1)
    if groups[0] is None and groups[2] is None:
        new_brightness = int(groups[1])
    # option 2)
    elif groups[0] is None and groups[2] is not None:
        new_brightness = round(int(groups[1]) * max_brightness / 100)
    # option 3)
    elif groups[0] is not None and groups[2] is None:
        if groups[0] == '+':
            new_brightness = cur_brightness + int(groups[1])
        else:
            new_brightness = cur_brightness - int(groups[1])
    # option 4)
    else:
        delta = round(int(groups[1]) * max_brightness / 100)
        if groups[0] == '+':
            new_brightness = cur_brightness + delta
        else:
            new_brightness = cur_brightness - delta

    with open(backlight_prefix_path + '/brightness', mode='w') as fd:
        print(new_brightness, file=fd)


def main(argv=None):
    args = docopt.docopt(__doc__, version='1', argv=argv)

    try:
        if args['set']:
            set_current_brightness(args['<value>'])
        else:
            print_current_brightness()

    except ValueError as e:
        raise docopt.DocoptExit(str(e))


if __name__ == '__main__':
    main()