From 912b331b94e536ec96b3409513f6ccd11d7c05db Mon Sep 17 00:00:00 2001 From: segaura Date: Sat, 13 Feb 2021 14:37:27 +0100 Subject: [PATCH 01/23] implemented mqttdaemon mode/option --- pyHPSU.py | 141 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 124 insertions(+), 17 deletions(-) diff --git a/pyHPSU.py b/pyHPSU.py index bd3d450..95d281f 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -18,10 +18,28 @@ import threading import csv import json +import paho.mqtt.publish as publish +import paho.mqtt.subscribe as subscribe +import paho.mqtt.client as mqtt SocketPort = 7060 +logger = None +n_hpsu = None +driver = None +port = None +lg_code = None +verbose = None +output_type = None def main(argv): + global logger + global n_hpsu + global driver + global port + global lg_code + global verbose + global output_type + cmd = [] port = None driver = "PYCAN" @@ -31,7 +49,6 @@ def main(argv): upload = False lg_code = "EN" languages = ["EN", "IT", "DE"] - logger = None pathCOMMANDS = "/etc/pyHPSU" global conf_file conf_file = None @@ -54,7 +71,6 @@ def main(argv): #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 @@ -62,6 +78,8 @@ def main(argv): restore_mode=False global options_list options_list={} + mqttdaemon_option_present = False + mqttdaemon_subscribe_topic = "command" # # get all plugins # @@ -75,7 +93,7 @@ def main(argv): 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=", "log_level=", "config_file="]) + 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=", "log_level=", "config_file=", "mqtt_daemon"]) except getopt.GetoptError: print('pyHPSU.py -d DRIVER -c COMMAND') print(' ') @@ -89,6 +107,7 @@ def main(argv): 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(' --mqtt_daemon set up an mqtt daemon that subscribe to a command topic and executes received command on HPSU') print(' -g --log set the log to file [filename]') print(' --log_level set the log level to [' + LOG_LEVEL_STRING + ']') print(' -h --help show help') @@ -142,6 +161,9 @@ def main(argv): lg_code = arg.upper() options_list["language"]=arg.upper() + elif opt in ("--mqtt_daemon"): + mqttdaemon_option_present = True + elif opt in ("-g", "--log"): log_handler = logging.FileHandler(arg) options_list["log_file"]=arg @@ -174,22 +196,27 @@ def main(argv): if verbose == "2": locale.setlocale(locale.LC_ALL, '') - # config if in auto mode - if auto: - read_from_conf_file=True + # 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 conf_file=default_conf_file + # ...but auto or mqttdaemon mode needs it loaded... + if auto or mqttdaemon_option_present: + # ...read it + read_from_conf_file=True # get config from file if given.... if read_from_conf_file: if conf_file==None: - logger.error("please provide a config file") + logger.critical("please provide a config file") sys.exit(9) else: try: with open(conf_file) as f: config.read_file(f) except IOError: - logger.error("config file not found") + logger.critical("config file not found") sys.exit(9) config.read(conf_file) if driver=="" and config.has_option('PYHPSU','PYHPSU_DEVICE'): @@ -200,30 +227,72 @@ def main(argv): lg_code=config['PYHPSU']['PYHPSU_LANG'] if output_type=="" and config.has_option('PYHPSU','OUTPUT_TYPE'): output_type=config['PYHPSU']['OUTPUT_TYPE'] + # added for mqttd daemon - else: - conf_file=default_conf_file + # MQTT hostname or IP + if config.has_option('MQTT', 'BROKER'): + brokerhost = config['MQTT']['BROKER'] + else: + brokerhost = 'localhost' + + # MQTT broker port + if config.has_option('MQTT', 'PORT'): + brokerport = int(config['MQTT']['PORT']) + else: + brokerport = 1883 + + # MQTT client name + if config.has_option('MQTT', 'CLIENTNAME'): + clientname = config['MQTT']['CLIENTNAME'] + else: + clientname = 'rotex' + # MQTT Username + if config.has_option('MQTT', 'USERNAME'): + username = config['MQTT']['USERNAME'] + else: + username = None + logger.error("Username not set!!!!!") + + #MQTT Password + if config.has_option('MQTT', "PASSWORD"): + password = config['MQTT']['PASSWORD'] + else: + password="None" + + #MQTT Prefix + if config.has_option('MQTT', "PREFIX"): + prefix = config['MQTT']['PREFIX'] + else: + prefix = "" + + #MQTT QOS + if config.has_option('MQTT', "QOS"): + qos = config['MQTT']['QOS'] + else: + qos = "0" + + logger.info("configuration parsing complete") # # now we should have all options...let's check them # # Check driver if driver not in ["ELM327", "PYCAN", "EMU", "HPSUD"]: - logger.error("please specify a correct driver [ELM327, PYCAN, EMU, HPSUD] ") + logger.critical("please specify a correct driver [ELM327, PYCAN, EMU, HPSUD] ") sys.exit(9) if driver == "ELM327" and port == "": - logger.error("please specify a correct port for the ELM327 device ") + logger.critical("please specify a correct port for the ELM327 device ") sys.exit(9) # Check output type if output_type not in PLUGIN_LIST: - logger.error("please specify a correct output_type [" + PLUGIN_STRING + "]") + logger.critical("please specify a correct output_type [" + PLUGIN_STRING + "]") sys.exit(9) # Check Language if lg_code not in languages: - logger.error("please specify a correct language [%s]" % " ".join(languages)) + logger.critical("please specify a correct language [%s]" % " ".join(languages)) sys.exit(9) # ------------------------------------ # try to query different commands in different periods @@ -241,7 +310,7 @@ def main(argv): timed_jobs["timer_" + job_period].append(each_key) # and add the value to this period wanted_periods=list(timed_jobs.keys()) else: - logger.error("please specify a value to query in config file ") + logger.critical("please specify a value to query in config file ") sys.exit(9) # @@ -271,7 +340,22 @@ def main(argv): # 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: + if mqttdaemon_option_present: + logger.info("creating new mqtt client instance: " + clientname) + client=mqtt.Client(clientname) + if username: + client.username_pw_set(username, password=password) + client.enable_logger() + + client.on_message=on_mqtt_message + logger.info("connecting to broker") + client.connect(brokerhost) + + logger.info("Subscribing to command topic") + client.subscribe(prefix + "/" + mqttdaemon_subscribe_topic + "/+") + + client.loop_forever() + elif auto and not backup_mode: while loop: ticker+=1 collected_cmds=[] @@ -309,7 +393,7 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): global backup_file # really needed? Driver is checked above #if not driver: - # print("Error, please specify driver [ELM327 or PYCAN, EMU, HPSUD]") + # logger.critical("Error, please specify driver [ELM327 or PYCAN, EMU, HPSUD]") # sys.exit(9) arrResponse = [] @@ -319,6 +403,9 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): for i in cmd: if ":" in i and c["name"] == i.split(":")[0]: setValue = i.split(":")[1] + if c["writable"] != "true": + logger.critical(c["name"] + " is a readonly command") + sys.exit(9) if not c["type"] == "value": setValue = float(setValue)*float(c["divisor"]) else: @@ -367,5 +454,25 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): hpsu_plugin = module.export(hpsu=n_hpsu, logger=logger, config_file=conf_file) hpsu_plugin.pushValues(vars=arrResponse) +def on_mqtt_message(client, userdata, message): + global logger + global driver + global port + global lg_code + global verbose + global output_type + 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) + hpsu_command_string = mqtt_command + ":" + mqtt_value + hpsu_command_list = [hpsu_command_string] + logger.info("setup HPSU to accept commands") + n_hpsu = HPSU(driver=driver, logger=logger, port=port, cmd=hpsu_command_list, lg_code=lg_code) + logger.info("send command to hpsu: hpsu_command_string") + read_can(driver, logger, port, hpsu_command_list, lg_code,verbose,output_type) + if __name__ == "__main__": main(sys.argv[1:]) From 8fc6ae2746bca6ef7a7648e8483f9c574dff7516 Mon Sep 17 00:00:00 2001 From: segaura Date: Sat, 13 Feb 2021 14:53:31 +0100 Subject: [PATCH 02/23] mqttdaemon mode README.md, COMMAND in conf file --- README.md | 23 +++++++++++++++++++++++ pyHPSU.py | 20 ++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e378a96..e2a2c68 100755 --- a/README.md +++ b/README.md @@ -151,6 +151,29 @@ The pyHPSUD.py is started via systemd: root@rotex:# systemctl enable hpsud.service root@rotex:# systemctl start hpsud.service +4. MQTT Daemon mode +pyHPSU starts in daemon mode, it subscribe an MQTT topic and listen forever waiting for commands. +MQTT coordinates are specified through configuration file: the same property used by mqtt output plugin plus an additional COMMANDTOPIC. +The daemon subscribe to the topic + + PREFIX / COMMANDTOPIC / + + +e.g. + configuration file (e.g. /etc/pyHPSU/pyhpsu.conf) + ... + [MQTT] + BROKER = 192.168.1.94 + PREFIX = myhpsu + COMMANDTOPIC = command + ... + + root@rotex:# pyHPSU.py --mqttdaemon + + user@anothersystem:# mosquitto_pub -h 192.168.1.94 -t "myhpsu/command/t_flow_day" -m 29 + + set the parameter t_flow_day to 29°C + + Now, you can query multiple values or run multiple pyHPSU.py processes. Simply set as driver HPSUD ("CANTCP") via commandline or the config file (PYHPSU section) i.e. root@rotex:# pyHPSU.py -d HPSUD -c t_dhw_setpoint1 diff --git a/pyHPSU.py b/pyHPSU.py index 95d281f..f774773 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -2,6 +2,15 @@ # # -*- coding: utf-8 -*- +# config inf conf_file for MQTT Daemon mode (defaults): +# [MQTT] +# BROKER = localhost +# PORT = 1883 +# USERNAME = +# PASSWORD = +# CLIENTNAME = rotex_hpsu +# PREFIX = rotex +# COMMANDTOPIC = command import serial import sys @@ -79,7 +88,7 @@ def main(argv): global options_list options_list={} mqttdaemon_option_present = False - mqttdaemon_subscribe_topic = "command" + mqttdaemon_command_topic = "command" # # get all plugins # @@ -265,6 +274,13 @@ def main(argv): else: prefix = "" + #MQTT MQTT Daemon command topic + if config.has_option('MQTT', "COMMAND"): + mqttdaemon_command_topic = config['MQTT']['COMMAND'] +# default already set +# else: +# mqttdaemon_command_topic = "" + #MQTT QOS if config.has_option('MQTT', "QOS"): qos = config['MQTT']['QOS'] @@ -352,7 +368,7 @@ def main(argv): client.connect(brokerhost) logger.info("Subscribing to command topic") - client.subscribe(prefix + "/" + mqttdaemon_subscribe_topic + "/+") + client.subscribe(prefix + "/" + mqttdaemon_command_topic + "/+") client.loop_forever() elif auto and not backup_mode: From 8dc36011eea80c11cb2a353d3e34d139b85131fd Mon Sep 17 00:00:00 2001 From: segaura Date: Sat, 13 Feb 2021 16:11:26 +0100 Subject: [PATCH 03/23] mqttdaemon read via mqtt --- README.md | 21 +++++++++++++++- pyHPSU.py | 75 +++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 71 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index e2a2c68..672f4b9 100755 --- a/README.md +++ b/README.md @@ -153,11 +153,18 @@ root@rotex:# systemctl start hpsud.service 4. MQTT Daemon mode pyHPSU starts in daemon mode, it subscribe an MQTT topic and listen forever waiting for commands. -MQTT coordinates are specified through configuration file: the same property used by mqtt output plugin plus an additional COMMANDTOPIC. +MQTT coordinates are specified through configuration file: the same property used by mqtt output plugin plus additional COMMANDTOPIC and STATUSTOPIC. The daemon subscribe to the topic PREFIX / COMMANDTOPIC / + +and publish to the topic + + PREFIX / STATUSTOPIC / + +publishing to COMMANDTOPIC with value '' or 'read' results in property red from hpsu and published to STATUSTOPIC +publishing to COMMANDTOPIC with another value results in pyHPSU trying to change that value on specified hpsu property + e.g. configuration file (e.g. /etc/pyHPSU/pyhpsu.conf) ... @@ -165,6 +172,7 @@ e.g. BROKER = 192.168.1.94 PREFIX = myhpsu COMMANDTOPIC = command + STATUSTOPIC = status ... root@rotex:# pyHPSU.py --mqttdaemon @@ -173,6 +181,17 @@ e.g. set the parameter t_flow_day to 29°C +e.g. + same config + + root@rotex:# pyHPSU.py --mqttdaemon + + user@anothersystem:# mosquitto_pub -h 192.168.1.94 -t "myhpsu/command/t_dhw" -m read + + publish the current value of t_dhw red from hpsu into this topic + + myhpsu/status/t_dhw + Now, you can query multiple values or run multiple pyHPSU.py processes. Simply set as driver HPSUD ("CANTCP") via commandline or the config file (PYHPSU section) i.e. root@rotex:# pyHPSU.py -d HPSUD -c t_dhw_setpoint1 diff --git a/pyHPSU.py b/pyHPSU.py index f774773..a3ef614 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -11,6 +11,7 @@ # CLIENTNAME = rotex_hpsu # PREFIX = rotex # COMMANDTOPIC = command +# STATUSTOPIC = status import serial import sys @@ -39,6 +40,11 @@ lg_code = None verbose = None output_type = None +mqtt_client = None +mqtt_prefix = None +mqttdaemon_command_topic = "command" +mqttdaemon_status_topic = "status" + def main(argv): global logger @@ -48,6 +54,10 @@ def main(argv): global lg_code global verbose global output_type + global mqtt_client + global mqtt_prefix + global mqttdaemon_command_topic + global mqttdaemon_status_topic cmd = [] port = None @@ -88,7 +98,6 @@ def main(argv): global options_list options_list={} mqttdaemon_option_present = False - mqttdaemon_command_topic = "command" # # get all plugins # @@ -240,39 +249,39 @@ def main(argv): # MQTT hostname or IP if config.has_option('MQTT', 'BROKER'): - brokerhost = config['MQTT']['BROKER'] + mqtt_brokerhost = config['MQTT']['BROKER'] else: - brokerhost = 'localhost' + mqtt_brokerhost = 'localhost' # MQTT broker port if config.has_option('MQTT', 'PORT'): - brokerport = int(config['MQTT']['PORT']) + mqtt_brokerport = int(config['MQTT']['PORT']) else: - brokerport = 1883 + mqtt_brokerport = 1883 # MQTT client name if config.has_option('MQTT', 'CLIENTNAME'): - clientname = config['MQTT']['CLIENTNAME'] + mqtt_clientname = config['MQTT']['CLIENTNAME'] else: - clientname = 'rotex' + mqtt_clientname = 'rotex' # MQTT Username if config.has_option('MQTT', 'USERNAME'): - username = config['MQTT']['USERNAME'] + mqtt_username = config['MQTT']['USERNAME'] else: - username = None + mqtt_username = None logger.error("Username not set!!!!!") #MQTT Password if config.has_option('MQTT', "PASSWORD"): - password = config['MQTT']['PASSWORD'] + mqtt_password = config['MQTT']['PASSWORD'] else: - password="None" + mqtt_password="None" #MQTT Prefix if config.has_option('MQTT', "PREFIX"): - prefix = config['MQTT']['PREFIX'] + mqtt_prefix = config['MQTT']['PREFIX'] else: - prefix = "" + mqtt_prefix = "" #MQTT MQTT Daemon command topic if config.has_option('MQTT', "COMMAND"): @@ -281,6 +290,13 @@ def main(argv): # else: # mqttdaemon_command_topic = "" + #MQTT MQTT Daemon status topic + if config.has_option('MQTT', "STATUS"): + mqttdaemon_status_topic = config['MQTT']['STATUS'] +# default already set +# else: +# mqttdaemon_status_topic = "" + #MQTT QOS if config.has_option('MQTT', "QOS"): qos = config['MQTT']['QOS'] @@ -357,20 +373,20 @@ def main(argv): # and handle the data as configured # if mqttdaemon_option_present: - logger.info("creating new mqtt client instance: " + clientname) - client=mqtt.Client(clientname) - if username: - client.username_pw_set(username, password=password) - client.enable_logger() + logger.info("creating new mqtt client instance: " + mqtt_clientname) + mqtt_client = mqtt.Client(mqtt_clientname) + if mqtt_username: + mqtt_client.username_pw_set(mqtt_username, password=mqtt_password) + mqtt_client.enable_logger() - client.on_message=on_mqtt_message + mqtt_client.on_message=on_mqtt_message logger.info("connecting to broker") - client.connect(brokerhost) + mqtt_client.connect(mqtt_brokerhost) logger.info("Subscribing to command topic") - client.subscribe(prefix + "/" + mqttdaemon_command_topic + "/+") + mqtt_client.subscribe(mqtt_prefix + "/" + mqttdaemon_command_topic + "/+") - client.loop_forever() + mqtt_client.loop_forever() elif auto and not backup_mode: while loop: ticker+=1 @@ -407,6 +423,10 @@ def main(argv): def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): global backup_file + global mqtt_prefix + global mqttdaemon_status_topic + global mqtt_client + # really needed? Driver is checked above #if not driver: # logger.critical("Error, please specify driver [ELM327 or PYCAN, EMU, HPSUD]") @@ -464,6 +484,9 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): print(error_message) logger.error(error_message) sys.exit(1) + elif output_type == "MQTT": + for r in arrResponse: + mqtt_client.publish(mqtt_prefix + "/" + mqttdaemon_status_topic + "/" + r["name"], r["resp"]) else: module_name=output_type.lower() module = importlib.import_module("HPSU.plugins." + module_name) @@ -478,17 +501,21 @@ def on_mqtt_message(client, userdata, message): global verbose global output_type 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) - hpsu_command_string = mqtt_command + ":" + 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=driver, logger=logger, port=port, cmd=hpsu_command_list, lg_code=lg_code) logger.info("send command to hpsu: hpsu_command_string") - read_can(driver, logger, port, hpsu_command_list, lg_code,verbose,output_type) + read_can(driver, logger, port, hpsu_command_list, lg_code,verbose,"MQTT") if __name__ == "__main__": main(sys.argv[1:]) From dc007a7c0bf2d77ca2b432fdc0a32a36059a3444 Mon Sep 17 00:00:00 2001 From: segaura Date: Sat, 13 Feb 2021 16:33:41 +0100 Subject: [PATCH 04/23] mqttdaemon little fixes and retained publish --- pyHPSU.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyHPSU.py b/pyHPSU.py index a3ef614..e9c2dec 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -484,9 +484,9 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): print(error_message) logger.error(error_message) sys.exit(1) - elif output_type == "MQTT": + elif output_type == "MQTTDAEMON": for r in arrResponse: - mqtt_client.publish(mqtt_prefix + "/" + mqttdaemon_status_topic + "/" + r["name"], r["resp"]) + mqtt_client.publish(mqtt_prefix + "/" + mqttdaemon_status_topic + "/" + r["name"], r["resp"], qos=0, retain=True) else: module_name=output_type.lower() module = importlib.import_module("HPSU.plugins." + module_name) @@ -514,8 +514,8 @@ def on_mqtt_message(client, userdata, message): hpsu_command_list = [hpsu_command_string] logger.info("setup HPSU to accept commands") n_hpsu = HPSU(driver=driver, logger=logger, port=port, cmd=hpsu_command_list, lg_code=lg_code) - logger.info("send command to hpsu: hpsu_command_string") - read_can(driver, logger, port, hpsu_command_list, lg_code,verbose,"MQTT") + logger.info("send command to hpsu: " + hpsu_command_string) + read_can(driver, logger, port, hpsu_command_list, lg_code,verbose,"MQTTDAEMON") if __name__ == "__main__": main(sys.argv[1:]) From 445861836d65ef6d5fa1c93b9729c7d683a2d3fc Mon Sep 17 00:00:00 2001 From: segaura Date: Mon, 15 Feb 2021 12:23:31 +0100 Subject: [PATCH 05/23] multiple output_type supported, mqttdaemon auto reread --- pyHPSU.py | 122 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 49 deletions(-) diff --git a/pyHPSU.py b/pyHPSU.py index e9c2dec..9cc619a 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -64,7 +64,8 @@ def main(argv): driver = "PYCAN" verbose = "1" show_help = False - output_type = "JSON" + # empty list, if none is specified with options and configuration, JSON default will be used + output_type = [] upload = False lg_code = "EN" languages = ["EN", "IT", "DE"] @@ -144,7 +145,7 @@ def main(argv): if opt in ("-b", "--backup"): backup_mode=True backup_file = arg - output_type = "BACKUP" + output_type.append("BACKUP") options_list["backup"]=arg if opt in ("-r", "--restore"): @@ -172,8 +173,12 @@ def main(argv): options_list["verbose"]="" elif opt in ("-o", "--output_type"): - output_type = arg.upper() - options_list["output_type"]=arg.upper() + if arg.upper() not in output_type: + output_type.append(arg.upper()) + if not "output_type" in options_list or options_list["output_type"] is None or options_list["output_type"]=="": + options_list["output_type"]=arg.upper() + else: + options_list["output_type"]+=", " + arg.upper() elif opt in ("-l", "--language"): lg_code = arg.upper() @@ -243,41 +248,35 @@ def main(argv): 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'] - # added for mqttd daemon + if len(output_type)==0 and config.has_option('PYHPSU','OUTPUT_TYPE'): + output_type.append(config['PYHPSU']['OUTPUT_TYPE']) - # MQTT hostname or IP if config.has_option('MQTT', 'BROKER'): mqtt_brokerhost = config['MQTT']['BROKER'] else: mqtt_brokerhost = 'localhost' - # MQTT broker port if config.has_option('MQTT', 'PORT'): mqtt_brokerport = int(config['MQTT']['PORT']) else: mqtt_brokerport = 1883 - # MQTT client name if config.has_option('MQTT', 'CLIENTNAME'): mqtt_clientname = config['MQTT']['CLIENTNAME'] else: mqtt_clientname = 'rotex' - # MQTT Username + if config.has_option('MQTT', 'USERNAME'): mqtt_username = config['MQTT']['USERNAME'] else: mqtt_username = None logger.error("Username not set!!!!!") - #MQTT Password if config.has_option('MQTT', "PASSWORD"): mqtt_password = config['MQTT']['PASSWORD'] else: mqtt_password="None" - #MQTT Prefix if config.has_option('MQTT', "PREFIX"): mqtt_prefix = config['MQTT']['PREFIX'] else: @@ -291,20 +290,29 @@ def main(argv): # mqttdaemon_command_topic = "" #MQTT MQTT Daemon status topic + # FIXME to be used for pyHPSU status, including MQTTDAEMON mode, not for actual parameter reading if config.has_option('MQTT', "STATUS"): mqttdaemon_status_topic = config['MQTT']['STATUS'] # default already set # else: # mqttdaemon_status_topic = "" - #MQTT QOS if config.has_option('MQTT', "QOS"): - qos = config['MQTT']['QOS'] + mqtt_qos = config['MQTT']['QOS'] + else: + mqtt_qos = "0" + + if config.has_option('MQTT', "RETAIN"): + mqtt_retain = config['MQTT']['RETAIN'] else: - qos = "0" + mqtt_retain = "False" logger.info("configuration parsing complete") + # default output_type if not specified + if len(output_type)==0: + output_type.append("JSON") + # # now we should have all options...let's check them # @@ -318,9 +326,10 @@ def main(argv): sys.exit(9) # Check output type - if output_type not in PLUGIN_LIST: - logger.critical("please specify a correct output_type [" + PLUGIN_STRING + "]") - sys.exit(9) + for plugin in output_type: + if plugin not in PLUGIN_LIST: + logger.critical("please specify a correct output_type [" + PLUGIN_STRING + "], " + plugin + " does not exist") + sys.exit(9) # Check Language if lg_code not in languages: @@ -380,11 +389,12 @@ def main(argv): mqtt_client.enable_logger() mqtt_client.on_message=on_mqtt_message - logger.info("connecting to broker") + logger.info("connecting to broker: " + mqtt_brokerhost) mqtt_client.connect(mqtt_brokerhost) - logger.info("Subscribing to command topic") - mqtt_client.subscribe(mqtt_prefix + "/" + mqttdaemon_command_topic + "/+") + command_topic = mqtt_prefix + "/" + mqttdaemon_command_topic + "/+" + logger.info("Subscribing to command topic: " + command_topic) + mqtt_client.subscribe(command_topic) mqtt_client.loop_forever() elif auto and not backup_mode: @@ -465,33 +475,38 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): if i == 4: logger.error('command %s failed' % (c["name"])) - if output_type == "JSON": - if len(arrResponse)!=0: - print(arrResponse) - elif output_type == "CSV": - for r in arrResponse: - print("%s,%s,%s" % (r["timestamp"], r["name"], r["resp"])) - elif output_type == "BACKUP": - error_message = "Writing Backup to " + str(backup_file) - print(error_message) - logger.info(error_message) - - try: - with open(backup_file, 'w') as outfile: - json.dump(arrResponse, outfile, sort_keys = True, indent = 4, ensure_ascii = False) - except FileNotFoundError: - error_message = "No such file or directory!!!" + for output_type_name in output_type: + if output_type_name == "JSON": + if len(arrResponse)!=0: + print(arrResponse) + elif output_type_name == "CSV": + for r in arrResponse: + print("%s,%s,%s" % (r["timestamp"], r["name"], r["resp"])) + elif output_type_name == "BACKUP": + error_message = "Writing Backup to " + str(backup_file) print(error_message) - logger.error(error_message) - sys.exit(1) - elif output_type == "MQTTDAEMON": - for r in arrResponse: - mqtt_client.publish(mqtt_prefix + "/" + mqttdaemon_status_topic + "/" + r["name"], r["resp"], qos=0, retain=True) - else: - module_name=output_type.lower() - module = importlib.import_module("HPSU.plugins." + module_name) - hpsu_plugin = module.export(hpsu=n_hpsu, logger=logger, config_file=conf_file) - hpsu_plugin.pushValues(vars=arrResponse) + logger.info(error_message) + + try: + with open(backup_file, 'w') as outfile: + json.dump(arrResponse, outfile, sort_keys = True, indent = 4, ensure_ascii = False) + except FileNotFoundError: + error_message = "No such file or directory!!!" + print(error_message) + logger.error(error_message) + sys.exit(1) + elif output_type_name == "MQTTDAEMON": + for r in arrResponse: + # retain=False to conform to usual mqtt plugin output + mqtt_client.publish(mqtt_prefix + "/" + r["name"], r["resp"], qos=0, retain=False) + # variant with timestamp and on "status" topic, not conforming with usual mqtt plugin output + #mqtt_client.publish(mqtt_prefix + "/" + mqttdaemon_status_topic + "/" + r["name"], "{'name': '%s', 'resp': '%s', 'timestamp': %s}" % (r["name"], r["resp"], r["timestamp"]), qos=0, retain=True) + + else: + module_name=output_type_name.lower() + module = importlib.import_module("HPSU.plugins." + module_name) + hpsu_plugin = module.export(hpsu=n_hpsu, logger=logger, config_file=conf_file) + hpsu_plugin.pushValues(vars=arrResponse) def on_mqtt_message(client, userdata, message): global logger @@ -515,7 +530,16 @@ def on_mqtt_message(client, userdata, message): logger.info("setup HPSU to accept commands") n_hpsu = HPSU(driver=driver, logger=logger, port=port, cmd=hpsu_command_list, lg_code=lg_code) logger.info("send command to hpsu: " + hpsu_command_string) - read_can(driver, logger, port, hpsu_command_list, lg_code,verbose,"MQTTDAEMON") + #exec('thread_mqttdaemon = threading.Thread(target=read_can(driver, logger, port, hpsu_command_list, lg_code,verbose,["MQTTDAEMON"]))') + #exec('thread_mqttdaemon.start()') + read_can(driver, logger, port, hpsu_command_list, lg_code,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(driver, logger, port, hpsu_command_string_reread_after_write_list, lg_code,verbose,["MQTTDAEMON"]))') + #exec('thread_mqttdaemon_reread.start()') + read_can(driver, logger, port, hpsu_command_string_reread_after_write_list, lg_code,verbose,["MQTTDAEMON"]) if __name__ == "__main__": main(sys.argv[1:]) From 85289397c6238a9d8d9f1e0b71731efa4f3c2cab Mon Sep 17 00:00:00 2001 From: segaura Date: Mon, 15 Feb 2021 16:04:07 +0100 Subject: [PATCH 06/23] mqttdaemon non-blocking loop, ondisconnect --- pyHPSU.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pyHPSU.py b/pyHPSU.py index 9cc619a..be02dd7 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -396,8 +396,11 @@ def main(argv): logger.info("Subscribing to command topic: " + command_topic) mqtt_client.subscribe(command_topic) - mqtt_client.loop_forever() - elif auto and not backup_mode: + # this blocks execution + #mqtt_client.loop_forever() + mqtt_client.loop_start() + + if auto and not backup_mode: while loop: ticker+=1 collected_cmds=[] @@ -508,6 +511,10 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): hpsu_plugin = module.export(hpsu=n_hpsu, logger=logger, config_file=conf_file) hpsu_plugin.pushValues(vars=arrResponse) +def on_disconnect(client, userdata,rc=0): + logger.debug("mqtt disConnected: result code " + str(rc)) + client.loop_stop() + def on_mqtt_message(client, userdata, message): global logger global driver From 1d4e6c6552cb4210b28746ae58be134180f6bac0 Mon Sep 17 00:00:00 2001 From: segaura Date: Mon, 15 Feb 2021 16:05:04 +0100 Subject: [PATCH 07/23] simplified if auto and not backup_mode condition --- pyHPSU.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyHPSU.py b/pyHPSU.py index be02dd7..9b2efc9 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -399,8 +399,11 @@ def main(argv): # this blocks execution #mqtt_client.loop_forever() mqtt_client.loop_start() - - if auto and not backup_mode: + + if 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 auto: while loop: ticker+=1 collected_cmds=[] @@ -414,9 +417,6 @@ def main(argv): 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: From 43ee5c80592f01b2a593631a8403561e38a57b40 Mon Sep 17 00:00:00 2001 From: segaura Date: Mon, 15 Feb 2021 16:16:36 +0100 Subject: [PATCH 08/23] mqtt loop, -a and --mqtt_daemon can live together --- pyHPSU.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyHPSU.py b/pyHPSU.py index 9b2efc9..0c482f2 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -547,6 +547,8 @@ def on_mqtt_message(client, userdata, message): #exec('thread_mqttdaemon_reread = threading.Thread(target=read_can(driver, logger, port, hpsu_command_string_reread_after_write_list, lg_code,verbose,["MQTTDAEMON"]))') #exec('thread_mqttdaemon_reread.start()') read_can(driver, logger, port, hpsu_command_string_reread_after_write_list, lg_code,verbose,["MQTTDAEMON"]) - + # restarts the loop + mqtt_client.loop_start() + if __name__ == "__main__": main(sys.argv[1:]) From d70a0eeceb17b112967a6813718db6d3c8cebedb Mon Sep 17 00:00:00 2001 From: segaura Date: Mon, 15 Feb 2021 16:59:58 +0100 Subject: [PATCH 09/23] mqttdaemon: added qos, retain, addtimestamp config --- pyHPSU.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/pyHPSU.py b/pyHPSU.py index 0c482f2..88d7c91 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -11,7 +11,9 @@ # CLIENTNAME = rotex_hpsu # PREFIX = rotex # COMMANDTOPIC = command -# STATUSTOPIC = status +# STATUSTOPIC = status ...for future use +# QOS = 0 +# ADDTIMESTAMP = False ...whether or not to add timestamp to published values import serial import sys @@ -42,6 +44,9 @@ output_type = None mqtt_client = None mqtt_prefix = None +mqtt_qos = 0 +mqtt_retain = False +mqtt_addtimestamp = False mqttdaemon_command_topic = "command" mqttdaemon_status_topic = "status" @@ -56,6 +61,9 @@ def main(argv): global output_type global mqtt_client global mqtt_prefix + global mqtt_qos + global mqtt_retain + global mqtt_addtimestamp global mqttdaemon_command_topic global mqttdaemon_status_topic @@ -298,14 +306,21 @@ def main(argv): # mqttdaemon_status_topic = "" if config.has_option('MQTT', "QOS"): - mqtt_qos = config['MQTT']['QOS'] + mqtt_qos = int(config['MQTT']['QOS']) else: - mqtt_qos = "0" + mqtt_qos = 0 if config.has_option('MQTT', "RETAIN"): - mqtt_retain = config['MQTT']['RETAIN'] + # every other value implies false + mqtt_retain = config['MQTT']['RETAIN'] == "True" else: - mqtt_retain = "False" + mqtt_retain = False + + if config.has_option('MQTT', "ADDTIMESTAMP"): + # every other value implies false + mqtt_addtimestamp = config['MQTT']['ADDTIMESTAMP'] == "True" + else: + mqtt_addtimestamp = False logger.info("configuration parsing complete") @@ -500,10 +515,12 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): sys.exit(1) elif output_type_name == "MQTTDAEMON": for r in arrResponse: - # retain=False to conform to usual mqtt plugin output - mqtt_client.publish(mqtt_prefix + "/" + r["name"], r["resp"], qos=0, retain=False) - # variant with timestamp and on "status" topic, not conforming with usual mqtt plugin output - #mqtt_client.publish(mqtt_prefix + "/" + mqttdaemon_status_topic + "/" + r["name"], "{'name': '%s', 'resp': '%s', 'timestamp': %s}" % (r["name"], r["resp"], r["timestamp"]), qos=0, retain=True) + if mqtt_addtimestamp: + # use the same format as JSON output + # with timestamp included, retain=true become more interesting + mqtt_client.publish(mqtt_prefix + "/" + r["name"], "{'name': '%s', 'resp': '%s', 'timestamp': %s}" % (r["name"], r["resp"], r["timestamp"]), qos=mqtt_qos, retain=mqtt_retain) + else: + mqtt_client.publish(mqtt_prefix + "/" + r["name"], r["resp"], qos=mqtt_qos, retain=mqtt_retain) else: module_name=output_type_name.lower() @@ -546,6 +563,7 @@ def on_mqtt_message(client, userdata, message): hpsu_command_string_reread_after_write_list = [hpsu_command_string_reread_after_write] #exec('thread_mqttdaemon_reread = threading.Thread(target=read_can(driver, logger, port, hpsu_command_string_reread_after_write_list, lg_code,verbose,["MQTTDAEMON"]))') #exec('thread_mqttdaemon_reread.start()') + logger.info("send same command in read mode to hpsu: " + hpsu_command_string) read_can(driver, logger, port, hpsu_command_string_reread_after_write_list, lg_code,verbose,["MQTTDAEMON"]) # restarts the loop mqtt_client.loop_start() From 788969e2257d22f28707206832ca74e8c1d66e4e Mon Sep 17 00:00:00 2001 From: segaura Date: Wed, 17 Feb 2021 11:30:17 +0100 Subject: [PATCH 10/23] fix: mqttdaemon disconnected by output plugin, more debug --- HPSU/canpi.py | 6 +++--- HPSU/plugins/mqtt.py | 9 +++------ pyHPSU.py | 3 ++- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/HPSU/canpi.py b/HPSU/canpi.py index 394caa5..d3730b1 100644 --- a/HPSU/canpi.py +++ b/HPSU/canpi.py @@ -107,10 +107,10 @@ def sendCommandWithID(self, cmd, setValue=None, priority=1): if (msg_data[2] == 0xfa and msg_data[3] == rcBUS.data[3] and msg_data[4] == rcBUS.data[4]) or (msg_data[2] != 0xfa and msg_data[2] == rcBUS.data[2]): rc = "%02X %02X %02X %02X %02X %02X %02X" % (rcBUS.data[0], rcBUS.data[1], rcBUS.data[2], rcBUS.data[3], rcBUS.data[4], rcBUS.data[5], rcBUS.data[6]) notTimeout = False - #print("got: " + str(rc)) + self.hpsu.logger.debug("CanPI, got: " + str(rc)) else: - self.hpsu.logger.error('SEND:%s' % (str(msg_data))) - self.hpsu.logger.error('RECV:%s' % (str(rcBUS.data))) + self.hpsu.logger.error('CanPI, SEND:%s' % (str(msg_data))) + self.hpsu.logger.error('CanPI, RECV:%s' % (str(rcBUS.data))) else: self.hpsu.logger.error('Not aquired bus') diff --git a/HPSU/plugins/mqtt.py b/HPSU/plugins/mqtt.py index 86bf37c..22312f3 100644 --- a/HPSU/plugins/mqtt.py +++ b/HPSU/plugins/mqtt.py @@ -76,17 +76,14 @@ def __init__(self, hpsu=None, logger=None, config_file=None): self.qos = "0" self.client=mqtt.Client(self.clientname) - #self.client.on_publish = self.on_publish() + self.client.on_publish = self.on_publish if self.username: self.client.username_pw_set(self.username, password=self.password) self.client.enable_logger() - - #def on_publish(self,client,userdata,mid): - # self.hpsu.logger.debug("data published, mid: " + str(mid) + "\n") - # pass - + def on_publish(self,client,userdata,mid): + self.hpsu.logger.debug("mqtt output plugin data published, mid: " + str(mid)) def pushValues(self, vars=None): diff --git a/pyHPSU.py b/pyHPSU.py index 88d7c91..cebcdd8 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -398,7 +398,8 @@ def main(argv): # if mqttdaemon_option_present: logger.info("creating new mqtt client instance: " + mqtt_clientname) - mqtt_client = mqtt.Client(mqtt_clientname) + # a different client name because otherwise mqtt output plugin closes this connection, too + mqtt_client = mqtt.Client(mqtt_clientname+"-mqttdaemon") if mqtt_username: mqtt_client.username_pw_set(mqtt_username, password=mqtt_password) mqtt_client.enable_logger() From 7c5c41e77d34bccc5de467fbead447d82727e5cf Mon Sep 17 00:00:00 2001 From: segaura Date: Wed, 17 Feb 2021 18:23:33 +0100 Subject: [PATCH 11/23] README.md mqttdaemon mode section updated --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 672f4b9..73831c9 100755 --- a/README.md +++ b/README.md @@ -160,10 +160,10 @@ The daemon subscribe to the topic and publish to the topic - PREFIX / STATUSTOPIC / + PREFIX / -publishing to COMMANDTOPIC with value '' or 'read' results in property red from hpsu and published to STATUSTOPIC -publishing to COMMANDTOPIC with another value results in pyHPSU trying to change that value on specified hpsu property +publishing to COMMANDTOPIC with value '' or 'read' results in property red from hpsu and published to mqtt (same topics used by mqtt output plugin) +publishing to COMMANDTOPIC with another value results in pyHPSU trying to change that value on specified hpsu property and than re-reading the same property and publishing the obtained value e.g. configuration file (e.g. /etc/pyHPSU/pyhpsu.conf) @@ -172,23 +172,24 @@ e.g. BROKER = 192.168.1.94 PREFIX = myhpsu COMMANDTOPIC = command - STATUSTOPIC = status ... root@rotex:# pyHPSU.py --mqttdaemon - user@anothersystem:# mosquitto_pub -h 192.168.1.94 -t "myhpsu/command/t_flow_day" -m 29 + user@anothersystem:# mosquitto_pub -h 192.168.1.94 -t "myhpsu/command/t_dhw" -m read - set the parameter t_flow_day to 29°C + publish the current value of t_dhw red from hpsu into the following topic + + myhpsu/status/t_dhw e.g. - same config + (with same config) - root@rotex:# pyHPSU.py --mqttdaemon + root@rotex:# pyHPSU.py --mqttdaemon -a -o mqtt - user@anothersystem:# mosquitto_pub -h 192.168.1.94 -t "myhpsu/command/t_dhw" -m read + user@anothersystem:# mosquitto_pub -h 192.168.1.94 -t "myhpsu/command/t_flow_day" -m 29 - publish the current value of t_dhw red from hpsu into this topic + set the parameter t_flow_day to 29°C, meanwhile pyHPSU is running in automatic mode and publishing periodically to the appopriate mqtt topics myhpsu/status/t_dhw From 3aa651d5e13a5e0422ee87bc167303ba3658d9d7 Mon Sep 17 00:00:00 2001 From: segaura Date: Wed, 17 Feb 2021 23:16:10 +0100 Subject: [PATCH 12/23] t_room command fixed, global exception mgmt, more canpi debug --- HPSU/canpi.py | 9 +++++---- etc/pyHPSU/commands_hpsu.json | 2 +- pyHPSU.py | 23 +++++++++++++++++------ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/HPSU/canpi.py b/HPSU/canpi.py index d3730b1..d961d9b 100644 --- a/HPSU/canpi.py +++ b/HPSU/canpi.py @@ -86,6 +86,7 @@ def sendCommandWithID(self, cmd, setValue=None, priority=1): try: msg = can.Message(arbitration_id=receiver_id, data=msg_data, extended_id=False, dlc=7) self.bus.send(msg) + self.hpsu.logger.debug("CanPI, %s sent: %s" % (cmd['name'], msg)) except Exception: self.hpsu.logger.exception('Error sending msg') @@ -107,12 +108,12 @@ def sendCommandWithID(self, cmd, setValue=None, priority=1): if (msg_data[2] == 0xfa and msg_data[3] == rcBUS.data[3] and msg_data[4] == rcBUS.data[4]) or (msg_data[2] != 0xfa and msg_data[2] == rcBUS.data[2]): rc = "%02X %02X %02X %02X %02X %02X %02X" % (rcBUS.data[0], rcBUS.data[1], rcBUS.data[2], rcBUS.data[3], rcBUS.data[4], rcBUS.data[5], rcBUS.data[6]) notTimeout = False - self.hpsu.logger.debug("CanPI, got: " + str(rc)) + self.hpsu.logger.debug("CanPI, %s got: %s" % (cmd['name'], str(rc))) else: - self.hpsu.logger.error('CanPI, SEND:%s' % (str(msg_data))) - self.hpsu.logger.error('CanPI, RECV:%s' % (str(rcBUS.data))) + self.hpsu.logger.warning('CanPI, %s SEND: %s' % (cmd.name, str(msg_data))) + self.hpsu.logger.warning('CanPI, %s RECV: %s' % (cmd.name, str(rcBUS.data))) else: - self.hpsu.logger.error('Not aquired bus') + self.hpsu.logger.warning('Not aquired bus') if notTimeout: self.hpsu.logger.warning('msg not sync, retry: %s' % i) diff --git a/etc/pyHPSU/commands_hpsu.json b/etc/pyHPSU/commands_hpsu.json index 148fa18..2972ca7 100755 --- a/etc/pyHPSU/commands_hpsu.json +++ b/etc/pyHPSU/commands_hpsu.json @@ -1452,7 +1452,7 @@ }, "t_room" :{ "name" : "t_room", - "command" : "81 00 FA 00 11 00 00", + "command" : "31 00 FA 00 11 00 00", "id" : "190", "divisor" : "10", "writable" : "false", diff --git a/pyHPSU.py b/pyHPSU.py index cebcdd8..5b1da5b 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -50,6 +50,11 @@ mqttdaemon_command_topic = "command" mqttdaemon_status_topic = "status" +def my_except_hook(exctype, value, traceback): + if exctype == KeyboardInterrupt: + print("Interrupted by user") + else: + sys.__excepthook__(exctype, value, traceback) def main(argv): global logger @@ -67,6 +72,7 @@ def main(argv): global mqttdaemon_command_topic global mqttdaemon_status_topic + sys.excepthook = my_except_hook cmd = [] port = None driver = "PYCAN" @@ -200,15 +206,16 @@ def main(argv): options_list["log_file"]=arg elif opt in ("--log_level"): - if arg == 'DEBUG': + level = arg.upper() + if level == 'DEBUG': desired_log_level = logging.DEBUG - elif arg == 'INFO': + elif level == 'INFO': desired_log_level = logging.INFO - elif arg == 'WARNING': + elif level == 'WARNING': desired_log_level = logging.WARNING - elif arg == 'ERROR': + elif level == 'ERROR': desired_log_level = logging.ERROR - elif arg == 'CRITICAL': + elif level == 'CRITICAL': desired_log_level = logging.CRITICAL else: print("Error, " + arg + " is not a valid value for log_level option, use [" + LOG_LEVEL_STRING + "]") @@ -570,4 +577,8 @@ def on_mqtt_message(client, userdata, message): mqtt_client.loop_start() if __name__ == "__main__": - main(sys.argv[1:]) + try: + main(sys.argv[1:]) + except Exception as e: + print("Exception: {}".format(type(e).__name__)) + print("Exception message: {}".format(e)) \ No newline at end of file From 2951947c45d728f95fceb1d3b1f8f29f469d6a68 Mon Sep 17 00:00:00 2001 From: segaura Date: Wed, 17 Feb 2021 23:50:15 +0100 Subject: [PATCH 13/23] better debug and global exception mgmt --- HPSU/HPSU.py | 4 ++-- HPSU/canpi.py | 12 ++++++------ pyHPSU.py | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/HPSU/HPSU.py b/HPSU/HPSU.py index a8356e2..ab2060c 100644 --- a/HPSU/HPSU.py +++ b/HPSU/HPSU.py @@ -49,7 +49,7 @@ def __init__(self, logger=None, driver=None, port=None, cmd=None, lg_code=None): command_translations_hpsu = '%s/commands_hpsu_%s.csv' % (self.pathCOMMANDS, LANG_CODE) if not os.path.isfile(command_translations_hpsu): command_translations_hpsu = '%s/commands_hpsu_%s.csv' % (self.pathCOMMANDS, "EN") - self.logger.info("loading command traslations file: "+command_translations_hpsu) + self.logger.info("HPSU %s, loading command traslations file: %s" % (cmd, command_translations_hpsu)) # check, if commands are json or csv # read all known commands with open(command_translations_hpsu, 'rU',encoding='utf-8') as csvfile: @@ -63,7 +63,7 @@ def __init__(self, logger=None, driver=None, port=None, cmd=None, lg_code=None): # read all known commands command_details_hpsu = '%s/commands_hpsu.json' % self.pathCOMMANDS - self.logger.info("loading command details file: "+command_details_hpsu) + self.logger.info("HPSU %s loading command details file: %s" % (cmd, command_details_hpsu)) with open(command_details_hpsu, 'rU',encoding='utf-8') as jsonfile: self.all_commands = json.load(jsonfile) self.command_dict=self.all_commands["commands"] diff --git a/HPSU/canpi.py b/HPSU/canpi.py index d961d9b..4d8be00 100644 --- a/HPSU/canpi.py +++ b/HPSU/canpi.py @@ -108,17 +108,17 @@ def sendCommandWithID(self, cmd, setValue=None, priority=1): if (msg_data[2] == 0xfa and msg_data[3] == rcBUS.data[3] and msg_data[4] == rcBUS.data[4]) or (msg_data[2] != 0xfa and msg_data[2] == rcBUS.data[2]): rc = "%02X %02X %02X %02X %02X %02X %02X" % (rcBUS.data[0], rcBUS.data[1], rcBUS.data[2], rcBUS.data[3], rcBUS.data[4], rcBUS.data[5], rcBUS.data[6]) notTimeout = False - self.hpsu.logger.debug("CanPI, %s got: %s" % (cmd['name'], str(rc))) + self.hpsu.logger.debug("CanPI %s, got: %s" % (cmd['name'], str(rc))) else: - self.hpsu.logger.warning('CanPI, %s SEND: %s' % (cmd.name, str(msg_data))) - self.hpsu.logger.warning('CanPI, %s RECV: %s' % (cmd.name, str(rcBUS.data))) + self.hpsu.logger.warning('CanPI %s, SEND: %s' % (cmd['name'], str(msg_data))) + self.hpsu.logger.warning('CanPI %s, RECV: %s' % (cmd['name'], str(rcBUS.data))) else: - self.hpsu.logger.warning('Not aquired bus') + self.hpsu.logger.warning('CanPI %s, Not aquired bus' % cmd['name']) if notTimeout: - self.hpsu.logger.warning('msg not sync, retry: %s' % i) + self.hpsu.logger.warning('CanPI %s, msg not sync, retry: %s' % (cmd['name'], i)) if i >= self.retry: - self.hpsu.logger.error('msg not sync, timeout') + self.hpsu.logger.error('CanPI %s, msg not sync, timeout' % cmd['name']) notTimeout = False rc = "KO" diff --git a/pyHPSU.py b/pyHPSU.py index 5b1da5b..db081d5 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -17,6 +17,7 @@ import serial import sys +import traceback #sys.path.append('/usr/share/pyHPSU/HPSU') #sys.path.append('/usr/share/pyHPSU/plugins') import os @@ -580,5 +581,6 @@ def on_mqtt_message(client, userdata, message): try: main(sys.argv[1:]) except Exception as e: - print("Exception: {}".format(type(e).__name__)) - print("Exception message: {}".format(e)) \ No newline at end of file + traceback.print_exc() + #print("Exception: {}".format(type(e).__name__)) + #print("Exception message: {}".format(e)) \ No newline at end of file From 4acbd3230d83bdefb3e78d16b561066e25e6d609 Mon Sep 17 00:00:00 2001 From: segaura Date: Thu, 18 Feb 2021 23:15:16 +0100 Subject: [PATCH 14/23] trying to solve mqttdaemon issues --- pyHPSU.py | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/pyHPSU.py b/pyHPSU.py index db081d5..0f752d4 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -95,7 +95,7 @@ def main(argv): ticker=0 loop=True auto=False - LOG_LEVEL_STRING = 'DEBUG, INFO, WARNING, ERROR, CRITICAL' + LOG_LEVEL_LIST = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] # default to loggin.error if --log_level option not present desired_log_level = logging.ERROR # default log to stdout if no file specified @@ -135,7 +135,7 @@ def main(argv): 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(' -o --output_type output type: [' + ", ".join(PLUGIN_LIST) + '] 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)) @@ -143,7 +143,7 @@ def main(argv): print(' -r --restore restore HPSU settings from file [filename]') print(' --mqtt_daemon set up an mqtt daemon that subscribe to a command topic and executes received command on HPSU') print(' -g --log set the log to file [filename]') - print(' --log_level set the log level to [' + LOG_LEVEL_STRING + ']') + print(' --log_level set the log level to [' + ", ".join(LOG_LEVEL_LIST) + ']') print(' -h --help show help') sys.exit(2) @@ -207,19 +207,9 @@ def main(argv): options_list["log_file"]=arg elif opt in ("--log_level"): - level = arg.upper() - if level == 'DEBUG': - desired_log_level = logging.DEBUG - elif level == 'INFO': - desired_log_level = logging.INFO - elif level == 'WARNING': - desired_log_level = logging.WARNING - elif level == 'ERROR': - desired_log_level = logging.ERROR - elif level == 'CRITICAL': - desired_log_level = logging.CRITICAL - else: - print("Error, " + arg + " is not a valid value for log_level option, use [" + LOG_LEVEL_STRING + "]") + desired_log_level = arg.upper() + if not desired_log_level in LOG_LEVEL_LIST: + print("Error, " + arg + " is not a valid value for log_level option, use [" + ", ".join(LOG_LEVEL_LIST)+ "]") sys.exit(2) options_list["cmd"]=cmd @@ -422,7 +412,8 @@ def main(argv): # this blocks execution #mqtt_client.loop_forever() - mqtt_client.loop_start() + if auto: + mqtt_client.loop_start() if backup_mode: n_hpsu = HPSU(driver=driver, logger=logger, port=port, cmd=cmd, lg_code=lg_code) @@ -454,10 +445,14 @@ def main(argv): logger.error("No such file or directory!!!") sys.exit(1) - else: + # 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 mqttdaemon_option_present): 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) + # if we reach this point (the end), we are not in auto mode so the loop is not started + mqtt_client.loop_forever() + def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): global backup_file global mqtt_prefix @@ -575,12 +570,14 @@ def on_mqtt_message(client, userdata, message): logger.info("send same command in read mode to hpsu: " + hpsu_command_string) read_can(driver, logger, port, hpsu_command_string_reread_after_write_list, lg_code,verbose,["MQTTDAEMON"]) # restarts the loop - mqtt_client.loop_start() + if auto: + mqtt_client.loop_start() if __name__ == "__main__": try: main(sys.argv[1:]) except Exception as e: + # print complete information traceback.print_exc() #print("Exception: {}".format(type(e).__name__)) #print("Exception message: {}".format(e)) \ No newline at end of file From 46eb79a05e2ed8f6b2d1f82126954292acc3c033 Mon Sep 17 00:00:00 2001 From: segaura Date: Tue, 23 Feb 2021 12:26:39 +0100 Subject: [PATCH 15/23] gitignore: another vscode folder --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8bd5644..1e0c1aa 100755 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ install_pyHPSU install .vscode/settings.json -.vscode/launch.json \ No newline at end of file +.vscode/launch.json +.vscode/.ropeproject/** From 964f3c563c7ec55cfbbf0b14988a5415323689c3 Mon Sep 17 00:00:00 2001 From: segaura Date: Thu, 25 Feb 2021 09:03:18 +0100 Subject: [PATCH 16/23] README.md formatting --- README.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 73831c9..c56013c 100755 --- a/README.md +++ b/README.md @@ -155,16 +155,12 @@ root@rotex:# systemctl start hpsud.service pyHPSU starts in daemon mode, it subscribe an MQTT topic and listen forever waiting for commands. MQTT coordinates are specified through configuration file: the same property used by mqtt output plugin plus additional COMMANDTOPIC and STATUSTOPIC. The daemon subscribe to the topic - - PREFIX / COMMANDTOPIC / + - +` PREFIX / COMMANDTOPIC / +` and publish to the topic - - PREFIX / - +` PREFIX / ` publishing to COMMANDTOPIC with value '' or 'read' results in property red from hpsu and published to mqtt (same topics used by mqtt output plugin) publishing to COMMANDTOPIC with another value results in pyHPSU trying to change that value on specified hpsu property and than re-reading the same property and publishing the obtained value - +``` e.g. configuration file (e.g. /etc/pyHPSU/pyhpsu.conf) ... @@ -192,7 +188,7 @@ e.g. set the parameter t_flow_day to 29°C, meanwhile pyHPSU is running in automatic mode and publishing periodically to the appopriate mqtt topics myhpsu/status/t_dhw - +``` Now, you can query multiple values or run multiple pyHPSU.py processes. Simply set as driver HPSUD ("CANTCP") via commandline or the config file (PYHPSU section) i.e. root@rotex:# pyHPSU.py -d HPSUD -c t_dhw_setpoint1 From edde2e8844e7eaab34d5c3579b2f67a16cb8dcbd Mon Sep 17 00:00:00 2001 From: segaura Date: Sat, 27 Feb 2021 00:09:39 +0100 Subject: [PATCH 17/23] mqttdaemon loop fix, mysql plugin (( fix, commands.json 4 untested new commands from fhem forum --- .gitattributes | 1 + HPSU/canpi.py | 1 + HPSU/plugins/mysql.py | 2 +- etc/pyHPSU/commands_hpsu.json | 2970 +++++++++++++++++---------------- pyHPSU.py | 3 +- 5 files changed, 1512 insertions(+), 1465 deletions(-) create mode 100644 .gitattributes mode change 100755 => 100644 etc/pyHPSU/commands_hpsu.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6b43d8e --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +text=auto diff --git a/HPSU/canpi.py b/HPSU/canpi.py index 4d8be00..1535b86 100644 --- a/HPSU/canpi.py +++ b/HPSU/canpi.py @@ -19,6 +19,7 @@ class CanPI(object): def __init__(self, hpsu=None): self.hpsu = hpsu try: + # TODO evaluate can.ThreadSafeBus self.bus = can.interface.Bus(channel='can0', bustype='socketcan_native') except Exception: self.hpsu.logger.exception('Error opening bus can0') diff --git a/HPSU/plugins/mysql.py b/HPSU/plugins/mysql.py index 3ce5e39..0e58a05 100644 --- a/HPSU/plugins/mysql.py +++ b/HPSU/plugins/mysql.py @@ -55,7 +55,7 @@ def __init__(self, hpsu=None, logger=None, config_file=None, config=None): if db_config.has_option('MYSQL','DB_USER'): db_user=db_config['MYSQL']['DB_USER'] else: - self.hpsu.logger.error(("No database user defined in config file.") + self.hpsu.logger.error("No database user defined in config file.") sys.exit(9) if db_config.has_option('MYSQL','DB_PASSWORD'): diff --git a/etc/pyHPSU/commands_hpsu.json b/etc/pyHPSU/commands_hpsu.json old mode 100755 new mode 100644 index 2972ca7..6a99e59 --- a/etc/pyHPSU/commands_hpsu.json +++ b/etc/pyHPSU/commands_hpsu.json @@ -1,1463 +1,1507 @@ -{ - "version" : "2.0", - "commands":{ - "t_hs" : { - "name" : "t_hs", - "command" : "31 00 FA 01 D6 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_hs_set" : { - "name" : "t_hs_set", - "command" : "31 00 02 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "water_pressure" : { - "name" : "water_pressure", - "command" : "31 00 1C 00 00 00 00", - "id" : "190", - "divisor" : "1000", - "writable" : "false", - "unit" : "bar", - "type" : "float" - }, - "t_ext" : { - "name" : "t_ext", - "command" : "61 00 FA 0A 0C 00 00", - "id" : "310", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_dhw" : { - "name" : "t_dhw", - "command" : "31 00 0E 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_dhw_set" : { - "name" : "t_dhw_set", - "command" : "31 00 03 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_return" : { - "name" : "t_return", - "command" : "31 00 16 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "flow_rate" : { - "name" : "flow_rate", - "command" : "31 00 FA 01 DA 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "lh", - "type" : "longint" - }, - "t_hc" : { - "name" : "t_hc", - "command" : "C1 00 0F 00 00 00 00", - "id" : "610", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_hc_set" : { - "name" : "t_hc_set", - "command" : "61 00 04 00 00 00 00", - "id" : "310", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "status_pump" : { - "name" : "status_pump", - "command" : "31 00 FA 0A 8C 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "runtime_comp" : { - "name" : "runtime_comp", - "command" : "31 00 FA 06 A5 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "hour", - "type" : "longint" - }, - "runtime_pump" : { - "name" : "runtime_pump", - "command" : "31 00 FA 06 A4 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "longint" - }, - "posmix" : { - "name" : "posmix", - "command" : "31 00 FA 06 9B 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "percent", - "type" : "longint" - }, - "qboh" : { - "name" : "qboh", - "command" : "31 00 FA 09 1C 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "qchhp" : { - "name" : "qchhp", - "command" : "31 00 FA 09 20 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "qsc" : { - "name" : "qsc", - "command" : "31 00 FA 06 A6 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "qch" : { - "name" : "qch", - "command" : "31 00 FA 06 A7 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "longint" - }, - "qwp" : { - "name" : "qwp", - "command" : "31 00 FA 09 30 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "qdhw" : { - "name" : "qdhw", - "command" : "31 00 FA 09 2C 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "sw_vers_01" : { - "name" : "sw_vers_01", - "command" : "31 00 FA 01 99 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "longint" - }, - "sw_vers_02" : { - "name" : "sw_vers_02", - "command" : "31 00 FA C0 B4 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "longint" - }, - "sw_vers_03" : { - "name" : "sw_vers_03", - "command" : "31 00 FA 02 4B 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "longint" - }, - "mode_01" : { - "name" : "mode_01", - "command" : "31 00 FA 01 12 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "", - "type" : "int", - "value_code" : { - "1" : "standby", - "3" : "heat", - "4" : "sink", - "5" : "summer", - "17" : "cool", - "11" : "auto 1", - "12" : "auto 2" - } - }, - "tvbh2" : { - "name" : "tvbh2", - "command" : "31 00 FA C1 02", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "tliq2" : { - "name" : "tliq2", - "command" : "31 00 FA C1 03", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "tr2" : { - "name" : "tr2", - "command" : "31 00 FA C1 04", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "ta2" : { - "name" : "ta2", - "command" : "31 00 FA C1 05", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "tdhw2" : { - "name" : "tdhw2", - "command" : "31 00 FA C1 06", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "quiet" : { - "name" : "quiet", - "command" : "31 00 FA C1 07", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "activated", - "2" : "only at night" - } - }, - "mode" : { - "name" : "mode", - "command" : "31 00 FA C0 F6", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "longint", - "value_code" : { - "0" : "standby", - "1" : "heating", - "2" : "cooling", - "3" : "3" - } - }, - "pump" : { - "name" : "pump", - "command" : "31 00 FA C0 F7", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "percent", - "type" : "longint" - }, - "ext" : { - "name" : "ext", - "command" : "31 00 FA C0 F8", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "longint" - }, - "ehs" : { - "name" : "ehs", - "command" : "31 00 FA C0 F9", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "rt" : { - "name" : "rt", - "command" : "31 00 FA C0 FA", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "longint" - }, - "bpv" : { - "name" : "bpv", - "command" : "31 00 FA C0 FB", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "percent", - "type" : "longint" - }, - "t_v1" : { - "name" : "t_v1", - "command" : "31 00 FA C0 FC", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_dhw1" : { - "name" : "t_dhw1", - "command" : "31 00 FA C0 FD", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_vbh" : { - "name" : "t_vbh", - "command" : "31 00 FA C0 FE", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_outdoor_ot1" : { - "name" : "t_outdoor_ot1", - "command" : "31 00 FA C0 FF", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_r1" : { - "name" : "t_r1", - "command" : "31 00 FA C1 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "v1" : { - "name" : "v1", - "command" : "31 00 FA C1 01", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "lh", - "type" : "longint" - }, - "t_room1_setpoint" : { - "name" : "t_room1_setpoint", - "command" : "31 00 05 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_room2_setpoint" : { - "name" : "t_room2_setpoint", - "command" : "31 00 06 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_room3_setpoint" : { - "name" : "t_room3_setpoint", - "command" : "31 00 07 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "heat_slope" : { - "name" : "heat_slope", - "command" : "31 00 FA 01 0E 00 00", - "id" : "190", - "divisor" : "100", - "writable" : "true", - "unit" : "", - "type" : "float" - }, - "t_dhw_setpoint1" : { - "name" : "t_dhw_setpoint1", - "command" : "31 00 13 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_dhw_setpoint2" : { - "name" : "t_dhw_setpoint2", - "command" : "31 00 FA 0A 06 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_dhw_setpoint3" : { - "name" : "t_dhw_setpoint3", - "command" : "31 00 FA 01 3E 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "hyst_hp" : { - "name" : "hyst_hp", - "command" : "31 00 FA 06 91 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_cooling" : { - "name" : "t_flow_cooling", - "command" : "31 00 FA 03 DD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "error" : { - "name" : "error", - "command" : "31 00 FA 13 88 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "value" - }, - "outdoor_type" : { - "name" : "outdoor_type", - "command" : "31 00 FA 06 9A 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "KW", - "type" : "value", - "value_code" : { - "0" : " ", - "1" : "4", - "2" : "6", - "3" : "8", - "4" : "11", - "5" : "14", - "6" : "16" - } - }, - "indoor_unit" : { - "name" : "indoor_unit", - "command" : "31 00 FA 06 99 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : " ", - "1" : "304", - "2" : "308", - "3" : "508", - "4" : "516" - } - }, - "func_heating" : { - "name" : "func_heating", - "command" : "A1 00 FA 06 D2 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "int", - "type" : "value" - }, - "hzu" : { - "name" : "hzu", - "command" : "31 00 FA 06 6C 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "equi_func" : { - "name" : "equi_func", - "command" : "A1 00 FA 06 D3 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "smart_grid" : { - "name" : "smart_grid", - "command" : "31 00 FA 06 93 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "modus_sg" : { - "name" : "modus_sg", - "command" : "31 00 FA 06 94 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "comfort", - "1" : "standard", - "2" : "eco" - } - }, - "ht_nt_func" : { - "name" : "ht_nt_func", - "command" : "31 00 FA 06 6F 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "deactivated", - "1" : "compressor off", - "2" : "compressor off, reserve heating off", - "3" : "all off" - } - }, - "ht_nt_contact" : { - "name" : "ht_nt_contact", - "command" : "31 00 FA 06 70 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "NO", - "1" : "NC" - } - }, - "room_therm" : { - "name" : "room_therm", - "command" : "31 00 FA 06 78 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "interlink" : { - "name" : "interlink", - "command" : "31 00 FA 06 79 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "air_purge" : { - "name" : "air_purge", - "command" : "31 00 FA 06 95 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "max_perf_pump" : { - "name" : "max_perf_pump", - "command" : "31 00 FA 06 7E 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "percent", - "type" : "longint" - }, - "min_perf_pump" : { - "name" : "min_perf_pump", - "command" : "31 00 FA 06 7F 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "percent", - "type" : "longint" - }, - "outside_conf" : { - "name" : "outside_conf", - "command" : "31 00 FA 09 61 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "sval", - "type" : "value", - "value_code" : { - "4" : "off", - "5" : "on" - } - }, - "storage_conf" : { - "name" : "storage_conf", - "command" : "31 00 FA 09 61 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "sval", - "type" : "value", - "value_code" : { - "0" : "off", - "2" : "thermostat", - "4" : "sensor" - } - }, - "pres_conf" : { - "name" : "pres_conf", - "command" : "31 00 FA 09 61 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "sval", - "type" : "value", - "value_code" : { - "10244" : "off", - "26628" : "on" - } - }, - "out_temp_adapt" : { - "name" : "out_temp_adapt", - "command" : "61 00 FA 0C 1F 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "power_dhw" : { - "name" : "power_dhw", - "command" : "31 00 FA 06 68 00 00", - "id" : "190", - "divisor" : "0.1", - "writable" : "true", - "unit" : "w", - "type" : "longint" - }, - "buh_s1_pow" : { - "name" : "buh_s1_pow", - "command" : "31 00 FA 06 69 00 00", - "id" : "190", - "divisor" : "0.1", - "writable" : "true", - "unit" : "w", - "type" : "longint" - }, - "buh_s2_pow" : { - "name" : "buh_s2_pow", - "command" : "31 00 FA 06 6A 00 00", - "id" : "190", - "divisor" : "0.1", - "writable" : "true", - "unit" : "w", - "type" : "longint" - }, - "power_biv" : { - "name" : "power_biv", - "command" : "31 00 FA 06 6B 00 00", - "id" : "190", - "divisor" : "0.1", - "writable" : "true", - "unit" : "w", - "type" : "longint" - }, - "tdiff_dhw_ch" : { - "name" : "tdiff_dhw_ch", - "command" : "31 00 FA 06 6D 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "", - "type" : "longint" - }, - "t_vbh1_max" : { - "name" : "t_vbh1_max", - "command" : "31 00 FA 06 6E 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "equi_temp" : { - "name" : "equi_temp", - "command" : "A1 00 FA 06 D4 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "quiet_mode" : { - "name" : "quiet_mode", - "command" : "31 00 FA 06 96 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on", - "2" : "only at night" - } - }, - "aux_fct" : { - "name" : "aux_fct", - "command" : "31 00 FA 06 96 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value" - }, - "aux_time" : { - "name" : "aux_time", - "command" : "31 00 FA 06 72 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "sec", - "type" : "longint" - }, - "t_dhw_1_min" : { - "name" : "t_dhw_1_min", - "command" : "31 00 FA 06 73 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "delta_t_ch" : { - "name" : "delta_t_ch", - "command" : "31 00 FA 06 83 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "v_var" : { - "name" : "v_var", - "command" : "31 00 FA 06 9C 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "lh", - "type" : "longint" - }, - "t_flow_ch_adj" : { - "name" : "t_flow_ch_adj", - "command" : "31 00 FA 06 A0 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_cool_adj" : { - "name" : "t_flow_cool_adj", - "command" : "31 00 FA 06 A1 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "min_pressure" : { - "name" : "min_pressure", - "command" : "31 00 FA 07 28 00 00", - "id" : "190", - "divisor" : "1000", - "writable" : "true", - "unit" : "bar", - "type" : "float" - }, - "max_pressure" : { - "name" : "max_pressure", - "command" : "31 00 FA 07 27 00 00", - "id" : "190", - "divisor" : "1000", - "writable" : "true", - "unit" : "bar", - "type" : "float" - }, - "setpoint_pressure" : { - "name" : "setpoint_pressure", - "command" : "31 00 FA 07 25 00 00", - "id" : "190", - "divisor" : "1000", - "writable" : "true", - "unit" : "bar", - "type" : "float" - }, - "max_pressure_drop" : { - "name" : "max_pressure_drop", - "command" : "31 00 FA 07 26 00 00", - "id" : "190", - "divisor" : "1000", - "writable" : "true", - "unit" : "bar", - "type" : "float" - }, - "hc_func" : { - "name" : "hc_func", - "command" : "61 00 FA 01 41 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "weather controlled", - "1" : "fixed value" - } - }, - "t_frost_protect" : { - "name" : "t_frost_protect", - "command" : "61 00 FA 0A 00 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "deg", - "type" : "longint" - }, - "insulation" : { - "name" : "insulation", - "command" : "61 00 FA 01 0C 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "512" : "low", - "1024" : "normal", - "2048" : "good", - "3072" : "very good" - } - }, - "screed" : { - "name" : "screed", - "command" : "61 00 FA 01 1A 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "256" : "on" - } - }, - "t_screed_day1" : { - "name" : "screed_day1", - "command" : "61 00 FA 0B B9 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day2" : { - "name" : "screed_day2", - "command" : "61 00 FA 0B BA 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day3" : { - "name" : "screed_day3", - "command" : "61 00 FA 0B BB 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day4" : { - "name" : "screed_day4", - "command" : "61 00 FA 0B BC 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day5" : { - "name" : "screed_day5", - "command" : "61 00 FA 0B BD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day6" : { - "name" : "screed_day6", - "command" : "61 00 FA 0B BE 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day7" : { - "name" : "screed_day7", - "command" : "61 00 FA 0B BD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day8" : { - "name" : "screed_day8", - "command" : "61 00 FA 0B C0 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day9" : { - "name" : "screed_day9", - "command" : "61 00 FA 0B C1 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day10" : { - "name" : "screed_day10", - "command" : "61 00 FA 0B C2 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day11" : { - "name" : "screed_day11", - "command" : "61 00 FA 0B C3 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day12" : { - "name" : "screed_day12", - "command" : "61 00 FA 0B C4 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day13" : { - "name" : "screed_day13", - "command" : "61 00 FA 0B C5 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day14" : { - "name" : "screed_day14", - "command" : "61 00 FA 0B C6 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day15" : { - "name" : "screed_day15", - "command" : "61 00 FA 0B C7 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day16" : { - "name" : "screed_day16", - "command" : "61 00 FA 0B C8 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day17" : { - "name" : "screed_day17", - "command" : "61 00 FA 0B C9 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day18" : { - "name" : "screed_day18", - "command" : "61 00 FA 0B CA 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day19" : { - "name" : "screed_day19", - "command" : "61 00 FA 0B CB 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day20" : { - "name" : "screed_day20", - "command" : "61 00 FA 0B CC 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day21" : { - "name" : "screed_day21", - "command" : "61 00 FA 0B CD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day22" : { - "name" : "screed_day22", - "command" : "61 00 FA 0B CD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day23" : { - "name" : "screed_day23", - "command" : "61 00 FA 0B CF 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day24" : { - "name" : "screed_day24", - "command" : "61 00 FA 0B D0 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day25" : { - "name" : "screed_day25", - "command" : "61 00 FA 0B D1 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day26" : { - "name" : "screed_day26", - "command" : "61 00 FA 0B D2 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day27" : { - "name" : "screed_day27", - "command" : "61 00 FA 0B D3 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day28" : { - "name" : "screed_day28", - "command" : "61 00 FA 0B D4 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_out_lim_day" : { - "name" : "t_out_lim_day", - "command" : "61 00 FA 01 16 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_out_lim_night" : { - "name" : "t_out_lim_night", - "command" : "61 00 FA 01 17 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_day" : { - "name" : "t_flow_day", - "command" : "61 00 FA 01 29 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_night" : { - "name" : "t_flow_night", - "command" : "61 00 FA 01 2A 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "max_t_flow" : { - "name" : "max_t_flow", - "command" : "61 00 28 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "min_t_flow" : { - "name" : "min_t_flow", - "command" : "61 00 FA 01 2B 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "hc_adapt" : { - "name" : "hc_adapt", - "command" : "61 00 FA 01 15 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "256" : "on" - } - }, - "start_tout_cool" : { - "name" : "start_tout_cool", - "command" : "61 00 FA 13 5B 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "max_tout_cool" : { - "name" : "max_tout_cool", - "command" : "61 00 FA 13 5C 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_cool_start" : { - "name" : "t_flow_cool_start", - "command" : "61 00 FA 13 5D 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_cool_max" : { - "name" : "t_flow_cool_max", - "command" : "61 00 FA 13 5E 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "min_t_flow_cool" : { - "name" : "min_t_flow_cool", - "command" : "61 00 FA 13 63 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_cool" : { - "name" : "t_flow_cool", - "command" : "61 00 FA 03 DD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "cool_setpoint_adj" : { - "name" : "cool_setpoint_adj", - "command" : "61 00 FA 13 59 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "circ_pump_dhw" : { - "name" : "circ_pump_dhw", - "command" : "31 00 FA 01 82 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "circ_pump_interval" : { - "name" : "circ_pump_interval", - "command" : "31 00 FA 06 5E 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value" - }, - "anti_leg_day" : { - "name" : "anti_leg_day", - "command" : "31 00 FA 01 01 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "256" : "Monday", - "512" : "Tuesday", - "768" : "Wednesday", - "1024" : "Thursday", - "1280" : "Friday", - "1536" : "Saturday", - "1792" : "Sunday", - "2048" : "Everyday" - } - }, - "anti_leg_time" : { - "name" : "anti_leg_time", - "command" : "31 00 FA FD F4 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value" - }, - "anti_leg_temp" : { - "name" : "anti_leg_temp", - "command" : "31 00 FA 05 87 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "max_dhw_loading" : { - "name" : "max_dhw_loading", - "command" : "31 00 FA 01 80 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "min", - "type" : "longint" - }, - "dhw_off_time" : { - "name" : "dhw_off_time", - "command" : "31 00 FA 4E 3F 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "", - "type" : "float" - }, - "one_hot_water" : { - "name" : "one_hot_water", - "command" : "31 00 FA 01 44 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "timer_boh" : { - "name" : "timer_boh", - "command" : "31 00 FA 06 92 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "min", - "type" : "longint" - }, - "t_reduced" : { - "name" : "t_reduced", - "command" : "61 00 08 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_absence" : { - "name" : "t_absence", - "command" : "61 00 FA 01 3D 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_room" :{ - "name" : "t_room", - "command" : "31 00 FA 00 11 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - } - } -} +{ + "version" : "2.0", + "commands":{ + "t_hs" : { + "name" : "t_hs", + "command" : "31 00 FA 01 D6 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_hs_set" : { + "name" : "t_hs_set", + "command" : "31 00 02 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "water_pressure" : { + "name" : "water_pressure", + "command" : "31 00 1C 00 00 00 00", + "id" : "190", + "divisor" : "1000", + "writable" : "false", + "unit" : "bar", + "type" : "float" + }, + "t_ext" : { + "name" : "t_ext", + "command" : "61 00 FA 0A 0C 00 00", + "id" : "310", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_dhw" : { + "name" : "t_dhw", + "command" : "31 00 0E 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_dhw_set" : { + "name" : "t_dhw_set", + "command" : "31 00 03 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_return" : { + "name" : "t_return", + "command" : "31 00 16 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "flow_rate" : { + "name" : "flow_rate", + "command" : "31 00 FA 01 DA 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "lh", + "type" : "longint" + }, + "t_hc" : { + "name" : "t_hc", + "command" : "C1 00 0F 00 00 00 00", + "id" : "610", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_hc_set" : { + "name" : "t_hc_set", + "command" : "61 00 04 00 00 00 00", + "id" : "310", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "status_pump" : { + "name" : "status_pump", + "command" : "31 00 FA 0A 8C 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "runtime_comp" : { + "name" : "runtime_comp", + "command" : "31 00 FA 06 A5 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "hour", + "type" : "longint" + }, + "runtime_pump" : { + "name" : "runtime_pump", + "command" : "31 00 FA 06 A4 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "longint" + }, + "posmix" : { + "name" : "posmix", + "command" : "31 00 FA 06 9B 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "percent", + "type" : "longint" + }, + "qboh" : { + "name" : "qboh", + "command" : "31 00 FA 09 1C 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "qchhp" : { + "name" : "qchhp", + "command" : "31 00 FA 09 20 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "qsc" : { + "name" : "qsc", + "command" : "31 00 FA 06 A6 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "qch" : { + "name" : "qch", + "command" : "31 00 FA 06 A7 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint" + }, + "qwp" : { + "name" : "qwp", + "command" : "31 00 FA 09 30 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "qdhw" : { + "name" : "qdhw", + "command" : "31 00 FA 09 2C 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "sw_vers_01" : { + "name" : "sw_vers_01", + "command" : "31 00 FA 01 99 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint" + }, + "sw_vers_02" : { + "name" : "sw_vers_02", + "command" : "31 00 FA C0 B4 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint" + }, + "sw_vers_03" : { + "name" : "sw_vers_03", + "command" : "31 00 FA 02 4B 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint" + }, + "mode_01" : { + "name" : "mode_01", + "command" : "31 00 FA 01 12 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "", + "type" : "int", + "value_code" : { + "1" : "standby", + "3" : "heat", + "4" : "sink", + "5" : "summer", + "17" : "cool", + "11" : "auto 1", + "12" : "auto 2" + } + }, + "tvbh2" : { + "name" : "tvbh2", + "command" : "31 00 FA C1 02", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "tliq2" : { + "name" : "tliq2", + "command" : "31 00 FA C1 03", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "tr2" : { + "name" : "tr2", + "command" : "31 00 FA C1 04", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "ta2" : { + "name" : "ta2", + "command" : "31 00 FA C1 05", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "tdhw2" : { + "name" : "tdhw2", + "command" : "31 00 FA C1 06", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "quiet" : { + "name" : "quiet", + "command" : "31 00 FA C1 07", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "activated", + "2" : "only at night" + } + }, + "mode" : { + "name" : "mode", + "command" : "31 00 FA C0 F6", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "longint", + "value_code" : { + "0" : "standby", + "1" : "heating", + "2" : "cooling", + "3" : "3" + } + }, + "pump" : { + "name" : "pump", + "command" : "31 00 FA C0 F7", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "percent", + "type" : "longint" + }, + "ext" : { + "name" : "ext", + "command" : "31 00 FA C0 F8", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "longint" + }, + "ehs" : { + "name" : "ehs", + "command" : "31 00 FA C0 F9", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "rt" : { + "name" : "rt", + "command" : "31 00 FA C0 FA", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "longint" + }, + "bpv" : { + "name" : "bpv", + "command" : "31 00 FA C0 FB", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "percent", + "type" : "longint" + }, + "t_v1" : { + "name" : "t_v1", + "command" : "31 00 FA C0 FC", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_dhw1" : { + "name" : "t_dhw1", + "command" : "31 00 FA C0 FD", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_vbh" : { + "name" : "t_vbh", + "command" : "31 00 FA C0 FE", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_outdoor_ot1" : { + "name" : "t_outdoor_ot1", + "command" : "31 00 FA C0 FF", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_r1" : { + "name" : "t_r1", + "command" : "31 00 FA C1 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "v1" : { + "name" : "v1", + "command" : "31 00 FA C1 01", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "lh", + "type" : "longint" + }, + "t_room1_setpoint" : { + "name" : "t_room1_setpoint", + "command" : "31 00 05 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_room2_setpoint" : { + "name" : "t_room2_setpoint", + "command" : "31 00 06 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_room3_setpoint" : { + "name" : "t_room3_setpoint", + "command" : "31 00 07 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "heat_slope" : { + "name" : "heat_slope", + "command" : "31 00 FA 01 0E 00 00", + "id" : "190", + "divisor" : "100", + "writable" : "true", + "unit" : "", + "type" : "float" + }, + "t_dhw_setpoint1" : { + "name" : "t_dhw_setpoint1", + "command" : "31 00 13 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_dhw_setpoint2" : { + "name" : "t_dhw_setpoint2", + "command" : "31 00 FA 0A 06 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_dhw_setpoint3" : { + "name" : "t_dhw_setpoint3", + "command" : "31 00 FA 01 3E 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "hyst_hp" : { + "name" : "hyst_hp", + "command" : "31 00 FA 06 91 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_cooling" : { + "name" : "t_flow_cooling", + "command" : "31 00 FA 03 DD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "error" : { + "name" : "error", + "command" : "31 00 FA 13 88 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "value" + }, + "outdoor_type" : { + "name" : "outdoor_type", + "command" : "31 00 FA 06 9A 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "KW", + "type" : "value", + "value_code" : { + "0" : " ", + "1" : "4", + "2" : "6", + "3" : "8", + "4" : "11", + "5" : "14", + "6" : "16" + } + }, + "indoor_unit" : { + "name" : "indoor_unit", + "command" : "31 00 FA 06 99 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : " ", + "1" : "304", + "2" : "308", + "3" : "508", + "4" : "516" + } + }, + "func_heating" : { + "name" : "func_heating", + "command" : "A1 00 FA 06 D2 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "int", + "type" : "value" + }, + "hzu" : { + "name" : "hzu", + "command" : "31 00 FA 06 6C 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "equi_func" : { + "name" : "equi_func", + "command" : "A1 00 FA 06 D3 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "smart_grid" : { + "name" : "smart_grid", + "command" : "31 00 FA 06 93 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "modus_sg" : { + "name" : "modus_sg", + "command" : "31 00 FA 06 94 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "comfort", + "1" : "standard", + "2" : "eco" + } + }, + "ht_nt_func" : { + "name" : "ht_nt_func", + "command" : "31 00 FA 06 6F 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "deactivated", + "1" : "compressor off", + "2" : "compressor off, reserve heating off", + "3" : "all off" + } + }, + "ht_nt_contact" : { + "name" : "ht_nt_contact", + "command" : "31 00 FA 06 70 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "NO", + "1" : "NC" + } + }, + "room_therm" : { + "name" : "room_therm", + "command" : "31 00 FA 06 78 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "interlink" : { + "name" : "interlink", + "command" : "31 00 FA 06 79 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "air_purge" : { + "name" : "air_purge", + "command" : "31 00 FA 06 95 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "max_perf_pump" : { + "name" : "max_perf_pump", + "command" : "31 00 FA 06 7E 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "percent", + "type" : "longint" + }, + "min_perf_pump" : { + "name" : "min_perf_pump", + "command" : "31 00 FA 06 7F 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "percent", + "type" : "longint" + }, + "outside_conf" : { + "name" : "outside_conf", + "command" : "31 00 FA 09 61 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "sval", + "type" : "value", + "value_code" : { + "4" : "off", + "5" : "on" + } + }, + "storage_conf" : { + "name" : "storage_conf", + "command" : "31 00 FA 09 61 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "sval", + "type" : "value", + "value_code" : { + "0" : "off", + "2" : "thermostat", + "4" : "sensor" + } + }, + "pres_conf" : { + "name" : "pres_conf", + "command" : "31 00 FA 09 61 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "sval", + "type" : "value", + "value_code" : { + "10244" : "off", + "26628" : "on" + } + }, + "out_temp_adapt" : { + "name" : "out_temp_adapt", + "command" : "61 00 FA 0C 1F 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "power_dhw" : { + "name" : "power_dhw", + "command" : "31 00 FA 06 68 00 00", + "id" : "190", + "divisor" : "0.1", + "writable" : "true", + "unit" : "w", + "type" : "longint" + }, + "buh_s1_pow" : { + "name" : "buh_s1_pow", + "command" : "31 00 FA 06 69 00 00", + "id" : "190", + "divisor" : "0.1", + "writable" : "true", + "unit" : "w", + "type" : "longint" + }, + "buh_s2_pow" : { + "name" : "buh_s2_pow", + "command" : "31 00 FA 06 6A 00 00", + "id" : "190", + "divisor" : "0.1", + "writable" : "true", + "unit" : "w", + "type" : "longint" + }, + "power_biv" : { + "name" : "power_biv", + "command" : "31 00 FA 06 6B 00 00", + "id" : "190", + "divisor" : "0.1", + "writable" : "true", + "unit" : "w", + "type" : "longint" + }, + "tdiff_dhw_ch" : { + "name" : "tdiff_dhw_ch", + "command" : "31 00 FA 06 6D 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "", + "type" : "longint" + }, + "t_vbh1_max" : { + "name" : "t_vbh1_max", + "command" : "31 00 FA 06 6E 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "equi_temp" : { + "name" : "equi_temp", + "command" : "A1 00 FA 06 D4 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "quiet_mode" : { + "name" : "quiet_mode", + "command" : "31 00 FA 06 96 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on", + "2" : "only at night" + } + }, + "aux_fct" : { + "name" : "aux_fct", + "command" : "31 00 FA 06 96 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value" + }, + "aux_time" : { + "name" : "aux_time", + "command" : "31 00 FA 06 72 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "sec", + "type" : "longint" + }, + "t_dhw_1_min" : { + "name" : "t_dhw_1_min", + "command" : "31 00 FA 06 73 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "delta_t_ch" : { + "name" : "delta_t_ch", + "command" : "31 00 FA 06 83 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "v_var" : { + "name" : "v_var", + "command" : "31 00 FA 06 9C 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "lh", + "type" : "longint" + }, + "t_flow_ch_adj" : { + "name" : "t_flow_ch_adj", + "command" : "31 00 FA 06 A0 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_cool_adj" : { + "name" : "t_flow_cool_adj", + "command" : "31 00 FA 06 A1 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "min_pressure" : { + "name" : "min_pressure", + "command" : "31 00 FA 07 28 00 00", + "id" : "190", + "divisor" : "1000", + "writable" : "true", + "unit" : "bar", + "type" : "float" + }, + "max_pressure" : { + "name" : "max_pressure", + "command" : "31 00 FA 07 27 00 00", + "id" : "190", + "divisor" : "1000", + "writable" : "true", + "unit" : "bar", + "type" : "float" + }, + "setpoint_pressure" : { + "name" : "setpoint_pressure", + "command" : "31 00 FA 07 25 00 00", + "id" : "190", + "divisor" : "1000", + "writable" : "true", + "unit" : "bar", + "type" : "float" + }, + "max_pressure_drop" : { + "name" : "max_pressure_drop", + "command" : "31 00 FA 07 26 00 00", + "id" : "190", + "divisor" : "1000", + "writable" : "true", + "unit" : "bar", + "type" : "float" + }, + "hc_func" : { + "name" : "hc_func", + "command" : "61 00 FA 01 41 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "weather controlled", + "1" : "fixed value" + } + }, + "t_frost_protect" : { + "name" : "t_frost_protect", + "command" : "61 00 FA 0A 00 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "deg", + "type" : "longint" + }, + "insulation" : { + "name" : "insulation", + "command" : "61 00 FA 01 0C 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "512" : "low", + "1024" : "normal", + "2048" : "good", + "3072" : "very good" + } + }, + "screed" : { + "name" : "screed", + "command" : "61 00 FA 01 1A 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "256" : "on" + } + }, + "t_screed_day1" : { + "name" : "screed_day1", + "command" : "61 00 FA 0B B9 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day2" : { + "name" : "screed_day2", + "command" : "61 00 FA 0B BA 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day3" : { + "name" : "screed_day3", + "command" : "61 00 FA 0B BB 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day4" : { + "name" : "screed_day4", + "command" : "61 00 FA 0B BC 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day5" : { + "name" : "screed_day5", + "command" : "61 00 FA 0B BD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day6" : { + "name" : "screed_day6", + "command" : "61 00 FA 0B BE 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day7" : { + "name" : "screed_day7", + "command" : "61 00 FA 0B BD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day8" : { + "name" : "screed_day8", + "command" : "61 00 FA 0B C0 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day9" : { + "name" : "screed_day9", + "command" : "61 00 FA 0B C1 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day10" : { + "name" : "screed_day10", + "command" : "61 00 FA 0B C2 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day11" : { + "name" : "screed_day11", + "command" : "61 00 FA 0B C3 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day12" : { + "name" : "screed_day12", + "command" : "61 00 FA 0B C4 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day13" : { + "name" : "screed_day13", + "command" : "61 00 FA 0B C5 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day14" : { + "name" : "screed_day14", + "command" : "61 00 FA 0B C6 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day15" : { + "name" : "screed_day15", + "command" : "61 00 FA 0B C7 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day16" : { + "name" : "screed_day16", + "command" : "61 00 FA 0B C8 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day17" : { + "name" : "screed_day17", + "command" : "61 00 FA 0B C9 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day18" : { + "name" : "screed_day18", + "command" : "61 00 FA 0B CA 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day19" : { + "name" : "screed_day19", + "command" : "61 00 FA 0B CB 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day20" : { + "name" : "screed_day20", + "command" : "61 00 FA 0B CC 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day21" : { + "name" : "screed_day21", + "command" : "61 00 FA 0B CD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day22" : { + "name" : "screed_day22", + "command" : "61 00 FA 0B CD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day23" : { + "name" : "screed_day23", + "command" : "61 00 FA 0B CF 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day24" : { + "name" : "screed_day24", + "command" : "61 00 FA 0B D0 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day25" : { + "name" : "screed_day25", + "command" : "61 00 FA 0B D1 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day26" : { + "name" : "screed_day26", + "command" : "61 00 FA 0B D2 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day27" : { + "name" : "screed_day27", + "command" : "61 00 FA 0B D3 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day28" : { + "name" : "screed_day28", + "command" : "61 00 FA 0B D4 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_out_lim_day" : { + "name" : "t_out_lim_day", + "command" : "61 00 FA 01 16 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_out_lim_night" : { + "name" : "t_out_lim_night", + "command" : "61 00 FA 01 17 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_day" : { + "name" : "t_flow_day", + "command" : "61 00 FA 01 29 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_night" : { + "name" : "t_flow_night", + "command" : "61 00 FA 01 2A 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "max_t_flow" : { + "name" : "max_t_flow", + "command" : "61 00 28 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "min_t_flow" : { + "name" : "min_t_flow", + "command" : "61 00 FA 01 2B 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "hc_adapt" : { + "name" : "hc_adapt", + "command" : "61 00 FA 01 15 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "256" : "on" + } + }, + "start_tout_cool" : { + "name" : "start_tout_cool", + "command" : "61 00 FA 13 5B 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "max_tout_cool" : { + "name" : "max_tout_cool", + "command" : "61 00 FA 13 5C 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_cool_start" : { + "name" : "t_flow_cool_start", + "command" : "61 00 FA 13 5D 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_cool_max" : { + "name" : "t_flow_cool_max", + "command" : "61 00 FA 13 5E 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "min_t_flow_cool" : { + "name" : "min_t_flow_cool", + "command" : "61 00 FA 13 63 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_cool" : { + "name" : "t_flow_cool", + "command" : "61 00 FA 03 DD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "cool_setpoint_adj" : { + "name" : "cool_setpoint_adj", + "command" : "61 00 FA 13 59 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "circ_pump_dhw" : { + "name" : "circ_pump_dhw", + "command" : "31 00 FA 01 82 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "circ_pump_interval" : { + "name" : "circ_pump_interval", + "command" : "31 00 FA 06 5E 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value" + }, + "anti_leg_day" : { + "name" : "anti_leg_day", + "command" : "31 00 FA 01 01 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "256" : "Monday", + "512" : "Tuesday", + "768" : "Wednesday", + "1024" : "Thursday", + "1280" : "Friday", + "1536" : "Saturday", + "1792" : "Sunday", + "2048" : "Everyday" + } + }, + "anti_leg_time" : { + "name" : "anti_leg_time", + "command" : "31 00 FA FD F4 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value" + }, + "anti_leg_temp" : { + "name" : "anti_leg_temp", + "command" : "31 00 FA 05 87 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "max_dhw_loading" : { + "name" : "max_dhw_loading", + "command" : "31 00 FA 01 80 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "min", + "type" : "longint" + }, + "dhw_off_time" : { + "name" : "dhw_off_time", + "command" : "31 00 FA 4E 3F 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "", + "type" : "float" + }, + "one_hot_water" : { + "name" : "one_hot_water", + "command" : "31 00 FA 01 44 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "timer_boh" : { + "name" : "timer_boh", + "command" : "31 00 FA 06 92 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "min", + "type" : "longint" + }, + "t_reduced" : { + "name" : "t_reduced", + "command" : "61 00 08 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_absence" : { + "name" : "t_absence", + "command" : "61 00 FA 01 3D 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_room" :{ + "name" : "t_room", + "command" : "31 00 FA 00 11 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "comp_active" : { + "name" : "comp_active", + "command" : "A1 00 61 00 00 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint", + "value_code" : { + "0" : "off", + "256" : "on" + } + }, + "pump_active" :{ + "name" : "pump_active", + "command" : "A1 00 FA FD AC 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint", + "value_code" : { + "0" : "off", + "256" : "on" + } + }, + "temperature_spread_pwm" : { + "name" : "temperature_spread_pwm", + "command" : "A1 00 FA 06 DB 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "offset_t_flow" : { + "name" : "offset_t_flow", + "command" : "A1 00 FA 06 E2 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + } + } +} diff --git a/pyHPSU.py b/pyHPSU.py index 0f752d4..ce67268 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -451,7 +451,8 @@ def main(argv): read_can(driver, logger, port, cmd, lg_code,verbose,output_type) # if we reach this point (the end), we are not in auto mode so the loop is not started - mqtt_client.loop_forever() + if mqtt_client is not None: + mqtt_client.loop_forever() def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): global backup_file From 20bcf72f50da182a31f3f7d3ca26465743eda533 Mon Sep 17 00:00:00 2001 From: segaura Date: Mon, 22 Mar 2021 10:12:09 +0100 Subject: [PATCH 18/23] README.md typo correction --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c56013c..1029814 100755 --- a/README.md +++ b/README.md @@ -170,7 +170,7 @@ e.g. COMMANDTOPIC = command ... - root@rotex:# pyHPSU.py --mqttdaemon + root@rotex:# pyHPSU.py --mqtt_daemon user@anothersystem:# mosquitto_pub -h 192.168.1.94 -t "myhpsu/command/t_dhw" -m read @@ -181,7 +181,7 @@ e.g. e.g. (with same config) - root@rotex:# pyHPSU.py --mqttdaemon -a -o mqtt + root@rotex:# pyHPSU.py --mqtt_daemon -a -o mqtt user@anothersystem:# mosquitto_pub -h 192.168.1.94 -t "myhpsu/command/t_flow_day" -m 29 From 91937e49d96c4c1096fcdf1a9b3c6137fba59f98 Mon Sep 17 00:00:00 2001 From: segaura Date: Fri, 26 Mar 2021 19:17:02 +0100 Subject: [PATCH 19/23] commands_hpsu.json reverted to DOS EOL --- etc/pyHPSU/commands_hpsu.json | 3014 ++++++++++++++++----------------- 1 file changed, 1507 insertions(+), 1507 deletions(-) diff --git a/etc/pyHPSU/commands_hpsu.json b/etc/pyHPSU/commands_hpsu.json index 6a99e59..205618a 100644 --- a/etc/pyHPSU/commands_hpsu.json +++ b/etc/pyHPSU/commands_hpsu.json @@ -1,1507 +1,1507 @@ -{ - "version" : "2.0", - "commands":{ - "t_hs" : { - "name" : "t_hs", - "command" : "31 00 FA 01 D6 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_hs_set" : { - "name" : "t_hs_set", - "command" : "31 00 02 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "water_pressure" : { - "name" : "water_pressure", - "command" : "31 00 1C 00 00 00 00", - "id" : "190", - "divisor" : "1000", - "writable" : "false", - "unit" : "bar", - "type" : "float" - }, - "t_ext" : { - "name" : "t_ext", - "command" : "61 00 FA 0A 0C 00 00", - "id" : "310", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_dhw" : { - "name" : "t_dhw", - "command" : "31 00 0E 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_dhw_set" : { - "name" : "t_dhw_set", - "command" : "31 00 03 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_return" : { - "name" : "t_return", - "command" : "31 00 16 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "flow_rate" : { - "name" : "flow_rate", - "command" : "31 00 FA 01 DA 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "lh", - "type" : "longint" - }, - "t_hc" : { - "name" : "t_hc", - "command" : "C1 00 0F 00 00 00 00", - "id" : "610", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_hc_set" : { - "name" : "t_hc_set", - "command" : "61 00 04 00 00 00 00", - "id" : "310", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "status_pump" : { - "name" : "status_pump", - "command" : "31 00 FA 0A 8C 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "runtime_comp" : { - "name" : "runtime_comp", - "command" : "31 00 FA 06 A5 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "hour", - "type" : "longint" - }, - "runtime_pump" : { - "name" : "runtime_pump", - "command" : "31 00 FA 06 A4 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "longint" - }, - "posmix" : { - "name" : "posmix", - "command" : "31 00 FA 06 9B 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "percent", - "type" : "longint" - }, - "qboh" : { - "name" : "qboh", - "command" : "31 00 FA 09 1C 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "qchhp" : { - "name" : "qchhp", - "command" : "31 00 FA 09 20 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "qsc" : { - "name" : "qsc", - "command" : "31 00 FA 06 A6 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "qch" : { - "name" : "qch", - "command" : "31 00 FA 06 A7 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "longint" - }, - "qwp" : { - "name" : "qwp", - "command" : "31 00 FA 09 30 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "qdhw" : { - "name" : "qdhw", - "command" : "31 00 FA 09 2C 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "sw_vers_01" : { - "name" : "sw_vers_01", - "command" : "31 00 FA 01 99 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "longint" - }, - "sw_vers_02" : { - "name" : "sw_vers_02", - "command" : "31 00 FA C0 B4 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "longint" - }, - "sw_vers_03" : { - "name" : "sw_vers_03", - "command" : "31 00 FA 02 4B 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "longint" - }, - "mode_01" : { - "name" : "mode_01", - "command" : "31 00 FA 01 12 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "", - "type" : "int", - "value_code" : { - "1" : "standby", - "3" : "heat", - "4" : "sink", - "5" : "summer", - "17" : "cool", - "11" : "auto 1", - "12" : "auto 2" - } - }, - "tvbh2" : { - "name" : "tvbh2", - "command" : "31 00 FA C1 02", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "tliq2" : { - "name" : "tliq2", - "command" : "31 00 FA C1 03", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "tr2" : { - "name" : "tr2", - "command" : "31 00 FA C1 04", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "ta2" : { - "name" : "ta2", - "command" : "31 00 FA C1 05", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "tdhw2" : { - "name" : "tdhw2", - "command" : "31 00 FA C1 06", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "quiet" : { - "name" : "quiet", - "command" : "31 00 FA C1 07", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "activated", - "2" : "only at night" - } - }, - "mode" : { - "name" : "mode", - "command" : "31 00 FA C0 F6", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "longint", - "value_code" : { - "0" : "standby", - "1" : "heating", - "2" : "cooling", - "3" : "3" - } - }, - "pump" : { - "name" : "pump", - "command" : "31 00 FA C0 F7", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "percent", - "type" : "longint" - }, - "ext" : { - "name" : "ext", - "command" : "31 00 FA C0 F8", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "longint" - }, - "ehs" : { - "name" : "ehs", - "command" : "31 00 FA C0 F9", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "kwh", - "type" : "longint" - }, - "rt" : { - "name" : "rt", - "command" : "31 00 FA C0 FA", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "longint", - "type" : "longint" - }, - "bpv" : { - "name" : "bpv", - "command" : "31 00 FA C0 FB", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "percent", - "type" : "longint" - }, - "t_v1" : { - "name" : "t_v1", - "command" : "31 00 FA C0 FC", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_dhw1" : { - "name" : "t_dhw1", - "command" : "31 00 FA C0 FD", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_vbh" : { - "name" : "t_vbh", - "command" : "31 00 FA C0 FE", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_outdoor_ot1" : { - "name" : "t_outdoor_ot1", - "command" : "31 00 FA C0 FF", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "t_r1" : { - "name" : "t_r1", - "command" : "31 00 FA C1 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "v1" : { - "name" : "v1", - "command" : "31 00 FA C1 01", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "lh", - "type" : "longint" - }, - "t_room1_setpoint" : { - "name" : "t_room1_setpoint", - "command" : "31 00 05 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_room2_setpoint" : { - "name" : "t_room2_setpoint", - "command" : "31 00 06 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_room3_setpoint" : { - "name" : "t_room3_setpoint", - "command" : "31 00 07 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "heat_slope" : { - "name" : "heat_slope", - "command" : "31 00 FA 01 0E 00 00", - "id" : "190", - "divisor" : "100", - "writable" : "true", - "unit" : "", - "type" : "float" - }, - "t_dhw_setpoint1" : { - "name" : "t_dhw_setpoint1", - "command" : "31 00 13 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_dhw_setpoint2" : { - "name" : "t_dhw_setpoint2", - "command" : "31 00 FA 0A 06 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_dhw_setpoint3" : { - "name" : "t_dhw_setpoint3", - "command" : "31 00 FA 01 3E 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "hyst_hp" : { - "name" : "hyst_hp", - "command" : "31 00 FA 06 91 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_cooling" : { - "name" : "t_flow_cooling", - "command" : "31 00 FA 03 DD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "error" : { - "name" : "error", - "command" : "31 00 FA 13 88 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "value" - }, - "outdoor_type" : { - "name" : "outdoor_type", - "command" : "31 00 FA 06 9A 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "KW", - "type" : "value", - "value_code" : { - "0" : " ", - "1" : "4", - "2" : "6", - "3" : "8", - "4" : "11", - "5" : "14", - "6" : "16" - } - }, - "indoor_unit" : { - "name" : "indoor_unit", - "command" : "31 00 FA 06 99 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : " ", - "1" : "304", - "2" : "308", - "3" : "508", - "4" : "516" - } - }, - "func_heating" : { - "name" : "func_heating", - "command" : "A1 00 FA 06 D2 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "int", - "type" : "value" - }, - "hzu" : { - "name" : "hzu", - "command" : "31 00 FA 06 6C 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "equi_func" : { - "name" : "equi_func", - "command" : "A1 00 FA 06 D3 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "smart_grid" : { - "name" : "smart_grid", - "command" : "31 00 FA 06 93 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "modus_sg" : { - "name" : "modus_sg", - "command" : "31 00 FA 06 94 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "comfort", - "1" : "standard", - "2" : "eco" - } - }, - "ht_nt_func" : { - "name" : "ht_nt_func", - "command" : "31 00 FA 06 6F 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "deactivated", - "1" : "compressor off", - "2" : "compressor off, reserve heating off", - "3" : "all off" - } - }, - "ht_nt_contact" : { - "name" : "ht_nt_contact", - "command" : "31 00 FA 06 70 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "NO", - "1" : "NC" - } - }, - "room_therm" : { - "name" : "room_therm", - "command" : "31 00 FA 06 78 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "interlink" : { - "name" : "interlink", - "command" : "31 00 FA 06 79 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "air_purge" : { - "name" : "air_purge", - "command" : "31 00 FA 06 95 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "max_perf_pump" : { - "name" : "max_perf_pump", - "command" : "31 00 FA 06 7E 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "percent", - "type" : "longint" - }, - "min_perf_pump" : { - "name" : "min_perf_pump", - "command" : "31 00 FA 06 7F 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "percent", - "type" : "longint" - }, - "outside_conf" : { - "name" : "outside_conf", - "command" : "31 00 FA 09 61 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "sval", - "type" : "value", - "value_code" : { - "4" : "off", - "5" : "on" - } - }, - "storage_conf" : { - "name" : "storage_conf", - "command" : "31 00 FA 09 61 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "sval", - "type" : "value", - "value_code" : { - "0" : "off", - "2" : "thermostat", - "4" : "sensor" - } - }, - "pres_conf" : { - "name" : "pres_conf", - "command" : "31 00 FA 09 61 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "sval", - "type" : "value", - "value_code" : { - "10244" : "off", - "26628" : "on" - } - }, - "out_temp_adapt" : { - "name" : "out_temp_adapt", - "command" : "61 00 FA 0C 1F 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "power_dhw" : { - "name" : "power_dhw", - "command" : "31 00 FA 06 68 00 00", - "id" : "190", - "divisor" : "0.1", - "writable" : "true", - "unit" : "w", - "type" : "longint" - }, - "buh_s1_pow" : { - "name" : "buh_s1_pow", - "command" : "31 00 FA 06 69 00 00", - "id" : "190", - "divisor" : "0.1", - "writable" : "true", - "unit" : "w", - "type" : "longint" - }, - "buh_s2_pow" : { - "name" : "buh_s2_pow", - "command" : "31 00 FA 06 6A 00 00", - "id" : "190", - "divisor" : "0.1", - "writable" : "true", - "unit" : "w", - "type" : "longint" - }, - "power_biv" : { - "name" : "power_biv", - "command" : "31 00 FA 06 6B 00 00", - "id" : "190", - "divisor" : "0.1", - "writable" : "true", - "unit" : "w", - "type" : "longint" - }, - "tdiff_dhw_ch" : { - "name" : "tdiff_dhw_ch", - "command" : "31 00 FA 06 6D 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "", - "type" : "longint" - }, - "t_vbh1_max" : { - "name" : "t_vbh1_max", - "command" : "31 00 FA 06 6E 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "equi_temp" : { - "name" : "equi_temp", - "command" : "A1 00 FA 06 D4 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "quiet_mode" : { - "name" : "quiet_mode", - "command" : "31 00 FA 06 96 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on", - "2" : "only at night" - } - }, - "aux_fct" : { - "name" : "aux_fct", - "command" : "31 00 FA 06 96 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value" - }, - "aux_time" : { - "name" : "aux_time", - "command" : "31 00 FA 06 72 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "sec", - "type" : "longint" - }, - "t_dhw_1_min" : { - "name" : "t_dhw_1_min", - "command" : "31 00 FA 06 73 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "delta_t_ch" : { - "name" : "delta_t_ch", - "command" : "31 00 FA 06 83 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "v_var" : { - "name" : "v_var", - "command" : "31 00 FA 06 9C 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "lh", - "type" : "longint" - }, - "t_flow_ch_adj" : { - "name" : "t_flow_ch_adj", - "command" : "31 00 FA 06 A0 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_cool_adj" : { - "name" : "t_flow_cool_adj", - "command" : "31 00 FA 06 A1 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "min_pressure" : { - "name" : "min_pressure", - "command" : "31 00 FA 07 28 00 00", - "id" : "190", - "divisor" : "1000", - "writable" : "true", - "unit" : "bar", - "type" : "float" - }, - "max_pressure" : { - "name" : "max_pressure", - "command" : "31 00 FA 07 27 00 00", - "id" : "190", - "divisor" : "1000", - "writable" : "true", - "unit" : "bar", - "type" : "float" - }, - "setpoint_pressure" : { - "name" : "setpoint_pressure", - "command" : "31 00 FA 07 25 00 00", - "id" : "190", - "divisor" : "1000", - "writable" : "true", - "unit" : "bar", - "type" : "float" - }, - "max_pressure_drop" : { - "name" : "max_pressure_drop", - "command" : "31 00 FA 07 26 00 00", - "id" : "190", - "divisor" : "1000", - "writable" : "true", - "unit" : "bar", - "type" : "float" - }, - "hc_func" : { - "name" : "hc_func", - "command" : "61 00 FA 01 41 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "weather controlled", - "1" : "fixed value" - } - }, - "t_frost_protect" : { - "name" : "t_frost_protect", - "command" : "61 00 FA 0A 00 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "deg", - "type" : "longint" - }, - "insulation" : { - "name" : "insulation", - "command" : "61 00 FA 01 0C 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "512" : "low", - "1024" : "normal", - "2048" : "good", - "3072" : "very good" - } - }, - "screed" : { - "name" : "screed", - "command" : "61 00 FA 01 1A 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "256" : "on" - } - }, - "t_screed_day1" : { - "name" : "screed_day1", - "command" : "61 00 FA 0B B9 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day2" : { - "name" : "screed_day2", - "command" : "61 00 FA 0B BA 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day3" : { - "name" : "screed_day3", - "command" : "61 00 FA 0B BB 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day4" : { - "name" : "screed_day4", - "command" : "61 00 FA 0B BC 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day5" : { - "name" : "screed_day5", - "command" : "61 00 FA 0B BD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day6" : { - "name" : "screed_day6", - "command" : "61 00 FA 0B BE 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day7" : { - "name" : "screed_day7", - "command" : "61 00 FA 0B BD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day8" : { - "name" : "screed_day8", - "command" : "61 00 FA 0B C0 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day9" : { - "name" : "screed_day9", - "command" : "61 00 FA 0B C1 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day10" : { - "name" : "screed_day10", - "command" : "61 00 FA 0B C2 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day11" : { - "name" : "screed_day11", - "command" : "61 00 FA 0B C3 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day12" : { - "name" : "screed_day12", - "command" : "61 00 FA 0B C4 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day13" : { - "name" : "screed_day13", - "command" : "61 00 FA 0B C5 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day14" : { - "name" : "screed_day14", - "command" : "61 00 FA 0B C6 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day15" : { - "name" : "screed_day15", - "command" : "61 00 FA 0B C7 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day16" : { - "name" : "screed_day16", - "command" : "61 00 FA 0B C8 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day17" : { - "name" : "screed_day17", - "command" : "61 00 FA 0B C9 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day18" : { - "name" : "screed_day18", - "command" : "61 00 FA 0B CA 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day19" : { - "name" : "screed_day19", - "command" : "61 00 FA 0B CB 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day20" : { - "name" : "screed_day20", - "command" : "61 00 FA 0B CC 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day21" : { - "name" : "screed_day21", - "command" : "61 00 FA 0B CD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day22" : { - "name" : "screed_day22", - "command" : "61 00 FA 0B CD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day23" : { - "name" : "screed_day23", - "command" : "61 00 FA 0B CF 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day24" : { - "name" : "screed_day24", - "command" : "61 00 FA 0B D0 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day25" : { - "name" : "screed_day25", - "command" : "61 00 FA 0B D1 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day26" : { - "name" : "screed_day26", - "command" : "61 00 FA 0B D2 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day27" : { - "name" : "screed_day27", - "command" : "61 00 FA 0B D3 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_screed_day28" : { - "name" : "screed_day28", - "command" : "61 00 FA 0B D4 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_out_lim_day" : { - "name" : "t_out_lim_day", - "command" : "61 00 FA 01 16 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_out_lim_night" : { - "name" : "t_out_lim_night", - "command" : "61 00 FA 01 17 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_day" : { - "name" : "t_flow_day", - "command" : "61 00 FA 01 29 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_night" : { - "name" : "t_flow_night", - "command" : "61 00 FA 01 2A 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "max_t_flow" : { - "name" : "max_t_flow", - "command" : "61 00 28 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "min_t_flow" : { - "name" : "min_t_flow", - "command" : "61 00 FA 01 2B 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "hc_adapt" : { - "name" : "hc_adapt", - "command" : "61 00 FA 01 15 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "256" : "on" - } - }, - "start_tout_cool" : { - "name" : "start_tout_cool", - "command" : "61 00 FA 13 5B 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "max_tout_cool" : { - "name" : "max_tout_cool", - "command" : "61 00 FA 13 5C 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_cool_start" : { - "name" : "t_flow_cool_start", - "command" : "61 00 FA 13 5D 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_cool_max" : { - "name" : "t_flow_cool_max", - "command" : "61 00 FA 13 5E 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "min_t_flow_cool" : { - "name" : "min_t_flow_cool", - "command" : "61 00 FA 13 63 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_flow_cool" : { - "name" : "t_flow_cool", - "command" : "61 00 FA 03 DD 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "cool_setpoint_adj" : { - "name" : "cool_setpoint_adj", - "command" : "61 00 FA 13 59 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "circ_pump_dhw" : { - "name" : "circ_pump_dhw", - "command" : "31 00 FA 01 82 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "circ_pump_interval" : { - "name" : "circ_pump_interval", - "command" : "31 00 FA 06 5E 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value" - }, - "anti_leg_day" : { - "name" : "anti_leg_day", - "command" : "31 00 FA 01 01 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "256" : "Monday", - "512" : "Tuesday", - "768" : "Wednesday", - "1024" : "Thursday", - "1280" : "Friday", - "1536" : "Saturday", - "1792" : "Sunday", - "2048" : "Everyday" - } - }, - "anti_leg_time" : { - "name" : "anti_leg_time", - "command" : "31 00 FA FD F4 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value" - }, - "anti_leg_temp" : { - "name" : "anti_leg_temp", - "command" : "31 00 FA 05 87 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "max_dhw_loading" : { - "name" : "max_dhw_loading", - "command" : "31 00 FA 01 80 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "min", - "type" : "longint" - }, - "dhw_off_time" : { - "name" : "dhw_off_time", - "command" : "31 00 FA 4E 3F 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "", - "type" : "float" - }, - "one_hot_water" : { - "name" : "one_hot_water", - "command" : "31 00 FA 01 44 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "longint", - "type" : "value", - "value_code" : { - "0" : "off", - "1" : "on" - } - }, - "timer_boh" : { - "name" : "timer_boh", - "command" : "31 00 FA 06 92 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "true", - "unit" : "min", - "type" : "longint" - }, - "t_reduced" : { - "name" : "t_reduced", - "command" : "61 00 08 00 00 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_absence" : { - "name" : "t_absence", - "command" : "61 00 FA 01 3D 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "t_room" :{ - "name" : "t_room", - "command" : "31 00 FA 00 11 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "false", - "unit" : "deg", - "type" : "float" - }, - "comp_active" : { - "name" : "comp_active", - "command" : "A1 00 61 00 00 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "longint", - "value_code" : { - "0" : "off", - "256" : "on" - } - }, - "pump_active" :{ - "name" : "pump_active", - "command" : "A1 00 FA FD AC 00 00", - "id" : "190", - "divisor" : "1", - "writable" : "false", - "unit" : "", - "type" : "longint", - "value_code" : { - "0" : "off", - "256" : "on" - } - }, - "temperature_spread_pwm" : { - "name" : "temperature_spread_pwm", - "command" : "A1 00 FA 06 DB 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - }, - "offset_t_flow" : { - "name" : "offset_t_flow", - "command" : "A1 00 FA 06 E2 00 00", - "id" : "190", - "divisor" : "10", - "writable" : "true", - "unit" : "deg", - "type" : "float" - } - } -} +{ + "version" : "2.0", + "commands":{ + "t_hs" : { + "name" : "t_hs", + "command" : "31 00 FA 01 D6 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_hs_set" : { + "name" : "t_hs_set", + "command" : "31 00 02 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "water_pressure" : { + "name" : "water_pressure", + "command" : "31 00 1C 00 00 00 00", + "id" : "190", + "divisor" : "1000", + "writable" : "false", + "unit" : "bar", + "type" : "float" + }, + "t_ext" : { + "name" : "t_ext", + "command" : "61 00 FA 0A 0C 00 00", + "id" : "310", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_dhw" : { + "name" : "t_dhw", + "command" : "31 00 0E 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_dhw_set" : { + "name" : "t_dhw_set", + "command" : "31 00 03 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_return" : { + "name" : "t_return", + "command" : "31 00 16 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "flow_rate" : { + "name" : "flow_rate", + "command" : "31 00 FA 01 DA 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "lh", + "type" : "longint" + }, + "t_hc" : { + "name" : "t_hc", + "command" : "C1 00 0F 00 00 00 00", + "id" : "610", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_hc_set" : { + "name" : "t_hc_set", + "command" : "61 00 04 00 00 00 00", + "id" : "310", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "status_pump" : { + "name" : "status_pump", + "command" : "31 00 FA 0A 8C 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "runtime_comp" : { + "name" : "runtime_comp", + "command" : "31 00 FA 06 A5 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "hour", + "type" : "longint" + }, + "runtime_pump" : { + "name" : "runtime_pump", + "command" : "31 00 FA 06 A4 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "longint" + }, + "posmix" : { + "name" : "posmix", + "command" : "31 00 FA 06 9B 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "percent", + "type" : "longint" + }, + "qboh" : { + "name" : "qboh", + "command" : "31 00 FA 09 1C 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "qchhp" : { + "name" : "qchhp", + "command" : "31 00 FA 09 20 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "qsc" : { + "name" : "qsc", + "command" : "31 00 FA 06 A6 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "qch" : { + "name" : "qch", + "command" : "31 00 FA 06 A7 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint" + }, + "qwp" : { + "name" : "qwp", + "command" : "31 00 FA 09 30 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "qdhw" : { + "name" : "qdhw", + "command" : "31 00 FA 09 2C 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "sw_vers_01" : { + "name" : "sw_vers_01", + "command" : "31 00 FA 01 99 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint" + }, + "sw_vers_02" : { + "name" : "sw_vers_02", + "command" : "31 00 FA C0 B4 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint" + }, + "sw_vers_03" : { + "name" : "sw_vers_03", + "command" : "31 00 FA 02 4B 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint" + }, + "mode_01" : { + "name" : "mode_01", + "command" : "31 00 FA 01 12 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "", + "type" : "int", + "value_code" : { + "1" : "standby", + "3" : "heat", + "4" : "sink", + "5" : "summer", + "17" : "cool", + "11" : "auto 1", + "12" : "auto 2" + } + }, + "tvbh2" : { + "name" : "tvbh2", + "command" : "31 00 FA C1 02", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "tliq2" : { + "name" : "tliq2", + "command" : "31 00 FA C1 03", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "tr2" : { + "name" : "tr2", + "command" : "31 00 FA C1 04", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "ta2" : { + "name" : "ta2", + "command" : "31 00 FA C1 05", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "tdhw2" : { + "name" : "tdhw2", + "command" : "31 00 FA C1 06", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "quiet" : { + "name" : "quiet", + "command" : "31 00 FA C1 07", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "activated", + "2" : "only at night" + } + }, + "mode" : { + "name" : "mode", + "command" : "31 00 FA C0 F6", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "longint", + "value_code" : { + "0" : "standby", + "1" : "heating", + "2" : "cooling", + "3" : "3" + } + }, + "pump" : { + "name" : "pump", + "command" : "31 00 FA C0 F7", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "percent", + "type" : "longint" + }, + "ext" : { + "name" : "ext", + "command" : "31 00 FA C0 F8", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "longint" + }, + "ehs" : { + "name" : "ehs", + "command" : "31 00 FA C0 F9", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "kwh", + "type" : "longint" + }, + "rt" : { + "name" : "rt", + "command" : "31 00 FA C0 FA", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "longint", + "type" : "longint" + }, + "bpv" : { + "name" : "bpv", + "command" : "31 00 FA C0 FB", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "percent", + "type" : "longint" + }, + "t_v1" : { + "name" : "t_v1", + "command" : "31 00 FA C0 FC", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_dhw1" : { + "name" : "t_dhw1", + "command" : "31 00 FA C0 FD", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_vbh" : { + "name" : "t_vbh", + "command" : "31 00 FA C0 FE", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_outdoor_ot1" : { + "name" : "t_outdoor_ot1", + "command" : "31 00 FA C0 FF", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "t_r1" : { + "name" : "t_r1", + "command" : "31 00 FA C1 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "v1" : { + "name" : "v1", + "command" : "31 00 FA C1 01", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "lh", + "type" : "longint" + }, + "t_room1_setpoint" : { + "name" : "t_room1_setpoint", + "command" : "31 00 05 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_room2_setpoint" : { + "name" : "t_room2_setpoint", + "command" : "31 00 06 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_room3_setpoint" : { + "name" : "t_room3_setpoint", + "command" : "31 00 07 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "heat_slope" : { + "name" : "heat_slope", + "command" : "31 00 FA 01 0E 00 00", + "id" : "190", + "divisor" : "100", + "writable" : "true", + "unit" : "", + "type" : "float" + }, + "t_dhw_setpoint1" : { + "name" : "t_dhw_setpoint1", + "command" : "31 00 13 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_dhw_setpoint2" : { + "name" : "t_dhw_setpoint2", + "command" : "31 00 FA 0A 06 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_dhw_setpoint3" : { + "name" : "t_dhw_setpoint3", + "command" : "31 00 FA 01 3E 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "hyst_hp" : { + "name" : "hyst_hp", + "command" : "31 00 FA 06 91 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_cooling" : { + "name" : "t_flow_cooling", + "command" : "31 00 FA 03 DD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "error" : { + "name" : "error", + "command" : "31 00 FA 13 88 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "value" + }, + "outdoor_type" : { + "name" : "outdoor_type", + "command" : "31 00 FA 06 9A 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "KW", + "type" : "value", + "value_code" : { + "0" : " ", + "1" : "4", + "2" : "6", + "3" : "8", + "4" : "11", + "5" : "14", + "6" : "16" + } + }, + "indoor_unit" : { + "name" : "indoor_unit", + "command" : "31 00 FA 06 99 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : " ", + "1" : "304", + "2" : "308", + "3" : "508", + "4" : "516" + } + }, + "func_heating" : { + "name" : "func_heating", + "command" : "A1 00 FA 06 D2 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "int", + "type" : "value" + }, + "hzu" : { + "name" : "hzu", + "command" : "31 00 FA 06 6C 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "equi_func" : { + "name" : "equi_func", + "command" : "A1 00 FA 06 D3 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "smart_grid" : { + "name" : "smart_grid", + "command" : "31 00 FA 06 93 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "modus_sg" : { + "name" : "modus_sg", + "command" : "31 00 FA 06 94 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "comfort", + "1" : "standard", + "2" : "eco" + } + }, + "ht_nt_func" : { + "name" : "ht_nt_func", + "command" : "31 00 FA 06 6F 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "deactivated", + "1" : "compressor off", + "2" : "compressor off, reserve heating off", + "3" : "all off" + } + }, + "ht_nt_contact" : { + "name" : "ht_nt_contact", + "command" : "31 00 FA 06 70 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "NO", + "1" : "NC" + } + }, + "room_therm" : { + "name" : "room_therm", + "command" : "31 00 FA 06 78 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "interlink" : { + "name" : "interlink", + "command" : "31 00 FA 06 79 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "air_purge" : { + "name" : "air_purge", + "command" : "31 00 FA 06 95 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "max_perf_pump" : { + "name" : "max_perf_pump", + "command" : "31 00 FA 06 7E 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "percent", + "type" : "longint" + }, + "min_perf_pump" : { + "name" : "min_perf_pump", + "command" : "31 00 FA 06 7F 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "percent", + "type" : "longint" + }, + "outside_conf" : { + "name" : "outside_conf", + "command" : "31 00 FA 09 61 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "sval", + "type" : "value", + "value_code" : { + "4" : "off", + "5" : "on" + } + }, + "storage_conf" : { + "name" : "storage_conf", + "command" : "31 00 FA 09 61 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "sval", + "type" : "value", + "value_code" : { + "0" : "off", + "2" : "thermostat", + "4" : "sensor" + } + }, + "pres_conf" : { + "name" : "pres_conf", + "command" : "31 00 FA 09 61 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "sval", + "type" : "value", + "value_code" : { + "10244" : "off", + "26628" : "on" + } + }, + "out_temp_adapt" : { + "name" : "out_temp_adapt", + "command" : "61 00 FA 0C 1F 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "power_dhw" : { + "name" : "power_dhw", + "command" : "31 00 FA 06 68 00 00", + "id" : "190", + "divisor" : "0.1", + "writable" : "true", + "unit" : "w", + "type" : "longint" + }, + "buh_s1_pow" : { + "name" : "buh_s1_pow", + "command" : "31 00 FA 06 69 00 00", + "id" : "190", + "divisor" : "0.1", + "writable" : "true", + "unit" : "w", + "type" : "longint" + }, + "buh_s2_pow" : { + "name" : "buh_s2_pow", + "command" : "31 00 FA 06 6A 00 00", + "id" : "190", + "divisor" : "0.1", + "writable" : "true", + "unit" : "w", + "type" : "longint" + }, + "power_biv" : { + "name" : "power_biv", + "command" : "31 00 FA 06 6B 00 00", + "id" : "190", + "divisor" : "0.1", + "writable" : "true", + "unit" : "w", + "type" : "longint" + }, + "tdiff_dhw_ch" : { + "name" : "tdiff_dhw_ch", + "command" : "31 00 FA 06 6D 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "", + "type" : "longint" + }, + "t_vbh1_max" : { + "name" : "t_vbh1_max", + "command" : "31 00 FA 06 6E 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "equi_temp" : { + "name" : "equi_temp", + "command" : "A1 00 FA 06 D4 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "quiet_mode" : { + "name" : "quiet_mode", + "command" : "31 00 FA 06 96 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on", + "2" : "only at night" + } + }, + "aux_fct" : { + "name" : "aux_fct", + "command" : "31 00 FA 06 96 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value" + }, + "aux_time" : { + "name" : "aux_time", + "command" : "31 00 FA 06 72 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "sec", + "type" : "longint" + }, + "t_dhw_1_min" : { + "name" : "t_dhw_1_min", + "command" : "31 00 FA 06 73 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "delta_t_ch" : { + "name" : "delta_t_ch", + "command" : "31 00 FA 06 83 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "v_var" : { + "name" : "v_var", + "command" : "31 00 FA 06 9C 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "lh", + "type" : "longint" + }, + "t_flow_ch_adj" : { + "name" : "t_flow_ch_adj", + "command" : "31 00 FA 06 A0 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_cool_adj" : { + "name" : "t_flow_cool_adj", + "command" : "31 00 FA 06 A1 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "min_pressure" : { + "name" : "min_pressure", + "command" : "31 00 FA 07 28 00 00", + "id" : "190", + "divisor" : "1000", + "writable" : "true", + "unit" : "bar", + "type" : "float" + }, + "max_pressure" : { + "name" : "max_pressure", + "command" : "31 00 FA 07 27 00 00", + "id" : "190", + "divisor" : "1000", + "writable" : "true", + "unit" : "bar", + "type" : "float" + }, + "setpoint_pressure" : { + "name" : "setpoint_pressure", + "command" : "31 00 FA 07 25 00 00", + "id" : "190", + "divisor" : "1000", + "writable" : "true", + "unit" : "bar", + "type" : "float" + }, + "max_pressure_drop" : { + "name" : "max_pressure_drop", + "command" : "31 00 FA 07 26 00 00", + "id" : "190", + "divisor" : "1000", + "writable" : "true", + "unit" : "bar", + "type" : "float" + }, + "hc_func" : { + "name" : "hc_func", + "command" : "61 00 FA 01 41 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "weather controlled", + "1" : "fixed value" + } + }, + "t_frost_protect" : { + "name" : "t_frost_protect", + "command" : "61 00 FA 0A 00 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "deg", + "type" : "longint" + }, + "insulation" : { + "name" : "insulation", + "command" : "61 00 FA 01 0C 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "512" : "low", + "1024" : "normal", + "2048" : "good", + "3072" : "very good" + } + }, + "screed" : { + "name" : "screed", + "command" : "61 00 FA 01 1A 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "256" : "on" + } + }, + "t_screed_day1" : { + "name" : "screed_day1", + "command" : "61 00 FA 0B B9 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day2" : { + "name" : "screed_day2", + "command" : "61 00 FA 0B BA 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day3" : { + "name" : "screed_day3", + "command" : "61 00 FA 0B BB 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day4" : { + "name" : "screed_day4", + "command" : "61 00 FA 0B BC 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day5" : { + "name" : "screed_day5", + "command" : "61 00 FA 0B BD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day6" : { + "name" : "screed_day6", + "command" : "61 00 FA 0B BE 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day7" : { + "name" : "screed_day7", + "command" : "61 00 FA 0B BD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day8" : { + "name" : "screed_day8", + "command" : "61 00 FA 0B C0 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day9" : { + "name" : "screed_day9", + "command" : "61 00 FA 0B C1 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day10" : { + "name" : "screed_day10", + "command" : "61 00 FA 0B C2 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day11" : { + "name" : "screed_day11", + "command" : "61 00 FA 0B C3 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day12" : { + "name" : "screed_day12", + "command" : "61 00 FA 0B C4 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day13" : { + "name" : "screed_day13", + "command" : "61 00 FA 0B C5 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day14" : { + "name" : "screed_day14", + "command" : "61 00 FA 0B C6 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day15" : { + "name" : "screed_day15", + "command" : "61 00 FA 0B C7 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day16" : { + "name" : "screed_day16", + "command" : "61 00 FA 0B C8 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day17" : { + "name" : "screed_day17", + "command" : "61 00 FA 0B C9 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day18" : { + "name" : "screed_day18", + "command" : "61 00 FA 0B CA 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day19" : { + "name" : "screed_day19", + "command" : "61 00 FA 0B CB 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day20" : { + "name" : "screed_day20", + "command" : "61 00 FA 0B CC 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day21" : { + "name" : "screed_day21", + "command" : "61 00 FA 0B CD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day22" : { + "name" : "screed_day22", + "command" : "61 00 FA 0B CD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day23" : { + "name" : "screed_day23", + "command" : "61 00 FA 0B CF 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day24" : { + "name" : "screed_day24", + "command" : "61 00 FA 0B D0 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day25" : { + "name" : "screed_day25", + "command" : "61 00 FA 0B D1 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day26" : { + "name" : "screed_day26", + "command" : "61 00 FA 0B D2 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day27" : { + "name" : "screed_day27", + "command" : "61 00 FA 0B D3 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_screed_day28" : { + "name" : "screed_day28", + "command" : "61 00 FA 0B D4 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_out_lim_day" : { + "name" : "t_out_lim_day", + "command" : "61 00 FA 01 16 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_out_lim_night" : { + "name" : "t_out_lim_night", + "command" : "61 00 FA 01 17 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_day" : { + "name" : "t_flow_day", + "command" : "61 00 FA 01 29 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_night" : { + "name" : "t_flow_night", + "command" : "61 00 FA 01 2A 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "max_t_flow" : { + "name" : "max_t_flow", + "command" : "61 00 28 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "min_t_flow" : { + "name" : "min_t_flow", + "command" : "61 00 FA 01 2B 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "hc_adapt" : { + "name" : "hc_adapt", + "command" : "61 00 FA 01 15 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "256" : "on" + } + }, + "start_tout_cool" : { + "name" : "start_tout_cool", + "command" : "61 00 FA 13 5B 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "max_tout_cool" : { + "name" : "max_tout_cool", + "command" : "61 00 FA 13 5C 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_cool_start" : { + "name" : "t_flow_cool_start", + "command" : "61 00 FA 13 5D 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_cool_max" : { + "name" : "t_flow_cool_max", + "command" : "61 00 FA 13 5E 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "min_t_flow_cool" : { + "name" : "min_t_flow_cool", + "command" : "61 00 FA 13 63 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_flow_cool" : { + "name" : "t_flow_cool", + "command" : "61 00 FA 03 DD 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "cool_setpoint_adj" : { + "name" : "cool_setpoint_adj", + "command" : "61 00 FA 13 59 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "circ_pump_dhw" : { + "name" : "circ_pump_dhw", + "command" : "31 00 FA 01 82 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "circ_pump_interval" : { + "name" : "circ_pump_interval", + "command" : "31 00 FA 06 5E 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value" + }, + "anti_leg_day" : { + "name" : "anti_leg_day", + "command" : "31 00 FA 01 01 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "256" : "Monday", + "512" : "Tuesday", + "768" : "Wednesday", + "1024" : "Thursday", + "1280" : "Friday", + "1536" : "Saturday", + "1792" : "Sunday", + "2048" : "Everyday" + } + }, + "anti_leg_time" : { + "name" : "anti_leg_time", + "command" : "31 00 FA FD F4 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value" + }, + "anti_leg_temp" : { + "name" : "anti_leg_temp", + "command" : "31 00 FA 05 87 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "max_dhw_loading" : { + "name" : "max_dhw_loading", + "command" : "31 00 FA 01 80 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "min", + "type" : "longint" + }, + "dhw_off_time" : { + "name" : "dhw_off_time", + "command" : "31 00 FA 4E 3F 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "", + "type" : "float" + }, + "one_hot_water" : { + "name" : "one_hot_water", + "command" : "31 00 FA 01 44 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "longint", + "type" : "value", + "value_code" : { + "0" : "off", + "1" : "on" + } + }, + "timer_boh" : { + "name" : "timer_boh", + "command" : "31 00 FA 06 92 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "true", + "unit" : "min", + "type" : "longint" + }, + "t_reduced" : { + "name" : "t_reduced", + "command" : "61 00 08 00 00 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_absence" : { + "name" : "t_absence", + "command" : "61 00 FA 01 3D 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "t_room" :{ + "name" : "t_room", + "command" : "31 00 FA 00 11 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "false", + "unit" : "deg", + "type" : "float" + }, + "comp_active" : { + "name" : "comp_active", + "command" : "A1 00 61 00 00 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint", + "value_code" : { + "0" : "off", + "256" : "on" + } + }, + "pump_active" :{ + "name" : "pump_active", + "command" : "A1 00 FA FD AC 00 00", + "id" : "190", + "divisor" : "1", + "writable" : "false", + "unit" : "", + "type" : "longint", + "value_code" : { + "0" : "off", + "256" : "on" + } + }, + "temperature_spread_pwm" : { + "name" : "temperature_spread_pwm", + "command" : "A1 00 FA 06 DB 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + }, + "offset_t_flow" : { + "name" : "offset_t_flow", + "command" : "A1 00 FA 06 E2 00 00", + "id" : "190", + "divisor" : "10", + "writable" : "true", + "unit" : "deg", + "type" : "float" + } + } +} From b402e4fe215693c325db5e825dc1cf79941410c0 Mon Sep 17 00:00:00 2001 From: segaura Date: Fri, 26 Mar 2021 19:58:15 +0100 Subject: [PATCH 20/23] fixed values (merging Spanni e7a2b46) --- etc/pyHPSU/commands_hpsu.json | 174 +++++++++++++++++----------------- pyHPSU.py | 5 +- 2 files changed, 90 insertions(+), 89 deletions(-) diff --git a/etc/pyHPSU/commands_hpsu.json b/etc/pyHPSU/commands_hpsu.json index 205618a..3a09cf5 100644 --- a/etc/pyHPSU/commands_hpsu.json +++ b/etc/pyHPSU/commands_hpsu.json @@ -100,8 +100,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "on" + "off" : "0", + "on" : "off" } }, "runtime_comp" : { @@ -221,13 +221,13 @@ "unit" : "", "type" : "int", "value_code" : { - "1" : "standby", - "3" : "heat", - "4" : "sink", - "5" : "summer", - "17" : "cool", - "11" : "auto 1", - "12" : "auto 2" + "standby" : "1", + "heat" : "3", + "sink" : "4", + "summer" : "5", + "cool" : "17", + "auto 1" : "11", + "auto 2" : "12" } }, "tvbh2" : { @@ -284,9 +284,9 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "activated", - "2" : "only at night" + "off" : "0", + "activated" :"1", + "only at night" : "2" } }, "mode" : { @@ -298,10 +298,10 @@ "unit" : "longint", "type" : "longint", "value_code" : { - "0" : "standby", - "1" : "heating", - "2" : "cooling", - "3" : "3" + "standby" :"0", + "heating" : "1", + "cooling" : "2", + "3": "3" } }, "pump" : { @@ -502,13 +502,13 @@ "unit" : "KW", "type" : "value", "value_code" : { - "0" : " ", - "1" : "4", - "2" : "6", - "3" : "8", - "4" : "11", - "5" : "14", - "6" : "16" + " " : "0", + "4" : "1", + "6" : "2", + "8" : "3", + "11" : "4", + "14" : "5", + "16" : "6" } }, "indoor_unit" : { @@ -520,11 +520,11 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : " ", - "1" : "304", - "2" : "308", - "3" : "508", - "4" : "516" + " " : "0", + "304" : "1", + "308" : "2", + "508" : "3", + "516" : "4" } }, "func_heating" : { @@ -545,8 +545,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "on" + "off" : "0", + "on" : "1" } }, "equi_func" : { @@ -558,8 +558,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "on" + "off" :"0", + "on" : "1" } }, "smart_grid" : { @@ -571,8 +571,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "on" + "off" : "0", + "on" : "1" } }, "modus_sg" : { @@ -584,9 +584,9 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "comfort", - "1" : "standard", - "2" : "eco" + "comfort" : "0", + "standard" : "1", + "eco" : "2" } }, "ht_nt_func" : { @@ -598,10 +598,10 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "deactivated", - "1" : "compressor off", - "2" : "compressor off, reserve heating off", - "3" : "all off" + "deactivated" : "0", + "compressor off" : "1", + "compressor off, reserve heating off" : "2", + "all off" : "3" } }, "ht_nt_contact" : { @@ -613,8 +613,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "NO", - "1" : "NC" + "NO" : "0", + "NC" : "1" } }, "room_therm" : { @@ -626,8 +626,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "on" + "off" : "0", + "on" : "1" } }, "interlink" : { @@ -639,8 +639,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "on" + "off" : "0", + "on" : "1" } }, "air_purge" : { @@ -652,8 +652,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "on" + "off": "0", + "on" : "1" } }, "max_perf_pump" : { @@ -683,8 +683,8 @@ "unit" : "sval", "type" : "value", "value_code" : { - "4" : "off", - "5" : "on" + "off" : "4", + "on" : "5" } }, "storage_conf" : { @@ -696,9 +696,9 @@ "unit" : "sval", "type" : "value", "value_code" : { - "0" : "off", - "2" : "thermostat", - "4" : "sensor" + "off" : "0", + "thermostat" : "2", + "sensor" : "4" } }, "pres_conf" : { @@ -710,8 +710,8 @@ "unit" : "sval", "type" : "value", "value_code" : { - "10244" : "off", - "26628" : "on" + "off" : "10244", + "on" : "26628" } }, "out_temp_adapt" : { @@ -795,9 +795,9 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "on", - "2" : "only at night" + "off" : "0", + "on" : "1", + "only at night" : "2" } }, "aux_fct" : { @@ -908,8 +908,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "weather controlled", - "1" : "fixed value" + "weather controlled" : "0", + "fixed value" : "1" } }, "t_frost_protect" : { @@ -930,11 +930,11 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "512" : "low", - "1024" : "normal", - "2048" : "good", - "3072" : "very good" + "off" : "0", + "low" : "512", + "normal" : "1024", + "good" : "2048", + "very good" : "3072" } }, "screed" : { @@ -946,8 +946,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "256" : "on" + "off" : "0", + "on" : "256" } }, "t_screed_day1" : { @@ -1265,8 +1265,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "256" : "on" + "off" : "0", + "on" :"256" } }, "start_tout_cool" : { @@ -1341,8 +1341,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "on" + "off" : "0", + "on" : "1" } }, "circ_pump_interval" : { @@ -1363,15 +1363,15 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "256" : "Monday", - "512" : "Tuesday", - "768" : "Wednesday", - "1024" : "Thursday", - "1280" : "Friday", - "1536" : "Saturday", - "1792" : "Sunday", - "2048" : "Everyday" + "off" : "0", + "monday" : "256", + "tuesday" : "512", + "wednesday" : "768", + "thursday" : "1024", + "friday" : "1280", + "saturday" : "1536", + "sunday" : "1792", + "everyday" : "2048" } }, "anti_leg_time" : { @@ -1419,8 +1419,8 @@ "unit" : "longint", "type" : "value", "value_code" : { - "0" : "off", - "1" : "on" + "off": "0", + "on" : "1" } }, "timer_boh" : { @@ -1468,8 +1468,8 @@ "unit" : "", "type" : "longint", "value_code" : { - "0" : "off", - "256" : "on" + "off" : "0", + "on" : "256" } }, "pump_active" :{ @@ -1481,8 +1481,8 @@ "unit" : "", "type" : "longint", "value_code" : { - "0" : "off", - "256" : "on" + "off" : "0", + "on" : "256" } }, "temperature_spread_pwm" : { diff --git a/pyHPSU.py b/pyHPSU.py index ce67268..ce2913f 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -478,8 +478,9 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): if not c["type"] == "value": setValue = float(setValue)*float(c["divisor"]) else: - logger.error('type "value" not implemented since yet') - return + if not setValue.isdigit(): + key=str(setValue) + setValue=c["value_code"][str(setValue)] i = 0 while i <= 3: From 5f15994a56976cf71d094be69969f860c4c9ee98 Mon Sep 17 00:00:00 2001 From: segaura Date: Sat, 27 Mar 2021 19:06:49 +0100 Subject: [PATCH 21/23] commands_hpsu.json fixed commands t_screed_day[7|22] aux_fct as per https://github.com/Spanni26/pyHPSU/issues/41 --- etc/pyHPSU/commands_hpsu.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/pyHPSU/commands_hpsu.json b/etc/pyHPSU/commands_hpsu.json index 3a09cf5..2ad3411 100644 --- a/etc/pyHPSU/commands_hpsu.json +++ b/etc/pyHPSU/commands_hpsu.json @@ -802,7 +802,7 @@ }, "aux_fct" : { "name" : "aux_fct", - "command" : "31 00 FA 06 96 00 00", + "command" : "31 00 FA 06 71 00 00", "id" : "190", "divisor" : "1", "writable" : "true", @@ -1006,7 +1006,7 @@ }, "t_screed_day7" : { "name" : "screed_day7", - "command" : "61 00 FA 0B BD 00 00", + "command" : "61 00 FA 0B BF 00 00", "id" : "190", "divisor" : "10", "writable" : "true", @@ -1141,7 +1141,7 @@ }, "t_screed_day22" : { "name" : "screed_day22", - "command" : "61 00 FA 0B CD 00 00", + "command" : "61 00 FA 0B CE 00 00", "id" : "190", "divisor" : "10", "writable" : "true", From 5ccd0bb87e92468a830b8cdaf636a0bf0a4146ad Mon Sep 17 00:00:00 2001 From: segaura Date: Sun, 4 Apr 2021 15:52:58 +0200 Subject: [PATCH 22/23] argparse, many fixes, 'desc' field in JSON output for commands with "values" --- HPSU/HPSU.py | 2 +- HPSU/canpi.py | 2 +- HPSU/plugins/mqtt.py | 2 + pyHPSU.py | 303 +++++++++++++++++-------------------------- 4 files changed, 124 insertions(+), 185 deletions(-) diff --git a/HPSU/HPSU.py b/HPSU/HPSU.py index ab2060c..1d7494c 100644 --- a/HPSU/HPSU.py +++ b/HPSU/HPSU.py @@ -63,7 +63,7 @@ def __init__(self, logger=None, driver=None, port=None, cmd=None, lg_code=None): # read all known commands command_details_hpsu = '%s/commands_hpsu.json' % self.pathCOMMANDS - self.logger.info("HPSU %s loading command details file: %s" % (cmd, command_details_hpsu)) + self.logger.info("HPSU %s, loading command details file: %s" % (cmd, command_details_hpsu)) with open(command_details_hpsu, 'rU',encoding='utf-8') as jsonfile: self.all_commands = json.load(jsonfile) self.command_dict=self.all_commands["commands"] diff --git a/HPSU/canpi.py b/HPSU/canpi.py index 1535b86..59bc841 100644 --- a/HPSU/canpi.py +++ b/HPSU/canpi.py @@ -78,7 +78,7 @@ def sendCommandWithID(self, cmd, setValue=None, priority=1): command = command+" %02X %02X" % (setValue >> 8, setValue & 0xff) if cmd["type"] == "value": setValue = int(setValue) - command = command+" 00 %02X" % (setValue) + command = command+" %02X %02X" % (setValue >> 8, setValue & 0xff) msg_data = [int(r, 16) for r in command.split(" ")] notTimeout = True diff --git a/HPSU/plugins/mqtt.py b/HPSU/plugins/mqtt.py index 22312f3..2d76730 100644 --- a/HPSU/plugins/mqtt.py +++ b/HPSU/plugins/mqtt.py @@ -75,6 +75,8 @@ def __init__(self, hpsu=None, logger=None, config_file=None): else: self.qos = "0" + # no need to create a different client name every time, because it only publish + logger.info("creating new mqtt client instance: " + self.clientname) self.client=mqtt.Client(self.clientname) self.client.on_publish = self.on_publish if self.username: diff --git a/pyHPSU.py b/pyHPSU.py index ce2913f..3e564bb 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -21,13 +21,14 @@ #sys.path.append('/usr/share/pyHPSU/HPSU') #sys.path.append('/usr/share/pyHPSU/plugins') import os -import getopt import time import locale +import uuid import importlib import logging from HPSU.HPSU import HPSU import configparser +import argparse import threading import csv import json @@ -38,11 +39,14 @@ SocketPort = 7060 logger = None n_hpsu = None +# global options object +options = None +# TODO remove in favor or options.driver driver = None +# TODO remove in favor or options.port port = None lg_code = None verbose = None -output_type = None mqtt_client = None mqtt_prefix = None mqtt_qos = 0 @@ -50,6 +54,8 @@ mqtt_addtimestamp = False mqttdaemon_command_topic = "command" mqttdaemon_status_topic = "status" +# unique randomized value per program execution that can be used where needed +execution_uuid = str(uuid.uuid4())[:8] def my_except_hook(exctype, value, traceback): if exctype == KeyboardInterrupt: @@ -58,13 +64,13 @@ def my_except_hook(exctype, value, traceback): sys.__excepthook__(exctype, value, traceback) def main(argv): + global options global logger global n_hpsu global driver global port global lg_code global verbose - global output_type global mqtt_client global mqtt_prefix global mqtt_qos @@ -74,46 +80,26 @@ def main(argv): global mqttdaemon_status_topic sys.excepthook = my_except_hook - cmd = [] - port = None - driver = "PYCAN" - verbose = "1" - show_help = False - # empty list, if none is specified with options and configuration, JSON default will be used - output_type = [] - upload = False - lg_code = "EN" + cmd = None languages = ["EN", "IT", "DE"] - 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 LOG_LEVEL_LIST = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] - # default to loggin.error if --log_level option not present - desired_log_level = logging.ERROR - # default log to stdout if no file specified - log_handler = logging.StreamHandler() # default log formatter log_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') #commands = [] #listCommands = [] global config config = configparser.ConfigParser() - 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={} - mqttdaemon_option_present = False # # get all plugins # @@ -126,101 +112,62 @@ def main(argv): 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 :") + 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", choices=languages, 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: - 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=", "log_level=", "config_file=", "mqtt_daemon"]) - except getopt.GetoptError: - print('pyHPSU.py -d DRIVER -c COMMAND') - print(' ') - print(' -a --auto do automatic 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: [' + ", ".join(PLUGIN_LIST) + '] 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(' --mqtt_daemon set up an mqtt daemon that subscribe to a command topic and executes received command on HPSU') - print(' -g --log set the log to file [filename]') - print(' --log_level set the log level to [' + ", ".join(LOG_LEVEL_LIST) + ']') - 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.append("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"): - if arg.upper() not in output_type: - output_type.append(arg.upper()) - if not "output_type" in options_list or options_list["output_type"] is None or options_list["output_type"]=="": - options_list["output_type"]=arg.upper() - else: - options_list["output_type"]+=", " + arg.upper() - - elif opt in ("-l", "--language"): - lg_code = arg.upper() - options_list["language"]=arg.upper() - - elif opt in ("--mqtt_daemon"): - mqttdaemon_option_present = True - - elif opt in ("-g", "--log"): - log_handler = logging.FileHandler(arg) - options_list["log_file"]=arg - - elif opt in ("--log_level"): - desired_log_level = arg.upper() - if not desired_log_level in LOG_LEVEL_LIST: - print("Error, " + arg + " is not a valid value for log_level option, use [" + ", ".join(LOG_LEVEL_LIST)+ "]") - sys.exit(2) - options_list["cmd"]=cmd - - # if no log file has been specified and driver is HPSUD then log nothing - if options_list.get("log_file") is None and driver == "HPSUD": - log_handler = logging.NullHandler + options = parser.parse_args() + except IOError as e: + parser.error(e) + if (options == None): + print(parser.usage) + exit(0) + else: + cmd = [] if options.cmd is None else options.cmd + driver = options.driver + backup_mode = options.backup_file is not None + if backup_mode: + options.output_type.append("BACKUP") + restore_mode = options.restore_file is not None + # 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.append("JSON") + read_from_conf_file = options.conf_file is not None + lg_code = options.language.upper() + port = options.port + verbose = options.verbose + # if no log file has been specified and driver is HPSUD then log nothing + if options.log_file is None and 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(desired_log_level) + _log_handler.setFormatter(log_formatter) + logger.addHandler(_log_handler) + logger.setLevel(options.log_level) if verbose == "2": locale.setlocale(locale.LC_ALL, '') @@ -229,33 +176,29 @@ def main(argv): if not read_from_conf_file: # ...set the default one... # NOTE: other modules may need to load it later - conf_file=default_conf_file + options.conf_file=default_conf_file # ...but auto or mqttdaemon mode needs it loaded... - if auto or mqttdaemon_option_present: + 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: - if conf_file==None: - logger.critical("please provide a config file") + try: + with open(options.conf_file) as f: + config.read_file(f) + except IOError: + logger.critical("config file not found") sys.exit(9) - else: - try: - with open(conf_file) as f: - config.read_file(f) - except IOError: - logger.critical("config file not found") - sys.exit(9) - config.read(conf_file) + config.read(options.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 len(output_type)==0 and config.has_option('PYHPSU','OUTPUT_TYPE'): - output_type.append(config['PYHPSU']['OUTPUT_TYPE']) + if len(options.output_type)==0 and config.has_option('PYHPSU','OUTPUT_TYPE'): + options.output_type.append(config['PYHPSU']['OUTPUT_TYPE']) if config.has_option('MQTT', 'BROKER'): mqtt_brokerhost = config['MQTT']['BROKER'] @@ -322,38 +265,19 @@ def main(argv): logger.info("configuration parsing complete") - # default output_type if not specified - if len(output_type)==0: - output_type.append("JSON") - # # now we should have all options...let's check them # - # Check driver - if driver not in ["ELM327", "PYCAN", "EMU", "HPSUD"]: - logger.critical("please specify a correct driver [ELM327, PYCAN, EMU, HPSUD] ") - sys.exit(9) - if driver == "ELM327" and port == "": logger.critical("please specify a correct port for the ELM327 device ") sys.exit(9) - # Check output type - for plugin in output_type: - if plugin not in PLUGIN_LIST: - logger.critical("please specify a correct output_type [" + PLUGIN_STRING + "], " + plugin + " does not exist") - sys.exit(9) - - # Check Language - if lg_code not in languages: - logger.critical("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: + 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 @@ -370,16 +294,16 @@ def main(argv): # # Print help # - if show_help: + if options.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: + 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)'))) - except KeyError: + else: error_message = """!!!!!! No translation for "%12s" !!!!!!!""" % (n_hpsu.command_dict[cmd]['name']) print(error_message) logger.error(error_message) @@ -394,10 +318,11 @@ def main(argv): # now its time to call the hpsu and do the REAL can query # and handle the data as configured # - if mqttdaemon_option_present: - logger.info("creating new mqtt client instance: " + mqtt_clientname) + if options.mqtt_daemon: + _mqttdaemon_clientname = mqtt_clientname + "-mqttdaemon-" + execution_uuid + 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(mqtt_clientname+"-mqttdaemon") + mqtt_client = mqtt.Client(_mqttdaemon_clientname) if mqtt_username: mqtt_client.username_pw_set(mqtt_username, password=mqtt_password) mqtt_client.enable_logger() @@ -412,13 +337,13 @@ def main(argv): # this blocks execution #mqtt_client.loop_forever() - if auto: + if options.auto: mqtt_client.loop_start() if 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 auto: + read_can(n_hpsu.backup_commands, verbose, options.output_type) + elif options.auto: while loop: ticker+=1 collected_cmds=[] @@ -429,42 +354,39 @@ def main(argv): 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 = threading.Thread(target=read_can, args=(collected_cmds,verbose,options.output_type))' % (period)) exec('thread_%s.start()' % (period)) time.sleep(1) elif restore_mode: restore_commands=[] try: - with open(backup_file, 'rU') as jsonfile: + 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=driver, logger=logger, port=port, cmd=restore_commands, lg_code=lg_code) - read_can(driver, logger, port, restore_commands, lg_code,verbose,output_type) + read_can(restore_commands, verbose, options.output_type) except FileNotFoundError: logger.error("No such file or directory!!!") sys.exit(1) # 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 mqttdaemon_option_present): + elif not (len(cmd)==0 and options.mqtt_daemon): 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) + read_can(cmd, 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() -def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): - global backup_file + +def read_can(cmd, verbose, output_type): + global options + global logger global mqtt_prefix global mqttdaemon_status_topic global mqtt_client - # really needed? Driver is checked above - #if not driver: - # logger.critical("Error, please specify driver [ELM327 or PYCAN, EMU, HPSUD]") - # sys.exit(9) - arrResponse = [] for c in n_hpsu.commands: @@ -480,7 +402,7 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): else: if not setValue.isdigit(): key=str(setValue) - setValue=c["value_code"][str(setValue)] + setValue=c["value_code"][key] i = 0 while i <= 3: @@ -491,7 +413,19 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): response = n_hpsu.parseCommand(cmd=c, response=rc, verbose=verbose) resp = n_hpsu.umConversion(cmd=c, response=response, verbose=verbose) - arrResponse.append({"name":c["name"], "resp":resp, "timestamp":response["timestamp"]}) + if "value_code" in c: + # FIXME special treatment is needed for commands sharing the same byte 'ouside_conf' and 'storage' conf + # while not fixed a warning is raised + # e.g. HPSU returns a value of 26628 for both of them and the two values have to be extracted from + # different part of the number + if resp in dict(map(reversed, c["value_code"].items())): + _resp_description = dict(map(reversed, c["value_code"].items()))[resp] + else: + _resp_description = 'unable to decode value ' + resp + logger.warning("command \"" + c["name"] + "\" " + _resp_description) + arrResponse.append({"name":c["name"], "resp":resp, "timestamp":response["timestamp"], "desc":_resp_description}) + else: + arrResponse.append({"name":c["name"], "resp":resp, "timestamp":response["timestamp"]}) else: i += 1 time.sleep(2.0) @@ -507,12 +441,12 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): for r in arrResponse: print("%s,%s,%s" % (r["timestamp"], r["name"], r["resp"])) elif output_type_name == "BACKUP": - error_message = "Writing Backup to " + str(backup_file) + error_message = "Writing Backup to " + str(options.backup_file) print(error_message) logger.info(error_message) try: - with open(backup_file, 'w') as outfile: + with open(options.backup_file, 'w') as outfile: json.dump(arrResponse, outfile, sort_keys = True, indent = 4, ensure_ascii = False) except FileNotFoundError: error_message = "No such file or directory!!!" @@ -524,14 +458,17 @@ def read_can(driver,logger,port,cmd,lg_code,verbose,output_type): if mqtt_addtimestamp: # use the same format as JSON output # with timestamp included, retain=true become more interesting - mqtt_client.publish(mqtt_prefix + "/" + r["name"], "{'name': '%s', 'resp': '%s', 'timestamp': %s}" % (r["name"], r["resp"], r["timestamp"]), qos=mqtt_qos, retain=mqtt_retain) + if "desc" in r: + mqtt_client.publish(mqtt_prefix + "/" + r["name"], "{'name': '%s', 'resp': '%s', 'timestamp': %s, 'desc': '%s'}" % (r["name"], r["resp"], r["timestamp"], r["desc"]), qos=mqtt_qos, retain=mqtt_retain) + else: + mqtt_client.publish(mqtt_prefix + "/" + r["name"], "{'name': '%s', 'resp': '%s', 'timestamp': %s}" % (r["name"], r["resp"], r["timestamp"]), qos=mqtt_qos, retain=mqtt_retain) else: mqtt_client.publish(mqtt_prefix + "/" + r["name"], r["resp"], qos=mqtt_qos, retain=mqtt_retain) else: module_name=output_type_name.lower() module = importlib.import_module("HPSU.plugins." + module_name) - hpsu_plugin = module.export(hpsu=n_hpsu, logger=logger, config_file=conf_file) + hpsu_plugin = module.export(hpsu=n_hpsu, logger=logger, config_file=options.conf_file) hpsu_plugin.pushValues(vars=arrResponse) def on_disconnect(client, userdata,rc=0): @@ -539,12 +476,12 @@ def on_disconnect(client, userdata,rc=0): client.loop_stop() def on_mqtt_message(client, userdata, message): + global options global logger global driver global port global lg_code global verbose - global output_type global n_hpsu logger.debug("complete topic: " + message.topic) @@ -560,19 +497,19 @@ def on_mqtt_message(client, userdata, message): logger.info("setup HPSU to accept commands") n_hpsu = HPSU(driver=driver, logger=logger, port=port, cmd=hpsu_command_list, lg_code=lg_code) logger.info("send command to hpsu: " + hpsu_command_string) - #exec('thread_mqttdaemon = threading.Thread(target=read_can(driver, logger, port, hpsu_command_list, lg_code,verbose,["MQTTDAEMON"]))') + #exec('thread_mqttdaemon = threading.Thread(target=read_can(hpsu_command_list, verbose, ["MQTTDAEMON"]))') #exec('thread_mqttdaemon.start()') - read_can(driver, logger, port, hpsu_command_list, lg_code,verbose,["MQTTDAEMON"]) + read_can(hpsu_command_list, 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(driver, logger, port, hpsu_command_string_reread_after_write_list, lg_code,verbose,["MQTTDAEMON"]))') + #exec('thread_mqttdaemon_reread = threading.Thread(target=read_can(hpsu_command_string_reread_after_write_list, verbose, ["MQTTDAEMON"]))') #exec('thread_mqttdaemon_reread.start()') logger.info("send same command in read mode to hpsu: " + hpsu_command_string) - read_can(driver, logger, port, hpsu_command_string_reread_after_write_list, lg_code,verbose,["MQTTDAEMON"]) + read_can(hpsu_command_string_reread_after_write_list, verbose, ["MQTTDAEMON"]) # restarts the loop - if auto: + if options.auto: mqtt_client.loop_start() if __name__ == "__main__": From c012194148547ecc0bbf9b6aa6bba583d53db54f Mon Sep 17 00:00:00 2001 From: segaura Date: Sun, 4 Apr 2021 19:48:38 +0200 Subject: [PATCH 23/23] options fields used where possible, configparser more compact instructions --- HPSU/HPSU.py | 4 +- HPSU/cantcp.py | 2 - HPSU/plugins/mqtt.py | 71 +++++------------ pyHPSU.py | 180 ++++++++++++++----------------------------- 4 files changed, 81 insertions(+), 176 deletions(-) diff --git a/HPSU/HPSU.py b/HPSU/HPSU.py index 1d7494c..2716a08 100644 --- a/HPSU/HPSU.py +++ b/HPSU/HPSU.py @@ -42,7 +42,7 @@ def __init__(self, logger=None, driver=None, port=None, cmd=None, lg_code=None): if not self.listCommands: #if we don't get a dict with commands # get language, if non given, take it from the system - LANG_CODE = lg_code.upper()[0:2] if lg_code else locale.getdefaultlocale()[0].split('_')[0].upper() + LANG_CODE = lg_code[0:2] if lg_code else locale.getdefaultlocale()[0].split('_')[0].upper() hpsuDict = {} # read the translation file. if it doesn't exist, take the english one @@ -220,6 +220,8 @@ def umConversion(self, cmd, response, verbose): resp = str(response["resp"]) else: resp = str(response["resp"]) + # TODO replaces resp with the decoded value, major breaking change to be discussed + # meanwhile, a 'desc' field is added to the output json #if cmd["value_code"]: # resp=cmd["value_code"][resp] return resp diff --git a/HPSU/cantcp.py b/HPSU/cantcp.py index 9d1050d..b423e74 100644 --- a/HPSU/cantcp.py +++ b/HPSU/cantcp.py @@ -9,8 +9,6 @@ import uuid import json -SocketPort = 7060 - class CanTCP(object): sock = None hpsu = None diff --git a/HPSU/plugins/mqtt.py b/HPSU/plugins/mqtt.py index 2d76730..fd4da6f 100644 --- a/HPSU/plugins/mqtt.py +++ b/HPSU/plugins/mqtt.py @@ -33,50 +33,26 @@ def __init__(self, hpsu=None, logger=None, config_file=None): else: sys.exit(9) - # MQTT hostname or IP - if self.config.has_option('MQTT', 'BROKER'): - self.brokerhost = self.config['MQTT']['BROKER'] - else: - self.brokerhost = 'localhost' - - # MQTT broker port - if self.config.has_option('MQTT', 'PORT'): - self.brokerport = int(self.config['MQTT']['PORT']) - else: - self.brokerport = 1883 - - # MQTT client name - if self.config.has_option('MQTT', 'CLIENTNAME'): - self.clientname = self.config['MQTT']['CLIENTNAME'] - else: - self.clientname = 'rotex' - # MQTT Username - if self.config.has_option('MQTT', 'USERNAME'): - self.username = self.config['MQTT']['USERNAME'] - else: - self.username = None - self.hpsu.logger.error("Username not set!!!!!") - - #MQTT Password - if self.config.has_option('MQTT', "PASSWORD"): - self.password = self.config['MQTT']['PASSWORD'] - else: - self.password="None" - - #MQTT Prefix - if self.config.has_option('MQTT', "PREFIX"): - self.prefix = self.config['MQTT']['PREFIX'] - else: - self.prefix = "" - - #MQTT QOS - if self.config.has_option('MQTT', "QOS"): - self.qos = self.config['MQTT']['QOS'] - else: - self.qos = "0" + # object to store entire MQTT config section + self.mqtt_config = self.config['MQTT'] + self.brokerhost = self.mqtt_config.get('BROKER', 'localhost') + self.brokerport = self.mqtt_config.getint('PORT', 1883) + self.clientname = self.mqtt_config.get('CLIENTNAME', 'rotex') + self.username = self.mqtt_config.get('USERNAME', None) + if self.username is None: + self.logger.error("Username not set!!!!!") + self.password = self.mqtt_config.get('PASSWORD', "NoPasswordSpecified") + self.prefix = self.mqtt_config.get('PREFIX', "") + self.qos = self.mqtt_config.getint('QOS', 0) + # every other value implies false + self.retain = self.mqtt_config.get('RETAIN', "NOT TRUE") == "True" + # every other value implies false + self.addtimestamp = self.mqtt_config.get('ADDTIMESTAMP', "NOT TRUE") == "True" + + self.logger.info("configuration parsing complete") # no need to create a different client name every time, because it only publish - logger.info("creating new mqtt client instance: " + self.clientname) + self.logger.info("creating new mqtt client instance: " + self.clientname) self.client=mqtt.Client(self.clientname) self.client.on_publish = self.on_publish if self.username: @@ -88,9 +64,10 @@ def on_publish(self,client,userdata,mid): self.hpsu.logger.debug("mqtt output plugin data published, mid: " + str(mid)) def pushValues(self, vars=None): - + #self.msgs=[] for r in vars: + self.logger.info("connecting to broker: " + self.brokerhost + ", port: " + str(self.brokerport)) self.client.connect(self.brokerhost, port=self.brokerport) msgs=[] if self.prefix: @@ -100,10 +77,4 @@ def pushValues(self, vars=None): ret=self.client.publish(r['name'],payload=r['resp'], qos=int(self.qos)) topic=r['name'] msg={'topic':topic,'payload':r['resp'], 'qos':self.qos, 'retain':False} - self.client.disconnect() - - - - - - + self.client.disconnect() \ No newline at end of file diff --git a/pyHPSU.py b/pyHPSU.py index 3e564bb..fa1a7c9 100644 --- a/pyHPSU.py +++ b/pyHPSU.py @@ -27,26 +27,18 @@ import importlib import logging from HPSU.HPSU import HPSU -import configparser import argparse +import configparser import threading -import csv import json import paho.mqtt.publish as publish import paho.mqtt.subscribe as subscribe import paho.mqtt.client as mqtt -SocketPort = 7060 logger = None n_hpsu = None # global options object options = None -# TODO remove in favor or options.driver -driver = None -# TODO remove in favor or options.port -port = None -lg_code = None -verbose = None mqtt_client = None mqtt_prefix = None mqtt_qos = 0 @@ -67,10 +59,6 @@ def main(argv): global options global logger global n_hpsu - global driver - global port - global lg_code - global verbose global mqtt_client global mqtt_prefix global mqtt_qos @@ -96,10 +84,6 @@ def main(argv): global config config = configparser.ConfigParser() PLUGIN_PATH="/usr/lib/python3/dist-packages/HPSU/plugins" - backup_mode=False - restore_mode=False - global options_list - options_list={} # # get all plugins # @@ -124,7 +108,7 @@ def main(argv): 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", choices=languages, default="EN", help="set the language to use [%s], default is \"EN\" " % " ".join(languages)) + 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") @@ -140,22 +124,16 @@ def main(argv): print(parser.usage) exit(0) else: - cmd = [] if options.cmd is None else options.cmd - driver = options.driver - backup_mode = options.backup_file is not None - if backup_mode: - options.output_type.append("BACKUP") - restore_mode = options.restore_file is not None # 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.append("JSON") + 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 - lg_code = options.language.upper() - port = options.port - verbose = options.verbose # if no log file has been specified and driver is HPSUD then log nothing - if options.log_file is None and driver == "HPSUD": + 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) @@ -169,7 +147,7 @@ def main(argv): logger.addHandler(_log_handler) logger.setLevel(options.log_level) - if verbose == "2": + if options.verbose == "2": locale.setlocale(locale.LC_ALL, '') # if no config file option is present... @@ -191,84 +169,42 @@ def main(argv): logger.critical("config file not found") sys.exit(9) config.read(options.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 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']) - if config.has_option('MQTT', 'BROKER'): - mqtt_brokerhost = config['MQTT']['BROKER'] - else: - mqtt_brokerhost = 'localhost' - - if config.has_option('MQTT', 'PORT'): - mqtt_brokerport = int(config['MQTT']['PORT']) - else: - mqtt_brokerport = 1883 - - if config.has_option('MQTT', 'CLIENTNAME'): - mqtt_clientname = config['MQTT']['CLIENTNAME'] - else: - mqtt_clientname = 'rotex' - - if config.has_option('MQTT', 'USERNAME'): - mqtt_username = config['MQTT']['USERNAME'] - else: - mqtt_username = None - logger.error("Username not set!!!!!") - - if config.has_option('MQTT', "PASSWORD"): - mqtt_password = config['MQTT']['PASSWORD'] - else: - mqtt_password="None" - - if config.has_option('MQTT', "PREFIX"): - mqtt_prefix = config['MQTT']['PREFIX'] - else: - mqtt_prefix = "" - - #MQTT MQTT Daemon command topic - if config.has_option('MQTT', "COMMAND"): - mqttdaemon_command_topic = config['MQTT']['COMMAND'] -# default already set -# else: -# mqttdaemon_command_topic = "" - - #MQTT MQTT Daemon status topic + # 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 - if config.has_option('MQTT', "STATUS"): - mqttdaemon_status_topic = config['MQTT']['STATUS'] -# default already set -# else: -# mqttdaemon_status_topic = "" - - if config.has_option('MQTT', "QOS"): - mqtt_qos = int(config['MQTT']['QOS']) - else: - mqtt_qos = 0 - - if config.has_option('MQTT', "RETAIN"): - # every other value implies false - mqtt_retain = config['MQTT']['RETAIN'] == "True" - else: - mqtt_retain = False - - if config.has_option('MQTT', "ADDTIMESTAMP"): - # every other value implies false - mqtt_addtimestamp = config['MQTT']['ADDTIMESTAMP'] == "True" - else: - mqtt_addtimestamp = False + 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 driver == "ELM327" and port == "": + if options.driver == "ELM327" and options.port == "": logger.critical("please specify a correct port for the ELM327 device ") sys.exit(9) @@ -295,7 +231,7 @@ def main(argv): # Print help # if options.show_help: - n_hpsu = HPSU(driver=driver, logger=logger, port=port, cmd=cmd, lg_code=lg_code) + 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')) @@ -328,8 +264,8 @@ def main(argv): mqtt_client.enable_logger() mqtt_client.on_message=on_mqtt_message - logger.info("connecting to broker: " + mqtt_brokerhost) - mqtt_client.connect(mqtt_brokerhost) + 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) @@ -340,9 +276,10 @@ def main(argv): if options.auto: mqtt_client.loop_start() - if backup_mode: - n_hpsu = HPSU(driver=driver, logger=logger, port=port, cmd=cmd, lg_code=lg_code) - read_can(n_hpsu.backup_commands, verbose, options.output_type) + # 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 @@ -353,27 +290,28 @@ def main(argv): 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=(collected_cmds,verbose,options.output_type))' % (period)) + 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) - elif restore_mode: + # 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=driver, logger=logger, port=port, cmd=restore_commands, lg_code=lg_code) - read_can(restore_commands, verbose, options.output_type) + 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(1) # 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=driver, logger=logger, port=port, cmd=cmd, lg_code=lg_code) - read_can(cmd, verbose, options.output_type) + 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: @@ -410,8 +348,8 @@ def read_can(cmd, verbose, output_type): if rc != "KO": i = 4 if not setValue: - response = n_hpsu.parseCommand(cmd=c, response=rc, verbose=verbose) - resp = n_hpsu.umConversion(cmd=c, response=response, verbose=verbose) + response = n_hpsu.parseCommand(cmd=c, response=rc, verbose=options.verbose) + resp = n_hpsu.umConversion(cmd=c, response=response, verbose=options.verbose) if "value_code" in c: # FIXME special treatment is needed for commands sharing the same byte 'ouside_conf' and 'storage' conf @@ -471,17 +409,13 @@ def read_can(cmd, verbose, output_type): hpsu_plugin = module.export(hpsu=n_hpsu, logger=logger, config_file=options.conf_file) hpsu_plugin.pushValues(vars=arrResponse) -def on_disconnect(client, userdata,rc=0): +def on_disconnect(client, userdata, rc=0): logger.debug("mqtt disConnected: result code " + str(rc)) client.loop_stop() def on_mqtt_message(client, userdata, message): global options global logger - global driver - global port - global lg_code - global verbose global n_hpsu logger.debug("complete topic: " + message.topic) @@ -495,19 +429,19 @@ def on_mqtt_message(client, userdata, message): hpsu_command_string = mqtt_command + ":" + mqtt_value hpsu_command_list = [hpsu_command_string] logger.info("setup HPSU to accept commands") - n_hpsu = HPSU(driver=driver, logger=logger, port=port, cmd=hpsu_command_list, lg_code=lg_code) + 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, verbose, ["MQTTDAEMON"]))') + #exec('thread_mqttdaemon = threading.Thread(target=read_can(hpsu_command_list, options.verbose, ["MQTTDAEMON"]))') #exec('thread_mqttdaemon.start()') - read_can(hpsu_command_list, verbose, ["MQTTDAEMON"]) + 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, verbose, ["MQTTDAEMON"]))') + #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, verbose, ["MQTTDAEMON"]) + read_can(hpsu_command_string_reread_after_write_list, options.verbose, ["MQTTDAEMON"]) # restarts the loop if options.auto: mqtt_client.loop_start()