switching states and sending messages defined for these states.
"""
- CONF_SCHEMA = {'properties':
- {'init': {'type': 'string'},
- 'states':
- {'type': 'object',
- 'patternProperties':
- {'^[A-Za-z ]+$':
- {'type': 'object',
- 'properties':
- {'entry':
- {'type': 'array', 'items': {'type': 'object'}},
- 'exit':
- {'type': 'array', 'items': {'type': 'object'}},
- 'commands':
- {'type': 'array', 'items': {'type': 'object'}},
- 'transitions':
- {'type': 'array',
- 'items':
- {'type': 'object',
- 'properties':
- {'trigger': {'type': 'object'},
- 'to': {'type': 'string'}},
- 'required': ['trigger', 'to']}}},
- 'required': ['commands', 'transitions']}},
- 'additionalProperties': False}},
- 'required': ['init', 'states']}
+ CONF_SCHEMA = {
+ "properties": {
+ "init": {"type": "string"},
+ "states": {
+ "type": "object",
+ "patternProperties": {
+ "^[A-Za-z ]+$": {
+ "type": "object",
+ "properties": {
+ "entry": {"type": "array", "items": {"type": "object"}},
+ "exit": {"type": "array", "items": {"type": "object"}},
+ "commands": {"type": "array", "items": {"type": "object"}},
+ "transitions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "trigger": {"type": "object"},
+ "to": {"type": "string"},
+ },
+ "required": ["trigger", "to"],
+ },
+ },
+ },
+ "required": ["commands", "transitions"],
+ }
+ },
+ "additionalProperties": False,
+ },
+ },
+ "required": ["init", "states"],
+ }
def process_conf(self) -> None:
"""Register plugin as bus client."""
- self._state = ''
+ self._state = ""
sends = []
- sends.append(MessageTemplate({'event': {'const': 'changed'},
- 'state': {'type': 'string'}}))
- sends.append(MessageTemplate({'state': {'type': 'string'}}))
- sends.append(MessageTemplate({'init': {'type': 'string'},
- 'states':
- {'type': 'object',
- 'patternProperties':
- {'^[A-Za-z ]+$':
- {'type': 'object',
- 'properties':
- {'commands':
- {'type': 'array',
- 'items': {'type': 'object'}},
- 'transitions':
- {'type': 'array',
- 'items':
- {'type': 'object',
- 'properties':
- {'trigger': {'type': 'object'},
- 'to': {'type': 'string'}},
- 'required': ['trigger', 'to']}}},
- 'required': ['commands',
- 'transitions']}},
- 'additionalProperties': False}}))
+ sends.append(
+ MessageTemplate(
+ {"event": {"const": "changed"}, "state": {"type": "string"}}
+ )
+ )
+ sends.append(MessageTemplate({"state": {"type": "string"}}))
+ sends.append(
+ MessageTemplate(
+ {
+ "init": {"type": "string"},
+ "states": {
+ "type": "object",
+ "patternProperties": {
+ "^[A-Za-z ]+$": {
+ "type": "object",
+ "properties": {
+ "commands": {
+ "type": "array",
+ "items": {"type": "object"},
+ },
+ "transitions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "trigger": {"type": "object"},
+ "to": {"type": "string"},
+ },
+ "required": ["trigger", "to"],
+ },
+ },
+ },
+ "required": ["commands", "transitions"],
+ }
+ },
+ "additionalProperties": False,
+ },
+ }
+ )
+ )
triggers = []
- for state in self.conf['states']:
- commands = self.conf['states'][state]['commands']
+ for state in self.conf["states"]:
+ commands = self.conf["states"][state]["commands"]
for command in commands:
template = MessageTemplate.from_message(command)
if template not in sends:
sends.append(template)
- transitions = self.conf['states'][state]['transitions']
+ transitions = self.conf["states"][state]["transitions"]
for transition in transitions:
- template = MessageTemplate(transition['trigger'])
+ template = MessageTemplate(transition["trigger"])
if template not in triggers:
triggers.append(template)
- self.bus.register(self.name, 'StateMachine', sends,
- [([MessageTemplate({'target':
- {'const': self.name},
- 'command':
- {'const': 'get state'}})],
- self._get_state),
- ([MessageTemplate({'target':
- {'const': self.name},
- 'command':
- {'const': 'get machine'}})],
- self._get_machine),
- ([MessageTemplate({'target':
- {'const': self.name},
- 'command':
- {'const': 'set state'},
- 'new state':
- {'type': 'string'}})],
- self._set_state),
- (triggers, self._trigger)])
+ self.bus.register(
+ self.name,
+ "StateMachine",
+ sends,
+ [
+ (
+ [
+ MessageTemplate(
+ {
+ "target": {"const": self.name},
+ "command": {"const": "get state"},
+ }
+ )
+ ],
+ self._get_state,
+ ),
+ (
+ [
+ MessageTemplate(
+ {
+ "target": {"const": self.name},
+ "command": {"const": "get machine"},
+ }
+ )
+ ],
+ self._get_machine,
+ ),
+ (
+ [
+ MessageTemplate(
+ {
+ "target": {"const": self.name},
+ "command": {"const": "set state"},
+ "new state": {"type": "string"},
+ }
+ )
+ ],
+ self._set_state,
+ ),
+ (triggers, self._trigger),
+ ],
+ )
async def _get_state(self, message: Message) -> None:
- await self.bus.send(Message(self.name,
- {'state': self._state}))
+ await self.bus.send(Message(self.name, {"state": self._state}))
async def _get_machine(self, message: Message) -> None:
- await self.bus.send(Message(self.name,
- {'init': self.conf['init'],
- 'states': self.conf['states']}))
+ await self.bus.send(
+ Message(
+ self.name, {"init": self.conf["init"], "states": self.conf["states"]}
+ )
+ )
async def _set_state(self, message: Message) -> None:
- if (message['new state'] != self._state and
- message['new state'] in self.conf['states']):
- assert isinstance(message['new state'], str)
- new_state = message['new state']
+ if (
+ message["new state"] != self._state
+ and message["new state"] in self.conf["states"]
+ ):
+ assert isinstance(message["new state"], str)
+ new_state = message["new state"]
commands = []
- if 'exit' in self.conf['states'][self._state]:
- commands += self.conf['states'][self._state]['exit']
+ if "exit" in self.conf["states"][self._state]:
+ commands += self.conf["states"][self._state]["exit"]
for command in commands:
await self.bus.send(Message(self.name, command))
self._state = new_state
- await self.bus.send(Message(self.name,
- {'event': 'changed',
- 'state': new_state}))
+ await self.bus.send(
+ Message(self.name, {"event": "changed", "state": new_state})
+ )
commands = []
- if 'entry' in self.conf['states'][self._state]:
- commands += self.conf['states'][self._state]['entry']
- if 'commands' in self.conf['states'][self._state]:
- commands += self.conf['states'][self._state]['commands']
+ if "entry" in self.conf["states"][self._state]:
+ commands += self.conf["states"][self._state]["entry"]
+ if "commands" in self.conf["states"][self._state]:
+ commands += self.conf["states"][self._state]["commands"]
for command in commands:
await self.bus.send(Message(self.name, command))
async def _trigger(self, message: Message) -> None:
- transitions = self.conf['states'][self._state]['transitions']
+ transitions = self.conf["states"][self._state]["transitions"]
for transition in transitions:
- if (MessageTemplate(transition['trigger']).check(message) and
- transition['to'] in self.conf['states']):
- assert isinstance(transition['to'], str)
- new_state = transition['to']
+ if (
+ MessageTemplate(transition["trigger"]).check(message)
+ and transition["to"] in self.conf["states"]
+ ):
+ assert isinstance(transition["to"], str)
+ new_state = transition["to"]
commands = []
- if 'exit' in self.conf['states'][self._state]:
- commands += self.conf['states'][self._state]['exit']
+ if "exit" in self.conf["states"][self._state]:
+ commands += self.conf["states"][self._state]["exit"]
for command in commands:
await self.bus.send(Message(self.name, command))
self._state = new_state
- await self.bus.send(Message(self.name,
- {'event': 'changed',
- 'state': new_state,
- 'trigger': message}))
+ await self.bus.send(
+ Message(
+ self.name,
+ {"event": "changed", "state": new_state, "trigger": message},
+ )
+ )
commands = []
- if 'entry' in self.conf['states'][self._state]:
- commands += self.conf['states'][self._state]['entry']
- if 'commands' in self.conf['states'][self._state]:
- commands += self.conf['states'][self._state]['commands']
+ if "entry" in self.conf["states"][self._state]:
+ commands += self.conf["states"][self._state]["entry"]
+ if "commands" in self.conf["states"][self._state]:
+ commands += self.conf["states"][self._state]["commands"]
for command in commands:
await self.bus.send(Message(self.name, command))
break
async def run(self) -> None:
"""Go into initial state."""
- if self.conf['init'] in self.conf['states']:
- self._state = self.conf['init']
+ if self.conf["init"] in self.conf["states"]:
+ self._state = self.conf["init"]
commands = []
- if 'entry' in self.conf['states'][self._state]:
- commands += self.conf['states'][self._state]['entry']
- if 'commands' in self.conf['states'][self._state]:
- commands += self.conf['states'][self._state]['commands']
+ if "entry" in self.conf["states"][self._state]:
+ commands += self.conf["states"][self._state]["entry"]
+ if "commands" in self.conf["states"][self._state]:
+ commands += self.conf["states"][self._state]["commands"]
for command in commands:
await self.bus.send(Message(self.name, command))