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.
sudo python3 …
) . – dessert Dec 07 '17 at 12:13$DISPLAY env
variable, which in my case is added and I'm still getting randomly the error. While the second one is about how to use crontab to launch GUI script, which I also do. And still have an error some times. – York's Dec 07 '17 at 13:16$DISPLAY env
programmatically as it is shown in my suggestion, it is not:0
each time. Also I think probably the value of$XAUTHORITY
is incorrect due a typo in my suggestion is shown how to get this value programmatically. – pa4080 Dec 07 '17 at 13:23env
for these variables, though it didn't help a lot, as I still receive error sometime. What is the typo in$XAUTHORITY
? – York's Dec 07 '17 at 13:26$XAUTHORITY
, I don't know: Are you sure the part/user/
is correct in your actual corn job? Are you running the job from the user'scrontab
? Could you check who is the owner of/home/<user>/.Xauthority
when you receive the error message? – pa4080 Dec 07 '17 at 13:35/home/user/.Xauthority
belong only to user, I run script from theuser
's crontab,/user/
is correct in my actual cron job. And$USER
variable is not defined when running the cron job. – York's Dec 07 '17 at 13:54