• 1 Post
  • 17 Comments
Joined 2 years ago
cake
Cake day: June 12th, 2023

help-circle












  • It’s really quite simple - but works pretty well. There are 3 components:

    Kiosk service

    A simple systemd service that starts a kiosk script.

    [Unit]
    Description=Kiosk
    Wants=graphical.target
    After=graphical.target
    
    [Service]
    Environment=DISPLAY=:0.0
    Environment=XAUTHORITY=/home/pi/.Xauthority
    Type=simple
    ExecStart=/bin/bash /home/pi/kiosk.sh
    Restart=on-abort
    User=pi
    Group=pi
    
    [Install]
    WantedBy=graphical.target
    

    Kiosk script

    The script in /home/pi/kiosk.sh just starts a web browser in full-screen mode pointed at my home assistant instance:

    #!/bin/bash
    
    xset s noblank
    xset s off
    xset -dpms
    
    export DISPLAY=:0.0 
    
    echo 0 > /sys/class/backlight/rpi_backlight/bl_power
    
    LANDING_PAGE="https://homeassistant.example.com/"
    
    unclutter -idle 0.5 -root &
    
    /usr/bin/chromium-browser --noerrdialogs --disable-infobars --kiosk $LANDING_PAGE
    
    

    Display service

    I have a very simple python/flask service that runs and exposes an endpoint that lets you turn on/off the display. It’s called by a homeassistant automation for when the motion detector senses or hasn’t sensed movement.

    Here’s the python - I have this started from another “kiosk.service” systemd service as well.

    #!/usr/bin/env python3
    import subprocess
    
    from flask import Flask
    from flask_restful import Api, Resource
    
    def turn_off_display():
        with(open(backlight_dev, 'w')) as dev:
            dev.write("1")
    
    
    def turn_on_display():
        with(open(backlight_dev, 'w')) as dev:
            dev.write("0")
    
    
    class DisplayController(Resource):
        def get(self, state):
            if state == 'off':
                turn_off_display()
            elif state == 'on':
                turn_on_display()
            else:
                return {'message': f'Unknown state {state} - should be off/on'}, 500
            return {"message": "Success"}
    
    
    def init():
        turn_on_display()
    
    
    if __name__ == "__main__":
        init()
        app = Flask(__name__)
        api = Api(app)
        api.add_resource(DisplayController, '/display/<string:state>')
        app.run(debug=False, host='0.0.0.0', port=3000)
    

    You can then have the HA rest action call this with “http://pidisplay:3000/display/on” or off.


  • For apt to install a local file I think you need either a fully qualified path or to use “./” at the start for a relative path.

    So “./$1/opensnitch_${1}_amd64.deb”

    apt install 1.6.5/opensnitch_1.6.5_amd64.deb 1.6.5/python3-opensnitch-ui_1.6.5_all.deb

    Edit: Here’s a better example of what I think you would want:

    #!/bin/bash
    # Often good to assign a numbered parameter to a variable
    VER="${1}"
    apt install "./${VER}/opensnitch_${VER}_amd64.deb" "./${VER}/python3-opensnitch-ui_${VER}_all.deb"
    

    Also - when debugging bash scripts it’s often helpful to just put “echo” before the line you’re questioning to see what exactly is being run. e.g.:

    #!/bin/bash
    VER="${1}"
    echo apt install "./${VER}/opensnitch_${VER}_amd64.deb" "./${VER}/python3-opensnitch-ui_${VER}_all.deb"
    

    That will show the the command that would have run rather than running it, then you can inspect it for errors and even copy/paste it to run it by hand.