exec_command/exec_command.py
2022-09-28 17:56:48 +02:00

76 lines
2.6 KiB
Python

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.__block_execution__ = False
mqtt.mqtt_client.__init__(self, config.APP_NAME, config.MQTT_SERVER, 1883, config.MQTT_USER, config.MQTT_PASS)
for topic in config.EXEC_LIST:
self.add_callback(topic, self.mqtt_rx)
# Start a pseudo process
self.process = subprocess.Popen(["sleep", "0"])
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.process.poll() is None:
self.process.kill()
logger.debug("Starting execution in background...")
self.exec_command(config.EXEC_LIST[message.topic]['command'], message)
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)
try:
ec.join()
finally:
ec.stop()