0

I'm writing a simple script that should periodically change the brightness of all the screens in the system. I figured out that for this I can use following command:

xrandr --output {display name} --brightness {float in a range [0.0,1.0]}

First I wanted to use xbacklight, but it turns out that it cannot control all the screens brightness, so I switched to xrandr.

When I run this command from the terminal it works fine, but next I tried to schedule it to a crontab to run it periodically, first it wasn't working at all, but then I found that I need to provide $DISPLAY env variable to cron so that the script will know where to look for X.

It seems to be working now, however not totally fine, because sometimes it gives error like this:

X Error of failed request:  BadAccess (attempt to access private resource denied)
  Major opcode of failed request:  131 (XInputExtension)
  Minor opcode of failed request:  57 ()
  Serial number of failed request:  18
  Current serial number in output stream:  19 

And I cannot get why this error occurs and what to do in order to fix it?

Here's the content of my crontab file:

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/user
DISPLAY=:0
XAUTHORITY=/home/user/.Xauthority

0 * * * * python3 /home/user/script.py > /home/user/scriptLog 2>&1

And the script (it runs every hour, and at first turns off the keybord and all screens for 5 minutes and then it turns them on):

#!/usr/bin/env python3

import time
import os
import sched

SEC_PER_HOUR = 60 * 60
MIN_PER_HOUR = 60
SEC_PER_MIN = 60
DEVICE_ACTIVE = 139
dur = 5

def xinput_set_prop(devices, prop, val):
    for id in devices:
        os.system("xinput set-prop {} --type=int --format=8 {} {}".format(id, prop, val))

def xrandr_set_brightness(devices, val):
    for id in devices:
        os.system("xrandr --output {} --brightness {}".format(id, val)) 

cur_t = time.time()

if cur_t / SEC_PER_HOUR - cur_t // SEC_PER_HOUR < dur / MIN_PER_HOUR:
    keyboard_ids = [line.replace("\n", "") for line in os.popen("""xinput list | sed -rn 's/.*id=//; s/\s+.*slave\s+keyboard.*//p'""")]
    monitor_ids = [line.replace("\n", "").split(" ")[-1] for line in os.popen("""xrandr --listmonitors""")]

    xrandr_set_brightness(monitor_ids, 0.01)
    xinput_set_prop(keyboard_ids, DEVICE_ACTIVE, 0)

    run_t = cur_t // SEC_PER_HOUR * SEC_PER_HOUR + dur / MIN_PER_HOUR + dur * SEC_PER_MIN
    del_t = run_t - cur_t

    s = sched.scheduler(time.time, time.sleep)
    s.enter(del_t, 1, xinput_set_prop, argument=(keyboard_ids, DEVICE_ACTIVE, 1))
    s.enter(del_t, 1, xrandr_set_brightness, argument=(monitor_ids, 1.0))
    s.run()

I'm using Ubuntu 16.04, with the Unity desktop.

York's
  • 11

0 Answers0