コード例 #1
0
ファイル: pyHPSU.py プロジェクト: svde/pyHPSU
def on_mqtt_message(client, userdata, message):
    global options
    global logger
    global n_hpsu

    logger.debug("complete topic: " + message.topic)
    mqtt_command = message.topic.split('/')[-1]
    logger.debug("command topic: " + mqtt_command)
    mqtt_value = str(message.payload.decode("utf-8"))
    logger.debug("value: " + mqtt_value)
    if mqtt_value == '' or mqtt_value == None or mqtt_value == "read":
        hpsu_command_string = mqtt_command
    else:
        hpsu_command_string = mqtt_command + ":" + mqtt_value
    hpsu_command_list = [hpsu_command_string]
    logger.info("setup HPSU to accept commands")
    n_hpsu = HPSU(driver=options.driver,
                  logger=logger,
                  port=options.port,
                  cmd=hpsu_command_list,
                  lg_code=options.lg_code)
    logger.info("send command to hpsu: " + hpsu_command_string)
    #exec('thread_mqttdaemon = threading.Thread(target=read_can(hpsu_command_list, options.verbose, ["MQTTDAEMON"]))')
    #exec('thread_mqttdaemon.start()')
    read_can(hpsu_command_list, options.verbose, ["MQTTDAEMON"])
    # if command was a write, re-read the value from HPSU and publish to MQTT
    if ":" in hpsu_command_string:
        hpsu_command_string_reread_after_write = hpsu_command_string.split(
            ":")[0]
        hpsu_command_string_reread_after_write_list = [
            hpsu_command_string_reread_after_write
        ]
        #exec('thread_mqttdaemon_reread = threading.Thread(target=read_can(hpsu_command_string_reread_after_write_list, options.verbose, ["MQTTDAEMON"]))')
        #exec('thread_mqttdaemon_reread.start()')
        logger.info("send same command in read mode to hpsu: " +
                    hpsu_command_string)
        read_can(hpsu_command_string_reread_after_write_list, options.verbose,
                 ["MQTTDAEMON"])
    # restarts the loop
    if options.auto:
        mqtt_client.loop_start()
コード例 #2
0
ファイル: pyHPSUd.py プロジェクト: gspascoal/pyHPSU
    def main2(self, argv):
        cmd = []
        driver = None
        verbose = "1"
        help = False
        port = None
        lg_code = None
        languages = ["EN", "IT", "DE"]

        try:
            opts, args = getopt.getopt(
                argv, "hp:d:v:l:g:",
                ["help", "port=", "driver=", "verbose=", "language=", "log="])
        except getopt.GetoptError:
            print('pyHPSUd.py -d DRIVER')
            print(' ')
            print(
                '           -d  --driver           driver name: [ELM327, PYCAN, EMU]'
            )
            print(
                '           -p  --port             port (eg COM or /dev/tty*, only for ELM327 driver)'
            )
            print(
                '           -v  --verbose          verbosity: [1, 2]   default 1'
            )
            print(
                '           -l  --language         set the language to use [%s]'
                % " ".join(languages))
            print(
                '           -g  --log              set the log to file [_filename]'
            )
            sys.exit(2)

        for opt, arg in opts:
            if opt in ("-h", "--help"):
                help = True
            elif opt in ("-d", "--driver"):
                driver = arg.upper()
            elif opt in ("-p", "--port"):
                port = arg
            elif opt in ("-v", "--verbose"):
                verbose = arg
            elif opt in ("-l", "--language"):
                lg_code = arg.upper()
                if lg_code not in languages:
                    print("Error, please specify a correct language [%s]" %
                          " ".join(languages))
                    sys.exit(9)
            elif opt in ("-g", "--log"):
                logger = logging.getLogger('domon')
                hdlr = logging.FileHandler(arg)
                formatter = logging.Formatter(
                    '%(asctime)s - %(levelname)s - %(message)s')
                hdlr.setFormatter(formatter)
                logger.addHandler(hdlr)
                logger.setLevel(logging.WARNING)

        self.hpsu = HPSU(driver=driver,
                         logger=None,
                         port=port,
                         cmd=cmd,
                         lg_code=lg_code)
        connection = pika.BlockingConnection(
            pika.ConnectionParameters(host='localhost'))
        channel = connection.channel()

        channel.queue_delete(queue='hpsu_queue')
        channel.queue_declare(queue='hpsu_queue',
                              arguments={"x-max-priority": 3})
        channel.basic_qos(prefetch_count=1)
        channel.basic_consume(self.on_request, queue='hpsu_queue')
        channel.start_consuming()
コード例 #3
0
def main(argv): 
    cmd = []
    port = None
    driver = None
    verbose = "1"
    help = False
    output_type = "JSON"
    cloud_plugin = None
    lg_code = None
    languages = ["EN", "IT", "DE"]
    logger = None

    try:
        opts, args = getopt.getopt(argv,"hc:p:d:v:o:u:l:g:", ["help", "cmd=", "port=", "driver=", "verbose=", "output_type=", "upload=", "language=", "log="])
    except getopt.GetoptError:
        print('pyHPSU.py -d DRIVER -c COMMAND')
        print(' ')
        print('           -d  --driver           driver name: [ELM327, PYCAN, EMU, HPSUD]')
        print('           -p  --port             port (eg COM or /dev/tty*, only for ELM327 driver)')
        print('           -o  --output_type      output type: [JSON, CSV, CLOUD] default JSON')
        print('           -c  --cmd              command: [see commands domain]')
        print('           -v  --verbose          verbosity: [1, 2]   default 1')
        print('           -u  --upload           upload on cloud: [_PLUGIN_]')
        print('           -l  --language         set the language to use [%s]' % " ".join(languages))
        print('           -g  --log              set the log to file [_filename]')
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            help = True
        elif opt in ("-d", "--driver"):
            driver = arg.upper()
        elif opt in ("-p", "--port"):
            port = arg
        elif opt in ("-c", "--cmd"):
            cmd.append(arg)
        elif opt in ("-v", "--verbose"):
            verbose = arg
        elif opt in ("-o", "--output_type"):
            output_type = arg.upper()
            if output_type not in ["JSON", "CSV", "CLOUD"]:
                print("Error, please specify a correct output_type [JSON, CSV, CLOUD]")
                sys.exit(9)
        elif opt in ("-u", "--upload"):
            cloud_plugin = arg.upper()
            if cloud_plugin not in ["EMONCMS"]:
                print("Error, please specify a correct plugin")
                sys.exit(9)
        elif opt in ("-l", "--language"):
            lg_code = arg.upper()   
            if lg_code not in languages:
                print("Error, please specify a correct language [%s]" % " ".join(languages))
                sys.exit(9)
        elif opt in ("-g", "--log"):
            logger = logging.getLogger('domon')
            hdlr = logging.FileHandler(arg)
            formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
            hdlr.setFormatter(formatter)
            logger.addHandler(hdlr)
            logger.setLevel(logging.ERROR)
    if verbose == "2":
        locale.setlocale(locale.LC_ALL, '')
        
    hpsu = HPSU(driver=driver, logger=logger, port=port, cmd=cmd, lg_code=lg_code)
    
    if help:
        if len(cmd) == 0:
            print("List available commands:")
            print("%12s - %-10s" % ('COMMAND', 'LABEL'))
            print("%12s---%-10s" % ('------------', '----------'))
            for cmd in hpsu.listCommands:
                print("%12s - %-10s" % (cmd['name'], cmd['label']))
        else:
            print("%12s - %-10s - %s" % ('COMMAND', 'LABEL', 'DESCRIPTION'))
            print("%12s---%-10s---%s" % ('------------', '----------', '---------------------------------------------------'))
            for c in hpsu.commands:
                print("%12s - %-10s - %s" % (c['name'], c['label'], c['desc']))
        sys.exit(0)

    if not driver:
        print("Error, please specify driver [ELM327 or PYCAN, EMU, HPSUD]")
        sys.exit(9)        

    arrResponse = []   
    for c in hpsu.commands:
        setValue = None
        for i in cmd:
            if ":" in i and c["name"] == i.split(":")[0]:
                setValue = i.split(":")[1]

        i = 0
        while i <= 3:
            rc = hpsu.sendCommand(c, setValue)
            if rc != "KO":            
                i = 4
                if not setValue:
                    response = hpsu.parseCommand(cmd=c, response=rc, verbose=verbose)
                    resp = hpsu.umConversion(cmd=c, response=response, verbose=verbose)

                    arrResponse.append({"name":c["name"], "resp":resp, "timestamp":response["timestamp"]})
            else:
                i += 1
                time.sleep(2.0)
                hpsu.printd('warning', 'retry %s command %s' % (i, c["name"]))
                if i == 4:
                    hpsu.printd('error', 'command %s failed' % (c["name"]))

    if output_type == "JSON":
        print(arrResponse)
    elif output_type == "CSV":
        for r in arrResponse:
            print("%s\t%s\t%s" % (r["timestamp"], r["name"], r["resp"]))
    elif output_type == "CLOUD":
        if not cloud_plugin:
            print ("Error, please specify a cloud_plugin")
            sys.exit(9)

        module = importlib.import_module("plugins.cloud")
        cloud = module.Cloud(plugin=cloud_plugin, hpsu=hpsu, logger=logger)
        cloud.pushValues(vars=arrResponse)
コード例 #4
0
ファイル: can.py プロジェクト: wlodarz/modbus2can
    def hpsu_handler(self, queue):
        '''
        '''

        hpsu = HPSU(driver=self.driver, logger=self.logger, port=self.port, cmd=[], lg_code=self.lg_code)
        while True:

            # get command
            t = queue.get()
            cmd = t.strip().split(':')
            paramName = cmd[1]
            print(cmd)

            if cmd[0] == 'g':
                # print("can getter")
                setValue = None
                cmd = [cmd[1]]
				
            if cmd[0] == 's':
                # print("can setter")	
                setValue = cmd[2]
                cmd = [cmd[1], cmd[2]]
                print('CAN SET')
                print(cmd)

            # print(hpsu.commands)
            for c in hpsu.commands:
                if c['name'] == cmd[0]:
                    # print(c)
                    if setValue:
                            # v = 
                            # v = int(float(setValue) * float(div))
                            print("Sending")
                            val = cmd[1]
                            div = c['div']
                            v = int(float(val) * float(div))
                            cmd[1] = str(v)
                            setValue = cmd[1]
                            # print(v)
                            print('CAN: sending set command {0} {1}'.format(c, setValue))
                    
                    # print("Receiving")
                    rc = hpsu.sendCommand(c, setValue)
                    if rc != "KO":
                        if not setValue:
                            # print("Current value")
                            response = hpsu.parseCommand(cmd=c, response=rc, verbose=self.verbose)
                            resp = hpsu.umConversion(cmd=c, response=response, verbose=self.verbose)
                            div = c['div']
                            v = int(float(resp) * float(div))
                            # print(div)
                            # print(resp)
                            # print(v)
                            # print("GET COMMAND OK")
                            self.params.setValueByName(paramName, float(resp))
                            print("CAN: GET COMMAND OK")
                        else:
                            self.params.setParamChanged(paramName, 0)
                            print("CAN: SET COMMAND OK")
                    else:
                        hpsu.printd('CAN: error', 'command %s failed' % (c["name"]))
コード例 #5
0
def main(argv):
    cmd = []
    port = None
    driver = "PYCAN"
    verbose = "1"
    show_help = False
    output_type = "JSON"
    upload = False
    lg_code = "EN"
    languages = ["EN", "IT", "DE"]
    logger = None
    pathCOMMANDS = "/etc/pyHPSU"
    global conf_file
    conf_file = None
    global default_conf_file
    default_conf_file = "/etc/pyHPSU/pyhpsu.conf"
    read_from_conf_file = False
    global auto
    global ticker
    ticker = 0
    loop = True
    auto = False
    #commands = []
    #listCommands = []
    global config
    config = configparser.ConfigParser()
    global n_hpsu
    env_encoding = sys.stdout.encoding
    PLUGIN_PATH = "/usr/lib/python3/dist-packages/HPSU/plugins"
    backup_mode = False
    global backup_file
    restore_mode = False
    global options_list
    options_list = {}
    #
    # get all plugins
    #
    PLUGIN_LIST = ["JSON", "CSV", "BACKUP"]
    PLUGIN_STRING = "JSON, CSV, BACKUP"
    for file in os.listdir(PLUGIN_PATH):
        if file.endswith(".py") and not file.startswith("__"):
            PLUGIN = file.upper().split(".")[0]
            PLUGIN_STRING += ", "
            PLUGIN_STRING += PLUGIN
            PLUGIN_LIST.append(PLUGIN)

    try:
        opts, args = getopt.getopt(argv, "ahc:p:d:v:o:l:g:f:b:r:", [
            "help", "cmd=", "port=", "driver=", "verbose=", "output_type=",
            "upload=", "language=", "log=", "config_file="
        ])
    except getopt.GetoptError:
        print('pyHPSU.py -d DRIVER -c COMMAND')
        print(' ')
        print('           -a  --auto            do atomatic queries')
        print(
            '           -f  --config          Configfile, overrides given commandline arguments'
        )
        print(
            '           -d  --driver          driver name: [ELM327, PYCAN, EMU, HPSUD], Default: PYCAN'
        )
        print(
            '           -p  --port            port (eg COM or /dev/tty*, only for ELM327 driver)'
        )
        print('           -o  --output_type     output type: [' +
              PLUGIN_STRING + '] default JSON')
        print(
            '           -c  --cmd             command: [see commands domain]')
        print('           -v  --verbose         verbosity: [1, 2]   default 1')
        print(
            '           -l  --language        set the language to use [%s], default is \"EN\" '
            % " ".join(languages))
        print(
            '           -b  --backup          backup configurable settings to file [filename]'
        )
        print(
            '           -r  --restore         restore HPSU settings from file [filename]'
        )
        print(
            '           -g  --log             set the log to file [_filename]')
        print('           -h  --help            show help')
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-a", "--auto"):
            auto = True
            options_list["auto"] = ""

        if opt in ("-f", "--config"):
            read_from_conf_file = True
            conf_file = arg
            options_list["config"] = arg

        if opt in ("-b", "--backup"):
            backup_mode = True
            backup_file = arg
            output_type = "BACKUP"
            options_list["backup"] = arg

        if opt in ("-r", "--restore"):
            restore_mode = True
            backup_file = arg
            options_list["restore"] = arg

        if opt in ("-h", "--help"):
            show_help = True
            options_list["help"] = ""

        elif opt in ("-d", "--driver"):
            driver = arg.upper()
            options_list["driver"] = arg.upper()

        elif opt in ("-p", "--port"):
            port = arg
            options_list["port"] = arg

        elif opt in ("-c", "--cmd"):
            cmd.append(arg)

        elif opt in ("-v", "--verbose"):
            verbose = arg
            options_list["verbose"] = ""

        elif opt in ("-o", "--output_type"):
            output_type = arg.upper()
            options_list["output_type"] = arg.upper()

        elif opt in ("-l", "--language"):
            lg_code = arg.upper()
            options_list["language"] = arg.upper()

        elif opt in ("-g", "--log"):
            logger = logging.getLogger('pyhpsu')
            hdlr = logging.FileHandler(arg)
            formatter = logging.Formatter(
                '%(asctime)s - %(levelname)s - %(message)s')
            hdlr.setFormatter(formatter)
            logger.addHandler(hdlr)
            logger.setLevel(logging.ERROR)
        options_list["cmd"] = cmd
    if verbose == "2":
        locale.setlocale(locale.LC_ALL, '')

    # config if in auto mode
    if auto:
        read_from_conf_file = True
        conf_file = default_conf_file

    # get config from file if given....
    if read_from_conf_file:
        if conf_file == None:
            print("Error, please provide a config file")
            sys.exit(9)
        else:
            try:
                with open(conf_file) as f:
                    config.read_file(f)
            except IOError:
                print("Error: config file not found")
                sys.exit(9)
        config.read(conf_file)
        if driver == "" and config.has_option('PYHPSU', 'PYHPSU_DEVICE'):
            driver = config['PYHPSU']['PYHPSU_DEVICE']
        if port == "" and config.has_option('PYHPSU', 'PYHPSU_PORT'):
            port = config['PYHPSU']['PYHPSU_PORT']
        if lg_code == "" and config.has_option('PYHPSU', 'PYHPSU_LANG'):
            lg_code = config['PYHPSU']['PYHPSU_LANG']
        if output_type == "" and config.has_option('PYHPSU', 'OUTPUT_TYPE'):
            output_type = config['PYHPSU']['OUTPUT_TYPE']

    else:
        conf_file = default_conf_file

    #
    # now we should have all options...let's check them
    #
    # Check driver
    if driver not in ["ELM327", "PYCAN", "EMU", "HPSUD"]:
        print(
            "Error, please specify a correct driver [ELM327, PYCAN, EMU, HPSUD] "
        )
        sys.exit(9)

    if driver == "ELM327" and port == "":
        print("Error, please specify a correct port for the ELM327 device ")
        sys.exit(9)

    # Check output type
    if output_type not in PLUGIN_LIST:
        print("Error, please specify a correct output_type [" + PLUGIN_STRING +
              "]")
        sys.exit(9)

    # Check Language
    if lg_code not in languages:
        print("Error, please specify a correct language [%s]" %
              " ".join(languages))
        sys.exit(9)
    # ------------------------------------
    # try to query different commands in different periods
    # Read them from config and group them
    #
    # create dictionary for the jobs
    if auto:
        timed_jobs = dict()
        if read_from_conf_file:  # if config is read from file
            if len(config.options('JOBS')):  # if there are configured jobs
                for each_key in config.options(
                        'JOBS'):  # for each value to query
                    job_period = config.get('JOBS', each_key)  # get the period
                    if not "timer_" + job_period in timed_jobs.keys(
                    ):  # if this period isn't still in the dict
                        timed_jobs["timer_" + job_period] = [
                        ]  # create a list for this period
                    timed_jobs["timer_" + job_period].append(
                        each_key)  # and add the value to this period
                wanted_periods = list(timed_jobs.keys())
            else:
                print("Error, please specify a value to query in config file ")
                sys.exit(9)

    #
    # Print help
    #
    if show_help:
        n_hpsu = HPSU(driver=driver,
                      logger=logger,
                      port=port,
                      cmd=cmd,
                      lg_code=lg_code)
        if len(cmd) == 0:
            print("List available commands:")
            print("%20s - %-10s" % ('COMMAND', 'LABEL'))
            print("%20s---%-10s" % ('------------', '----------'))
            for cmd in sorted(n_hpsu.command_dict):
                try:
                    print("%20s - %-10s" % (n_hpsu.command_dict[cmd]['name'],
                                            n_hpsu.command_dict[cmd]['label']))
                except KeyError:
                    print("""!!!!!! No translation for "%12s" !!!!!!!""" %
                          (n_hpsu.command_dict[cmd]['name']))
        else:
            print("%12s - %-10s - %s" % ('COMMAND', 'LABEL', 'DESCRIPTION'))
            print("%12s---%-10s---%s" %
                  ('------------', '----------',
                   '---------------------------------------------------'))
            for c in n_hpsu.commands:
                print("%12s - %-10s - %s" % (c['name'], c['label'], c['desc']))
        sys.exit(0)

        #
        # now its time to call the hpsu and do the REAL can query
        # and handle the data as configured
        #
    if auto and not backup_mode:
        while loop:
            ticker += 1
            collected_cmds = []
            for period_string in timed_jobs.keys():
                period = period_string.split("_")[1]
                if not ticker % int(period):
                    for job in timed_jobs[period_string]:
                        collected_cmds.append(str(job))
            if len(collected_cmds):
                n_hpsu = HPSU(driver=driver,
                              logger=logger,
                              port=port,
                              cmd=collected_cmds,
                              lg_code=lg_code)
                exec(
                    'thread_%s = threading.Thread(target=read_can, args=(driver,logger,port,collected_cmds,lg_code,verbose,output_type))'
                    % (period))
                exec('thread_%s.start()' % (period))
            time.sleep(1)
    elif backup_mode:
        n_hpsu = HPSU(driver=driver,
                      logger=logger,
                      port=port,
                      cmd=cmd,
                      lg_code=lg_code)
        read_can(driver, logger, port, n_hpsu.backup_commands, lg_code,
                 verbose, output_type)
    elif restore_mode:
        restore_commands = []
        try:
            with open(backup_file, 'rU') as jsonfile:
                restore_settings = json.load(jsonfile)
                for command in restore_settings:
                    restore_commands.append(
                        str(command["name"]) + ":" + str(command["resp"]))
                n_hpsu = HPSU(driver=driver,
                              logger=logger,
                              port=port,
                              cmd=restore_commands,
                              lg_code=lg_code)
                read_can(driver, logger, port, restore_commands, lg_code,
                         verbose, output_type)
        except FileNotFoundError:
            print("No such file or directory!!!")
            sys.exit(1)

    else:
        n_hpsu = HPSU(driver=driver,
                      logger=logger,
                      port=port,
                      cmd=cmd,
                      lg_code=lg_code)
        read_can(driver, logger, port, cmd, lg_code, verbose, output_type)
コード例 #6
0
ファイル: pyHPSU.py プロジェクト: svde/pyHPSU
def main(argv):
    global options
    global logger
    global n_hpsu
    global mqtt_client
    global mqtt_prefix
    global mqtt_qos
    global mqtt_retain
    global mqtt_addtimestamp
    global mqttdaemon_command_topic
    global mqttdaemon_status_topic

    sys.excepthook = my_except_hook
    cmd = None
    languages = ["EN", "IT", "DE"]
    global default_conf_file
    default_conf_file = "/etc/pyHPSU/pyhpsu.conf"
    read_from_conf_file = False
    global ticker
    ticker = 0
    loop = True
    LOG_LEVEL_LIST = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
    # default log formatter
    log_formatter = logging.Formatter(
        '%(asctime)s - %(levelname)s - %(message)s')
    #commands = []
    #listCommands = []
    global config
    config = configparser.ConfigParser()
    PLUGIN_PATH = "/usr/lib/python3/dist-packages/HPSU/plugins"
    #
    # get all plugins
    #
    PLUGIN_LIST = ["JSON", "CSV", "BACKUP"]
    PLUGIN_STRING = "JSON, CSV, BACKUP"
    for file in os.listdir(PLUGIN_PATH):
        if file.endswith(".py") and not file.startswith("__"):
            PLUGIN = file.upper().split(".")[0]
            PLUGIN_STRING += ", "
            PLUGIN_STRING += PLUGIN
            PLUGIN_LIST.append(PLUGIN)

    parser = argparse.ArgumentParser(
        description=
        "pyHPSU is a set of python scripts and other files to read and modify the values\nof the Rotex® HPSU (possibly) also identical heating pumps from Daikin®).",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=
        "- If no command is specified, all commands in dictionary are executed\n- To set a value use <command>:<value>"
    )
    parser.add_argument(
        "--dictionary",
        action="store_true",
        dest="show_help",
        help="show complete command dictionary or specific command help")
    parser.add_argument('--version',
                        action='version',
                        version='%(prog)s 1.0-BETA1')
    parser.add_argument("-a",
                        "--auto",
                        action="store_true",
                        help="do automatic queries")
    parser.add_argument(
        "-f",
        "--config",
        dest="conf_file",
        help="Configfile, overrides given commandline arguments")
    backup_restore_group = parser.add_mutually_exclusive_group()
    backup_restore_group.add_argument(
        "-b",
        "--backup",
        dest="backup_file",
        help="backup configurable settings to file [filename]")
    backup_restore_group.add_argument(
        "-r",
        "--restore",
        dest="restore_file",
        help="restore HPSU settings from file [filename]")
    parser.add_argument("-g",
                        "--log",
                        dest="log_file",
                        help="set the log to file [filename]")
    parser.add_argument("--log_level",
                        choices=LOG_LEVEL_LIST,
                        type=str.upper,
                        default="ERROR",
                        help="set the log level to [" +
                        ", ".join(LOG_LEVEL_LIST) + "]")
    parser.add_argument(
        "-l",
        "--language",
        dest="lg_code",
        choices=languages,
        type=str.upper,
        default="EN",
        help="set the language to use [%s], default is \"EN\" " %
        " ".join(languages))
    parser.add_argument(
        "-d",
        "--driver",
        type=str.upper,
        default="PYCAN",
        help="driver name: [ELM327, PYCAN, EMU, HPSUD], Default: PYCAN")
    parser.add_argument("-c",
                        "--cmd",
                        action="append",
                        help="command: [see commands dictionary]")
    parser.add_argument("-o",
                        "--output_type",
                        action="append",
                        type=str.upper,
                        choices=PLUGIN_LIST,
                        help="output type: [" + ", ".join(PLUGIN_LIST) +
                        "] default JSON")
    parser.add_argument("-v",
                        "--verbose",
                        default="1",
                        help="verbosity: [1, 2] default 1")
    parser.add_argument(
        "-p",
        "--port",
        help="port (eg COM or /dev/tty*, only for ELM327 driver)")
    parser.add_argument(
        "--mqtt_daemon",
        action="store_true",
        help=
        "set up an mqtt daemon that subscribe to a command topic and executes received command on HPSU"
    )

    try:
        options = parser.parse_args()
    except IOError as e:
        parser.error(e)
    if (options == None):
        print(parser.usage)
        sys.exit(os.EX_USAGE)
    else:
        # set the default value if no output_type is chosen (not possible with add_argument() because it does
        # not detect duplication e.g. when JSON is also chosen)
        if options.output_type is None:
            options.output_type = ["JSON"]
        cmd = [] if options.cmd is None else options.cmd
        if options.backup_file is not None:
            options.output_type.append("BACKUP")
        read_from_conf_file = options.conf_file is not None
        # if no log file has been specified and driver is HPSUD then log nothing
        if options.log_file is None and options.driver == "HPSUD":
            _log_handler = logging.NullHandler
        elif options.log_file is not None:
            _log_handler = logging.FileHandler(options.log_file)
        else:
            # default log to stdout if no file specified
            _log_handler = logging.StreamHandler()

    logger = logging.getLogger('pyhpsu')
    _log_handler.setFormatter(log_formatter)
    logger.addHandler(_log_handler)
    logger.setLevel(options.log_level)

    if options.verbose == "2":
        locale.setlocale(locale.LC_ALL, '')

    # if no config file option is present...
    if not read_from_conf_file:
        # ...set the default one...
        # NOTE: other modules may need to load it later
        options.conf_file = default_conf_file
        # ...but auto or mqttdaemon mode needs it loaded...
        if options.auto or options.mqtt_daemon:
            # ...read it
            read_from_conf_file = True

    # get config from file if given....
    if read_from_conf_file:
        try:
            with open(options.conf_file) as f:
                config.read_file(f)
        except IOError:
            logger.critical("config file not found")
            sys.exit(os.EX_CONFIG)
        config.read(options.conf_file)
        if options.driver == "" and config.has_option('PYHPSU',
                                                      'PYHPSU_DEVICE'):
            options.driver = config['PYHPSU']['PYHPSU_DEVICE']
        if options.port == "" and config.has_option('PYHPSU', 'PYHPSU_PORT'):
            options.port = config['PYHPSU']['PYHPSU_PORT']
        if options.lg_code == "" and config.has_option('PYHPSU',
                                                       'PYHPSU_LANG'):
            options.lg_code = config['PYHPSU']['PYHPSU_LANG'].upper()
        if len(options.output_type) == 0 and config.has_option(
                'PYHPSU', 'OUTPUT_TYPE'):
            options.output_type.append(config['PYHPSU']['OUTPUT_TYPE'])

        # object to store entire MQTT config section
        mqtt_config = config['MQTT']
        # MQTT Daemon command topic
        mqttdaemon_command_topic = mqtt_config.get('COMMAND', 'command')
        # MQTT Daemon status topic
        # FIXME to be used for pyHPSU status, including MQTTDAEMON mode, not for actual parameter reading
        mqttdaemon_status_topic = mqtt_config.get('STATUS', 'status')
        mqtt_brokerhost = mqtt_config.get('BROKER', 'localhost')
        mqtt_brokerport = mqtt_config.getint('PORT', 1883)
        mqtt_clientname = mqtt_config.get('CLIENTNAME', 'rotex')
        mqtt_username = mqtt_config.get('USERNAME', None)
        if mqtt_username is None:
            logger.error("Username not set!!!!!")
        mqtt_password = mqtt_config.get('PASSWORD', "NoPasswordSpecified")
        mqtt_prefix = mqtt_config.get('PREFIX', "")
        mqtt_qos = mqtt_config.getint('QOS', 0)
        # every other value implies false
        mqtt_retain = mqtt_config.get('RETAIN', "NOT TRUE") == "True"
        # every other value implies false
        mqtt_addtimestamp = mqtt_config.get('ADDTIMESTAMP',
                                            "NOT TRUE") == "True"

        logger.info("configuration parsing complete")

    #
    # now we should have all options...let's check them
    #
    if options.driver == "ELM327" and options.port == "":
        logger.critical("please specify a correct port for the ELM327 device ")
        sys.exit(os.EX_CONFIG)

    # ------------------------------------
    # try to query different commands in different periods
    # Read them from config and group them
    #
    # create dictionary for the jobs
    if options.auto:
        timed_jobs = dict()
        if read_from_conf_file:  # if config is read from file
            if len(config.options('JOBS')):  # if there are configured jobs
                for each_key in config.options(
                        'JOBS'):  # for each value to query
                    job_period = config.get('JOBS', each_key)  # get the period
                    if not "timer_" + job_period in timed_jobs.keys(
                    ):  # if this period isn't still in the dict
                        timed_jobs["timer_" + job_period] = [
                        ]  # create a list for this period
                    timed_jobs["timer_" + job_period].append(
                        each_key)  # and add the value to this period
                wanted_periods = list(timed_jobs.keys())
            else:
                logger.critical(
                    "please specify a value to query in config file ")
                sys.exit(os.EX_CONFIG)

    #
    # Print help
    #
    if options.show_help:
        n_hpsu = HPSU(driver=options.driver,
                      logger=logger,
                      port=options.port,
                      cmd=cmd,
                      lg_code=options.lg_code)
        if len(cmd) == 0:
            print("List available commands:")
            print("%20s - %-10s" % ('COMMAND', 'LABEL'))
            print("%20s---%-10s" % ('------------', '----------'))
            for cmd in sorted(n_hpsu.command_dict):
                if 'label' in n_hpsu.command_dict[cmd]:
                    print("%20s - %-10s" %
                          (n_hpsu.command_dict[cmd]['name'],
                           (n_hpsu.command_dict[cmd]['label']) +
                           ('' if n_hpsu.command_dict[cmd]['writable']
                            == 'true' else ' (readonly)')))
                else:
                    error_message = """!!!!!! No translation for "%12s" !!!!!!!""" % (
                        n_hpsu.command_dict[cmd]['name'])
                    print(error_message)
                    logger.error(error_message)
        else:
            print("%12s - %-10s - %s" % ('COMMAND', 'LABEL', 'DESCRIPTION'))
            print("%12s---%-10s---%s" %
                  ('------------', '----------',
                   '---------------------------------------------------'))
            for c in n_hpsu.commands:
                print("%12s - %-10s - %s" %
                      (c['name'], c['label'] +
                       ('' if c['writable'] == 'true' else ' (readonly)'),
                       c['desc']))
        sys.exit(os.EX_USAGE)

        #
        # now its time to call the hpsu and do the REAL can query
        # and handle the data as configured
        #
    if options.mqtt_daemon:
        # adding the PID at the end of the client name ensures every process have a different client name
        _mqttdaemon_clientname = mqtt_clientname + "-mqttdaemon-" + str(
            os.getpid())
        logger.info("creating new mqtt client instance: " +
                    _mqttdaemon_clientname)
        # a different client name because otherwise mqtt output plugin closes this connection, too
        mqtt_client = mqtt.Client(_mqttdaemon_clientname)
        if mqtt_username:
            mqtt_client.username_pw_set(mqtt_username, password=mqtt_password)
            mqtt_client.enable_logger()

        mqtt_client.on_message = on_mqtt_message
        logger.info("connecting to broker: " + mqtt_brokerhost + ", port: " +
                    str(mqtt_brokerport))
        mqtt_client.connect(mqtt_brokerhost, mqtt_brokerport)

        command_topic = mqtt_prefix + "/" + mqttdaemon_command_topic + "/+"
        logger.info("Subscribing to command topic: " + command_topic)
        mqtt_client.subscribe(command_topic)

        # this blocks execution
        #mqtt_client.loop_forever()
        if options.auto:
            mqtt_client.loop_start()

    # if a backup file is specified we are in backup mode
    if options.backup_file is not None:
        n_hpsu = HPSU(driver=options.driver,
                      logger=logger,
                      port=options.port,
                      cmd=cmd,
                      lg_code=options.lg_code)
        read_can(n_hpsu.backup_commands, options.verbose, options.output_type)
    elif options.auto:
        while loop:
            ticker += 1
            collected_cmds = []
            for period_string in timed_jobs.keys():
                period = period_string.split("_")[1]
                if not ticker % int(period):
                    for job in timed_jobs[period_string]:
                        collected_cmds.append(str(job))
            if len(collected_cmds):
                n_hpsu = HPSU(driver=options.driver,
                              logger=logger,
                              port=options.port,
                              cmd=collected_cmds,
                              lg_code=options.lg_code)
                exec(
                    'thread_%s = threading.Thread(target=read_can, args=(collected_cmds,options.verbose,options.output_type))'
                    % (period))
                exec('thread_%s.start()' % (period))
            time.sleep(1)
    # if a restore file is specified we are in restore mode
    elif options.restore_file is not None:
        restore_commands = []
        try:
            with open(options.restore_file, 'rU') as jsonfile:
                restore_settings = json.load(jsonfile)
                for command in restore_settings:
                    restore_commands.append(
                        str(command["name"]) + ":" + str(command["resp"]))
                n_hpsu = HPSU(driver=options.driver,
                              logger=logger,
                              port=options.port,
                              cmd=restore_commands,
                              lg_code=options.lg_code)
                read_can(restore_commands, options.verbose,
                         options.output_type)
        except FileNotFoundError:
            logger.error("No such file or directory!!!")
            sys.exit(os.EX_NOINPUT)

    # FIXME if no command is specified and mqttdaemon mode is active, don't query all the commands (this has to be discussed)
    elif not (len(cmd) == 0 and options.mqtt_daemon):
        n_hpsu = HPSU(driver=options.driver,
                      logger=logger,
                      port=options.port,
                      cmd=cmd,
                      lg_code=options.lg_code)
        read_can(cmd, options.verbose, options.output_type)

    # if we reach this point (the end), we are not in auto mode so the loop is not started
    if mqtt_client is not None:
        mqtt_client.loop_forever()