piframe/docs/scheduled_display.md

3.9 KiB

HDMI Scheduled On/Off

The below comamnds will setup automatic on/off of the monitor connected to the HDMI port on your PiFrame. This is handy as overnight few people are looking at their photos and by turning off the display you'll save power and make the screen last longer.

The below is setup to turn the display on at 0600 and off at 0000. Please adjust accordingly.


pip3 install -U python-dotenv

cat > /etc/default/screen-on-off <<EOF
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# YOU MUST TWEAK THE screen-on.timer AND screen-off.timer IF CHANGING THESE VALUES
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# MUST BE A VALID TIME AND HAVE "*-*-* " AT THE START OF THE STRING
#    Hours, Minutes and Seconds MUST be 0 padded (aka : we are using datetime.time.fromisoformat in the python3 stdlib)
#    WE DO NOT SUPPORT DATES!!!!!
TIME_SCREEN_ON="*-*-* 06:00:00"
TIME_SCREEN_OFF="*-*-* 00:00:00"
# Indicate the ON time is the following day (aka turn off at night, on following next morning)
#    REMEMBER: MIDNIGHT IS TODAY!
#    To set true use 'true'
#    To set false use ''
TIME_ON_IS_NEXT_DAY=''
EOF

cat > /usr/local/bin/screen-on-off <<EOF
#!/usr/bin/python3
# Load up the config file
from pathlib import Path
from dotenv import load_dotenv
env_path = Path('/etc/default/screen-on-off')
load_dotenv(dotenv_path=env_path)

# Get values from env vars
import os
TIME_SCREEN_ON = os.getenv("TIME_SCREEN_ON")
TIME_SCREEN_OFF = os.getenv("TIME_SCREEN_OFF")
TIME_ON_IS_NEXT_DAY = bool(os.getenv("TIME_ON_IS_NEXT_DAY"))

# Strip variables of data we don't support
TIME_SCREEN_ON = TIME_SCREEN_ON.strip('*-*-* ')
TIME_SCREEN_OFF = TIME_SCREEN_OFF.strip('*-*-* ')

# Convert strings to timestamps
from datetime import datetime, time, timedelta
current = datetime.now()
on = datetime.combine(current, time.fromisoformat(TIME_SCREEN_ON))
off = datetime.combine(current, time.fromisoformat(TIME_SCREEN_OFF))

# Adjust day of off time in case it's an overnight off
if TIME_ON_IS_NEXT_DAY:
    on = on + timedelta(days=1)

# Let's do the quick checks to see if we are within the screen off window
turn_on = True
if on < off:
    if on <= current <= off:
        turn_on = False
else:
    if off <= current <= on:
        turn_on = False

# Turn screen on or off based on the schedule
import subprocess
if turn_on:
    subprocess.check_call(['/opt/vc/bin/vcgencmd', 'display_power', '1'])
else:
    subprocess.check_call(['/opt/vc/bin/vcgencmd', 'display_power', '0'])
EOF

chmod a+x /usr/local/bin/screen-on-off

cat > /etc/systemd/system/screen-on-off.service <<EOF
[Unit]
Description=auto-set screen on/off if rebooting (this will keep the screen off all but briefly during overnight reboots if the off window is set for overnight)
After=getty.target

[Service]
ExecStart=/usr/local/bin/screen-on-off
Type=oneshot

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now screen-on-off.service

cat > /etc/systemd/system/screen-on.timer <<EOF
[Unit]
Description=Turn on display

[Timer]
OnCalendar=*-*-* 06:00:00
Persistent=true

[Install]
WantedBy=timers.target
EOF
cat > /etc/systemd/system/screen-on.service <<EOF
[Unit]
Description=Turn on display

[Service]
Type=oneshot
ExecStart=/opt/vc/bin/vcgencmd display_power 1
StandardOutput=journal

[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/screen-off.timer <<EOF
[Unit]
Description=Turn off display

[Timer]
OnCalendar=*-*-* 00:00:00
Persistent=true

[Install]
WantedBy=timers.target
EOF
cat > /etc/systemd/system/screen-off.service <<EOF
[Unit]
Description=Turn off display

[Service]
Type=oneshot
ExecStart=/opt/vc/bin/vcgencmd display_power 0
StandardOutput=journal

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable screen-on.timer
systemctl enable screen-off.timer