Execute a command on receiving a mqtt message
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

exec_command.py 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import config
  2. import json
  3. import logging
  4. import mqtt
  5. import os
  6. import report
  7. import subprocess
  8. import time
  9. try:
  10. from config import APP_NAME as ROOT_LOGGER_NAME
  11. except ImportError:
  12. ROOT_LOGGER_NAME = 'root'
  13. logger = logging.getLogger(ROOT_LOGGER_NAME).getChild('main')
  14. 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)
  15. my_handler.setLevel(logging.INFO)
  16. my_handler.setFormatter(logging.Formatter("%(asctime)s: %(message)s"))
  17. bell_log = logging.getLogger('root')
  18. bell_log.setLevel(logging.INFO)
  19. bell_log.addHandler(my_handler)
  20. class exec_command(mqtt.mqtt_client):
  21. def __init__(self):
  22. self.__block_execution__ = False
  23. mqtt.mqtt_client.__init__(self, config.APP_NAME, config.MQTT_SERVER, 1883, config.MQTT_USER, config.MQTT_PASS)
  24. for topic in config.EXEC_LIST:
  25. self.add_callback(topic, self.mqtt_rx)
  26. # Start a pseudo process
  27. self.process = subprocess.Popen(["sleep", "0"])
  28. def exec_command(self, cmd, message):
  29. self.process = subprocess.Popen(cmd.split(" "))
  30. if 'bell' in message.topic:
  31. bell_log.info('Door Bell activated (%s)', message.topic)
  32. def mqtt_rx(self, client, userdate, message):
  33. payload = None
  34. key = config.EXEC_LIST[message.topic].get('key')
  35. data = config.EXEC_LIST[message.topic].get('data')
  36. if key is None:
  37. try:
  38. payload = message.payload.decode('utf-8')
  39. except:
  40. logger.exception("Error decoding mqtt message")
  41. else:
  42. try:
  43. payload = json.loads(message.payload)
  44. except:
  45. logger.exception("Error decoding json mqtt message")
  46. else:
  47. try:
  48. payload = payload.get(key)
  49. except AttributeError:
  50. logger.exception("payload seems to be no dictionary")
  51. if data is None or payload == data:
  52. if self.process.poll() is None:
  53. self.process.kill()
  54. logger.debug("Starting execution in background...")
  55. self.exec_command(config.EXEC_LIST[message.topic]['command'], message)
  56. if __name__ == '__main__':
  57. report.appLoggingConfigure(config.__BASEPATH__, config.LOGTARGET, ((config.APP_NAME, config.LOGLVL), ), fmt=config.formatter, host=config.LOGHOST, port=config.LOGPORT)
  58. #
  59. ec = exec_command()
  60. #
  61. while True:
  62. time.sleep(30)
  63. try:
  64. ec.join()
  65. finally:
  66. ec.stop()