DEV Community

loading...
Cover image for Aw, snap - refresh web app in Chromium kiosk mode after it breaks

Aw, snap - refresh web app in Chromium kiosk mode after it breaks

Kai Walter
35+ years software and IT project veteran
Updated on ・2 min read

Inspired by Scott Hanselmans wall mounted Family Calendar I installed a monitor with an attached Raspberry Pi Zero W 2 years back and been experimenting with various technical approaches to host the web page for this family board. Currently it is Blazor WebAssembly.

This app occasionally breaks (or has to recover from a wireless connection loss). Surely I will invest some time in the future to get down to the actual root cause of the problem, but until then I wanted to have a more or less intelligent way of refreshing when the kiosk app breaks.

setup required

  • Linux scrot utility to capture screen
  • Python 3 with PIL library installed to evaluate color of captured screen
  • xdotool to refresh Chromium page

shell script to drive the process

The script evalscreen.sh

  1. uses scrot to capture a low quality (20% is sufficient for evaluation) screen image
  2. runs image through Python script evalimage.py (see below)
  3. with Python script signals an error level not equal to 0 a refresh with xdotool is initiated
#!/bin/sh

export DISPLAY=:0.0
export XAUTHORITY=/home/pi/.Xauthority

scrot -q 20 screen.png

$(dirname "$0")/evalimage.py

if [ $? -eq 0 ]
then
    echo $(date -u) "OK"
else
    echo $(date -u) "Aborted->Refresh"
    xdotool key --window $(xdotool getactivewindow) ctrl+R
fi

This script is scheduled each minute with cron:

# m h  dom mon dow   command
*/1 *   *   *   *    /home/pi/evalscreen/evalscreen.sh >> /home/pi/evalscreen/evalscreen.log 2>&1

Python script to evaluate the image

Based on this StackOverflow post I created this Python script evalimage.py that determines the most present color in the captured image. As my family board has a black background I assume when the most present color is not black, it is broken. When assumed broken it exits with error level 1.

#! /usr/bin/python

from PIL import Image
import sys

def get_main_color(file):
    img = Image.open(file)
    colors = img.getcolors(256*1024) #put a higher value if there are many colors in your image
    max_occurence, most_present = 0, 0
    try:
        for c in colors:
            if c[0] > max_occurence:
                (max_occurence, most_present) = c
        return most_present
    except TypeError:
        #Too many colors in the image
    return (0, 0, 0)

if get_main_color('screen.png') != (0, 0, 0):
    print('Aw,snap')
    sys.exit(1)

cleaning up

Not to forget that the growing log file needs to be kept in check. For that I added a file /etc/logrotate.d/evalscreen:

/home/pi/evalscreen/evalscreen.log {
  rotate 12
  daily
  compress
  missingok
  notifempty
}

use & extend

You may use and extend these scripts from my repo by just cloning it to your pi users home.

closing

After looking into the issue itself after some days it turned out that I just needed to do a clean reinstall of chromium-browser and rpi-chromium-mods.

Discussion (3)

Collapse
sujal profile image
sujal

Hey there - this is a nice little utility. I'm about to modify it for my own kiosk screens at home. Do you have this checked into GitHub anywhere? Happy to fork and adapt so that people can easily follow along (and collaborate if needed). If not, will just reference this post when I stick it in my home automation catch all project.

Thanks for putting this together.

Sujal

Collapse
kaiwalter profile image
Kai Walter Author • Edited

Hey Sujal, sure not a problem. Added this repo: github.com/KaiWalter/evalscreen

Collapse
flavio_frontini_9b6718c36 profile image
Flavio Frontini

Hello, its really what i was looking for. Unfortunately i am not able to make it working on my Pi Zero. I get:
File "./evalimage.py", line 19
if get_main_color('screen.png') != (0, 0, 0):
^
IndentationError: expected an indented block

Do you have an idea of why?
Thank you!