1

I have a Raspberry Pi with Raspbian Buster Lite which I start in KIOSK mode with autologin. The purpose is to display a single web page on the connected 7" touchscreen (with Chromium). If the system is idle, my python script should detect it and dim the screen automatically. When a user interacts with the screen again, it should light up.

This is my script (dim_screen.py):

#!/usr/bin/env python3
import subprocess
import time
import sys

from rpi_backlight import Backlight

backlight = Backlight()

# read arguments from the run command: 
# idle time before dim (in seconds)
idleTimeBeforeDimMS = int( sys.argv[1] )*1000

# brightness when dimmed (between 0 and 100)
brightnessDimmed = int( sys.argv[2] )
brightnessFull = 100

def get(cmd):
    # just a helper function
    return subprocess.check_output(cmd).decode("utf-8").strip()

isIdle0 = False
stateChanged = False
timeIntervalToWatchChangesS = 100 / 1000

while True:
    time.sleep( timeIntervalToWatchChangesS )

    currentIdleTimeMS = int( get("xprintidle") )

    isIdle = currentIdleTimeMS > idleTimeBeforeDimMS
    stateChanged = isIdle0 != isIdle

    if isIdle and stateChanged:
        # idling
        backlight.brightness = brightnessDimmed
    elif not isIdle and stateChanged:
        # active
        backlight.brightness = brightnessFull

    # set current state as initial one for the next loop cycle
    isIdle0 = isIdle

My script works as expected when I start it from a SSH (I can test it by connecting to my Pi from Putty on a Windows 10 computer): pi@raspberrypi:~$ /usr/bin/python3 /home/pi/startup_scripts/dim_screen.py 10 25

Unfortunately this is not the case when I try to run the script as a service on boot from systemd (or via systemctl start dim_screen.service). I can't get it to work.

This is my dim_screen.service file:

[Unit]
Description=Ensures that the 7" raspberry pi screen automatically will dim to 10% brightness after 25 minutes of user not interacting with it 
After=multi-user.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/startup_scripts/dim_screen.py 10 25

[Install]
WantedBy=multi-user.target

If I do a reboot and run sudo systemctl status dim_screen.service, I get this:

Terminal with output failure

I believe that the most important debug info is this line: Command 'xprintidle' returned non-zero exit status 1.

That's strange I think? Here is what happens if I run xprintidle in the terminal:

pi@raspberrypi:~$ xprintidle
11399922

In other words, I get a valid response from xprintidle. I believe there is something else that I do not understand?

What is the correct way to start my python script (dim_screen.py) as a service?

2
  • In the systemd case, xprintidle doesn't have access to the X server, and doesn't have $DISPLAY defined.
    – waltinator
    Commented Oct 11, 2020 at 23:01
  • Thanks for the answer but is it possible to give it access? I think I don't quite understand why it hasn't? xprintidle is accessible from my terminal?
    – Hauns TM
    Commented Oct 14, 2020 at 15:40

1 Answer 1

0

THIS TEXT DOES NOT ANSWER THE ORIGINAL QUESTION. IT'S A WORKAROUND

Since I was unable to understand the reason why xprintidle-returned-non-zero-exit-status-1, I was forced to try a workaround.

When I set up the Pi to run chromium in kiosk mode, I followed a tutorial on how it could be done: RASPBERRY PI TOUCHSCREEN KIOSK SETUP 10 STEPS. In the tutorial, I was instructed to configure an Openbox window manager. I was able to invoke the pythonscript as a forked process just before the Chromium browser was fired off. This "solution" probably breaks all possible rules on best practices, but it solved my problem. At least until I can manage to find out a better way to do it.

This is my /etc/xdg/openbox/autostart:

#
# These things are run when an Openbox X Session is started.
# You may place a similar script in $HOME/.config/openbox/autostart
# to run user-specific things.
#

# If you want to use GNOME config tools...
#
#if test -x /usr/lib/arm-linux-gnueabihf/gnome-settings-daemon >/dev/null; then
#  /usr/lib/arm-linux-gnueabihf/gnome-settings-daemon &
#elif which gnome-settings-daemon >/dev/null 2>&1; then
#  gnome-settings-daemon &
#fi

# If you want to use XFCE config tools...
#
#xfce-mcs-manager &

# First, add commands to turn off power management, screen blanking and screen saving. We don▒^`^yt want those features in a kiosk.
xset -dpms                      # turn off display power management system
xset s noblank          # turn off screen blanking
xset s off                      # turn off screen saver

# Next if Chromium crashed it may pop up error messages next time it starts. This is another feature that we don▒^`^yt want in a kiosk.
# Remove exit errors from the config files that could trigger a warning

sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' ~/.config/chromium/'Local State'
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/; s/"exit_type":"[^"]\+"/"exit_type":"Normal"/' ~/.config/chromium/Default/Preferences

# invoke the script which dims the (only) screen when user is idle
/usr/bin/python3 /home/pi/startup_scripts/dim_screen.py 10 25 &

# Finally, update autostart to run the Chromium browser in kiosk mode. Pass in an environment variable ($KIOSK_URL) that contains the URL of the Web app to launch.
# Run Chromium in kiosk mode
chromium-browser  --noerrdialogs --disable-infobars --kiosk --check-for-update-interval=31536000 $KIOSK_URL

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .