From: Benjamin Braatz Date: Fri, 5 Mar 2021 10:55:35 +0000 (+0100) Subject: Harmonise state message conventions X-Git-Tag: v0.3.0~73 X-Git-Url: http://git.graph-it.com/?a=commitdiff_plain;h=08bf4e7c318debf4f91d6acc7ca2327bdb26b7fe;p=graphit%2Fcontrolpi.git Harmonise state message conventions Change from 'changed' Boolean to 'event': 'changed', document 'event': 'changed', 'get state' and 'set state'. --- diff --git a/conf.json b/conf.json index 468ecea..d2be665 100644 --- a/conf.json +++ b/conf.json @@ -62,7 +62,7 @@ "State Change Logger": { "plugin": "Log", "filter": [ - { "sender": "Example State", "changed": true } + { "sender": "Example State", "event": "changed" } ] } } diff --git a/controlpi-plugins/util.py b/controlpi-plugins/util.py index 0e598a2..68f78b3 100644 --- a/controlpi-plugins/util.py +++ b/controlpi-plugins/util.py @@ -1,7 +1,7 @@ """Provide utility plugins for all kinds of systems. TODO: documentation, doctests, check configurations during _process_conf -TODO: State, AndState, OrState? +TODO: AndState, OrState? """ import asyncio @@ -75,19 +75,19 @@ class State(BasePlugin): async def _receive(self, message: Message) -> None: if 'command' in message: if message['command'] == 'get state': - await self._bus.send({'sender': self._name, - 'state': self._state, - 'changed': False}) + answer = {'sender': self._name, 'state': self._state} + await self._bus.send(answer) elif message['command'] == 'set state': if 'state' in message and self._state != message['state']: self._state: bool = message['state'] - await self._bus.send({'sender': self._name, - 'state': self._state, - 'changed': True}) + event = {'sender': self._name, 'event': 'changed', + 'state': self._state} + await self._bus.send(event) def _process_conf(self, conf: PluginConfiguration) -> None: self._state = False - sends: list[Message] = [{'sender': self._name, 'state': bool}] + sends: list[Message] = [{'event': 'changed', 'state': bool}, + {'state': bool}] receives: list[Message] = [{'target': self._name, 'command': 'get state'}, {'target': self._name, diff --git a/doc/index.md b/doc/index.md index 2d95ac2..eb05ba8 100644 --- a/doc/index.md +++ b/doc/index.md @@ -125,6 +125,8 @@ eingehalten werden, sind aber: Sie haben in der Regel einen Schlüssel `'event'` mit einem Wert, der die Art des Ereignisses passend benennt und eventuell weitere Schlüssel, die dieses näher beschreiben. + Auch das Registrieren und Deregistrieren von Klienten am Bus selbst wird + als Ereignis mit einem `'event'`-Schlüssel signalisiert. - Einige Nachrichten sind als Kommandos an einen bestimmten Klienten gedacht. Sie haben in der Regel einen Schlüssel `'target'` mit dem Namen dieses @@ -135,6 +137,27 @@ eingehalten werden, sind aber: Debug-Oberflächen, diese Nachrichten empfangen und verarbeiten, da `'target'`-Schlüssel von der Infrastruktur bzw. dem Bus nicht speziell behandelt werden.) +- Das `State`-Plugin ist ein Beispiel, welche Nachrichten (Boolesche) + Zustände senden und empfangen sollten: + Bei Änderung des Zustandes wird ein Ereignis mit `'event'`-Wert + `'changed'` und dem neuen Zustand als `'state'`-Wert geschickt. + Das Plugin reagiert auf ein `'get state'`-Kommando, indem es eine + Nachricht mit dem Schlüssel `'state'` und dem aktuellen Zustand als Wert + (aber ohne `'event'`-Schlüssel schickt, da kein wirkliches Ereignis + eingetreten ist) schickt. + Da in diesem Plugin der Zustand auch von außen setzbar ist, reagiert es + auf ein `'set state'`-Kommando, das einen `'state'`-Schlüssel mit einem + neuen, zu setzenden Wert enthält, indem es diesen Zustand setzt (und eine + Ereignis-Nachricht sendet, wenn dies eine Änderung war). +- Sowohl der Bus selbst als auch das `State`-Plugin senden als Reaktion auf + `'get …'`-Nachrichten Antworten, die genau so aufgebaut sind wie die + Ereignis-Nachrichten, die sie auch aktiv senden, wenn eine Änderung + eingetreten ist. + Hierdurch können Klienten diese Nachrichten gleich behandeln, wenn das + Änderungs-Ereignis für sie nicht relevant ist, sondern nur die weiteren + Informationen in der Nachricht (der jetzt aktuelle Zustand der + `State`-Instanz bzw. das Vorhandensein und das Interface eines Klienten + am Bus). Hinsichtlich der Reihenfolge in der verschiedene Klienten, die alle für die gleiche Nachricht registriert sind, diese erhalten, werden von der @@ -265,7 +288,7 @@ angestoßen. "State Change Logger": { "plugin": "Log", "filter": [ - { "sender": "Example State", "changed": true } + { "sender": "Example State", "event": "changed" } ] } } @@ -320,7 +343,8 @@ Nachrichten stattfindet. ``` Debug Logger: {'sender': '', 'event': 'registered', 'client': 'Example State', - 'sends': [{'sender': 'Example State', 'state': ""}], + 'sends': [{'event': 'changed', 'state': ""}, + {'state': ""}], 'receives': [{'target': 'Example State', 'command': 'get state'}, {'target': 'Example State', 'command': 'set state', 'state': ""}]} @@ -360,7 +384,7 @@ Debug Logger: {'sender': '', 'event': 'registered', 'client': 'Test Procedure', Debug Logger: {'sender': '', 'event': 'registered', 'client': 'Debug Logger', 'sends': [], 'receives': [{}]} Debug Logger: {'sender': '', 'event': 'registered', 'client': 'State Change Logger', - 'sends': [], 'receives': [{'sender': 'Example State', 'changed': True}]} + 'sends': [], 'receives': [{'sender': 'Example State', 'event': 'changed'}]} ``` Die Instanz `Debug Logger` zeigt uns alle im System verschickten Nachrichten an. Zunächst meldet der Nachrichten-Bus selbst alle @@ -384,7 +408,7 @@ sie wurden von `Debug Logger` empfangen. Debug Logger: {'sender': 'WaitCheck', 'event': 'finished'} Debug Logger: {'sender': 'TriggerStateCheck', 'target': 'Example State', 'command': 'get state'} Debug Logger: {'sender': 'TriggerWaitCheck', 'target': 'WaitCheck', 'command': 'wait'} -Debug Logger: {'sender': 'Example State', 'state': False, 'changed': False} +Debug Logger: {'sender': 'Example State', 'state': False} ``` Nach einer Sekunde ist die Wartezeit der `Wait`-Instanz `WaitCheck` das erste Mal abgelaufen und daraufhin werden auch die beiden @@ -394,10 +418,11 @@ geändert hat) antwortet. ``` Debug Logger: {'sender': 'WaitOff', 'event': 'finished'} -Debug Logger: {'sender': 'TriggerStateOffOn', 'target': 'Example State', 'command': 'set state', 'state': True} +Debug Logger: {'sender': 'TriggerStateOffOn', 'target': 'Example State', + 'command': 'set state', 'state': True} Debug Logger: {'sender': 'TriggerWaitOffOn', 'target': 'WaitOn', 'command': 'wait'} -Debug Logger: {'sender': 'Example State', 'state': True, 'changed': True} -State Change Logger: {'sender': 'Example State', 'state': True, 'changed': True} +Debug Logger: {'sender': 'Example State', 'event': 'changed', 'state': True} +State Change Logger: {'sender': 'Example State', 'event': 'changed', 'state': True} ``` Eine weitere halbe Sekunde später sorgt der Ablauf der Instanz `WaitOff` dafür, dass `Example State` auf `True` gesetzt wird. Hier reagiert jetzt @@ -407,17 +432,18 @@ auch der `State Change Logger`. Debug Logger: {'sender': 'WaitCheck', 'event': 'finished'} Debug Logger: {'sender': 'TriggerStateCheck', 'target': 'Example State', 'command': 'get state'} Debug Logger: {'sender': 'TriggerWaitCheck', 'target': 'WaitCheck', 'command': 'wait'} -Debug Logger: {'sender': 'Example State', 'state': True, 'changed': False} +Debug Logger: {'sender': 'Example State', 'state': True} ``` Wiederum eine halbe Sekunde später wird durch Ablauf von `WaitCheck` wieder eine Abfrage des Zustands ausgelöst. ``` Debug Logger: {'sender': 'WaitOn', 'event': 'finished'} -Debug Logger: {'sender': 'TriggerStateOnOff', 'target': 'Example State', 'command': 'set state', 'state': False} +Debug Logger: {'sender': 'TriggerStateOnOff', 'target': 'Example State', + 'command': 'set state', 'state': False} Debug Logger: {'sender': 'TriggerWaitOnOff', 'target': 'WaitOff', 'command': 'wait'} -Debug Logger: {'sender': 'Example State', 'state': False, 'changed': True} -State Change Logger: {'sender': 'Example State', 'state': False, 'changed': True} +Debug Logger: {'sender': 'Example State', 'event': 'changed', 'state': False} +State Change Logger: {'sender': 'Example State', 'event': 'changed', 'state': False} ``` Nachdem `WaitOn` das erste Mal abgelaufen ist, wird `Example State` wieder auf `False` gesetzt.