Ankündigung

Einklappen
Keine Ankündigung bisher.

Smart Mirror mit smartVISU

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Smart Mirror mit smartVISU

    Weil ich gefragt wurde, stelle ich hier meinen Magic Mirror vor. Eigentlich gibt es hier im KNX-UF erstaunlich wenig von solchen zu lesen.

    Auf die Hardware möchte ich nicht im Detail eingehen, dazu gibt es genügend Blogbeiträge zu finden.
    Meiner weicht vielleicht in zwei Punkten etwas vom üblichen ab:

    1. Da es ein Garderobenspiegel werden sollte, welcher relativ hoch und schmall (ca. 40 x 80cm) ist, konnte ich keinen vollflächigen Bildschirm verwenden.
    Ein 19" ohne Breitbild (also 5:4) wie er Ende der 0er-Jahren verbreitet war, hat sich von der Abmessung (Bildbreite 37.7cm, komplettes Panel ca. 39.5cm) als perfekt erwiesen und ist sehr günstig gebraucht zu bekommen.

    2. Weil der WAF nach etwas optisch nicht zu wuchtigem verlangte, hat mein Spiegel einen Aluminium- anstelle eines öfters anzutreffenden Holzrahmens.
    Damit er nicht zu dick wirkt, habe ich dafür U-Profile genommen, welche in der Tiefe nur den Spiegel und das Panel fassen. Dahinter habe ich dann etwas nach innen versetzt Leisten angebracht, um Platz für den Controller zu haben. Das ergibt eine Art Schattenfuge anstelle eines dicken durchgehenden Rahmens.
    Damit er nicht zu dick wird, habe ich einen Monitor mit externem Netzteil verwendet (Belinea 10 19 25 / 11 19 24). Die Schattenfuge konnte damit etwa gleich breit gewählt werden wie das Aluminiumprofil (28mm).
    Oben und unten hat er keine Leisten, so dass er gut hinterlüftet ist.


    Als Software nutze ich entgegen vielen anderen Projekte keine lokale Engine wie MagicMirror², sondern zeige einfach eine Seite der smartVISU im Browser an.
    Dies hat für mich diverse Vorteile:
    • Nutzung der bestehenden Visu und Infrastruktur.
    • Einfache Integration in KNX.
    • Sehr einfach aufzusetzen ohne ein neues Produkt zu erlernen.
    • Einmal aufgesetzt muss man am RasPi des Spiegels nichts mehr ändern, den Inhalt definiert man in der smartVISU.
    • Komplett freie Gestaltung mit HTML möglich.
    • Läuft problemlos auf einem günstigen Raspberry Pi Zero W.

    Dies alleine ist recht einfach einzurichten. Es muss nur ein Browser mit vordefinierter URL automatisch im Kioskmodus gestartet werden.
    Um etwas Struktur rein zu bringen, beschreibe ich dies separat im nachfolgenden Beitrag.

    P.S.: Natürlich könnt Ihr auch eine andere Visu verwenden, ich würde euch das jedoch übel nehmen.
    You do not have permission to view this gallery.
    This gallery has 3 photos.

    #2
    Alle grün geschriebenen Dateien habe ich auch gesammelt als ZIP angehängt, damit diese einfach reinkopiert werden können.

    Das Betriebssystem ist ein offizielles Raspbian Buster with desktop.
    Dessen Installation und Einrichtung beschreibe ich hier nicht, dies ist anderorts ausreichend nachzulesen. Ich bin dieser simplen Anleitung gefolgt, welche die Installation ohne Tastatur am RasPi in wenigen Schritten beschreibt.

    Beim Booten soll automatisch der Browser Chromium im Kioskmodus mit der entsprechenden URL geladen werden. Dazu ist folgende Konfiguration notwendig:


    1. Unclutter installieren per   sudo apt-get install unclutter . Dies wird gebraucht, um den Mauszeiger auszublenden.


    2.   sudo raspi-config  ausführen.
      3 - Boot Options - Configure options for start-up  öffnen.
      B1 - Desktop / CLI - Choose whether to boot into a desktop environment or the command line  auswählen.
      B4 - Desktop Autologin - Desktop GUI, automatically logged in as 'pi' user  setzen.

    Um zu verhindern, dass die Netwerkverbindung beim Start des Browsers noch nicht bereit ist, kann noch folgende Option gesetzt werden:
      B2 - Wait for Network at Boot - Choose whether to wait for network connection during boot  auf   Yes  setzen.


    3. Script um Chromium im Kioskmodus zu starten anlegen /opt/spiegel/kiosk.sh:
    Code:
    #!/bin/bash
    
    export DISPLAY=:0
    
    pkill -o chromium
    
    sed -i 's/"exited_cleanly": false/"exited_cleanly": true/' ~/.config/chromium/Default/Preferences &> /dev/null
    sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' ~/.config/chromium/Default/Preferences &> /dev/null
    
    chromium-browser --noerrdialogs --disable-infobars --kiosk "[COLOR=#FF0000]http://192.168.0.11/smartVISU/index.php?pages=spiegel[/COLOR]" &>/dev/null &
    Hier die URL eurer Visu-Seite eintragen. Ich verwende ein separates Pageset, welches ich mit dem Parameter   pages  aufrufe (möglich ab smartVISU 2.9).
    Für den einfacheren Aufruf kann man dem Script execution Recht geben per:   sudo chmod a+x /opt/spiegel/kiosk.sh 

    Diese Anweisungen können auch direkt im nachfolgenden Startscript integriert werden. Als separates Script kann es aber zusätzlich verwendet werden, um den Browser später neu zu starten (z.B. aufgerufen per SSH oder wie unten beschrieben per Taster). Deshalb steht auch das   pkill  zu Beginn drin. Dies ist etwa nötig, wenn man die Visu-Seite angepasst hat, sonst müsste man dazu den Raspberry neu booten.


    4. LXDE Startscript /etc/xdg/lxsession/LXDE-pi/autostart anpassen:
    Code:
    # Mauszeiger ausblenden
    @unclutter
    
    # Bildschirmschoner deaktivieren
    #@xscreensaver -no-splash
    @xset s off
    @xset -dpms
    @xset s noblank
    
    #Chromium im Vollbildmodus starten
    /bin/bash /opt/spiegel/kiosk.sh
    Damit zeigt der Spiegel nach einem Neustart die Visu an und erfüllt bereits seinen Zweck.

    Um den Monitor auszuschalten, kann am einfachsten die Netzspannung per KNX-Aktor geschalten werden. Den RasPi hingegen würde ich am Netz lassen, weil der Start sonst zu lange dauert und er nicht einfach ausgeschaltet sondern sauber heruntergefahrenwerden sollte.
    Da ich aber in der Nähe weder eine grüne Leitung noch geschaltete Adern habe, wollte ich dies im RasPi selbst lösen. Der Schaltbefehl von KNX kommt per SmartHomeNG (SHNG). Auch der Status wird auf diesem Weg zurückgemeldet.
    Zusätzlich lässt sich mein Panel auch lokal mit kapazitiven Sensoren ein- und ausschalten sowie den Browser neu starten. Damit könnten auch noch weitere beliebige Aktionen lokal oder per SmartHomeNG ausgelöst werden.Für diese Erweiterungen habe ich ein paar Scripts und Services erstellt, welche ich im nachfolgenden Beitrag beschreibe.
    Angehängte Dateien

    Kommentar


      #3
      Schalten per SmartHomeNG (und damit per KNX)

      Es gibt verschieden Möglichkeiten um den Monitor auszuschalten. Ich nutze mit   vcgencmd display_power 0  die einfachste. Der Monitor geht dadurch in den Standby. Die entsprechenden Befehle habe ich für einfaches Ein-, Aus- und Umschalten in ein Bash-Script verpackt. Dieses Script meldet auch den Status an SHNG unter Verwendung des Network-Plugins.
      Schaltbefehle von SHNG werden ebenfalls per Network-Plugin versendet und von einem Service empfangen. Auch dieser braucht nur ein kleines Bash-Script.

      Script für Displayschaltung /opt/spiegel/displaypower.sh:
      Code:
      #!/bin/bash
      
      # Argument einlesen
      arg=$1
      
      if [ -z "$arg" ] # kein Argument übergeben, Status umschalten
      then
      
        # aktuellen Status lesen
        displaystatus=$(vcgencmd display_power | tr -d '[:space:]' | tail -c 1)
      
        # Wert umdrehen
        if [ $displaystatus == "0" ]
        then
          arg=1
        else
          arg=0
        fi
      fi
      
      # Monitor schalten und neuen Status lesen
      displaystatus=$(vcgencmd display_power "$arg" | tr -d '[:space:]' | tail -c 1)
      
      # Neuen Status an SHNG melden
      echo "$displaystatus" | nc -uw 1 [COLOR=#FF0000]192.168.0.11[/COLOR] 4919
      
      echo "$displaystatus"
      Hier IP oder Hostname eures SHNG eintragen.
      Für den direkten Aufruf wieder das execution Recht setzen:   sudo chmod a+x /opt/spiegel/displaypower.sh Bei Aufruf ohne Argument schaltet das Script den Displaystatus um, mit einem Argument 0 oder 1 in den entsprechenden Zustand.

      Bash-Script für Netzwerkbefehl /opt/spiegel/displaycontroludp.sh:
      Code:
      #!/bin/bash
      
      # Erstes eingegangenes Zeichen lesen
      IFS= read -r -N 1 -t 5 arg
      
      now=$(date +"%T")
      echo $now "$arg"
      
      # Umsetzung von T(true) und F(alse) auf 1/0
      if [ $arg == "T" ]
      then
        arg=1
      elif [ $arg == "F" ]
      then
        arg=0
      fi
      
      # Monitor schalten, falls Argument 0 oder 1 ist
      if [ $arg -eq 0 ] || [ $arg -eq 1 ]
      then
        vcgencmd display_power $arg
      else # Meldung bei ungültigem Argument
        echo invalid argument \'"$arg"\'
      fi
      Service /etc/systemd/system/displaycontroludp.service:
      Code:
      [Unit]
      Description=Display Control Service
      After=network.target displaycontroludp.socket
      Requires=displaycontroludp.socket
      
      [Service]
      ExecStart=/bin/bash /opt/spiegel/displaycontroludp.sh
      StandardInput=socket
      
      [Install]
      WantedBy=multi-user.target
      Socket (nimmt automatisch eingehende Verbindungen an) /etc/systemd/system/displaycontroludp.socket:
      Code:
      [Unit]
      Description=Display Control Socket
      PartOf=displaycontroludp.service
      
      [Socket]
      ListenDatagram=4919
      
      [Install]
      WantedBy=sockets.target

      Network-Plugin in SHNG in ./etc/plugin.yaml einfügen:
      Code:
      nw:
          plugin_name: network
      SHNG Item:
      Code:
      Spiegel:
          type: bool
          knx_dpt: 1
          knx_cache: [COLOR=#FF0000]5/6/0[/COLOR]
          knx_send: [COLOR=#FF0000]5/6/1[/COLOR]
          knx_reply: [COLOR=#FF0000]5/6/1[/COLOR]
          visu_acl: rw
          nw_udp_send: "[COLOR=#FF0000]192.168.0.21[/COLOR]:4919=itemvalue"
          nw_udp_listen: 4919
      IP oder Hostname eures Spiegels eintragen sowie Gruppenadressen anpassen.

      Um den Socket danach zu aktivieren und starten folgendes eingeben:
      Code:
      sudo systemctl daemon-reload && sudo systemctl enable displaycontroludp.socket && sudo systemctl start displaycontroludp.socket

      Lokale Bedienung

      Für die lokale Bedienung hat mein Spiegel zusätzlich hinter dem unteren Rand verdeckt zwei kapazitive Sensoren (TTP223B Modul).Fasst man unten rechts oder links leicht hinter den Rahmen, kann man den Monitor ein- und ausschalten. (Es war eine WAF-Anforderung, damit man das Gesicht ohne Überlagerung betrachten kann).
      Aktiviert man den Taster länger, wird der Browser neu gestartet (notwendig, wenn man die Visu-Seite geändert hat oder er sich mal aufhängt). Dadurch muss man den RasPi nicht gleich ganz neu starten.
      Natürlich wären rechts und links auch unterschiedliche Aktionen möglich, z.B. blättern zwischen mehreren Visuseiten oder auch setzen von Items auf SHNG (wieder per Network Plugin).

      Das Python-Script für die Tasterauswertung /opt/spiegel/touchgpio.py:
      Code:
      #!/usr/bin/env python3
      import RPi.GPIO as GPIO
      import time
      
      from subprocess import call
      
      GPIO.setmode(GPIO.BCM)
      
      LONGTICKS = 20
      
      pins = {
          23: {
                  'press': lambda: print('Display set to {}'.format(call("./displaypower.sh")))
                  ,'long': lambda: print('Restart chromium {}'.format(call("./displaypower.sh 1 ; ./kiosk.sh", shell=True)))
                  #,'short': lambda: print('short 23')
                  #,'hold': lambda: print('hold 23')
                  #,'release': lambda: print('release 23')
              },
          24: {
                  'press': lambda: print('Display set to {}'.format(call("./displaypower.sh")))
                  ,'long': lambda: print('Restart chromium {}'.format(call("./displaypower.sh 1 ; ./kiosk.sh", shell=True)))
                  #,'short': lambda: print('short 24')
                  #,'hold': lambda: print('hold 24')
                  #,'release': lambda: print('release 24')
              }
      }
      
      for pin, conf in pins.items():
          GPIO.setup(pin, GPIO.IN)
          conf['pin_active'] = GPIO.input(pin)
          conf['ticks'] = 0
      
      
      while True:
      
          for pin, conf in pins.items():
      
              pin_active = GPIO.input(pin)
      
              if pin_active != conf['pin_active']:
      
                  if pin_active and 'press' in conf:
                      conf['press']()
      
                  elif not pin_active and 'release' in conf:
                      conf['release']()
      
                  if not pin_active and conf['ticks'] < LONGTICKS and 'short' in conf:
                      conf['short']()
      
                  conf['ticks'] = 0
                  conf['pin_active'] = pin_active
      
              elif pin_active:
      
                  if 'hold' in conf:
                      conf['hold']()
      
                  if conf['ticks'] == LONGTICKS and 'long' in conf:
                      conf['long']()
      
                  if conf['ticks'] <= LONGTICKS:
                      conf['ticks'] += 1
      
          time.sleep(0.1)
      Im oberen Teil lässt sich definieren, bei welcher Aktion an welchem GPIO was geschehen soll. Im vorliegenden Fall ist dies an Pin 23 und 24 Umschalten des Monitors bei Berührung sowie Einschalten und Browserneustart bei länger als 2 Sekunden halten.

      Dieses Script wird mit folgendem Service automatisch gestartet /etc/systemd/system/touchgpio.service:
      Code:
      [Unit]
      Description=Touch Input
      After=multi-user.target
      
      [Service]
      Type=simple
      ExecStart=/usr/bin/python3 /opt/spiegel/touchgpio.py
      WorkingDirectory=/opt/spiegel
      Restart=always
      RestartSec=3
      User=spiegel
      
      [Install]
      WantedBy=multi-user.target
      Auch diesen aktivieren und starten mit:
      Code:
      sudo systemctl daemon-reload && sudo systemctl enable touchgpio.service && sudo systemctl start touchgpio.service

      Das alles läuft bei mir jetzt schon etwa 2 Wochen sehr zufriedenstellend.
      Verbesserungs- und Erweiterungsvorschläge sind trotzdem gerne willkommen.

      Kommentar


        #4
        Guten Morgen,
        und danke für die sehr detaillierte Anleitung!

        Viele Grüße

        Kommentar


          #5
          Klasse gemacht!

          Darf ich fragen, was Du für ein Glas genommen hast? Ist das Spionglas oder normales Glas mit Spiegelfolie?
          Viele Grüße,
          Stefan

          DIY-Bastelprojekte: || >> Smelly One << || >> BURLI << ||

          Kommentar


            #6
            Wow, klasse Projekt!!! Vielen Dank für die detaillierte Anleitung. Wird also auch noch ein Projekt von mir sein

            Gruss aus Härkingen.

            Kommentar


              #7
              Es ist ein Glas-Spionspiegel 4mm mit 12% Transmission.
              Den Hersteller weiss ich nicht, ich habe ihn von einem Glasverarbeiter aus der Region.
              Gekostet hat er CHF 80.- für 40x90cm, was ähnlich oder sogar günstiger ist wie bei Deutschen Online-Händlern.

              Kommentar


                #8
                Danke Dir!
                Viele Grüße,
                Stefan

                DIY-Bastelprojekte: || >> Smelly One << || >> BURLI << ||

                Kommentar


                  #9
                  Servus Stefan, auch der - offensichtlich - "einzelne" dankt Dir ....
                  Gruß, JG

                  Kommentar


                    #10
                    Zugegebenermassen warst du nicht ganz der einzige.
                    Und meine Vermutung, dass es auch andere interessieren könnte, scheint sich bewahrheitet zu haben.

                    Kommentar


                      #11
                      Hat offensichtlich noch wer gefragt Danke.

                      Kommentar

                      Lädt...
                      X