
-Die Aktionfunktion `coPushConf` synchronisiert die durch die Datenfunktion
+Die Aktionfunktion `copushconf` synchronisiert die durch die Datenfunktion
`d1_coconf` generierte Konfiguration auf die coRoot-ControlPi-Instanz
selbst.
Diese wird hierdurch mit dieser geänderten Konfiguration neu gestartet.
coRoot-Instanz](tutorials/doorpi/coRoot-Debug-Interface.png)
## Datenmodell erstellen
+Eine Übersicht über das Datenmodell ist im folgenden Diagramm dargestellt:
+
+
+
+Am singulären Knoten `d1` ist nur das Attribut `d1doorpicoconf`
+hinzugekommen.
+Es enthält die Vorlage für die Konfiguration einer DoorPi-Instanz, die im
+folgenden Abschnitt genauer angesehen wird.
+
+Mit der Instanz des singulären Knotens können beliebig viele
+d1DoorPi-Instanzen verknüpft sein.
+Um der Root-Instanz gegenüber identifizierbar zu sein, wird für jede
+d1DoorPi-Instanz die MAC-Adresse im Attribut `macadresse` hinterlegt.
+Diese kontrollieren jeweils das Öffnen einer Tür.
+
+Die Personen, die diese Tür öffnen dürfen sind durch mit den
+d1DoorPi-Instanzen verknüpfte d1Person-Instanzen repräsentiert, die
+wiederum mehrere durch d1NFCTag-Instanzen repräsentierte Tags besitzen
+können, mit denen sie die Türen öffnen können.
+
+Hierzu haben d1NFCTag-Instanzen ein Attribut `uid`, das in den
+Attributknoten `d1person_uids` und `d1doorpi_uids` aggregiert wird.
+
+Alle Versuche, sich an einem d1DoorPi zu identifizieren, sollen in
+d1Log-Instanzen protokolliert werden.
+Wenn das dabei verwendete NFC-Tag dem System bekannt sind, werden die
+zugehörigen d1NFCTag- und d1Person-Instanzen verknüpft.
+Außerdem wird festgehalten, ob die Tür geöffnet wurde.
## DoorPi einbinden
+Die Vorlage für die Konfiguration der einzelnen DoorPis ist an der Instanz
+des singulären Knotens d1Parameter im Attribut `d1doorpicoconf` hinterlegt:
+```json
+{
+ "Kartenleser": {
+ "plugin": "NFCReader"
+ },
+ "Türöffner": {
+ "plugin": "HackPin",
+ "pin": 2
+ },
+ "Tür": {
+ "plugin": "StateMachine",
+ "init": "zu",
+ "states": {
+ "zu": {
+ "commands": [
+ {
+ "target": "Türöffner",
+ "command": "set state",
+ "new state": false
+ }
+ ],
+ "transitions": [
+ {
+ "trigger": {
+ "sender": {
+ "const": "Kartenleser"
+ },
+ "event": {
+ "const": "changed"
+ },
+ "state": {
+ "const": true
+ },
+ "card": {"enum": []}
+ },
+ "to": "offen"
+ },
+ {
+ "trigger": {
+ "target": {
+ "const": "Tür"
+ },
+ "command": {
+ "const": "auf"
+ }
+ },
+ "to": "offen"
+ }
+ ]
+ },
+ "offen": {
+ "commands": [
+ {
+ "target": "Türöffner",
+ "command": "set state",
+ "new state": true
+ },
+ {
+ "target": "Offenhalten",
+ "command": "wait"
+ }
+ ],
+ "transitions": [
+ {
+ "trigger": {
+ "sender": {
+ "const": "Offenhalten"
+ },
+ "event": {
+ "const": "finished"
+ }
+ },
+ "to": "zu"
+ }
+ ]
+ }
+ }
+ },
+ "Offenhalten": {
+ "plugin": "Wait",
+ "seconds": 3
+ },
+ "DoorPi-Master": {
+ "plugin": "WSClient",
+ "url": "",
+ "client": "",
+ "up filter": [
+ {
+ "sender": {
+ "const": "Kartenleser"
+ },
+ "event": {
+ "const": "changed"
+ },
+ "state": {
+ "const": true
+ }
+ },
+ {
+ "sender": {
+ "const": "Tür"
+ },
+ "event": {
+ "const": "changed"
+ },
+ "state": {
+ "const": "offen"
+ }
+ }
+ ],
+ "down filter": [
+ {
+ "target": {
+ "const": "Tür"
+ },
+ "command": {
+ "const": "auf"
+ }
+ }
+ ]
+ },
+ "Debug": {
+ "plugin": "WSServer",
+ "web": {
+ "/": {
+ "module": "controlpi_plugins.wsserver",
+ "location": "Debug"
+ }
+ }
+ }
+}
+```
+
+Für den Kartenleser wird das Plugin `NFCReader` aus dem Controlpi-Paket
+[controlpi-nfc](https://docs.graph-it.com/graphit/controlpi-nfc) verwendet,
+zur Steuerung der Tür ein `HackPin`-Plugin aus dem Paket
+[controlpi-pinio](https://docs.graph-it.com/graphit/controlpi-pinio).
+Ihr Zusammenspiel wird durch ein `StateMachine`-Plugin aus dem Paket
+[controlpi-statemachine](https://docs.graph-it.com/graphit/controlpi-statemachine)
+definiert.
+
+Die Verbindung zur Root-Instanz wird über ein `WSClient`-Plugin aus dem
+Paket
+[controlpi-wsclient](https://docs.graph-it.com/graphit/controlpi-wsclient)
+hergestellt.
+Hierbei werden das Auflegen eines NFC-Tags und das Öffnen der Tür durch die
+Statemachine als Nachrichten an die Root-Instanz weitergegeben und der
+Befehl zum Öffnen der Tür von der Root-Instanz entgegen genommen.
+Schließlich wird durch ein `WSServer`-Plugin aus dem Paket
+[controlpi-wsserver](https://docs.graph-it.com/graphit/controlpi-wsserver)
+eine Debug-Oberfläche zur Verfügung gestellt.
+
+Auf einem DoorPi müssen also alle diese Pakete und ihre Abhängigkeiten
+installiert sein.
+Hierfür bietet sich das generiche
+[ControlPi-Image](https://docs.graph-it.com/graphit/controlpi-image) an.
+
+In der Datenfunktion `d1doorpi_coconf` müssen dann in dieser Vorlage nur
+noch die URL der Root-Instanz, der Name des DoorPi bzw. der Tür und die
+erlaubten NFC-Tags gesetzt werden:
+
+
+
+Die Konfiguration der Root-Instanz in der Datenfunktion `d1_coconf` wird so
+angepasst, dass sie die Konfigurationen der einzelnen DoorPis aufsammelt
+und jeweils, wenn diese eine Verbindung aufbauen auf diese überträgt:
+
+
## Kommunikation Graph<->DoorPi einrichten
+Vom Graphen zu den DoorPis findet (neben dem Pushen der Konfigurationen)
+nur eine Kommunikation durch die sehr einfache Aktionfunktion
+`d1doorpi_oeffnen` statt, die es ermöglicht, eine Tür manuell aus dem
+Graphen zu öffnen:
+
+
+
+In die andere Richtung wurde in den Konfigurationen der einzelnen
+DoorPi-Instanzen und der Root-Instanz bereits festgelegt, dass die
+Ereignisse beim Auflegen eines NFC-Tags auf die Kartenleser und beim Öffnen
+der Tür durch die Statemachine nach oben bis zum Graphen weitergegeben
+werden.
+
+Diese werden jetzt durch eine Überarbeitung der Aktionfunktion
+`comessage_d1` (die alle Nachrichten der Root-Instanz zum Graphmodul `d1`
+erhält) verarbeitet:
+
+
+
+Beim Auflegen einer Karte wird eine d1Log-Instanz angelegt, mit dem
+meldenden d1DoorPi verknüpft und die Zeit und die Tag-ID gesetzt.
+Wenn aufgrund eines solchen Ereignisses eine Tür geöffnet wird, wird der
+entsprechende Log-Eintrag gesucht und das Attribut `geoeffnet` entsprechend
+gesetzt.