Dieses Paket enthält ein Plugin für das ControlPi-System, mit dem Statemachines konfiguriert werden können, die auf Nachrichten des zentralen Nachrichten-Busses des ControlPi-Systems reagieren und bei Zustands-Wechseln Kommandos/Nachrichten an andere Komponenten des Systems schicken.
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-statemachine.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-statemachine.git
Eine minimale ControlPi-Konfiguration, die dieses Plugin benutzt, ist im git-Repository enthalten:
{
"Debug": {
"plugin": "WSServer",
"port": 8080,
"web": {
"/": { "module": "controlpi_plugins.wsserver",
"location": "Debug" }
}
},
"Engine Button": {
"plugin": "Alias",
"from": {
"target": { "const": "Engine Button" },
"command": { "const": "press" }
},
"to": {
"event": "pressed"
}
},
"Emergency Button": {
"plugin": "Alias",
"from": {
"target": { "const": "Emergency Button" },
"command": { "const": "press"}
},
"to": {
"event": "pressed"
}
},
"Engine": {
"plugin": "State"
},
"Delay": {
"plugin": "Wait",
"seconds": 5
},
"Machine": {
"plugin": "StateMachine",
"init": "off",
"states": {
"emergency": {
"commands": [
{
"target": "Engine",
"command": "set state",
"new state": false
}
],
"transitions": [
{
"trigger": {
"sender": { "const": "Emergency Button" },
"event": { "const": "pressed" }
},
"to": "off"
}
]
},
"off": {
"commands": [
{
"target": "Engine",
"command": "set state",
"new state": false
}
],
"transitions": [
{
"trigger": {
"sender": { "const": "Emergency Button" },
"event": { "const": "pressed" }
},
"to": "emergency"
},
{
"trigger": {
"sender": { "const": "Engine Button" },
"event": { "const": "pressed" }
},
"to": "on"
}
]
},
"on": {
"commands": [
{
"target": "Engine",
"command": "set state",
"new state": true
}
],
"transitions": [
{
"trigger": {
"sender": { "const": "Emergency Button" },
"event": { "const": "pressed" }
},
"to": "emergency"
},
{
"trigger": {
"sender": { "const": "Engine Button" },
"event": { "const": "pressed" }
},
"to": "delay"
}
]
},
"delay": {
"commands": [
{
"target": "Delay",
"command": "wait"
}
],
"transitions": [
{
"trigger": {
"sender": { "const": "Emergency Button" },
"event": { "const": "pressed" }
},
"to": "emergency"
},
{
"trigger": {
"sender": { "const": "Delay" },
"event": { "const": "finished" }
},
"to": "off"
}
]
}
}
}
}
Die Konfiguration einer StateMachine
-Plugin-Instanz enthält ein Attribut
init
, das den initialen Zustand der Maschine benennt, und ein Attribut
states
, das ein Objekt enthält, dessen Schlüssel alle möglichen Zustände
der Statemachine sind.
Für jeden Zustand wird in commands
eine Liste von Nachrichten angegeben,
die beim Betreten des Zustands gesendet werden sollen, während in
transitions
eine Liste von Transitionen definiert wird, die jeweils ein
Nachrichten-Schema als trigger
und den Zustand, in den gewechselt werden
soll, als to
haben.
In der Debug-Oberfläche sieht das Beispiel folgendermaßen aus:
Die beiden Alias
-Instanzen simulieren Taster und die State
-Instanz
Engine
einen Motor, der von der Statemachine gesteuert wird.
Aus dem initialen Zustand off
kann durch Drücken des Engine Button
in
den Zustand on
gewechselt werden.
Nochmaliges Drücken des Engine Button
schaltet die Maschine aber nicht
sofort ab, sondern wechelt in einen fünf-sekündigen Nachlauf im Zustand
delay
.
Dies wird dadurch erreicht, dass beim Betreten des Zustands dem
Wait
-Plugin Delay
das Kommando wait
geschickt wird und der Zustand
dann durch eine Transition, die auf das finished
-Event reagiert verlassen
wird.
Außerdem kann die Maschine aus jedem Zustand heraus durch Drücken des
Emergency Button
sofort abgeschaltet werden, wobei in den Zustand
emergency
gewechselt wird.
Dieser kann nur verlassen werden, wenn durch nochmaliges Drücken des
Emergency Button
bestätigt wird, dass die Gefahr vorüber ist.