Harmonise state message conventions
authorBenjamin Braatz <bb@bbraatz.eu>
Fri, 5 Mar 2021 10:55:35 +0000 (11:55 +0100)
committerBenjamin Braatz <bb@bbraatz.eu>
Fri, 5 Mar 2021 10:55:35 +0000 (11:55 +0100)
Change from 'changed' Boolean to 'event': 'changed',
document 'event': 'changed', 'get state' and 'set state'.

conf.json
controlpi-plugins/util.py
doc/index.md

index 468ecea427dea2e04dcbb2a8237d0b5c5609ae3a..d2be6653a160bd931864dc6f1b563dd3a68a87ad 100644 (file)
--- 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" }
         ]
     }
 }
index 0e598a23a8e9355b02f4271fbb80c1dc1c358ba2..68f78b387b3d9856eba36fd83c37fe66b72d363d 100644 (file)
@@ -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,
index 2d95ac216f1a6fbc18512482de2972bc163af41b..eb05ba88c2cbf70f10e4a599c5f9c93914a8b6e1 100644 (file)
@@ -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': "<class 'bool'>"}],
+    'sends': [{'event': 'changed', 'state': "<class 'bool'>"},
+              {'state': "<class 'bool'>"}],
     'receives': [{'target': 'Example State', 'command': 'get state'},
                  {'target': 'Example State', 'command': 'set state',
                   'state': "<class 'bool'>"}]}
@@ -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.