import config import json import logging import mqtt import os import report import subprocess import time try: from config import APP_NAME as ROOT_LOGGER_NAME except ImportError: ROOT_LOGGER_NAME = 'root' logger = logging.getLogger(ROOT_LOGGER_NAME).getChild('main') my_handler = logging.handlers.RotatingFileHandler(os.path.join(config.__BASEPATH__, 'door_bell.log'), mode='a', maxBytes=5*1024*1024, backupCount=3, encoding=None, delay=0) my_handler.setLevel(logging.INFO) my_handler.setFormatter(logging.Formatter("%(asctime)s: %(message)s")) bell_log = logging.getLogger('root') bell_log.setLevel(logging.INFO) bell_log.addHandler(my_handler) class exec_command(mqtt.mqtt_client): def __init__(self): self.__enabled__ = True mqtt.mqtt_client.__init__(self, config.APP_NAME, config.MQTT_SERVER, 1883, config.MQTT_USER, config.MQTT_PASS) self.add_callback(config.ENABLED_TOPIC + '/set', self.set_enabled) for topic in config.EXEC_LIST: self.add_callback(topic, self.mqtt_rx) # Start a pseudo process self.process = subprocess.Popen(["sleep", "0"]) self.publish_states() def set_enabled(self, client, userdata, message): try: payload = json.loads(message.payload) except: logger.exception("Error decoding json mqtt message") else: if self.__enabled__ != payload: self.__enabled__ = payload self.publish_states() def exec_command(self, cmd, message): self.process = subprocess.Popen(cmd.split(" ")) if 'bell' in message.topic: bell_log.info('Door Bell activated (%s)', message.topic) def mqtt_rx(self, client, userdate, message): payload = None key = config.EXEC_LIST[message.topic].get('key') data = config.EXEC_LIST[message.topic].get('data') if key is None: try: payload = message.payload.decode('utf-8') except: logger.exception("Error decoding mqtt message") else: try: payload = json.loads(message.payload) except: logger.exception("Error decoding json mqtt message") else: try: payload = payload.get(key) except AttributeError: logger.exception("payload seems to be no dictionary") if data is None or payload == data: if self.__enabled__: if self.process.poll() is None: self.process.kill() logger.debug("Starting execution in background...") self.exec_command(config.EXEC_LIST[message.topic]['command'], message) else: logger.info("Execution is disabled") def publish_states(self): self.send(config.ENABLED_TOPIC, json.dumps(self.__enabled__)) if __name__ == '__main__': report.appLoggingConfigure(config.__BASEPATH__, config.LOGTARGET, ((config.APP_NAME, config.LOGLVL), ), fmt=config.formatter, host=config.LOGHOST, port=config.LOGPORT) # ec = exec_command() # while True: time.sleep(30) ec.publish_states() try: ec.join() finally: ec.stop()