Thomas shares makes

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 configuration to control my Home Assistant instance with it.

Software

AppDaemon serves the dashboard over HTTP, so the touchscreen's raspberry pi has to show the webpage using a web browser.

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 shell script 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

Liked something? Worked on something similar? Let me know what you think on Twitter!
You can direct-message me, or mention me @thouters