Thomas' writings, builds, toys

2018-11-08

Home Assistant Touch Screen

Touch display on the wall

My 2017 Christmas present was a voucher for the local electronics shop. I spent it on an 'official 7" raspberry pi touch screen display', which is a nice capacitive touchscreen that you can hook up to a raspberry pi.

I 3d-printed an enclosure from thingiverse for it, and fitted an RGB LED string around the edges as an extra.

Initially I created an AppDaemon HAdashboard config to control my Home Assistant instance with it.

Software

Appdaemon serves the dashboard over HTTP, so the touchscreen's raspberry pi has to show them using a webbrowser.

GUI

The GUI is composed of browser-like 'tab' pages. These are actually all separate appdaemon dashboards, linking to each other with a common header of shortcut icons. Although this is is a raspberry pi 3, switching tabs is very slow. Because of this, and to have more configurability, I consider recreating this using python and pygame.

  • Lighting for ‘scenes’/’moods’
  • Internet radio control
  • Heating control
  • Security (sensors/siren)
Lighting control Heating control

Backlight

I created a simple bash daemon that exposes the pi's display backlight over MQTT, and it's integrated into home assistant as a simple light.

- platform: mqtt
  name: "vestel_bl"
  retain: false
  command_topic: "vestel_bl/cmd"
  state_topic: "vestel_bl/status"
  qos: 1
  payload_on: "on"
  payload_off: "off"

The shellscript polls the xset command to publish backlight status updates while it subscribes to turn on/off commands to call xset dpms to force the backlight on/off when wanted.

#!/bin/bash
set -ex

bl_reporter()
{
    OLD_STATE=""
    while true
    do
        NEW_STATE=$(xset q|grep "Monitor is"|cut -d' ' -f5 | tr '[:upper:]' '[:lower:]')
        if [ "$OLD_STATE" != "$NEW_STATE" ]
        then
            echo "State changed to $NEW_STATE"
            mosquitto_pub -h hass -u mqtt -P pass -t vestel_bl/status -m "$NEW_STATE"
        fi
        OLD_STATE="$NEW_STATE"
        sleep 0.5
    done
}
bl_reporter &

mosquitto_sub -h hass -u mqtt -P pass -t vestel_bl/cmd -v |while read -r message
do
    topic=$(echo "$message"|cut -d' ' -f 1)
    payload=$(echo "$message"|cut -d' ' -f 2)
    echo "topic ${topic}"
    echo "payload ${payload}"
    case $topic in
      vestel_bl/cmd)
        case $payload in
          on)
        xset dpms force on
        ;;
          off)
        xset dpms force off
        ;;
        *)
            echo "invalid command $payload"
        ;;
        esac

        ;;
      *)
        echo "Not implemented $topic"
        ;;
    esac
done

Startup

I wrote a bash script that starts Chromium in kiosk mode after Home assistant is started, it periodically polls the server and only starts the browser when the server is ready.

#!/bin/bash
#MQTT server IP/port
dst="192.168.2.25 1883"
service_cmd="/home/pi/tixel/tixel.py"
while true
do
    while ! nc -z $dst
    do
        #wait until the MQTT server is up
        #as a online-check of the HA server
        sleep 5
    done

    pid_service=
    while [[ -z $pid_service ]]
    do
        sleep 1
        #call jobs command so set baseline
        jobs &>/dev/null
        echo starting service
        $service_cmd 2>&1 &
        #call jobs -n to get new jobs since last jobs call
        new_job_started="$(jobs -n)"
        if [ -n "$new_job_started" ];then
        pid_service=$!
        else
        pid_service=
        fi
    done
    echo watching $pid_service

    #check both MQTT and subprocess
    while nc -z $dst
    do
        sleep 10
        if [ -n "$pid_service" -a ! -e /proc/$pid_service ]
        then
                break
        fi
        echo still alive
    done
    echo killing service / service stopped
    kill $pid_service
done

LED control

I added a DIY python daemon which connects to my MQTT server which I use to control the LED string using the Adafruit RGB pixel library.

Electronics

The LED string has APA102 LED's, which are daisy-chained, serially controlled using the pi's SPi Clk/Data lines.

The backside of the display

I didn't want to run 230V over the wires going to the display, so to overcome voltage drop on the line, I ran 12V, and included an Olimex DCDC converter to provide a stable 5V to the pi.

Raspberry pi and DCDC

Enclosure

I found this enclosure on thingiverse: https://www.thingiverse.com/thing:1503651 In the meantime I modelled it myself in OpenSCAD, ready to be used for a more customized re-spin.

Side of the display enclosure