From b2a8ab23083cd72ebcf0994619ebd0991bbb7c27 Mon Sep 17 00:00:00 2001 From: JingleManSweep Date: Sat, 28 May 2011 19:55:43 +0100 Subject: [PATCH] Performance improvements and a couple of extra plugins --- .gitignore | 2 ++ mhub/controllers.py | 5 ++- mhub/plugins/byebyestandby.py | 24 +++++++++---- mhub/plugins/email.py | 10 ++++-- mhub/plugins/events.py | 62 +++++++++++++++++++++++++++++++++ mhub/plugins/lirc.py | 4 +-- mhub/plugins/logic_processor.py | 4 +-- mhub/plugins/notify.py | 56 +++++++++++++++++++++++++++++ mhub/plugins/rss.py | 2 ++ mhub/utils.py | 28 +++++++++++++-- 10 files changed, 181 insertions(+), 16 deletions(-) create mode 100644 mhub/plugins/events.py create mode 100644 mhub/plugins/notify.py diff --git a/.gitignore b/.gitignore index 530b62f..e5505c2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ MANIFEST build dist +#*# +*~ \ No newline at end of file diff --git a/mhub/controllers.py b/mhub/controllers.py index 7c5fb07..d8bc67d 100644 --- a/mhub/controllers.py +++ b/mhub/controllers.py @@ -159,8 +159,11 @@ def start(self): self.on_init() + cfg_general = self.cfg.get("general", dict()) + mq_poll_interval = float(cfg_general.get("poll_interval", 0.1)) + mq_task = task.LoopingCall(self.poll_message) - mq_task.start(0.01) + mq_task.start(mq_poll_interval) for plugin_name, plugin_inst in self.plugins.iteritems(): if not hasattr(plugin_inst, "tasks"): continue diff --git a/mhub/plugins/byebyestandby.py b/mhub/plugins/byebyestandby.py index 42a3700..11e56a1 100644 --- a/mhub/plugins/byebyestandby.py +++ b/mhub/plugins/byebyestandby.py @@ -6,7 +6,7 @@ class Plugin(object): - """ Logic Processor Plugin """ + """ ByeByeStandby online controller plugin """ def __init__(self, cfg, producer, logger): @@ -19,7 +19,7 @@ def __init__(self, cfg, producer, logger): self.producer = producer self.logger = logger self.tasks = list() - + def on_init(self): @@ -34,21 +34,31 @@ def on_message(self, data, message): action, params = data.get("action"), data.get("params") - if action == "%s.action" % (self.name): - + if action == "%s.switch" % (self.name): device, state = params.get("device", None), params.get("state", None) - device = device.upper() state_desc = "ON" if state else "OFF" - if device is not None and state is not None: self.logger.info("ByeByeStandby Trigger: %s %s" % (device, state_desc)) self.switch(device, state) + if action == "%s.scene" % (self.name): + scenes = self.cfg.get("scenes", dict()) + name = params.get("name") + if name in scenes: + self.logger.debug("Scene '%s' running" % (name)) + scene = scenes.get(name) + for action in scene: + device, state = action.get("device"), action.get("state") + self.switch(device, state) + def switch(self, device, state): + + """ BBS device switcher helper """ + state = 1 if state else 0 h, u = device[0], device[1:] - cmd = "D:%i%s%02d:E" % (int(state), h, int(u)) + cmd = "D:%i%s%02d:E" % (int(state), h.upper(), int(u)) self.socket.sendto(cmd, (self.cfg.get("host"), self.cfg.get("port"))) time.sleep(1) diff --git a/mhub/plugins/email.py b/mhub/plugins/email.py index 77f29f3..970d874 100644 --- a/mhub/plugins/email.py +++ b/mhub/plugins/email.py @@ -9,7 +9,7 @@ class Plugin(object): - """ Email Sending Plugin """ + """ Email sending plugin """ def __init__(self, cfg, producer, logger): @@ -24,9 +24,13 @@ def __init__(self, cfg, producer, logger): self.tasks = list() + def on_init(self): + + """ On initialisation handler """ + def on_message(self, data, message): - """ On AMQP message handler """ + """ AMQP on-message handler """ action, params = data.get("action"), data.get("params") @@ -43,6 +47,8 @@ def on_message(self, data, message): def send_email(self, recipients, subject, body, attachments=None): + """ Send email helper """ + self.logger.debug("To: %s" % (", ".join(recipients))) self.logger.debug("Subject: %s" % (subject)) diff --git a/mhub/plugins/events.py b/mhub/plugins/events.py new file mode 100644 index 0000000..a57a085 --- /dev/null +++ b/mhub/plugins/events.py @@ -0,0 +1,62 @@ +import datetime +import fnmatch + +class Plugin(object): + + """ Events plugin """ + + def __init__(self, cfg, producer, logger): + + """ Constructor """ + + self.name = "events" + self.description = "Event management plugin" + self.author = "MHub" + self.cfg = cfg + self.producer = producer + self.logger = logger + self.tasks = list() + + + def on_message(self, data, message): + + """ On AMQP message handler """ + + action, params = data.get("action"), data.get("params") + + self.process_events(action, params) + + + def on_init(self): + + """ On Init """ + + self.events = self.cfg.get("events", list()) + + + def process_events(self, action, params): + + """ Event processor helper """ + + for name, event in self.events.iteritems(): + + triggers = event.get("triggers", list()) + actions = event.get("actions", list()) + + match = False + + for trigger in triggers: + + if fnmatch.fnmatch(action, trigger): + match = True + break + + if match: + + for action in actions: + + self.producer.publish({ + "action": action.get("action"), + "params": action.get("params", dict()) + }) + diff --git a/mhub/plugins/lirc.py b/mhub/plugins/lirc.py index ec37e16..d3610c6 100644 --- a/mhub/plugins/lirc.py +++ b/mhub/plugins/lirc.py @@ -21,7 +21,7 @@ def on_init(self): """ Main plugin initialisation """ - self.tasks = [(0.10, self.process_events)] + self.tasks = [(0.1, self.process_events)] self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.socket.setblocking(False) try: @@ -49,4 +49,4 @@ def process_events(self): "command": parts[2], "remote": parts[3] } - }) \ No newline at end of file + }) diff --git a/mhub/plugins/logic_processor.py b/mhub/plugins/logic_processor.py index 0e7495b..35bf7c7 100644 --- a/mhub/plugins/logic_processor.py +++ b/mhub/plugins/logic_processor.py @@ -15,7 +15,7 @@ def __init__(self, cfg, producer, logger): self.cfg = cfg self.producer = producer self.logger = logger - self.tasks = [(0.01, self.on_tick)] + self.tasks = [(0.1, self.on_tick)] self.scripts = dict() self.env = dict() @@ -119,4 +119,4 @@ def setup_scripts(self): self.scripts[trigger] = list() self.scripts[trigger].append(contents) else: - self.logger.debug("Script not found") \ No newline at end of file + self.logger.debug("Script not found") diff --git a/mhub/plugins/notify.py b/mhub/plugins/notify.py new file mode 100644 index 0000000..861ccc1 --- /dev/null +++ b/mhub/plugins/notify.py @@ -0,0 +1,56 @@ +import datetime +import fnmatch + +class Plugin(object): + + """ Notify Plugin """ + + def __init__(self, cfg, producer, logger): + + """ Constructor """ + + self.name = "notify" + self.description = "Notifications (libnotify)" + self.author = "MHub" + self.cfg = cfg + self.producer = producer + self.logger = logger + self.tasks = list() + + + def on_message(self, data, message): + + """ On AMQP message handler """ + + action, params = data.get("action"), data.get("params") + + if self.matches_patterns(action): + + title = params.get("title", "") + message = params.get("message", "") + + try: + import pynotify + if pynotify.init("MHub"): + n = pynotify.Notification(title, message) + n.show() + except: + pass + + + def on_init(self): + + """ On Init """ + + self.patterns = self.cfg.get("patterns", list("*")) + + + def matches_patterns(self, action): + + match = False + + for pattern in self.patterns: + match = fnmatch.fnmatch(action, pattern) + if match: break + + return match diff --git a/mhub/plugins/rss.py b/mhub/plugins/rss.py index 0fd4c8b..765166f 100644 --- a/mhub/plugins/rss.py +++ b/mhub/plugins/rss.py @@ -28,6 +28,8 @@ def on_init(self): def get_feeds(self): + """ RSS feed parser helper """ + feeds = self.cfg.get("feeds") for url in feeds: diff --git a/mhub/utils.py b/mhub/utils.py index 80bc7f2..ae1f5e5 100644 --- a/mhub/utils.py +++ b/mhub/utils.py @@ -96,7 +96,8 @@ def configurator(filename=None): cfg = { "general": { - "plugins_path": os.path.join(base_dir, "plugins") + "plugins_path": os.path.join(base_dir, "plugins"), + "poll_interval": 0.1 }, "amqp": { "host": "localhost", @@ -108,7 +109,12 @@ def configurator(filename=None): "byebyestandby": { "enabled": False, "host": "192.168.1.100", - "port": 53008 + "port": 53008, + "scenes": { + "test": [ + {"device": "a1", "state": False} + ] + } }, "echo": { "enabled": True @@ -159,6 +165,24 @@ def configurator(filename=None): } } }, + "notify": { + "enabled": False, + "patterns": [ + "twitter.*", + "*.action" + ] + }, + "events": { + "enabled": False, + "events": { + "test": { + "triggers": ["some.trigger"], + "actions": [ + {"action": "some.action", "params": {}} + ] + } + } + }, "websocket": { "enabled": False }