Anthias (Screenly)

Overview

Anthias (AKA Screenly) is a simple, open-source digital signage system that runs well on a raspberry pi or Intel PC. When plugged into a monitor, it displays images, video or web sites in slideshow fashion. It’s managed directly though a web interface on the device and there are fleet and support options.

Preparation

On a Raspberry Pi

Use the Raspberry Pi Imager to create a 64 bit Raspberry Pi OS Lite image. Select the gear icon at the bottom right to enable SSH, create a user, configure networking, and set the locale. Use SSH continue configuration.

setterm --cursor on

sudo raspi-config nonint do_change_locale en_US-UTF-8
sudo raspi-config nonint do_configure_keyboard us
sudo raspi-config nonint do_wifi_country US
sudo timedatectl set-timezone America/New_York
  
sudo raspi-config nonint do_hostname SOMENAME

sudo apt update;sudo apt upgrade -y

sudo reboot

On a PC

Install Debian

Boot from the Debian installer ISO and make the following choices.

  • In disk layout, use the whole disk but change the main partition from EXT4 to BTRFS (for resiliency)
  • In software selection, deselect desktop options and choose only SSH and common utilities

After installing, add sudo and allow the user you created during install to use it without prompt. (as per Athnias docs)

# Become root
apt install sudo
adduser SOMEBODY sudo
echo "SOMEBODY ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/SOMEBODY
chmod 0440 /etc/sudoers.d/SOMEBODY

Configure WiFi

Use the newer iwd service for better handling of outages. It expects resolved for DNS.

sudo apt install iwd systemd-resolved
sudo systemctl enable --now iwd systemd-resolved

Set iwd to handle DHCP for WiFi. This is more reliable for outage recovery.

sed -i 's/^#\s*EnableNet.*/EnableNetworkConfiguration=true/' /etc/iwd/main.conf

Tell iwd which WiFi network to join. It will connect as soon as you save the config.

# Generate a preshared key from the SSID and Passphrase
python3 -c 'import hashlib; print(hashlib.pbkdf2_hmac("sha1", b"Your_Passphrase", b"Your_SSID", 4096, 32).hex())'

sudo vi /var/lib/iwd/Your_SSID.psk
# Add this section if it's a hidden SSID
[Settings]
Hidden=true

[Security]
PreSharedKey=paste_your_python_output_hash_here

Harden the System

Let’s make the PC more resilient to power loss and hangs. Using BTRFS helps a lot, but we can also configure the BIOS, update the kernel settings and use a watchdog timer.

Turn Back On

Enter the BIOS and under power settings, configure to power-on on power recovery.

Reboot On Panic

Configure the system to reboot instead of hang on a kernel panic.

sudo vi /etc/sysctl.d/99-panic-reboot.conf
kernel.panic = 10
kernel.panic_on_oops = 1
Handle Failed Boots

Change GRUB to handle failed boots better.

echo "GRUB_RECORDFAIL_TIMEOUT=2" | sudo tee -a /etc/default/grub

sudo update-grub
Add the Watchdog Service

Your chipset may provide a watchdog timer that once engaged, will trigger a power-cycle if the operating system stops updating it.

ls -la /dev/watchdog*

If you have any devices listed, you can install and configure the Watchdog service.

sudo apt install watchdog
sudo systemctl stop  watchdog.service

# Load the module early in the boot
echo "iTCO_wdt" | sudo tee /etc/modules-load.d/watchdog.conf

sudo vi /etc/watchdog.conf

Add these to the bottom

# Tell the daemon to talk to your Dell's hardware chip
watchdog-device = /dev/watchdog

# Send a heartbeat to the hardware chip every 10 seconds
interval = 10

# Force a hardware reset if the system remains frozen for 60 seconds
watchdog-timeout = 60

# Test that you can allocate memory
allocatable-memory = 1
sudo systemctl start  watchdog.service

Enable automatic updates and enable reboots

You normally want to apply security automatically, and control updates to the rest. If you don’t have a good structure you can of course apply all, as this config exemplifies.

sudo apt -y install unattended-upgrades

sudo tee /etc/apt/apt.conf.d/52unattended-upgrades-local > /dev/null <<'EOF'
Unattended-Upgrade::Origins-Pattern {
        "origin=Debian";
};

Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";

Unattended-Upgrade::Allow-APT-Mark-Fallback "true";
EOF

sudo systemctl restart unattended-upgrades.service

Installation

sudo apt install curl

# When prompted, install the latest but don't allow Anthias to manage the network
bash <(curl -sL https://www.screenly.io/install-ose.sh)

You can add a regular update by dropping a cronjob for the Anthias update script.

sudo tee /etc/cron.d/anthias-update > /dev/null <<'EOF'
# Anthias weekly update
0 3 * * 0 root /home/SOMEBODY/screenly/bin/run_upgrade.sh
EOF

Operation

Adding Content

Navigate to the Web UI at the IP address of the device. You may wish to enter the settings and add authentication and change the device name.

You may add common graphic types, mp4, web and youtube links. It will let you know if it fails to download the youtube video. Some heavy web pages fail to render correctly, but most do.

Images must be sized to for the screen. In most cases this is 1080. Larger images are scaled down, but smaller images are not scaled up. For example, PowerPoint is often used to create slides, but it exports at 720. On a 1080 screen creates black boarders. You can change the resolution on the Pi with rasp-config or add a registry key to Windows to change PowerPoint’s output size.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\PowerPoint\Options]
"ExportBitmapResolution"=dword:00000096

Schedule the Screen

You may want to turn off the display during non-operation hours. The vcgencmd command can turn off video output and some displays will choose to enter power-savings mode. Some displays misbehave or ignore the command, so testing is warranted.

Note: This is only for the Raspberry Pi. Most PCs lack the CEC interface needed without a dedicated add-on.

sudo tee /etc/cron.d/screenpower << EOF

# m h dom mon dow usercommand

# Turn monitor on
30 7  * * 1-5 root /usr/bin/vcgencmd display_power 1

# Turn monitor off
30 19 * * 1-5 root /usr/bin/vcgencmd display_power 0

# Weekly Reboot just in case
0 7 * * 1 root /sbin/shutdown -r +10 "Monday reboot in 10 minutes"
EOF

Troubleshooting

YouTube Fail

You may find you must download the video manually and then upload to Anthias. Use the utility yt-dlp to list and then download the mp4 version of a video

yt-dlp --list-formats https://www.youtube.com/watch?v=YE7VzlLtp-4
yt-dlp --format 22 https://www.youtube.com/watch?v=YE7VzlLtp-4

WiFi Disconnect

WiFi can go up and down, and some variants of the OS do not automatically reconnect. You way want to add the following script to keep connected. This is mostly for the Pi as iwd is fault tolerant.

sudo touch /usr/local/bin/checkwifi
sudo chmod +x /usr/local/bin/checkwifi
sudo vim.tiny /usr/local/bin/checkwifi
#!/bin/bash

# Exit if WiFi isn't configured
grep -q ssid /etc/wpa_supplicant/wpa_supplicant.conf || exit 

# In the case of multiple gateways (when connected to wired and wireless)
# the `grep -m 1` will exit on the first match, presumably the lowest metric
GATEWAY=$(ip route list | grep -m 1 default | awk '{print $3}')

ping -c4 $GATEWAY > /dev/null

if [ $? != 0 ]
then
  logger checkwifi fail `date`
  service wpa_supplicant restart
  service dhcpcd restart
else
  logger checkwifi success `date`
fi
sudo tee /etc/cron.d/checkwifi << EOF
# Check WiFi connection
*/5 * * * * /usr/bin/sudo -H /usr/local/bin/checkwifi >> /dev/null 2>&1"
EOF

Hidden WiFi

If you didn’t set up WiFi during imaging, you can use raspi-config after boot, but you must add a line if it’s a hidden network, and reboot.

sudo sed -i '/psk/a\        scan_ssid=1' /etc/wpa_supplicant/wpa_supplicant.conf

Splash Screen

You may want to turn this off or adjust it.

# You can turn off the splash screen in the GUI or in the .conf
sed -i 's/show_splash =.*/show_splash = off/' /home/pi/.screenly/screenly.conf

# Or you can correct it in the docker file
vi ./screenly/docker-compose.yml

White Screen or Hung

Anthias works best when the graphics are the correct size. It will attempt to display images that are too large, but this flashes a white screen and eventually hangs the box (at least in the current version). Not all users get the hang of sizing things correctly, so if you have issues, try this script.

#!/bin/bash

# If this device isn't running signage, exit
[ -d /home/pi/screenly_assets ] || { echo "No screenly image asset directory, exiting"; exit 1; }

# Check that mediainfo and imagemagick convert are available
command -v mediainfo || { echo "mediainfo command not available, exiting"; exit 1; }
command -v convert  || { echo "imagemagick convert not available, exiting"; exit 1; }

cd /home/pi/screenly_assets

for FILE in *.png *.jpe *.gif
do
        # if the file doesn't exist, skip this iteration 
        [ -f $FILE ] || continue
        
        # Use mediainfo to get the dimensions at it's much faster than imagemagick              
        read -r NAME WIDTH HEIGHT <<<$(echo -n "$FILE ";mediainfo --Inform="Image;%Width% %Height%" $FILE)

        # if it's too big, use imagemagick's convert. (the mogify command doesn't resize reliably) 
        if [ "$WIDTH" -gt "1920" ] || [ "$HEIGHT" -gt "1080" ]
        then
                echo $FILE $WIDTH x $HEIGHT
                convert $FILE -resize 1920x1080 -gravity center $FILE
        fi
done

No Video After Power Outage

If the display is off when you boot the pi, it may decide there is no monitor. When someone does turn on the display, there is no output. Enable hdmi_force_hotplug in the `/boot/config.txt`` to avoid this problem, and specify the group and mode to 1080 and 30hz.

sed -i 's/.*hdmi_force_hotplug.*/hdmi_force_hotplug=1/' /boot/config.txt
sed -i 's/.*hdmi_group=.*/hdmi_group=2/' /boot/config.txt
sed -i 's/.*hdmi_mode=.*/hdmi_mode=81/' /boot/config.txt

Last modified May 27, 2026: Updated Signage for x86 (23969fa)