'content': 'Test Message'}
"""
import asyncio
+import datetime
from controlpi import BasePlugin, Message, MessageTemplate
Optional configuration keys:
- - 'to': translated message to be sent.
+ - 'to': translated message(s) to be sent.
- 'translate': array of pairs of keys to be translated.
"""
async def run(self) -> None:
"""Run no code proactively."""
pass
+
+
+class Counter(BasePlugin):
+ """Count messages confirming to a given template.
+
+ The plugin counts messages confirming to the given template. The
+ counter can be queried and reset by commands. The 'reset' command also
+ queries the last count before the reset:
+ >>> import controlpi
+ >>> asyncio.run(controlpi.test(
+ ... {"Test Counter": {"plugin": "Counter",
+ ... "count": {"id": {"const": 42}}}},
+ ... [{"target": "Test Counter", "command": "get count"},
+ ... {"id": 42}, {"id": 42}, {"id": 49},
+ ... {"target": "Test Counter", "command": "get count"},
+ ... {"id": 42}, {"id": 42}, {"id": 42},
+ ... {"target": "Test Counter", "command": "reset"},
+ ... {"target": "Test Counter", "command": "get count"},
+ ... {"id": 42}, {"id": 42}, {"id": 42},
+ ... {"target": "Test Counter", "command": "get count"}]))
+ ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+ test(): {'sender': '', 'event': 'registered',
+ 'client': 'Test Counter', 'plugin': 'Counter',
+ 'sends': [{'count': {'type': 'integer'}}],
+ 'receives': [{'id': {'const': 42}},
+ {'target': {'const': 'Test Counter'},
+ 'command': {'const': 'get count'}},
+ {'target': {'const': 'Test Counter'},
+ 'command': {'const': 'reset'}}]}
+ test(): {'sender': 'test()', 'target': 'Test Counter',
+ 'command': 'get count'}
+ test(): {'sender': 'Test Counter', 'count': 0}
+ test(): {'sender': 'test()', 'id': 42}
+ test(): {'sender': 'test()', 'id': 42}
+ test(): {'sender': 'test()', 'id': 49}
+ test(): {'sender': 'test()', 'target': 'Test Counter',
+ 'command': 'get count'}
+ test(): {'sender': 'Test Counter', 'count': 2}
+ test(): {'sender': 'test()', 'id': 42}
+ test(): {'sender': 'test()', 'id': 42}
+ test(): {'sender': 'test()', 'id': 42}
+ test(): {'sender': 'test()', 'target': 'Test Counter',
+ 'command': 'reset'}
+ test(): {'sender': 'Test Counter', 'count': 5}
+ test(): {'sender': 'test()', 'target': 'Test Counter',
+ 'command': 'get count'}
+ test(): {'sender': 'Test Counter', 'count': 0}
+ test(): {'sender': 'test()', 'id': 42}
+ test(): {'sender': 'test()', 'id': 42}
+ test(): {'sender': 'test()', 'id': 42}
+ test(): {'sender': 'test()', 'target': 'Test Counter',
+ 'command': 'get count'}
+ test(): {'sender': 'Test Counter', 'count': 3}
+ """
+
+ CONF_SCHEMA = {'properties': {'count': {'type': 'object'}},
+ 'required': ['count']}
+ """Schema for Counter plugin configuration.
+
+ Required configuration key:
+
+ - 'count': template of messages to be counted.
+ """
+
+ def process_conf(self) -> None:
+ """Register plugin as bus client."""
+ self._count = 0
+ self._template = MessageTemplate(self.conf['count'])
+ sends = [MessageTemplate({'count': {'type': 'integer'}})]
+ receives = [self._template,
+ MessageTemplate({'target': {'const': self.name},
+ 'command': {'const': 'get count'}}),
+ MessageTemplate({'target': {'const': self.name},
+ 'command': {'const': 'reset'}})]
+ self.bus.register(self.name, 'Counter', sends, receives, self.receive)
+
+ async def receive(self, message: Message) -> None:
+ """Send current date and time as message."""
+ if self._template.check(message):
+ self._count += 1
+ if ('target' in message and message['target'] == self.name and
+ 'command' in message):
+ if message['command'] == 'get count':
+ await self.bus.send(Message(self.name, {'count': self._count}))
+ elif message['command'] == 'reset':
+ count = self._count
+ self._count = 0
+ await self.bus.send(Message(self.name, {'count': count}))
+
+ async def run(self) -> None:
+ """Run no code proactively."""
+ pass
+
+
+class Date(BasePlugin):
+ """Send message with current date.
+
+ The plugin reacts to 'get date' commands by sending messages with
+ a 'date' key:
+ >>> import controlpi
+ >>> asyncio.run(controlpi.test(
+ ... {"Test Date": {"plugin": "Date"}},
+ ... [{"target": "Test Date", "command": "get date"}]))
+ ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+ test(): {'sender': '', 'event': 'registered',
+ 'client': 'Test Date', 'plugin': 'Date',
+ 'sends': [{'date': {'type': 'string'}}],
+ 'receives': [{'target': {'const': 'Test Date'},
+ 'command': {'const': 'get date'}}]}
+ test(): {'sender': 'test()', 'target': 'Test Date',
+ 'command': 'get date'}
+ test(): {'sender': 'Test Date', 'date': ...}
+
+ The format of the date can be configured with the 'format'
+ configuration key:
+ >>> asyncio.run(controlpi.test(
+ ... {"Test Date": {"plugin": "Date",
+ ... "format": "%Y%m%d%H%M%S%f"}},
+ ... [{"target": "Test Date", "command": "get date"}]))
+ ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+ test(): {'sender': '', 'event': 'registered',
+ 'client': 'Test Date', 'plugin': 'Date',
+ 'sends': [{'date': {'type': 'string'}}],
+ 'receives': [{'target': {'const': 'Test Date'},
+ 'command': {'const': 'get date'}}]}
+ test(): {'sender': 'test()', 'target': 'Test Date',
+ 'command': 'get date'}
+ test(): {'sender': 'Test Date', 'date': ...}
+ """
+
+ CONF_SCHEMA = {'properties': {'format':
+ {'type': 'string',
+ 'default': '%Y-%m-%d %H:%M:%S'}}}
+ """Schema for Date plugin configuration.
+
+ Optional configuration key:
+
+ - 'format': format for the sent datetime string.
+ Default: '%Y-%m-%d %H:%M:%S'
+ """
+
+ def process_conf(self) -> None:
+ """Register plugin as bus client."""
+ sends = [MessageTemplate({'date': {'type': 'string'}})]
+ receives = [MessageTemplate({'target': {'const': self.name},
+ 'command': {'const': 'get date'}})]
+ self.bus.register(self.name, 'Date', sends, receives, self.date)
+
+ async def date(self, message: Message) -> None:
+ """Send current date and time as message."""
+ date = datetime.datetime.now().strftime(self.conf['format'])
+ await self.bus.send(Message(self.name, {'date': date}))
+
+ async def run(self) -> None:
+ """Run no code proactively."""
+ pass