Visualisierung in Django – Anbindung von SPS und Pokey

Ziel der ganzen Automatisierung im Haus ist es für uns, viele Funktionen entweder gar nicht mehr zu bedienen, oder eine einfache und intuitive Bedienung zu ermöglichen. Um eine Funktion im Haus auszuführen, können wir entweder die normalen (Licht-)Schalter im Haus drücken oder auf die beiden Raspberry Pi Displays zurückgegriffen werden, auf denen die Visualisierung angezeigt wird.

Wie die Daten von den verschiedenen Komponenten auf diese Displays kommen, soll im folgenden gezeigt werden.

Zusammenwirkung der Komponenten

Die zentrale Komponente für die Visualisierung im Haus ist der auf Django basierende Webserver. Dieser liefert HTML, CSS und Javascript aus, wie man es von Webservern gewöhnt ist. Zum Django Webserver gehört auch die Datenbank MariaDB, die ebenfalls von der SPS direkt mit Daten gefüttert wird. Wie das geht, zeigt dieser Post. Weiterhin kommuniziert Django direkt mit der Beckhoff SPS per ADS.

Die Kommunikation mit dem Pokeys findet per UDP statt. Dabei sammelt unsere Django Instanz alle Daten zusammen und bereitet sie für die Visualisierung auf. Auch die eigentliche Visualisierung findet per Templates aus Django heraus statt.

Einsteig in die Visualisierung

Die beiden Raspberry Pis mit Display zeigen ihre jeweilige Startseite an, das eine im Hochformat, das andere im Querformat. Die Startseite im Wintergarten sieht dabei wie folgt aus:

Startbildschirm der Visualisierung

Die auf dieser Seite verwendeten Icons gehören zum KNX UF Iconset von OpenAutomationProject. Das Set ist sehr umfangreich und sehr gut für die Umsetzung einer Visualisierung geeignet.

Auf dem obigen Bild kann man schon einige Verknüpfungen zu anderen Komponenten im Haus erkennen. Diese haben wir teilweise in einzelnen Artikeln vorgestellt. Aktuell sind folgende Punkte vorhanden:

  • Temperatur: Anzeige der aktuellen Temperatur im Wintergarten und Link auf Daten der Wetterstation im Garten
  • Musik: Anzeige des Status einer Heos Box und Link auf Steuerungsseite für diese Box (über das Heos Telnet Protocol)
  • Beleuchtung: Link auf Lichtsteuerung im Wintergarten (über die SPS)
  • Beschattung: Link auf Markisensteuerung im Wintergarten (über die SPS)
  • Bewässerung: Gartenbewässerung über den Pokeys steuern (Teil 1)

Zusammenspiel zwischen Django, SPS und Pokeys

Für die Beleuchtung und Beschattung nutzen wir die ADS Kommunikation mit der SPS. Diese nutzen wir auch für eine andere Funktion, die auf einen anderen Teil der Visualisierung angeboten wird. Dabei handelt es sich um die Visualisierung der Zustände der Räume, aktuell sind das Licht und Temperatur.

Wie das aussieht, kann man im folgenden sehen:

Visualisierung - Darstellung Zustand des Kellers

Das Bild zeigt unseren Keller, wobei in einem Raum das Licht angeschaltet ist. Die Lampen können wir durch einen Klick an- und ausgeschalten. In 4 Räumen sind außerdem Messpunkte für die Temperatur vorhanden, die wir ebenfalls anzeigen.

Darstellung per SVG und CSS

Den dargestellten Grundriss haben wir mit SVG gezeichnet. SVG ist sehr ähnlich zu HTML. Aktuelle Browsern verstehen es nativ, so dass man damit recht einfach Grafiken erzeugen kann. Es gibt diverse Tools um automatisiert SVG zu erzeugen, aber für so eine einfache Abbildung wie den Grundriss funktioniert das auch manuell sehr gut. Für den Grundriss verwenden wir einfache Linien, als Polyline mit diversen Koordinaten als Eckpunkte versehen sind.

Die Lampen sind einfache Kreise im SVG und die Temperaturen werden per Text-Element eingeblendet. Zusammengefasst in einem Django Template sieht es wie folgt aus:

 <svg>
     <g id="base">
         <polyline id="out" class="white" points="300,60 120,60 120,330 280,330 280,390 590,390 590,10 460,10 300,10 300,60" />
         <polyline id="r1" class="white" points="280,330 280,200  120,200" />
         <polyline id="r2" class="white" points="200,330 200,270 280,270" />
         <polyline id="r3" class="white" points="280,200 280,60" />
         <polyline id="r4" class="white" points="280,100 590,100" />
         <polyline id="r5" class="white" points="280,200 340,200 340,260 440,260 440,340 590,340"  />
         <polyline id="r6" class="white" points="440,260 590,260" />
     </g>
     <g id="lights">
         <circle id="1101" class="{% if lights.1101 %}on{%else%}off{% endif %}" cx="340" cy="320" r="10"/> 
         <a xlink:href="/sensor/1202/{% if lights.1202 %}off{%else%}on{% endif %}/?redirect=/room/kg/">
             <circle class="black" cx="250" cy="300" r="20"/>
             <circle id="1202" class="{% if lights.1202 %}on{%else%}off{% endif %}" cx="250" cy="300" r="10"/> 
         </a>
         <!-- weitere Lampen -->
     </g>
     <g id="temps">
         <text id="1380" class="temp" x="220" y="220">{{temps.1380}}</text> 
         <text id="1480" class="temp" x="220" y="190">{{temps.1480}}</text> 
         <text id="1580" class="temp" x="420" y="90" >{{temps.1580}}</text> 
         <text id="1680" class="temp" x="350" y="250">{{temps.1680}}</text> 
     </g>
 </svg>

Damit die Visualisierung klappt, benötigen wir im CSS einige Definitionen. Hier ein paar Beispiele, wie diese aussehen können.

svg .white {
    stroke: #FFFFFF;
    stroke-width: 3;
    fill: none;
}

svg #lights circle.on {
    stroke: #FFFFAA;
    stroke-width: 2px;
    fill: #FFFFAA;
}

Die SVG spezifischen Styles sind dabei zwischen den Styles für HTML eingebunden. Auch die Adressierung funktioniert analog.

In dem weiter oben stehenden SVG Template sind auch einige Variablen in geschweiften Klammern zu erkennen. Diese werden in der View von Django mit Daten gefüllt. Der View sieht dabei wie folgt aus:

from django.views import View
from django.shortcuts import render

class KGView(View):
    def get(self, request):
        light_status = get_sensor_data("1101,1202,1302,1401,1501,1601")
        temps = dict()
        temps['1380'] = Sensor.objects.get(id='1380').formatted_value
        temps['1480'] = Sensor.objects.get(id='1480').formatted_value
        temps['1580'] = Sensor.objects.get(id='1580').formatted_value
        temps['1680'] = Sensor.objects.get(id='1680').formatted_value
        context = {'lights': light_status, 'temps': temps}
        return render(request, 'show_kg.html', context)

Sammeln der Daten

Ein View bei Django ist ein Klasse, in der die Funktion get implementiert sein muss, wenn man per GET-Request auf die HTML Seite zugreift. Bei Formularen, die man per POST verwendet nutzen wir dementsprechend eine post Funktion.

Den Parameter request werten wir nicht aus, übergeben ihn aber an die render Funktion, die am Ende die Webseite erzeugt.

Daten per ADS abfragen

Als erstes sammeln wir den aktuellen Zustand aller Lampen ein. Dies passiert in der get_sensor_data Funktion. Diese Funktion fragt die Daten per ADS ab.

Grundsätzlich bauen wir dazu auf der Funktion, die hier beschrieben ist auf. Wir fassen mit der get_sensor_data Funktion nur das Sammeln mehrerer Sensoren zusammen, um in der View gleich die gesammelten Sensordaten weiterverarbeiten zu können.

Daten vom Pokey auslesen

Danach holen wir die Daten der Temperatur Sensoren ab. Dies ist als eine Funktion im Sensor Model implementiert, die die Daten in der Datenbank konvertiert. Die Daten für die Temperatur lesen wir also immer aus der Datenbank aus. Dafür müssen die Daten also regelmäßig vom Pokeys abgefragt und danach in die Datenbank geschrieben werden.

Übergabe ans Template

Die gesammelten Daten können einfach als Dictionary an das Template übergeben werden. Dadurch stehen sie dann als Variablen im Template zur Verfügung und können dort wie oben beschrieben mit geschweiften Klammern ausgewertet werden.

Wie geht es weiter mit der Visualisierung …

Django bietet eine einfache Möglichkeit, Daten aus verschiedenen Quellen zusammenzutragen und an das HTML Template zu übergeben. So sollen immer mehr Systeme angebunden werden. Um hier eine bessere Struktur auszubauen, werden die Anwendungen zukünftig in Containern separiert. Wie das geht, zeigt bald ein neuer Artikel.

Eine Antwort auf „Visualisierung in Django – Anbindung von SPS und Pokey“

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.