12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- 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()
|