diff --git a/sane2MQTT.py b/sane2MQTT.py index e69de29..76b483f 100644 --- a/sane2MQTT.py +++ b/sane2MQTT.py @@ -0,0 +1,195 @@ +#!/usr/bin/python3 + +# \brief sane2MQTT +# \author Pascal Gollor +# \copyright cc 2020 by-sa + +import optparse, logging, signal, time, re, argparse +import paho.mqtt.client as mqtt + + +DEFAULT_MQTT_SERVER = "127.0.0.1" +DEFAULT_MQTT_PORT = 1883 +DEFAULT_TOPIC = "sane" # without leading / + + +## detecting kill signal +# source: http://stackoverflow.com/questions/18499497/how-to-process-sigterm-signal-gracefully +class GracefulKiller: + def __init__(self): + self.kill_now = False + + signal.signal(signal.SIGINT, self.exit_gracefully) + signal.signal(signal.SIGTERM, self.exit_gracefully) + # end __init__ + + def exit_gracefully(self, signum, frame): + self.kill_now = True + # end exit_gracefully +# end class GracefulKiller + + +def on_connect(client, userdata, flags, rc): + userdata['logger'].info("Connected with result code: %i", rc) +# end on_connect + + +def on_disconnect(client, userdata, rc): + msg = "Disconnected with result code: %i" + if (rc): + userdata['logger'].error(msg, rc) + else: + userdata['logger'].info(msg, rc) + # end if +# end on_disconnect + + +def main(): + parser = optparse.OptionParser( + usage = "%prog [options]", + description = "sane2MQTT controls scanner with sane via MQTT", + version="%prog 0.1a" + ) + + group = optparse.OptionGroup(parser, "MQTT settings") + group.add_option("-s", "--server", + dest = "server", + help = "mqtt server, default %default", + default = DEFAULT_MQTT_SERVER + ) + group.add_option("--port", + dest = "port", + action = "store", + type = 'int', + help = "mqtt server port, default %default", + default = DEFAULT_MQTT_PORT + ) + group.add_option("-k", "--keepalive", + dest = "keepalive", + action = "store", + type = 'int', + help = "keepalive option for mqtt server, default %default", + default = 60 + ) + group.add_option("-t", "--topic", + dest = "topic", + help = "topic to publish to without leading /, default %default", + default = DEFAULT_TOPIC + ) + group.add_option("-u", "--username", + dest = "username", + help = "connection username", + default = "" + ) + group.add_option("-p", "--password", + dest = "password", + help = "connection password", + default = "" + ) + parser.add_option_group(group) + + + group = optparse.OptionGroup(parser, "Basic settings") + group.add_option("-l", "--loglevel", + dest = "loglevel", + action = "store", + type = 'int', + help = str(logging.CRITICAL) + ": critical " + str(logging.ERROR) + ": error " + str(logging.WARNING) + ": warning " + str(logging.INFO) + ":info " + str(logging.DEBUG) + ":debug", + default = logging.ERROR + ) + group.add_option("-v", "--verbose", + dest = "verbose", + action = "store_true", + help = "show debug messages (overrites loglevel to debug)", + default = False + ) + parser.add_option_group(group) + + # parse options + (options, _) = parser.parse_args() + + # add infos to userdata + userdata = dict() + userdata["topic"] = options.topic + + # init logging + loglevel = int(options.loglevel) + if (options.verbose): + loglevel = logging.DEBUG + # end if + logger = logging.getLogger("miflora2mqtt") + logger.setLevel(loglevel) + ch = logging.StreamHandler() + ch.setLevel(loglevel) + formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s') + formatter.datefmt = '%Y-%m-%d %H:%M:%S' + ch.setFormatter(formatter) + logger.addHandler(ch) + + # add killer + killer = GracefulKiller() + + # add MQTT client + client = mqtt.Client() + + # set user data for callbacks + client.user_data_set(userdata) + + # register callbacks + client.on_connect = on_connect + client.on_disconnect = on_disconnect + client.on_message = on_message + + # check username and password + if (len(options.username) > 0): + if (len(options.password) == 0): + raise ValueError("please do not use username without password") + # end if + + client.username_pw_set(options.username, options.password) + # end if + + # debug output + logger.debug("server: %s" ,options.server) + logger.debug("port: %i", options.port) + logger.debug("topic: %s", options.topic) + + # connect to mqttclient + logger.debug("connect to mqtt client") + client.connect(options.server, options.port, options.keepalive) + + # start client loop + client.loop_start() + + # forever loop + try: + logger.debug("start program loop") + + while (1): + + + time.sleep(0.1) + + if (killer.kill_now): + raise KeyboardInterrupt + # end if + # end while + except KeyboardInterrupt: + logger.debug("exit program loop") + # end try + + # disconnecting + logger.debug("disconnecting from MQTT server") + client.loop_stop() + client.disconnect() +# end main + + + +if __name__ == "__main__": + try: + main() + except Exception as e: + logging.error(str(e)) + # end try +# end if