Ein RapsberryPi (DoorPi) soll über einen NFC-Reader RFID-Tags auslesen. Ist die Tag-ID in der Liste der zugelassenen Tags, wird über ein Relais der Türöffner betätigt.
Die entsprechenden Daten über die Personen, die Zugriff auf die Türen bekommen sollen, werden im Graphen verwaltet. Werden die Daten dort geändert, werden diese Informationen automatisch an den DoorPi übertragen. Jeder Person können beliebig viele Tags und beliebig viele Türen zugeordnet werden.
Wird ein Tag an einen NFC-Reader gehalten, so wird ein Log-Eintrag im Graphen erzeugt, welcher die Information über den Zeitpunkt, die Tag-ID (und damit über die Person, wenn das Tag bekannt ist) und die Gewährung oder Verweigerung des Zugangs speichert.
Für die Umsetzung wird ein neues, lokales Graphmodul angelegt, welches über eine ControlPi-Instanz mit dem DoorPi in beide Richtungen kommuniziert.
Das singuläre Graphmodul doorpi
mit dem Kürzel d1
wird mit Hilfe des
Tasks "Graphmodul anlegen" erzeugt:
In diesem Graphmodul werden später alle für die DoorPi-Anwendung spezifischen Graphstrukturen angelegt.
Dann wird eine coRoot-Instanz für dieses Graphmodul mit Hilfe des Tasks "coRoot anlegen" erzeugt:
Die Strukturen, die später angepasst werden müssen, sind vor allem die
Aktionfunktion comessage_d1
und die Datenfunktion d1_coconf
.
Die Aktionfunktion comessage_d1
verarbeitet Nachrichten, die von der
coRoot-Instanz an den Graphen gesendet werden:
Die Datenfunktion d1_coconf
erzeugt die ControlPi-Konfiguration für die
coRoot-Instanz:
Diese enthält zunächst nur drei Instanzen der Plugins WSServer
, Graph
und Periodic
.
Mit der Instanz des Plugins WSServer
werden sich später untergeordnete
ControlPi-Instanzen verbinden.
Außerdem können ihr mit service('controlpi.send','d1',['key'=>'value']);
Nachrichten aus dem Graphen gesendet werden.
Die Instanz des Plugins Graph
synchronisiert Nachrichten, die dem
gegebenen Filter entsprechen, in den Graphen und wird ein Mal pro Sekunde
von der Instanz des Plugins Periodic
aufgerufen.
Diese Konfiguration wird später durch Strukturen erweitert, die aus den
weiteren Graph-Strukturen im Modul doorpi
abgeleitet werden.
Im automatisch generierten Tab ControlPi
des singulären Knotens des
Graphmoduls sind sowohl die Verknüpfung zur coRoot-Instanz als auch die
initial gesetzten Attribute zu sehen:
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.
Das WSServer
-Plugin stellt außerdem eine Debug-Oberfläche zur Verfügung:
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.
Die Vorlage für die Konfiguration der einzelnen DoorPis ist an der Instanz
des singulären Knotens d1Parameter im Attribut d1doorpicoconf
hinterlegt:
{
"Kartenleser": {
"plugin": "NFCReader"
},
"Türöffner": {
"plugin": "HackPin",
"pin": 2
},
Für den Kartenleser wird das Plugin NFCReader
aus dem Controlpi-Paket
controlpi-nfc verwendet,
zur Steuerung der Tür ein HackPin
-Plugin aus dem Paket
controlpi-pinio.
"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
},
Das Zusammenspiel von Kartenleser und Türöffner wird durch ein
StateMachine
-Plugin aus dem Paket
controlpi-statemachine
definiert.
"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"
}
}
]
},
Die Verbindung zur Root-Instanz wird über ein WSClient
-Plugin aus dem
Paket
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.
"Debug": {
"plugin": "WSServer",
"web": {
"/": {
"module": "controlpi_plugins.wsserver",
"location": "Debug"
}
}
}
}
Schließlich wird durch ein WSServer
-Plugin aus dem Paket
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 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:
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.