Skip to content

Commit

Permalink
Merge pull request #608 from peuter/dev-docs
Browse files Browse the repository at this point in the history
add some background documentation for developers
  • Loading branch information
ChristianMayer committed Sep 9, 2017
2 parents 0350743 + 01a4996 commit f8c5f2b
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 4 deletions.
2 changes: 1 addition & 1 deletion doc/manual/de/colab/dev/test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Zu kann man z.B. prüfen ob das Klicken auf einen Switch den passenden Wert an d
wenn das Backend ein Update für den Switch liefert, dieser diesen entsprechend anzeigt.

Unittests
----------
---------

Als Testrunner für die Unittests kommt `Karma <https://karma-runner.github.io>`__ zum Einsatz.
Ausgeführt werden die Tests über das Kommandozeilen-Tool Grunt.
Expand Down
1 change: 1 addition & 0 deletions doc/manual/de/colab/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ Mithilfe bei der Entwicklung
* ..

.. toctree::
:glob:

dev/test

Expand Down
Empty file.
2 changes: 2 additions & 0 deletions doc/manual/de/config/url-params.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ funktionieren.
Default: 0 (testMode=0)
Options: 0 (testMode=0), 1 (testMode=1)
.. _enableCache:

*enableCache* - Caching aktivieren
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
176 changes: 176 additions & 0 deletions doc/manual/de/devel/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
****************************
Informationen für Entwickler
****************************

Diese Seite liefert eine Einführung in die internen Zusammenhänge und Hintergründe der CometVisu und richtet sich in
erster Linie an Entwickler.

Grundlagen der Software
-----------------------

Die CometVisu ist seit Version 0.11 auf dem `Qooxdoo-Framework <http://www.qooxdoo.org>`__ aufgebaut.
Das Qooxdoo Framework bietet ein eigenes Objekt-Orientiertes Klassensystem (inkl. erweiterten Features wie: Interfaces
Mixins, Abstakte Klasse, Singletons, einfache Type-Checks für Properties, usw.) mit dem sich ein komplexes und
dennoch strukturiertes Software-System aufbauen lässt.

Ebenso liefert es eine vollständige Toolchain (Qooxdoo-Generator) mit, die Klassenabhängigkeiten automatisch auflöst und daraus
entweder Entwickler Versionen (source-Version) oder Releases (build-Versionen) baut.

Unterschiede in der Javascript-Unterstützung der verschiedenen Browser werden automatisch ausgeglichen und der
Generator erstellt für die Releases unterschiedliche Build-Versionen für die 4 wichtigsten Browser-Engines.

Weitere Qooxdoo-Features die die CometVisu nutzt:

* `Parts <http://www.qooxdoo.org/current/pages/development/parts_using.html>`__:
Teile des Codes, die nicht immer benötigt werden, werden in *Parts* ausgelagert, die bei Bedarf nachgeladen werden.
Die CometVisu nutzt dies für Plugins und die Widget-Pakete (Es gibt zwar momentan nur das *Pure*-Widgetpaket,
weitere sind jedoch möglich).

Da die CometVisu eigene Widgets liefert inkl. Layout und CSS-basiertem Design, wird der komplette UI Teil von
Qooxdoo nicht benutzt. Dieser liefert eigene Layoutmanager und Widgets mit nicht CSS-basiertem Design.
Es wäre jedoch möglich ein neues auf Qooxdoo-UI basierendes Widgetpaket zu implementieren, welches parallel nutzbar ist.

Startverhalten
--------------

Der Ablauf des Ladens der Visu läuft nach dem CometVisu-Protokoll in folgenden Schritten:

.. uml::
:caption: Start-Kommunikation zwischen CometVisu und Backend
:align: center

autonumber

CometVisu -> Backend: Lade Konfigurationsdatei
Backend -> CometVisu: Konfigurationsdatei mit optionalen Headern schicken
CometVisu -> Backend: Login
Backend -> CometVisu: Bestätigung des Logins mit optionaler Backend-Konfiguration
CometVisu -> Backend: Lese Werte vom Backend


#. Laden der Konfigurationsdatei ``visu_config*.xml``
#. Der Server kann diese Datei mit 2 optionalen Headern ausliefern, die der CometVisu weitere Informationen
über das Backend zu liefern:

* ``X-CometVisu-Backend-LoginUrl``: Pfad unter der der Client das Login ausführen kann.
* ``X-CometVisu-Backend-Name``: Der Name des zu verwendenden Backends.
#. Die CometVisu authentifiziert sich beim Backend (zur Zeit implementiert kein Backend eine echte Authenfizierung)
#. Das Backend bestätigt die Authentifizierung und liefert Informationen als JSON zurück:

``v``: Ist die Protokollversion

``s``: Die Session ID

``c``: Die optionale Backend-Konfiguration


.. code-block:: json
{
"v":"0.0.1",
"s":"0",
"c": {
"name":"openhab2",
"transport":"sse",
"baseURL":"/rest/cv/",
"resources": {
"read":"r",
"rrd":"rrdfetch",
"write":"w"
}
}
}
#. Die CometVisu fängt an die Werte vom Backend abzufragen, zunächst initial alle benötigten Werten und im
zweiten Schritt wird nur noch auf Änderungen der Werte gelauscht.

Transportschichten
------------------

Die Transportschichten sind für die Kommunikation zwischen CometVisu und Backend ab dem Moment des erfolgreichen
Logins verantwortlich. Die wesentliche Aufgabe besteht also darin, Werte vom Backend abzufragen (lesende Anfrage)
und Wertänderungen zum Backend zu schicken (schreibende Anfrage).

Zur Zeit unterstützt die CometVisu zwei unterschiedliche Transportschichten:

* :ref:`Long polling <long-polling>`: wird vom Default-Backend benutzt
* :ref:`Server sent events <sse>`: wird vom openHAB-Backend benutzt

.. toctree::

transport/long-polling
transport/sse

Caching
-------

Die CometVisu nutzt eigene Caching Mechanismen um das initiale Laden zu beschleunigen.
Die meiste Zeit wird benötigt um die XML-Konfigurationsdatei vom Server zu laden, dann zu parsen und daraus
den HTML Code zu generieren der die tatsächliche Visu im Browser darstellt.

Da sich der Inhalt der Konfigurationsdatei in der Regel selten ändert, liegt es Nahe diese nicht jedesmal erneut zu laden und
zu parsen. Daher wird nach dem ersten Parsen der erzeugte HTML und die internen Datenstrukturen im *LocalStorage* des Browsers
abgespeichert. Beim nächsten Laden der Visu werden diese Daten ausgelesen und die Oberfläche sofort dargestellt.
Erst danach fragt die Visu die Konfigurationsdatei vom Server ab und vergleicht ob es Änderungen gegeben hat.
Sofern dies nicht der Fall ist wird die gerade geladenen Datei verworfen, andernfalls der Parse und Speicher-Vorgang erneut
durchgeführt und die Daten aus dem Cache werden verworfen.

Das Caching kann durch den URL-Parameter :ref:`enableCache` beeinflusst werden.


Der NotificationRouter
----------------------

Es gibt einen internen ``NotificationRouter`` der für verschiedene Zwecke benutzt wird.
Hauptfunktion dieses Routers ist es Nachrichten entgegenzunehmen und an den richtigen
Empfänger weiterzuleiten. Mögliche Empfänger sind z.B. das ``NotificationCenter`` und der
``PopupHandler``. Beide kümmern sich dann um die Anzeige der Nachricht, entweder in der Nachrichtenzentrale (die am
rechten Rand eingeblendet wird und eine Liste von Nachrichten anzeigt) oder als Popup.

Eine Nachricht hat immer ein *Topic*, welches der thematischen Zuordnung dient, einen Titel, Text und diverse
Konfigurations-Optionen.

Folgenden *Topics* werden zur Zeit genutzt:

* ``cv.error``: Allgemeine Fehler
* ``cv.config.error``: Fehler die beim Einlesen der Config-Datei aufgetreten sind
* ``cv.state.*``: Namespace für alle in den :ref:`Benachrichtigungen <notifications>` benutzten Nachrichten

Ein Nachrichtenempfänger (``NotificationHandler``) kann sich nun für eines oder mehrere solcher Topics registrieren:

.. code-block:: javascript
cv.core.notifications.Router.getInstance().registerMessageHandler(this, {
'cv.config.error': {
type: "error",
icon: "message_attention"
},
'cv.error': {
type: "error",
icon: "message_attention"
}
});
Auch Wildcards sind möglich:

.. code-block:: javascript
cv.core.notifications.Router.getInstance().registerMessageHandler(this, {
'cv.*': {}
});
Fehlerbehandlung
----------------

Der NotificationRouter wird auch dazu genutzt alle nicht abgefangenen Fehler zur Laufzeit der Visu anzuzeigen.
Diese Fehler werden als Popup angezeigt und ermöglichen es dem Nutzer direkt ein Issue auf Github mit vorausgefüllten
Formular mit den wichtigsten Informationen zu eröffnen. Diese Funktion ist nur
in den Build-Versionen aktiv (also auch in den Releases), während der Entwicklung werden die Fehler weiterhin
auf der Javascript-Konsole des Browsers angezeigt.

Weitere Fehler werden, je nach Art, entweder als Popup oder als Nachricht in der Nachrichtenzentrale angezeigt.
Als ein wichtiges Beispiel wären hier noch Verbindungsprobleme mit dem Backend zu nennen. Diese werden ebenfalls
als Popup über der Visu angezeigt, solange das Problem besteht.

Der ``NotificationRouter`` wird ebenfalls für die :ref:`Benachrichtigungen <notifications>` genutzt.
25 changes: 25 additions & 0 deletions doc/manual/de/devel/transport/long-polling.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.. _long-polling:

Long polling
^^^^^^^^^^^^

Lesende Anfragen
****************

Beim Long polling stellt die CometVisu eine Verbindung zum Backend her und lässt diese offen bis das Backend Daten sendet.
Die initiale Anfrage nach allen Werten beantwortet das Backend sofort. Die darauffolgenden Anfragen werden beantwortet,
sobald ein neuer Wert eintrifft. Dieser wird dann an die CometVisu gesendet, worauf die Verbindung geschlossen und sofort
wieder aufgebaut wird.

.. HINT::

Als Besonderheit ist hier noch der interne *Watchdog* zu nennen, welcher eine Long polling Anfrage automatisch
beendet und neu started, wenn innerhalb von 60 Sekunden keine Antwort gekommen ist.

Schreibende Anfragen
********************

Wenn ein neuer Wert an das Backend gesendet werden soll (weil z.B. der Benutzer ein Widget bedient hat), wird
eine neue Anfrage, die vollkommen unabhängig von den lesenden Anfragen ist, an das Backend gesendet.
Hier bestätigt das Backend auch lediglich das erfolgreiche Empfangen der Anfrage, neue Werte werden immer nur über
die lesenden Anfragen gesendet.
25 changes: 25 additions & 0 deletions doc/manual/de/devel/transport/sse.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.. _sse:

Server sent events (SSE)
^^^^^^^^^^^^^^^^^^^^^^^^

Lesende Anfragen
****************

Bei *Server sent events* wird eine einmalige lesende Verbindung aufgebaut. Über diese schickt das Backend
initial einmalig alle angefragten Werte, danach nur noch geänderte Werte.

.. HINT::
Der Browser kümmert sich automatisch um die Wiederherstellung der Verbindung bei Abbrüchen.
Daher kommt der interne *Watchdog* bei SSE in der Regel nicht zum Einsatz.

Der Browser muss diese Technologie jedoch überstützen.
Eine Übersicht der unterstützen Browser liefert `Caniuse <http://caniuse.com/eventsource/embed/>`__.

Schreibende Anfragen
********************

Wenn ein neuer Wert an das Backend gesendet werden soll (weil z.B. der Benutzer ein Widget bedient hat), wird
eine neue Anfrage, die vollkommen unabhängig von den lesenden Anfragen ist an das Backend gesendet.
Hier bestätigt das Backend auch lediglich das erfolgreiche Empfangen der Anfrage, neue Werte werden immer nur über
die lesenden Anfragen gesendet.
1 change: 1 addition & 0 deletions doc/manual/de/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,6 @@ oder `hier <http://de.selfhtml.org/helferlein/farben.htm>`__
install/index
config/index
colab/index
devel/index
faq

2 changes: 1 addition & 1 deletion source/resource/visu_config.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
<xsd:attribute name="flavour" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>level:expert</xsd:appinfo>
<xsd:documentation xml:lang="en">Selection of a display variant. See also :ref:'flavour'.</xsd:documentation>
<xsd:documentation xml:lang="en">Selection of a display variant. See also :ref:`flavour`.</xsd:documentation>
<xsd:documentation xml:lang="de">Auswahl der Darstellungsvariante. Siehe auch :ref:`Flavour &lt;flavour&gt;`.</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
Expand Down
4 changes: 2 additions & 2 deletions utils/docutils/directives/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
import sh
import json
import os
import ConfigParser
import configparser

root_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..', '..', '..'))

class Version:
_source_version = None
config = ConfigParser.ConfigParser()
config = configparser.ConfigParser()
config.read(os.path.join(root_dir, 'utils', 'config.ini'))

@classmethod
Expand Down

0 comments on commit f8c5f2b

Please sign in to comment.