Add 'get state' command to AndSet and OrSet.
authorBenjamin Braatz <benjamin.braatz@graph-it.com>
Wed, 20 Oct 2021 07:03:59 +0000 (09:03 +0200)
committerBenjamin Braatz <benjamin.braatz@graph-it.com>
Wed, 20 Oct 2021 07:03:59 +0000 (09:03 +0200)
controlpi_plugins/state.py

index 7e7bd0b9d502dc3a6b4dffde12d0fd0a4d353c46..ac615c5a933ef1124fae7153d7f545f20d4f1fcc 100644 (file)
@@ -459,8 +459,10 @@ class AndSet(BasePlugin):
     ...       "new state": True},
     ...      {"target": "Test State 2", "command": "set state",
     ...       "new state": True},
+    ...      {"target": "Test AndSet", "command": "get state"},
     ...      {"target": "Test State 1", "command": "set state",
-    ...       "new state": False}]))
+    ...       "new state": False},
+    ...      {"target": "Test AndSet", "command": "get state"}]))
     ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
     test(): {'sender': '', 'event': 'registered', ...
     test(): {'sender': 'test()', 'target': 'Test State 1',
@@ -472,12 +474,22 @@ class AndSet(BasePlugin):
     test(): {'sender': 'Test AndSet', 'target': 'Test State 3',
              'command': 'set state', 'new state': True}
     test(): {'sender': 'Test State 3', 'event': 'changed', 'state': True}
+    test(): {'sender': 'test()', 'target': 'Test AndSet',
+             'command': 'get state'}
+    test(): {'sender': 'Test AndSet', 'target': 'Test State 3',
+             'command': 'set state', 'new state': True}
+    test(): {'sender': 'Test State 3', 'state': True}
     test(): {'sender': 'test()', 'target': 'Test State 1',
              'command': 'set state', 'new state': False}
     test(): {'sender': 'Test State 1', 'event': 'changed', 'state': False}
     test(): {'sender': 'Test AndSet', 'target': 'Test State 3',
              'command': 'set state', 'new state': False}
     test(): {'sender': 'Test State 3', 'event': 'changed', 'state': False}
+    test(): {'sender': 'test()', 'target': 'Test AndSet',
+             'command': 'get state'}
+    test(): {'sender': 'Test AndSet', 'target': 'Test State 3',
+             'command': 'set state', 'new state': False}
+    test(): {'sender': 'Test State 3', 'state': False}
     """
 
     CONF_SCHEMA = {'properties': {'input states': {'type': 'array',
@@ -499,7 +511,8 @@ class AndSet(BasePlugin):
                                              self.conf['output state']},
                                   'command': {'const': 'set state'},
                                   'new state': {'type': 'boolean'}})]
-        receives = []
+        receives = [MessageTemplate({'target': {'const': self.name},
+                                     'command': {'const': 'get state'}})]
         self.states: Dict[str, bool] = {}
         for state in self.conf['input states']:
             receives.append(MessageTemplate({'sender': {'const': state},
@@ -511,16 +524,25 @@ class AndSet(BasePlugin):
 
     async def receive(self, message: Message) -> None:
         """Process messages of combined states."""
-        assert isinstance(message['sender'], str)
-        assert isinstance(message['state'], bool)
-        self.states[message['sender']] = message['state']
-        new_state = all(self.states.values())
-        if self.state != new_state:
-            self.state = new_state
+        if ('target' in message and message['target'] == self.name and
+                'command' in message and message['command'] == 'get state'):
             await self.bus.send(Message(self.name,
                                         {'target': self.conf['output state'],
                                          'command': 'set state',
                                          'new state': self.state}))
+        if ('state' in message and
+                message['sender'] in self.conf['input states']):
+            assert isinstance(message['sender'], str)
+            assert isinstance(message['state'], bool)
+            self.states[message['sender']] = message['state']
+            new_state = all(self.states.values())
+            if self.state != new_state:
+                self.state = new_state
+                await self.bus.send(Message(self.name,
+                                            {'target':
+                                             self.conf['output state'],
+                                             'command': 'set state',
+                                             'new state': self.state}))
 
     async def run(self) -> None:
         """Run no code proactively."""
@@ -544,6 +566,7 @@ class OrSet(BasePlugin):
     ...                      "output state": "Test State 3"}},
     ...     [{"target": "Test State 1", "command": "set state",
     ...       "new state": True},
+    ...      {"target": "Test OrSet", "command": "get state"},
     ...      {"target": "Test State 2", "command": "set state",
     ...       "new state": True},
     ...      {"target": "Test State 1", "command": "set state",
@@ -556,6 +579,11 @@ class OrSet(BasePlugin):
     test(): {'sender': 'Test OrSet', 'target': 'Test State 3',
              'command': 'set state', 'new state': True}
     test(): {'sender': 'Test State 3', 'event': 'changed', 'state': True}
+    test(): {'sender': 'test()', 'target': 'Test OrSet',
+             'command': 'get state'}
+    test(): {'sender': 'Test OrSet', 'target': 'Test State 3',
+             'command': 'set state', 'new state': True}
+    test(): {'sender': 'Test State 3', 'state': True}
     test(): {'sender': 'test()', 'target': 'Test State 2',
              'command': 'set state', 'new state': True}
     test(): {'sender': 'Test State 2', 'event': 'changed', 'state': True}
@@ -583,7 +611,8 @@ class OrSet(BasePlugin):
                                              self.conf['output state']},
                                   'command': {'const': 'set state'},
                                   'new state': {'type': 'boolean'}})]
-        receives = []
+        receives = [MessageTemplate({'target': {'const': self.name},
+                                     'command': {'const': 'get state'}})]
         self.states: Dict[str, bool] = {}
         for state in self.conf['input states']:
             receives.append(MessageTemplate({'sender': {'const': state},
@@ -595,16 +624,25 @@ class OrSet(BasePlugin):
 
     async def receive(self, message: Message) -> None:
         """Process messages of combined states."""
-        assert isinstance(message['sender'], str)
-        assert isinstance(message['state'], bool)
-        self.states[message['sender']] = message['state']
-        new_state = any(self.states.values())
-        if self.state != new_state:
-            self.state = new_state
+        if ('target' in message and message['target'] == self.name and
+                'command' in message and message['command'] == 'get state'):
             await self.bus.send(Message(self.name,
                                         {'target': self.conf['output state'],
                                          'command': 'set state',
                                          'new state': self.state}))
+        if ('state' in message and
+                message['sender'] in self.conf['input states']):
+            assert isinstance(message['sender'], str)
+            assert isinstance(message['state'], bool)
+            self.states[message['sender']] = message['state']
+            new_state = any(self.states.values())
+            if self.state != new_state:
+                self.state = new_state
+                await self.bus.send(Message(self.name,
+                                            {'target':
+                                             self.conf['output state'],
+                                             'command': 'set state',
+                                             'new state': self.state}))
 
     async def run(self) -> None:
         """Run no code proactively."""