Graph-IT

ControlPi-Plugin für Websocket-Client

Dieses Paket enthält ein Plugin für das ControlPi-System, mit dem eine Websocket-Verbindung zu einer anderen ControlPi-Instanz mit einem WSServer-Plugin hergestellt werden kann.

Installation

Eine ausführliche Dokumentation ist in der Dokumentation der ControlPi-Infrastruktur zu finden.

Der Code dieses Plugins kann mit git geclonet werden:

$ git clone git://git.graph-it.com/graphit/controlpi-wsclient.git

(Falls Zugang zu diesem Server per SSH besteht und Änderungen gepusht werden sollen, sollte stattdessen die SSH-URL benutzt werden.)

Dann kann es editierbar in ein virtuelles Environment installiert werden:

(venv)$ pip install --editable <Pfad zum Code-Repository>

Auf dem Raspberry Pi (oder wenn keine Code-Änderungen gewünscht sind) kann es auch direkt, ohne einen git-Clone installiert werden:

(venv)$ pip install git+git://git.graph-it.com/graphit/controlpi-wsclient.git

Benutzung

Als Beispiel bauen wir eine kleine übergeordnete Steuerung auf. Es verbinden sich dabei zwei WSClient-Instanzen, switch und machine, mit einem Controller, und dieser sorgt dafür dass das Schalten des switch zur machine weitergeleitet wird.

Die Konfiguration des Controller ist:

{
    "Controller": {
        "plugin": "WSServer",
        "port": 8080,
        "web": {
            "/": { "module": "controlpi_plugins.wsserver",
                   "location": "Debug" }
        }
    },
    "Machine on": {
        "plugin": "Alias",
        "from": {
            "original sender": { "const": "switch/Switch" },
            "state": { "const": true }
        },
        "to": {
            "target": "machine/Machine",
            "command": "set state",
            "new state": true
        }
    },
    "Machine off": {
        "plugin": "Alias",
        "from": {
            "original sender": { "const": "switch/Switch" },
            "state": { "const": false }
        },
        "to": {
            "target": "machine/Machine",
            "command": "set state",
            "new state": false
        }
    }
}

Sie enthält nur das WSServer-Plugin, mit dem sich beide untergeordneten ControlPi-Instanzen verbinden und die beiden Alias-Plugins, die Zustände des Schalters an die Maschine weiterleiten. Hierbei wird davon ausgegangen, dass die untergeordneten Instanzen sich jeweils mit dem richtigen Namen anmelden und auch eine Plugin-Instanz des richtigen Namens enthalten. Dabei wird auf den Schlüssel "original sender" gematcht, da der "sender" innerhalb der übergeordneten Instanz die Websocket-Verbindung ohne weitere Unterscheidung ist, wir uns aber für genau eine Instanz auf der anderen Seite interessieren.

Die Konfiguration des Schalters ist:

{
    "Debug": {
        "plugin": "WSServer",
        "port": 8081,
        "web": {
            "/": { "module": "controlpi_plugins.wsserver",
                   "location": "Debug" }
        }
    },
    "Controller": {
        "plugin": "WSClient",
        "url": "ws://localhost:8080",
        "client": "switch",
        "up filter": [ { "sender": { "const": "Switch" } } ],
        "down filter": []
    },
    "Switch": {
        "plugin": "State"
    }
}

Und die Konfiguration der Maschine ist:

{
    "Debug": {
        "plugin": "WSServer",
        "port": 8082,
        "web": {
            "/": { "module": "controlpi_plugins.wsserver",
                   "location": "Debug" }
        }
    },
    "Controller": {
        "plugin": "WSClient",
        "url": "ws://localhost:8080",
        "interface": "eno1",
        "client": "machine",
        "up filter": [],
        "down filter": [ { "target": { "const": "Machine" } } ]
    },
    "Machine": {
        "plugin": "State"
    }
}

Ein WSClient-Plugin wird mit der "url" zur übergeordneten Instanz, einem "client"-Namen, unter dem sie sich dort anmeldet, und einem "up filter" und einem "down filter" konfiguriert, die angeben welche Nachrichten über den Websocket weitergeleitet werden sollen. In diesem Fall sollen vom Schalter nur Nachrichten des Switch nach oben weitergeleitet werden und von der Maschine nur Nachrichten an die Machine nach unten.

Außerdem kann optional ein interface angegeben werden, was zur Folge hat, dass im "connection opened"-Ereignis die MAC-Adresse dieses Interfaces mitgesendet wird. Dies kann z.B. genutzt werden, um der untergeordneten Instanz daraufhin automatisch ihre Konfiguration zu übermitteln. In der Debug-Oberfläche des Controllers sehen die beiden Verbindungs-Ereignisse demzufolge so aus:

Verbindungen in der Debug-Oberfläche

Jetzt wird in der Debug-Oberfläche des Schalters dieser geschaltet:

Debug-Oberfläche Schalter

Wir sehen dies in der Debug-Oberfläche des Controllers ankommen, was den entsprechenden Alias auslöst, der wiederum eine Nachricht an die Maschine auslöst:

Debug-Oberfläche Controller

Und in der Oberfläche der Maschine sehen wir schließlich, wie dieses dazu führt, dass die Maschine tatsächlich geschaltet wird:

Debug-Oberfläche Maschine