You are not logged in.

#1 2015-03-31 17:59:17

boogerlad
Member
Registered: 2013-04-20
Posts: 48

Unable to open XServer [Resource temporarily unavailable] systemctl

How do I allow programs/scripts that I've written access the current x session when it's a systemd service? Here are the scripts in question: https://github.com/boogerlad/ready2sleep

I did this: https://wiki.archlinux.org/index.php/Sy … er#DISPLAY

But still, I'm getting the error in the subject. Any ideas?

Last edited by boogerlad (2015-03-31 19:29:55)

Offline

#2 2015-04-01 15:38:42

berbae
Member
From: France
Registered: 2007-02-12
Posts: 1,302

Re: Unable to open XServer [Resource temporarily unavailable] systemctl

Here is a working solution:

$ cat ~/bin/ready2sleep 
#!/bin/bash
network()
{
        i=0
        io=0
        while read line #loop through interfaces
        do
                i=$((i + 1))
                if [ "$i" -gt 2 ] #skip first two lines
                then
                        arr=($line)
                        io=$(($io + ${arr[1]} + ${arr[9]})) #1 = receive, 9 = transmit
                fi
        done < /proc/net/dev
        echo $io #in bytes
}
if [ -f ~/tmp/sleep ]
then
        source ~/tmp/sleep
fi
if [ -z "$c" ]; then c=0; fi
if [ -z "$p" ]; then p=0; fi
if [ -z "$n" ]; then n=0; fi
if [ -z "$oldIO" ]; then oldIO=$(network); fi
if [ ! -f ~/tmp/ss.png ]; then
    import -silent -window root ~/tmp/ss.png
fi

if [ "$(awk 'BEGIN{i=0}
{sum[i]=$2+$3+$4+$5; idle[i++]=$5}
END {printf "%d\n", 100*( (sum[1]-sum[0]) - (idle[1]-idle[0]) ) / (sum[1]-sum[0])}
' <( head -n 1 /proc/stat; sleep 0.5; head -n 1 /proc/stat))" -lt 5 ]
then
        c=$((c+1))
else
        c=0
fi
import -silent -window root ~/tmp/ss2.png
same="  Channel distortion: MSE
    red: 0 (0)
    green: 0 (0)
    blue: 0 (0)
    all: 0 (0)"
compar="$(compare -verbose -metric MSE ~/tmp/ss.png ~/tmp/ss2.png null: 2>&1|sed -n '4,8p')"
if [ "$compar" == "$same" ]
then
        p=$((p+1))
else
        p=0
fi
mv ~/tmp/ss2.png ~/tmp/ss.png
io=$(network)
if [ $((io - oldIO)) -lt 6144000 ] #50*1024*120
then
        n=$((n+1))
else
        n=0
fi

if [ "$c" -ge "$1" ] && [ "$p" -ge "$2" ] && [ "$n" -ge "$3" ]
then
        c=0
        p=0
        n=0
        echo "systemctl suspend"
fi

echo -en "c=$c\np=$p\nn=$n\noldIO=$io" > ~/tmp/sleep

I use the 'import' and 'compare' commands from ImageMagick instead of graphicsmagick.
This script doesn't need root privileges to run.
Then I use the 'systemd --user' daemon to do what you wish to implement:

$ cat ~/.config/systemd/user/ready2sleep.service 
[Unit]
Description=checks if computer is idle

[Service]
Type=oneshot
Environment=DISPLAY=:0
Nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
ExecStart=/home/berbae/bin/ready2sleep 3 3 3
$ cat ~/.config/systemd/user/ready2sleep.timer 
[Unit]
Description=checks if computer is idle every 2 minutes

[Timer]
AccuracySec=1us
OnActiveSec=10
OnUnitActiveSec=10

I changed the values for testing, and I don't really suspend my machine but I only write:
avril 01 17:15:06 arch64 ready2sleep[3206]: systemctl suspend
in the journal instead.
Of course replace:
        echo "systemctl suspend"
with
        systemctl suspend
to do the real thing.

I made the test with
$ systemctl --user start ready2sleep.timer

You need to authorize the user to suspend your machine for that to work entirely without root rights.

For that to work automatically when you log in, just write that:

$ cat ~/.config/systemd/user/default.target
[Unit]
Description=Default target for user
Wants=ready2sleep.timer

I hope that will help you; for me it was a training exercise.
Bye.

Edit: It is 'default.target' not 'default.target.off'; I forgot to remove the .off termination.

Last edited by berbae (2015-04-01 20:29:03)

Offline

Board footer

Powered by FluxBB