TODO: documentation, doctests
"""
import jsonschema # type: ignore
-from typing import Iterable, Mapping, Any
+from typing import Mapping, Any
from controlpi import BasePlugin, Message, PluginConfiguration
class StateMachine(BasePlugin):
async def _receive(self, message: Message) -> None:
if ('target' in message and message['target'] == self._name and
- 'command' in message and message['command'] == 'get state'):
- answer = {'sender': self._name, 'state': self._current_state}
- await self._bus.send(answer)
+ 'command' in message):
+ if message['command'] == 'get state':
+ answer = {'sender': self._name,
+ 'state': self._current_state}
+ await self._bus.send(answer)
+ if message['command'] == 'get machine':
+ answer = {'sender': self._name,
+ 'init': self._init,
+ 'states': self._states}
+ await self._bus.send(answer)
for transition in self._states[self._current_state]['transitions']:
for trigger in transition['triggers']:
matches = True
break
def _process_conf(self, conf: PluginConfiguration) -> None:
- self._current_state = conf['init']
+ self._init = conf['init']
+ self._current_state = ''
self._states: Mapping[str, Any] = conf['states']
sends: list[Message] = [{'event': {'const': 'changed'},
'state': {'type': 'string'}},
- {'state': {'type': 'string'}}]
+ {'state': {'type': 'string'}},
+ {'init': {'type': 'string'}, 'states':
+ {'type': 'object', 'patternProperties':
+ {'.+': {'type': 'object', 'properties':
+ {'commands': {'type': 'array'},
+ 'transitions': {'type': 'array'}},
+ 'additionalProperties': False}},
+ 'additionalProperties': False}}]
receives: list[Message] = [{'target': {'const': self._name},
- 'command': {'const': 'get state'}}]
+ 'command': {'const': 'get state'}},
+ {'target': {'const': self._name},
+ 'command': {'const': 'get machine'}}]
for state in self._states:
for message in self._states[state]['commands']:
sends.append(template_from_message(message))
async def run(self) -> None:
await super().run()
- for message in self._states[self._current_state]['commands']:
+ self._current_state = self._init
+ for message in self._states[self._init]['commands']:
complete_message = {'sender': self._name}
complete_message.update(message)
await self._bus.send(complete_message)