diff --git a/README.md b/README.md index f40a9c36..96ab3409 100755 --- a/README.md +++ b/README.md @@ -256,8 +256,8 @@ print(parameters.get("ID_Ba_Hz_akt").options()) # returns a list of possible val # Now we increase the heating controller target temperature by 2 Kelvin heating_offset = l.holdings.get(2) # Get an object for the offset -heating_offset.value = 2.0 # Set the desired value -l.holdings["heating_mode"] = "Offset" # Set the value to activate the offset mode +heating_offset.value = 2.0 # Queue the desired value by setting the field's value +l.holdings["heating_mode"] = "Offset" # Queue the value to activate the offset mode l.write() # Write down the values to the heatpump ``` diff --git a/luxtronik/__init__.py b/luxtronik/__init__.py index 9f5fa168..278a5516 100755 --- a/luxtronik/__init__.py +++ b/luxtronik/__init__.py @@ -6,7 +6,7 @@ import logging -from luxtronik.common import get_host_lock +from luxtronik.common import LuxtronikSettings, get_host_lock # noqa: F401 from luxtronik.discover import discover # noqa: F401 from luxtronik.cfi import ( diff --git a/luxtronik/cfi/calculations.py b/luxtronik/cfi/calculations.py index 784f9be3..986e7e8c 100644 --- a/luxtronik/cfi/calculations.py +++ b/luxtronik/cfi/calculations.py @@ -8,10 +8,11 @@ CALCULATIONS_DEFINITIONS_LIST, CALCULATIONS_OFFSET, CALCULATIONS_DEFAULT_DATA_TYPE, + CALCULATIONS_OUTDATED, ) from luxtronik.cfi.constants import CALCULATIONS_FIELD_NAME -from luxtronik.data_vector import DataVector +from luxtronik.cfi.vector import DataVectorConfig from luxtronik.datatypes import Base @@ -24,28 +25,16 @@ CALCULATIONS_DEFAULT_DATA_TYPE ) -class Calculations(DataVector): +class Calculations(DataVectorConfig): """Class that holds all calculations.""" name = CALCULATIONS_FIELD_NAME definitions = CALCULATIONS_DEFINITIONS - - _obsolete = { - "ID_WEB_SoftStand": "get_firmware_version()" - } - - def __init__(self): - super().__init__() - for d in CALCULATIONS_DEFINITIONS: - self._data.add(d, d.create_field()) - - @property - def calculations(self): - return self._data + _outdated = CALCULATIONS_OUTDATED def get_firmware_version(self): """Get the firmware version as string.""" - return "".join([super(Calculations, self).get(i).value for i in range(81, 91)]) + return "".join([str(super(Calculations, self).get(i).value) for i in range(81, 91)]) def _get_firmware_version(self): """Get the firmware version as string like in previous versions.""" diff --git a/luxtronik/cfi/interface.py b/luxtronik/cfi/interface.py index 0d030f3b..f2b2bea8 100644 --- a/luxtronik/cfi/interface.py +++ b/luxtronik/cfi/interface.py @@ -5,7 +5,7 @@ import struct import time -from luxtronik.common import get_host_lock +from luxtronik.common import LuxtronikSettings, get_host_lock from luxtronik.cfi.constants import ( LUXTRONIK_DEFAULT_PORT, LUXTRONIK_PARAMETERS_WRITE, @@ -162,23 +162,27 @@ def _write_and_read(self, parameters, data): return self._read(data) def _write(self, parameters): - for index, value in parameters.queue.items(): - if not isinstance(index, int) or not isinstance(value, int): - LOGGER.warning( - "%s: Parameter id '%s' or value '%s' invalid!", - self._host, - index, - value, - ) - continue - LOGGER.info("%s: Parameter '%d' set to '%s'", self._host, index, value) - self._send_ints(LUXTRONIK_PARAMETERS_WRITE, index, value) - cmd = self._read_int() - LOGGER.debug("%s: Command %s", self._host, cmd) - val = self._read_int() - LOGGER.debug("%s: Value %s", self._host, val) - # Flush queue after writing all values - parameters.queue = {} + if not isinstance(parameters, Parameters): + LOGGER.error(f"Only parameters are writable!"): + return + for definition, field in parameters.items(): + if field.write_pending: + field.write_pending = False + value = field.raw + if not isinstance(definition.index, int) or not field.check_for_write(parameters.safe): + LOGGER.warning( + "%s: Parameter id '%s' or value '%s' invalid!", + self._host, + definition.index, + value, + ) + continue + LOGGER.info("%s: Parameter '%d' set to '%s'", self._host, definition.index, value) + self._send_ints(LUXTRONIK_PARAMETERS_WRITE, definition.index, value) + cmd = self._read_int() + LOGGER.debug("%s: Command %s", self._host, cmd) + val = self._read_int() + LOGGER.debug("%s: Value %s", self._host, val) # Give the heatpump a short time to handle the value changes/calculations: time.sleep(WAIT_TIME_AFTER_PARAMETER_WRITE) @@ -274,17 +278,20 @@ def _parse(self, data_vector, raw_data): undefined = {i for i in range(0, raw_len)} # integrate the data into the fields - for pair in data_vector.data.pairs(): + for pair in data_vector.data.items(): definition, field = pair # skip this field if there are not enough data next_idx = definition.index + definition.count if next_idx > raw_len: # not enough registers - field.raw = None + if not LuxtronikSettings.preserve_last_read_value_on_fail: + field.raw = None continue # remove all used indices from the list of undefined indices for index in range(definition.index, next_idx): undefined.discard(index) + # integrate_data() also resets the write_pending flag, + # intentionally only for read fields pair.integrate_data(raw_data, LUXTRONIK_CFI_REGISTER_BIT_SIZE) # create an unknown field for additional data diff --git a/luxtronik/cfi/parameters.py b/luxtronik/cfi/parameters.py index 345b7d1b..f578b81c 100644 --- a/luxtronik/cfi/parameters.py +++ b/luxtronik/cfi/parameters.py @@ -8,10 +8,11 @@ PARAMETERS_DEFINITIONS_LIST, PARAMETERS_OFFSET, PARAMETERS_DEFAULT_DATA_TYPE, + PARAMETERS_OUTDATED, ) from luxtronik.cfi.constants import PARAMETERS_FIELD_NAME -from luxtronik.data_vector import DataVector +from luxtronik.cfi.vector import DataVectorConfig LOGGER = logging.getLogger(__name__) @@ -23,35 +24,9 @@ PARAMETERS_DEFAULT_DATA_TYPE ) -class Parameters(DataVector): +class Parameters(DataVectorConfig): """Class that holds all parameters.""" name = PARAMETERS_FIELD_NAME definitions = PARAMETERS_DEFINITIONS - - def __init__(self, safe=True): - """Initialize parameters class.""" - super().__init__() - self.safe = safe - self.queue = {} - for d in PARAMETERS_DEFINITIONS: - self._data.add(d, d.create_field()) - - @property - def parameters(self): - return self._data - - def set(self, target, value): - """Set parameter to new value.""" - index, parameter = self._lookup(target, with_index=True) - if index is not None: - if parameter.writeable or not self.safe: - raw = parameter.to_heatpump(value) - if isinstance(raw, int): - self.queue[index] = raw - else: - LOGGER.error("Value '%s' for Parameter '%s' not valid!", value, parameter.name) - else: - LOGGER.warning("Parameter '%s' not safe for writing!", parameter.name) - else: - LOGGER.warning("Parameter '%s' not found", target) + _outdated = PARAMETERS_OUTDATED diff --git a/luxtronik/cfi/vector.py b/luxtronik/cfi/vector.py new file mode 100644 index 00000000..8b6c9892 --- /dev/null +++ b/luxtronik/cfi/vector.py @@ -0,0 +1,83 @@ + +import logging + +from luxtronik.data_vector import DataVector + + +LOGGER = logging.getLogger(__name__) + +############################################################################### +# Configuration interface data-vector +############################################################################### + +class DataVectorConfig(DataVector): + """Specialized DataVector for Luxtronik configuration fields.""" + + def _init_instance(self, safe): + """Re-usable method to initialize all instance variables.""" + super()._init_instance(safe) + + def __init__(self, safe=True): + """ + Initialize the data-vector instance. + Creates field objects for definitions and stores them in the data vector. + + Args: + safe (bool): If true, prevent fields marked as + not secure from being written to. + """ + self._init_instance(safe) + + # Add all available fields + for d in self.definitions: + self._data.add(d, d.create_field()) + + @classmethod + def empty(cls, safe=True): + """ + Initialize the data-vector instance without any fields. + + Args: + safe (bool): If true, prevent fields marked as + not secure from being written to. + """ + obj = cls.__new__(cls) # this don't call __init__() + obj._init_instance(safe) + return obj + + def add(self, def_field_name_or_idx, alias=None): + """ + Adds an additional field to this data vector. + Mainly used for data vectors created via `empty()` + to read/write individual fields. Existing fields will not be overwritten. + + Args: + def_field_name_or_idx (LuxtronikDefinition | Base | str | int): + Field to add. Either by definition, name or index, or the field itself. + alias (Hashable | None): Alias, which can be used to access the field again. + + Returns: + Base | None: The added field object if this could be added or + the existing field, otherwise None. In case a field + + Note: + It is not possible to add fields which are not defined. + To add custom fields, add them to the used `LuxtronikDefinitionsList` + (`cls.definitions`) first. + If multiple fields added for the same index/name, the last added takes precedence. + """ + # Look-up the related definition + definition, field = self._get_definition(def_field_name_or_idx, True) + if definition is None: + return None + + # Check if the field already exists + existing_field = self._data.get(definition, None) + if existing_field is not None: + return existing_field + + # Add a (new) field + if field is None: + field = definition.create_field() + self._data.add_sorted(definition, field, alias) + return field \ No newline at end of file diff --git a/luxtronik/cfi/visibilities.py b/luxtronik/cfi/visibilities.py index 79d5f603..224f8f32 100644 --- a/luxtronik/cfi/visibilities.py +++ b/luxtronik/cfi/visibilities.py @@ -8,10 +8,11 @@ VISIBILITIES_DEFINITIONS_LIST, VISIBILITIES_OFFSET, VISIBILITIES_DEFAULT_DATA_TYPE, + VISIBILITIES_OUTDATED, ) from luxtronik.cfi.constants import VISIBILITIES_FIELD_NAME -from luxtronik.data_vector import DataVector +from luxtronik.cfi.vector import DataVectorConfig LOGGER = logging.getLogger(__name__) @@ -23,17 +24,9 @@ VISIBILITIES_DEFAULT_DATA_TYPE, ) -class Visibilities(DataVector): +class Visibilities(DataVectorConfig): """Class that holds all visibilities.""" name = VISIBILITIES_FIELD_NAME definitions = VISIBILITIES_DEFINITIONS - - def __init__(self): - super().__init__() - for d in VISIBILITIES_DEFINITIONS: - self._data.add(d, d.create_field()) - - @property - def visibilities(self): - return self._data + _outdated = VISIBILITIES_OUTDATED diff --git a/luxtronik/collections.py b/luxtronik/collections.py index 9190bdf7..8ead2a59 100644 --- a/luxtronik/collections.py +++ b/luxtronik/collections.py @@ -205,8 +205,7 @@ def integrate_data(self, raw_data, num_bits, data_offset=-1): class LuxtronikFieldsDictionary: """ - Dictionary that behaves like the earlier data vector dictionaries (index-field-dictionary), - with the addition that obsolete fields are also supported and can be addressed by name. + Dictionary that maps definitions, names or indices to added fields. Aliases are also supported. """ @@ -228,15 +227,12 @@ def __getitem__(self, def_field_name_or_idx): return self.get(def_field_name_or_idx) def __len__(self): - return len(self._def_lookup._index_dict) + """Return the number of added fields.""" + return len(self._pairs) def __iter__(self): - """ - Iterate over all non-obsolete indices. If an index is assigned multiple times, - only the index of the preferred definition will be output. - """ - all_related_defs = self._def_lookup._index_dict.values() - return iter([d.index for d in self._pairs if d in all_related_defs]) + """Return the iterator over all definitions related to the added fields.""" + return iter([d for d, _ in self._pairs]) def __contains__(self, def_field_name_or_idx): """ @@ -265,26 +261,16 @@ def __contains__(self, def_field_name_or_idx): return def_field_name_or_idx in self._def_lookup def values(self): - """ - Iterator for all added non-obsolete fields. If an index is assigned multiple times, - only the field of the preferred definition will be output. - """ - all_related_defs = self._def_lookup._index_dict.values() - return iter([f for d, f in self._pairs if d in all_related_defs]) + """Return the iterator over all added fields.""" + return iter([f for _, f in self._pairs]) def items(self): - """ - Iterator for all non-obsolete index-field-pairs (list of tuples with - 0: index, 1: field) contained herein. If an index is assigned multiple times, - only the index-field-pair of the preferred definition will be output. - """ - all_related_defs = self._def_lookup._index_dict.values() - return iter([(d.index, f) for d, f in self._pairs if d in all_related_defs]) + """Return the iterator over all added definition-field-pairs.""" + return iter(self._pairs) + @property def pairs(self): - """ - Return all definition-field-pairs contained herein. - """ + """Return all definition-field-pairs contained herein.""" return self._pairs @property diff --git a/luxtronik/common.py b/luxtronik/common.py index dbef88a7..013a84a7 100644 --- a/luxtronik/common.py +++ b/luxtronik/common.py @@ -1,6 +1,16 @@ from threading import RLock +############################################################################### +# User adjust-able settings class +############################################################################### + +class LuxtronikSettings: + + # If False, overwrite existing values with None in case of a transmission error. + # Otherwise, leave the previous value unchanged. + preserve_last_read_value_on_fail = True + ############################################################################### # Multi-threading lock mechanism ############################################################################### diff --git a/luxtronik/constants.py b/luxtronik/constants.py index 894b3d31..65185d75 100644 --- a/luxtronik/constants.py +++ b/luxtronik/constants.py @@ -17,7 +17,3 @@ # Since version 3.92.0, all unavailable 16 bit signed data fields # have been returning this value (0x7FFF) LUXTRONIK_VALUE_FUNCTION_NOT_AVAILABLE: Final = 32767 - -LUXTRONIK_NAME_CHECK_NONE: Final = "none" -LUXTRONIK_NAME_CHECK_PREFERRED: Final = "preferred" -LUXTRONIK_NAME_CHECK_OBSOLETE: Final = "obsolete" diff --git a/luxtronik/data_vector.py b/luxtronik/data_vector.py index 97512c9b..efa2c41d 100644 --- a/luxtronik/data_vector.py +++ b/luxtronik/data_vector.py @@ -2,12 +2,9 @@ import logging -from luxtronik.constants import ( - LUXTRONIK_NAME_CHECK_PREFERRED, - LUXTRONIK_NAME_CHECK_OBSOLETE, -) - from luxtronik.collections import LuxtronikFieldsDictionary +from luxtronik.datatypes import Base, Unknown +from luxtronik.definitions import LuxtronikDefinition LOGGER = logging.getLogger(__name__) @@ -18,19 +15,104 @@ ############################################################################### class DataVector: - """Class that holds a vector of data entries.""" + """ + Class that holds a vector of data fields. + + Provides access to fields by name, index or alias. + To use aliases, they must first be registered here (locally = only valid + for this vector) or directly in the `LuxtronikDefinitionsList` + (globally = valid for all newly created vector). + """ name = "DataVector" + # DataVector specific list of definitions as `LuxtronikDefinitionsList` + definitions = None # override this + _obsolete = {} - def __init__(self): - """Initialize DataVector class.""" + +# Field construction methods ################################################## + + @classmethod + def create_unknown_field(cls, idx): + """ + Create an unknown field object. + Be careful! The used controller firmware + may not support this field. + + Args: + idx (int): Register index. + + Returns: + Unknown: A field instance of type `Unknown`. + """ + return Unknown(f"unknown_{cls.name}_{idx}", False) + + @classmethod + def create_any_field(cls, def_name_or_idx): + """ + Create a field object from an available definition + (= included in class variable `cls.definitions`). + Be careful! The used controller firmware + may not support this field. + + If `def_name_or_idx` + - is a definition -> create the field from the provided definition + - is a name -> lookup the definition by name and create the field + - is a idx -> lookup definition by index and create the field + + Args: + def_name_or_idx (LuxtronikDefinition | str | int): Definitions object, + field name or register index. + + Returns: + Base | None: The created field, or None if not found or not valid. + """ + if isinstance(def_name_or_idx, LuxtronikDefinition): + definition = def_name_or_idx + else: + # The definitions object hold all available definitions + definition = cls.definitions.get(def_name_or_idx) + if definition is not None and definition.valid: + return definition.create_field() + return None + + def create_field(self, def_name_or_idx): + """ + Create a field object from a version-dependent definition (= included in + class variable `cls.definitions` and is valid for `self.version`). + + If `def_name_or_idx` + - is a definition -> create the field from the provided definition + - is a name -> lookup the definition by name and create the field + - is a idx -> lookup definition by index and create the field + + Args: + def_name_or_idx (str | int): Definitions object, + field name or register index. + + Returns: + Base | None: The created field, or None if not found or not valid. + """ + definition, _ = self._get_definition(def_name_or_idx, False) + if definition is not None and definition.valid: + return definition.create_field() + return None + + +# constructor, magic methods and iterators #################################### + + def _init_instance(self, safe): + """Re-usable method to initialize all instance variables.""" + self.safe = safe + + # Dictionary that holds all fields self._data = LuxtronikFieldsDictionary() - def __iter__(self): - """Iterator for the data entries.""" - return iter(self._data.items()) + def __init__(self): + """Initialize DataVector class.""" + self._init_instance(True) @property def data(self): @@ -54,6 +136,19 @@ def __setitem__(self, def_name_or_idx, value): """ return self.set(def_name_or_idx, value) + def __len__(self): + """ + Forward the `LuxtronikFieldsDictionary.__len__` method. + Please check its documentation. + """ + return len(self._data) + + def __iter__(self): + """ + Forward the `LuxtronikFieldsDictionary.__iter__` method. + Please check its documentation. + """ + return iter(self._data) def __contains__(self, def_field_name_or_idx): """ @@ -62,64 +157,124 @@ def __contains__(self, def_field_name_or_idx): """ return def_field_name_or_idx in self._data - def _name_lookup(self, name): + def values(self): + """ + Forward the `LuxtronikFieldsDictionary.values` method. + Please check its documentation. + """ + return self._data.values() + + def items(self): + """ + Forward the `LuxtronikFieldsDictionary.items` method. + Please check its documentation. + """ + return iter(self._data.items()) + + +# Alias methods ############################################################### + + def register_alias(self, def_field_name_or_idx, alias): + """ + Forward the `LuxtronikFieldsDictionary.register_alias` method. + Please check its documentation. + """ + return self._data.register_alias(def_field_name_or_idx, alias) + + +# Get and set methods ######################################################### + + def _get_definition(self, def_field_name_or_idx, all_not_version_dependent): + """ + Look-up a definition by name, index, a field instance or by the definition itself. + + If `def_field_name_or_idx` + - is a definition -> lookup the definition by the definition's name + - is a field -> lookup the definition by the field's name + - is a name -> lookup the field by the name + - is a idx -> lookup the field by the index + + Args: + def_field_name_or_idx (LuxtronikDefinition | Base | str | int): + Definition object, field object, field name or register index. + all_not_version_dependent (bool): If true, look up the definition + within the `cls.definitions` otherwise within `self._data` (which + contain all definitions related to all added fields) + + Returns: + tuple[LuxtronikDefinition | None, Base | None]: + A definition-field-pair tuple: + Index 0: Return the found or given definitions, otherwise None + Index 1: Return the given field, otherwise None + """ + definition = def_field_name_or_idx + field = None + if isinstance(def_field_name_or_idx, Base): + # In case we got a field, search for the description by the field name + definition = def_field_name_or_idx.name + field = def_field_name_or_idx + if not isinstance(def_field_name_or_idx, LuxtronikDefinition): + if all_not_version_dependent: + # definitions contains all available definitions + definition = self.definitions.get(definition) + else: + # _data.def_dict contains only valid and previously added definitions + definition = self._data.def_dict.get(definition) + return definition, field + + def get(self, def_field_name_or_idx, default=None): """ - Try to find the index using the given field name. + Retrieve an added field by definition, field, name or register index. + Triggers a key error when we try to query obsolete fields. + + If `def_field_name_or_idx` + - is a definition -> lookup the field by the definition + - is a field -> lookup the field by the field's name + - is a name -> lookup the field by the name + - is a idx -> lookup the field by the index Args: - name (string): Field name. + def_field_name_or_idx (LuxtronikDefinition | Base | str | int): + Definition, name, or register index to be used to search for the field. Returns: - tuple[int | None, str | None]: - 0: Index found or None - 1: New preferred name, if available, otherwise None + Base | None: The field found or the provided default if not found. + + Note: + If multiple fields added for the same index/name, + the last added takes precedence. """ - obsolete_entry = self._obsolete.get(name, None) + # check for obsolete + obsolete_entry = self._obsolete.get(def_field_name_or_idx, None) if obsolete_entry: - return None, obsolete_entry - for index, entry in self._data.items(): - check_result = entry.check_name(name) - if check_result == LUXTRONIK_NAME_CHECK_PREFERRED: - return index, None - elif check_result == LUXTRONIK_NAME_CHECK_OBSOLETE: - return index, entry.name - return None, None - - def _lookup(self, target, with_index=False): - """ - Lookup an entry - - "target" could either be its id or its name. - - In case "with_index" is set, also the index is returned. - """ - if isinstance(target, str): - try: - # Try to get entry by id - target_index = int(target) - except ValueError: - # Get entry by name - target_index, new_name = self._name_lookup(target) - if new_name is not None: - raise KeyError(f"The name '{target}' is obsolete! Use '{new_name}' instead.") - elif isinstance(target, int): - # Get entry by id - target_index = target - else: - target_index = None - - target_entry = self._data.get(target_index, None) - if target_entry is None: - LOGGER.warning("entry '%s' not found", target) - if with_index: - return target_index, target_entry - return target_entry - - def get(self, target): - """Get entry by id or name.""" - entry = self._lookup(target) - return entry - - def set(self, target, value): - "TODO: Placeholder for future changes" - pass + raise KeyError(f"The name '{def_field_name_or_idx}' is obsolete! Use '{obsolete_entry}' instead.") + # look-up the field + field = self._data.get(def_field_name_or_idx, default) + if field is None: + LOGGER.warning(f"entry '{def_field_name_or_idx}' not found") + return field + + def set(self, def_field_name_or_idx, value): + """ + Set the data of a field to the given value. + + The value is set, even if the field marked as non-writeable. + No data validation is performed either. + + If `def_field_name_or_idx` + - is a definition -> lookup the field by the definition and set the value + - is a field -> set the value of this field + - is a name -> lookup the field by the name and set the value + - is a idx -> lookup the field by the index and set the value + + Args: + def_field_name_or_idx (LuxtronikDefinition | Base | int | str): + Definition, name, or register index to be used to search for the field. + It is also possible to pass the field itself. + value (int | List[int]): Value to set + """ + field = def_field_name_or_idx + if not isinstance(field, Base): + field = self.get(def_field_name_or_idx) + if field is not None: + field.value = value \ No newline at end of file diff --git a/luxtronik/datatypes.py b/luxtronik/datatypes.py index f8431c4b..b0e29312 100755 --- a/luxtronik/datatypes.py +++ b/luxtronik/datatypes.py @@ -1,19 +1,18 @@ """datatype conversions.""" import datetime +import logging import socket import struct -from luxtronik.constants import ( - LUXTRONIK_NAME_CHECK_NONE, - LUXTRONIK_NAME_CHECK_PREFERRED, - LUXTRONIK_NAME_CHECK_OBSOLETE, -) from luxtronik.common import classproperty from functools import total_ordering +LOGGER = logging.getLogger(__name__) + + @total_ordering class Base: """Base datatype, no conversions.""" @@ -44,6 +43,8 @@ def __init__(self, names, writeable=False): @classmethod def to_heatpump(cls, value): """Converts value into heatpump units.""" + if not isinstance(value, int): + return None return value @classmethod @@ -61,19 +62,6 @@ def name(self): """Return the (most common) name of the entry.""" return self._names[0] - def check_name(self, name): - """ - Check whether a name matches one of the supported entry names. - The result string can be used to trigger a exception for obsolete names. - """ - name_lower = name.lower() - if name_lower == self.name.lower(): - return LUXTRONIK_NAME_CHECK_PREFERRED - elif name_lower in (n.lower() for n in self._names): - return LUXTRONIK_NAME_CHECK_OBSOLETE - else: - return LUXTRONIK_NAME_CHECK_NONE - @property def value(self): """Return the stored value converted from heatpump units.""" @@ -83,6 +71,8 @@ def value(self): def value(self, value): """Converts the value into heatpump units and store it.""" self._raw = self.to_heatpump(value) + if self._raw is None: + LOGGER.warning(f"Value '{value}' not valid for field '{self.name}'") self.write_pending = True @property @@ -92,7 +82,7 @@ def raw(self): @raw.setter def raw(self, raw): - """Store the raw data.""" + """Store the raw data. For internal use only""" self._raw = raw self.write_pending = False @@ -105,7 +95,7 @@ def __repr__(self): f"name: {self.name}, " f"writeable: {self.writeable}, " f"value: {self.value}, " - f"raw: {self._raw}, " + f"raw: {self.raw}, " f"write_pending: {self.write_pending}, " f"class: {self.datatype_class}, " f"unit: {self.datatype_unit}" @@ -127,7 +117,7 @@ def __eq__(self, other): return False return ( - self.value == other.value + self._raw == other._raw and self.datatype_class == other.datatype_class and self.datatype_unit == other.datatype_unit ) @@ -136,11 +126,35 @@ def __lt__(self, other): """Compares two datatype objects and returns which one contains the lower value""" return ( - self.value < other.value + self._raw < other._raw and self.datatype_class == other.datatype_class and self.datatype_unit == other.datatype_unit ) + def check_for_write(self, safe=True): + """ + Returns true if the field is writable and the field data is valid. + + Args: + safe (bool, Default: True): Flag for blocking write operations + if the field is not marked as writable + + Returns: + bool: True if the data is writable, otherwise False. + """ + if self.writeable or not safe: + # We support integers + if isinstance(self._raw, int): + return True + # and list of integers + elif isinstance(self._raw, list) and all(isinstance(value, int) for value in self._raw): + return True + else: + LOGGER.error(f"Value of '{self.name}' invalid!") + else: + LOGGER.warning(f"'{self.name}' not safe for writing!") + return False + class SelectionBase(Base): """Selection base datatype, converts from and to list of codes.""" @@ -165,7 +179,7 @@ def sanitize_option(cls, option): @classmethod def from_heatpump(cls, value): - if value is None: + if not isinstance(value, int): return None if value in cls.codes: return cls.codes.get(value) @@ -319,11 +333,16 @@ class Bool(Base): @classmethod def from_heatpump(cls, value): + if not isinstance(value, int): + return None return bool(value) @classmethod def to_heatpump(cls, value): - return int(value) + try: + return int(bool(value)) + except Exception: + return None class Frequency(Base): @@ -347,10 +366,14 @@ class IPv4Address(Base): @classmethod def from_heatpump(cls, value): + if not isinstance(value, int): + return None return socket.inet_ntoa(struct.pack(">i", value)) @classmethod def to_heatpump(cls, value): + if not isinstance(value, str): + return None return struct.unpack(">i", socket.inet_aton(value))[0] @@ -361,7 +384,7 @@ class Timestamp(Base): @classmethod def from_heatpump(cls, value): - if value is None: + if not isinstance(value, int): return None if value <= 0: return datetime.datetime.fromtimestamp(0) @@ -369,6 +392,8 @@ def from_heatpump(cls, value): @classmethod def to_heatpump(cls, value): + if not isinstance(value, (int, float, datetime.datetime)): + return None return datetime.datetime.timestamp(value) @@ -560,12 +585,14 @@ class Hours2(Base): @classmethod def from_heatpump(cls, value): - if value is None: + if not isinstance(value, int): return None return 1 + value / 2 @classmethod def to_heatpump(cls, value): + if not isinstance(value, int): + return None return round((value - 1) * 2) @@ -595,6 +622,20 @@ class Count(Base): datatype_class = "count" +class Version(Base): + """Version datatype, converts from and to a Heatpump Version.""" + + datatype_class = "version" + + concatenate_multiple_data_chunks = False + + @classmethod + def from_heatpump(self, value): + if not isinstance(value, list): + return None + return "".join([chr(c) for c in value]).strip("\x00") + + class Character(Base): """Character datatype, converts from and to a Character.""" @@ -602,6 +643,8 @@ class Character(Base): @classmethod def from_heatpump(cls, value): + if not isinstance(value, int): + return None if value == 0: return "" return chr(value) @@ -614,6 +657,8 @@ class MajorMinorVersion(Base): @classmethod def from_heatpump(cls, value): + if not isinstance(value, int): + return None if value > 0: major = value // 100 minor = value % 100 @@ -932,7 +977,7 @@ class TimeOfDay(Base): @classmethod def from_heatpump(cls, value): - if value is None: + if not isinstance(value, int): return None hours = value // 3600 minutes = (value // 60) % 60 @@ -942,6 +987,8 @@ def from_heatpump(cls, value): @classmethod def to_heatpump(cls, value): + if not isinstance(value, str): + return None d = [int(v) for v in value.split(":")] val = d[0] * 3600 + d[1] * 60 @@ -958,7 +1005,7 @@ class TimeOfDay2(Base): @classmethod def from_heatpump(cls, value): - if value is None: + if not isinstance(value, int): return None value_low = value & 0xFFFF @@ -972,6 +1019,8 @@ def from_heatpump(cls, value): @classmethod def to_heatpump(cls, value): + if not isinstance(value, str): + return None d = value.split("-") low = [int(v) for v in d[0].split(":")] high = [int(v) for v in d[1].split(":")] @@ -1087,10 +1136,10 @@ class FullVersion(Base): @classmethod def from_heatpump(cls, value): - if isinstance(value, list) and len(value) >= 3: + if not isinstance(value, list) or len(value) <= 2: + return None + if len(value) >= 3: return f"{value[0]}.{value[1]}.{value[2]}" - else: - return "0" class Unknown(Base): diff --git a/luxtronik/definitions/calculations.py b/luxtronik/definitions/calculations.py index 0530ab85..8d1267ff 100644 --- a/luxtronik/definitions/calculations.py +++ b/luxtronik/definitions/calculations.py @@ -41,6 +41,7 @@ Timestamp, Unknown, MajorMinorVersion, + Version, Voltage, ) @@ -48,6 +49,8 @@ # to obtain the correct address of the data fields CALCULATIONS_OFFSET: Final = 0 CALCULATIONS_DEFAULT_DATA_TYPE: Final = 'INT32' +CALCULATIONS_OUTDATED = { +} CALCULATIONS_DEFINITIONS_LIST: Final = [ { @@ -860,6 +863,16 @@ "unit": 'enum', "description": '', }, + { + "index": 81, + "count": 10, + "names": ['ID_WEB_SoftStand'], + "type": Version, + "writeable": False, + "datatype": 'UINT32', + "unit": '', + "description": '', + }, { "index": 81, "count": 1, @@ -2370,20 +2383,30 @@ "unit": 'Hz', "description": '', }, + { + "index": 232, + "names": ['Unknown_Calculation_232'], + "type": Unknown, + }, { "index": 232, "count": 1, - "names": ['Vapourisation_Temperature', 'Unknown_Calculation_232'], + "names": ['Vapourisation_Temperature'], "type": Celsius, "writeable": False, "datatype": 'INT32', "unit": '°C/10', "description": '', }, + { + "index": 233, + "names": ['Unknown_Calculation_233'], + "type": Unknown, + }, { "index": 233, "count": 1, - "names": ['Liquefaction_Temperature', 'Unknown_Calculation_233'], + "names": ['Liquefaction_Temperature'], "type": Celsius, "writeable": False, "datatype": 'INT32', @@ -2410,50 +2433,75 @@ "unit": '', "description": '', }, + { + "index": 236, + "names": ['Unknown_Calculation_236'], + "type": Unknown, + }, { "index": 236, "count": 1, - "names": ['ID_WEB_Freq_VD_Soll', 'Unknown_Calculation_236'], + "names": ['ID_WEB_Freq_VD_Soll'], "type": Frequency, "writeable": False, "datatype": 'UINT32', "unit": 'Hz', "description": '', }, + { + "index": 237, + "names": ['Unknown_Calculation_237'], + "type": Unknown, + }, { "index": 237, "count": 1, - "names": ['ID_WEB_Freq_VD_Min', 'Unknown_Calculation_237'], + "names": ['ID_WEB_Freq_VD_Min'], "type": Frequency, "writeable": False, "datatype": 'UINT32', "unit": 'Hz', "description": '', }, + { + "index": 238, + "names": ['Unknown_Calculation_238'], + "type": Unknown, + }, { "index": 238, "count": 1, - "names": ['ID_WEB_Freq_VD_Max', 'Unknown_Calculation_238'], + "names": ['ID_WEB_Freq_VD_Max'], "type": Frequency, "writeable": False, "datatype": 'UINT32', "unit": 'Hz', "description": '', }, + { + "index": 239, + "names": ['Unknown_Calculation_239'], + "type": Unknown, + }, { "index": 239, "count": 1, - "names": ['VBO_Temp_Spread_Soll', 'Unknown_Calculation_239'], + "names": ['VBO_Temp_Spread_Soll'], "type": Kelvin, "writeable": False, "datatype": 'INT32', "unit": 'K/10', "description": '', }, + { + "index": 240, + "names": ['Unknown_Calculation_240'], + "type": Unknown, + }, { "index": 240, "count": 1, - "names": ['VBO_Temp_Spread_Ist', 'Unknown_Calculation_240'], + "names": ['VBO_Temp_Spread_Ist'], "type": Kelvin, "writeable": False, "datatype": 'INT32', @@ -2470,20 +2518,30 @@ "unit": '%', "description": '', }, + { + "index": 242, + "names": ['Unknown_Calculation_242'], + "type": Unknown, + }, { "index": 242, "count": 1, - "names": ['HUP_Temp_Spread_Soll', 'Unknown_Calculation_242'], + "names": ['HUP_Temp_Spread_Soll'], "type": Kelvin, "writeable": False, "datatype": 'INT32', "unit": 'K/10', "description": '', }, + { + "index": 243, + "names": ['Unknown_Calculation_243'], + "type": Unknown, + }, { "index": 243, "count": 1, - "names": ['HUP_Temp_Spread_Ist', 'Unknown_Calculation_243'], + "names": ['HUP_Temp_Spread_Ist'], "type": Kelvin, "writeable": False, "datatype": 'INT32', @@ -2630,10 +2688,15 @@ "unit": 'W', "description": '', }, + { + "index": 258, + "names": ['Unknown_Calculation_258'], + "type": Unknown, + }, { "index": 258, "count": 1, - "names": ['RBE_Version', 'Unknown_Calculation_258'], + "names": ['RBE_Version'], "type": MajorMinorVersion, "writeable": False, "datatype": 'UINT32', diff --git a/luxtronik/definitions/holdings.py b/luxtronik/definitions/holdings.py index f7b7b67e..2f5b5110 100644 --- a/luxtronik/definitions/holdings.py +++ b/luxtronik/definitions/holdings.py @@ -30,6 +30,8 @@ # to obtain the correct address of the data fields HOLDINGS_OFFSET: Final = 10000 HOLDINGS_DEFAULT_DATA_TYPE: Final = 'INT16' +HOLDINGS_OUTDATED = { +} HOLDINGS_DEFINITIONS_LIST: Final = [ { diff --git a/luxtronik/definitions/inputs.py b/luxtronik/definitions/inputs.py index 7140e582..13ce5244 100644 --- a/luxtronik/definitions/inputs.py +++ b/luxtronik/definitions/inputs.py @@ -35,6 +35,8 @@ # to obtain the correct address of the data fields INPUTS_OFFSET: Final = 10000 INPUTS_DEFAULT_DATA_TYPE: Final = 'INT16' +INPUTS_OUTDATED = { +} INPUTS_DEFINITIONS_LIST: Final = [ { diff --git a/luxtronik/definitions/parameters.py b/luxtronik/definitions/parameters.py index d5b5040e..dbdf8d56 100644 --- a/luxtronik/definitions/parameters.py +++ b/luxtronik/definitions/parameters.py @@ -42,6 +42,8 @@ # to obtain the correct address of the data fields PARAMETERS_OFFSET: Final = 0 PARAMETERS_DEFAULT_DATA_TYPE: Final = 'INT32' +PARAMETERS_OUTDATED = { +} PARAMETERS_DEFINITIONS_LIST: Final = [ { @@ -10914,10 +10916,15 @@ "unit": '', "description": '', }, + { + "index": 1087, + "names": ['Unknown_Parameter_1087'], + "type": Unknown, + }, { "index": 1087, "count": 1, - "names": ['SILENT_MODE', 'Unknown_Parameter_1087'], + "names": ['SILENT_MODE'], "type": OnOffMode, "writeable": False, "datatype": 'UINT32', @@ -10964,220 +10971,330 @@ "unit": '', "description": '', }, + { + "index": 1092, + "names": ['Unknown_Parameter_1092'], + "type": Unknown, + }, { "index": 1092, "count": 1, - "names": ['ID_Einst_SuSilence', 'Unknown_Parameter_1092'], + "names": ['ID_Einst_SuSilence'], "type": TimerProgram, "writeable": False, "datatype": 'UINT32', "unit": 'enum', "description": '', }, + { + "index": 1093, + "names": ['Unknown_Parameter_1093'], + "type": Unknown, + }, { "index": 1093, "count": 1, - "names": ['ID_Einst_SilenceTimer_0', 'Unknown_Parameter_1093'], + "names": ['ID_Einst_SilenceTimer_0'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1094, + "names": ['Unknown_Parameter_1094'], + "type": Unknown, + }, { "index": 1094, "count": 1, - "names": ['ID_Einst_SilenceTimer_1', 'Unknown_Parameter_1094'], + "names": ['ID_Einst_SilenceTimer_1'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1095, + "names": ['Unknown_Parameter_1095'], + "type": Unknown, + }, { "index": 1095, "count": 1, - "names": ['ID_Einst_SilenceTimer_2', 'Unknown_Parameter_1095'], + "names": ['ID_Einst_SilenceTimer_2'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1096, + "names": ['Unknown_Parameter_1096'], + "type": Unknown, + }, { "index": 1096, "count": 1, - "names": ['ID_Einst_SilenceTimer_3', 'Unknown_Parameter_1096'], + "names": ['ID_Einst_SilenceTimer_3'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1097, + "names": ['Unknown_Parameter_1097'], + "type": Unknown, + }, { "index": 1097, "count": 1, - "names": ['ID_Einst_SilenceTimer_4', 'Unknown_Parameter_1097'], + "names": ['ID_Einst_SilenceTimer_4'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1098, + "names": ['Unknown_Parameter_1098'], + "type": Unknown, + }, { "index": 1098, "count": 1, - "names": ['ID_Einst_SilenceTimer_5', 'Unknown_Parameter_1098'], + "names": ['ID_Einst_SilenceTimer_5'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1099, + "names": ['Unknown_Parameter_1099'], + "type": Unknown, + }, { "index": 1099, "count": 1, - "names": ['ID_Einst_SilenceTimer_6', 'Unknown_Parameter_1099'], + "names": ['ID_Einst_SilenceTimer_6'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1100, + "names": ['Unknown_Parameter_1100'], + "type": Unknown, + }, { "index": 1100, "count": 1, - "names": ['ID_Einst_SilenceTimer_7', 'Unknown_Parameter_1100'], + "names": ['ID_Einst_SilenceTimer_7'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1101, + "names": ['Unknown_Parameter_1101'], + "type": Unknown, + }, { "index": 1101, "count": 1, - "names": ['ID_Einst_SilenceTimer_8', 'Unknown_Parameter_1101'], + "names": ['ID_Einst_SilenceTimer_8'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1102, + "names": ['Unknown_Parameter_1102'], + "type": Unknown, + }, { "index": 1102, "count": 1, - "names": ['ID_Einst_SilenceTimer_9', 'Unknown_Parameter_1102'], + "names": ['ID_Einst_SilenceTimer_9'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1103, + "names": ['Unknown_Parameter_1103'], + "type": Unknown, + }, { "index": 1103, "count": 1, - "names": ['ID_Einst_SilenceTimer_10', 'Unknown_Parameter_1103'], + "names": ['ID_Einst_SilenceTimer_10'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1104, + "names": ['Unknown_Parameter_1104'], + "type": Unknown, + }, { "index": 1104, "count": 1, - "names": ['ID_Einst_SilenceTimer_11', 'Unknown_Parameter_1104'], + "names": ['ID_Einst_SilenceTimer_11'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1105, + "names": ['Unknown_Parameter_1105'], + "type": Unknown, + }, { "index": 1105, "count": 1, - "names": ['ID_Einst_SilenceTimer_12', 'Unknown_Parameter_1105'], + "names": ['ID_Einst_SilenceTimer_12'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1106, + "names": ['Unknown_Parameter_1106'], + "type": Unknown, + }, { "index": 1106, "count": 1, - "names": ['ID_Einst_SilenceTimer_13', 'Unknown_Parameter_1106'], + "names": ['ID_Einst_SilenceTimer_13'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1107, + "names": ['Unknown_Parameter_1107'], + "type": Unknown, + }, { "index": 1107, "count": 1, - "names": ['ID_Einst_SilenceTimer_14', 'Unknown_Parameter_1107'], + "names": ['ID_Einst_SilenceTimer_14'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1108, + "names": ['Unknown_Parameter_1108'], + "type": Unknown, + }, { "index": 1108, "count": 1, - "names": ['ID_Einst_SilenceTimer_15', 'Unknown_Parameter_1108'], + "names": ['ID_Einst_SilenceTimer_15'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1109, + "names": ['Unknown_Parameter_1109'], + "type": Unknown, + }, { "index": 1109, "count": 1, - "names": ['ID_Einst_SilenceTimer_16', 'Unknown_Parameter_1109'], + "names": ['ID_Einst_SilenceTimer_16'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1110, + "names": ['Unknown_Parameter_1110'], + "type": Unknown, + }, { "index": 1110, "count": 1, - "names": ['ID_Einst_SilenceTimer_17', 'Unknown_Parameter_1110'], + "names": ['ID_Einst_SilenceTimer_17'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1111, + "names": ['Unknown_Parameter_1111'], + "type": Unknown, + }, { "index": 1111, "count": 1, - "names": ['ID_Einst_SilenceTimer_18', 'Unknown_Parameter_1111'], + "names": ['ID_Einst_SilenceTimer_18'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1112, + "names": ['Unknown_Parameter_1112'], + "type": Unknown, + }, { "index": 1112, "count": 1, - "names": ['ID_Einst_SilenceTimer_19', 'Unknown_Parameter_1112'], + "names": ['ID_Einst_SilenceTimer_19'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', "unit": '', "description": '', }, + { + "index": 1113, + "names": ['Unknown_Parameter_1113'], + "type": Unknown, + }, { "index": 1113, "count": 1, - "names": ['ID_Einst_SilenceTimer_20', 'Unknown_Parameter_1113'], + "names": ['ID_Einst_SilenceTimer_20'], "type": TimeOfDay2, "writeable": False, "datatype": 'UINT32', @@ -11234,10 +11351,15 @@ "unit": '', "description": '', }, + { + "index": 1119, + "names": ['Unknown_Parameter_1119'], + "type": Unknown, + }, { "index": 1119, "count": 1, - "names": ['LAST_DEFROST_TIMESTAMP', 'Unknown_Parameter_1119'], + "names": ['LAST_DEFROST_TIMESTAMP'], "type": Timestamp, "writeable": False, "datatype": 'UINT32', @@ -11404,20 +11526,30 @@ "unit": '', "description": '', }, + { + "index": 1136, + "names": ['Unknown_Parameter_1136'], + "type": Unknown, + }, { "index": 1136, "count": 1, - "names": ['HEAT_ENERGY_INPUT', 'Unknown_Parameter_1136'], + "names": ['HEAT_ENERGY_INPUT'], "type": Energy, "writeable": False, "datatype": 'UINT32', "unit": 'kWh/10', "description": '', }, + { + "index": 1137, + "names": ['Unknown_Parameter_1137'], + "type": Unknown, + }, { "index": 1137, "count": 1, - "names": ['DHW_ENERGY_INPUT', 'Unknown_Parameter_1137'], + "names": ['DHW_ENERGY_INPUT'], "type": Energy, "writeable": False, "datatype": 'UINT32', @@ -11434,10 +11566,15 @@ "unit": '', "description": '', }, + { + "index": 1139, + "names": ['Unknown_Parameter_1139'], + "type": Unknown, + }, { "index": 1139, "count": 1, - "names": ['COOLING_ENERGY_INPUT', 'Unknown_Parameter_1139'], + "names": ['COOLING_ENERGY_INPUT'], "type": Energy, "writeable": False, "datatype": 'UINT32', @@ -11524,10 +11661,15 @@ "unit": '', "description": '', }, + { + "index": 1148, + "names": ['Unknown_Parameter_1148'], + "type": Unknown, + }, { "index": 1148, "count": 1, - "names": ['HEATING_TARGET_TEMP_ROOM_THERMOSTAT', 'Unknown_Parameter_1148'], + "names": ['HEATING_TARGET_TEMP_ROOM_THERMOSTAT'], "type": Celsius, "writeable": True, "datatype": 'INT32', diff --git a/luxtronik/definitions/visibilities.py b/luxtronik/definitions/visibilities.py index d8df6bbe..502d05b6 100644 --- a/luxtronik/definitions/visibilities.py +++ b/luxtronik/definitions/visibilities.py @@ -19,6 +19,8 @@ # to obtain the correct address of the data fields VISIBILITIES_OFFSET: Final = 0 VISIBILITIES_DEFAULT_DATA_TYPE: Final = 'INT32' +VISIBILITIES_OUTDATED = { +} VISIBILITIES_DEFINITIONS_LIST: Final = [ { diff --git a/luxtronik/scripts/__init__.py b/luxtronik/scripts/__init__.py index c9072d23..86e259bf 100644 --- a/luxtronik/scripts/__init__.py +++ b/luxtronik/scripts/__init__.py @@ -25,8 +25,8 @@ def print_dump_row(number, field): def dump_fields(data_vector): print_dump_header(f"{data_vector.name}s") - for index, field in data_vector.data.items(): - print_dump_row(index, field) + for definition, field in data_vector.data.items(): + print_dump_row(definition.index, field) def print_watch_header(screen, caption): cols, _ = screen.get_visible_size() @@ -41,11 +41,11 @@ def get_watch_row(short_name, number, prev_field, this_field): return text def update_changes(changes, prev_data_vector, this_data_vector): - for index, this_field in this_data_vector.data.items(): + for definition, this_field in this_data_vector.data.items(): short_name = this_data_vector.name[:4] - key = f"{short_name}_{str(index).zfill(5)}" - prev_field = prev_data_vector.get(index) + key = f"{short_name}_{str(definition.index).zfill(5)}" + prev_field = prev_data_vector.get(definition.name) if this_field.raw != prev_field.raw: - changes[key] = get_watch_row(short_name, index, prev_field, this_field) + changes[key] = get_watch_row(short_name, definition.index, prev_field, this_field) elif key in changes: - changes[key] = get_watch_row(short_name, index, prev_field, None) + changes[key] = get_watch_row(short_name, definition.index, prev_field, None) diff --git a/luxtronik/shi/contiguous.py b/luxtronik/shi/contiguous.py index fcb6c500..d28d8fbd 100644 --- a/luxtronik/shi/contiguous.py +++ b/luxtronik/shi/contiguous.py @@ -6,6 +6,7 @@ import logging +from luxtronik.common import LuxtronikSettings from luxtronik.collections import LuxtronikDefFieldPair from luxtronik.shi.constants import LUXTRONIK_SHI_REGISTER_BIT_SIZE @@ -166,6 +167,9 @@ def integrate_data(self, data_arr): f"Data to integrate not valid! Expected length {self.overall_count} " \ + f"but got {data_len}: data = {data_arr}, block = {self}" ) + if not LuxtronikSettings.preserve_last_read_value_on_fail: + for definition, field in self._parts: + field.raw = None return False first = self.first_index diff --git a/luxtronik/shi/holdings.py b/luxtronik/shi/holdings.py index 1df95e68..1bd065eb 100644 --- a/luxtronik/shi/holdings.py +++ b/luxtronik/shi/holdings.py @@ -8,6 +8,7 @@ HOLDINGS_DEFINITIONS_LIST, HOLDINGS_OFFSET, HOLDINGS_DEFAULT_DATA_TYPE, + HOLDINGS_OUTDATED, ) from luxtronik.shi.constants import HOLDINGS_FIELD_NAME @@ -28,7 +29,4 @@ class Holdings(DataVectorSmartHome): name = HOLDINGS_FIELD_NAME definitions = HOLDINGS_DEFINITIONS - - @property - def holdings(self): - return self._data \ No newline at end of file + _outdated = HOLDINGS_OUTDATED \ No newline at end of file diff --git a/luxtronik/shi/inputs.py b/luxtronik/shi/inputs.py index 3a87f703..cf36a8ef 100644 --- a/luxtronik/shi/inputs.py +++ b/luxtronik/shi/inputs.py @@ -8,6 +8,7 @@ INPUTS_DEFINITIONS_LIST, INPUTS_OFFSET, INPUTS_DEFAULT_DATA_TYPE, + INPUTS_OUTDATED, ) from luxtronik.shi.constants import INPUTS_FIELD_NAME @@ -28,7 +29,4 @@ class Inputs(DataVectorSmartHome): name = INPUTS_FIELD_NAME definitions = INPUTS_DEFINITIONS - - @property - def inputs(self): - return self._data \ No newline at end of file + _outdated = INPUTS_OUTDATED \ No newline at end of file diff --git a/luxtronik/shi/interface.py b/luxtronik/shi/interface.py index 025bbc0c..202d6461 100644 --- a/luxtronik/shi/interface.py +++ b/luxtronik/shi/interface.py @@ -2,8 +2,8 @@ import logging -from luxtronik.collections import get_data_arr from luxtronik.common import classproperty, version_in_range +from luxtronik.collections import get_data_arr from luxtronik.datatypes import Base from luxtronik.definitions import ( LuxtronikDefinition, @@ -321,6 +321,8 @@ def _integrate_data(self, telegrams_data): success = True for block, telegram, read_not_write in telegrams_data: if (read_not_write == READ): + # integrate_data() also resets the write_pending flag, + # intentionally only for read fields valid = block.integrate_data(telegram.data) if not valid: LOGGER.debug(f"Failed to integrate read data into {block}") @@ -379,16 +381,14 @@ def _prepare_write_field(self, definition, field, safe, data): if not field.write_pending and data is None: return False - # Abort if field is not writeable - if safe and not (definition.writeable and field.writeable): - LOGGER.warning("Field marked as non-writeable: " \ - + f"name={definition.name}, data={field.raw}") - return False - # Override the field's data with the provided data if data is not None: field.value = data + # Abort if field is not writeable or the value is invalid + if not field.check_for_write(safe): + return False + # Abort if insufficient data is provided if not get_data_arr(definition, field, LUXTRONIK_SHI_REGISTER_BIT_SIZE): LOGGER.warning("Data error / insufficient data provided: " \ @@ -469,12 +469,12 @@ def _collect_fields(self, blocks_list, data_vector, definitions, read_not_write) # Trial-and-error mode: Add a block for every field blocks = ContiguousDataBlockList(definitions.name, read_not_write) if (read_not_write == READ): - for definition, field in data_vector.data.pairs(): + for definition, field in data_vector.data.items(): # _prepare_read_field will never fail, no need to call it #if self._prepare_read_field(definition, field): blocks.append_single(definition, field) else: - for definition, field in data_vector.data.pairs(): + for definition, field in data_vector.data.items(): if self._prepare_write_field(definition, field, data_vector.safe, None): blocks.append_single(definition, field) if len(blocks) > 0: @@ -488,7 +488,7 @@ def _collect_fields(self, blocks_list, data_vector, definitions, read_not_write) else: blocks = ContiguousDataBlockList(definitions.name, read_not_write) # Organize data into contiguous blocks - for definition, field in data_vector.data.pairs(): + for definition, field in data_vector.data.items(): if self._prepare_write_field(definition, field, data_vector.safe, None): blocks.collect(definition, field) if len(blocks) > 0: diff --git a/luxtronik/shi/vector.py b/luxtronik/shi/vector.py index 36e7d39b..9acceab0 100644 --- a/luxtronik/shi/vector.py +++ b/luxtronik/shi/vector.py @@ -2,10 +2,7 @@ import logging from luxtronik.common import version_in_range -from luxtronik.collections import LuxtronikFieldsDictionary from luxtronik.data_vector import DataVector -from luxtronik.datatypes import Base, Unknown -from luxtronik.definitions import LuxtronikDefinition from luxtronik.shi.constants import LUXTRONIK_LATEST_SHI_VERSION from luxtronik.shi.contiguous import ContiguousDataBlockList @@ -18,82 +15,13 @@ ############################################################################### class DataVectorSmartHome(DataVector): - """ - Specialized DataVector for Luxtronik smart home fields. - - Provides access to fields by name, index or alias. - To use aliases, they must first be registered here (locally = only valid - for this vector) or directly in the `LuxtronikDefinitionsList` - (globally = valid for all newly created vector). - """ - - # DataVector specific list of definitions as `LuxtronikDefinitionsList` - definitions = None # override this - -# Field construction methods ################################################## - - @classmethod - def create_unknown_field(cls, idx): - """ - Create an unknown field object. - Be careful! The used controller firmware - may not support this field. - - Args: - idx (int): Register index. - - Returns: - Unknown: A field instance of type 'Unknown'. - """ - return Unknown(f"unknown_{cls.name}_{idx}", False) - - @classmethod - def create_any_field(cls, name_or_idx): - """ - Create a field object from an available definition - (= included in class variable `cls.definitions`). - Be careful! The used controller firmware - may not support this field. - - Args: - name_or_idx (str | int): Field name or register index. - - Returns: - Base | None: The created field, or None if not found or not valid. - """ - # The definitions object hold all available definitions - definition = cls.definitions.get(name_or_idx) - if definition is not None and definition.valid: - return definition.create_field() - return None - - def create_field(self, name_or_idx): - """ - Create a field object from a version-dependent definition (= included in - class variable `cls.definitions` and is valid for `self.version`). - - Args: - name_or_idx (str | int): Field name or register index. - - Returns: - Base | None: The created field, or None if not found or not valid. - """ - definition, _ = self._get_definition(name_or_idx, False) - if definition is not None and definition.valid: - return definition.create_field() - return None - - -# Constructors and magic methods ############################################## + """Specialized DataVector for Luxtronik smart home fields.""" def _init_instance(self, version, safe): """Re-usable method to initialize all instance variables.""" - self.safe = safe + super()._init_instance(safe) self._version = version - # Dictionary that holds all fields - self._data = LuxtronikFieldsDictionary() - # Instead of re-create the block-list on every read, we just update it # on first time used or on next time used if some fields are added. self._read_blocks_up_to_date = False @@ -143,57 +71,22 @@ def empty(cls, version=LUXTRONIK_LATEST_SHI_VERSION, safe=True): obj._init_instance(version, safe) return obj - def __len__(self): - return len(self._data.pairs()) - - def __iter__(self): - return iter([definition for definition, _ in self._data.pairs()]) - - -# properties and access methods ############################################### - @property def version(self): return self._version - def values(self): - return iter([field for _, field in self._data.pairs()]) - - def items(self): - return iter(self._data.pairs()) - - -# Find, add and alias methods ################################################# - - def _get_definition(self, def_field_name_or_idx, all_not_version_dependent): + def update_read_blocks(self): """ - Look-up a definition by name, index, a field instance or by the definition itself. - - Args: - def_field_name_or_idx (LuxtronikDefinition | Base | str | int): - Definition object, field object, field name or register index. - all_not_version_dependent (bool): If true, look up the definition - within the `cls.definitions` otherwise within `self.def_dict` (which - contain all definitions related to all added fields) + (Re-)Create the data block list (`ContiguousDataBlockList`) for read-operations. - Returns: - tuple[LuxtronikDefinition | None, Base | None]: - A definition-field-pair tuple: - Index 0: Return the found or given definitions, otherwise None - Index 1: Return the given field, otherwise None + Since the data blocks do not change as long as no new fields are added, + it is sufficient to regenerate them only when a change occurs. """ - definition = def_field_name_or_idx - field = None - if isinstance(def_field_name_or_idx, Base): - definition = def_field_name_or_idx.name - field = def_field_name_or_idx - if not isinstance(def_field_name_or_idx, LuxtronikDefinition): - if all_not_version_dependent: - definition = self.definitions.get(definition) - else: - # def_dict contains only valid and addable definitions - definition = self._data.def_dict.get(definition) - return definition, field + if not self._read_blocks_up_to_date: + self._read_blocks.clear() + for definition, field in self._data.items(): + self._read_blocks.collect(definition, field) + self._read_blocks_up_to_date = True def add(self, def_field_name_or_idx, alias=None): """ @@ -234,76 +127,4 @@ def add(self, def_field_name_or_idx, alias=None): self._read_blocks_up_to_date = False self._data.add_sorted(definition, field, alias) return field - return None - - def register_alias(self, def_field_name_or_idx, alias): - """ - Add an alternative name (or anything hashable else) - that can be used to access a specific field. - - Args: - def_field_name_or_idx (LuxtronikDefinition | Base | str | int): - Field to which the alias is to be added. - Either by definition, name, register index, or the field itself. - alias (Hashable): Alias, which can be used to access the field again. - - Returns: - Base | None: The field to which the alias was added, - or None if not possible - """ - return self._data.register_alias(def_field_name_or_idx, alias) - - -# Data-blocks methods ######################################################### - - def update_read_blocks(self): - """ - (Re-)Create the data block list (`ContiguousDataBlockList`) for read-operations. - - Since the data blocks do not change as long as no new fields are added, - it is sufficient to regenerate them only when a change occurs. - """ - if not self._read_blocks_up_to_date: - self._read_blocks.clear() - for definition, field in self._data.pairs(): - self._read_blocks.collect(definition, field) - self._read_blocks_up_to_date = True - - -# Data and access methods ##################################################### - - def get(self, def_name_or_idx, default=None): - """ - Retrieve a field by definition, name or register index. - - Args: - def_name_or_idx (LuxtronikDefinition | str | int): - Definition, name, or register index to be used to search for the field. - - Returns: - Base | None: The field found or the provided default if not found. - - Note: - If multiple fields added for the same index/name, - the last added takes precedence. - """ - return self._data.get(def_name_or_idx, default) - - def set(self, def_field_name_or_idx, value): - """ - Set field to new value. - - The value is set, even if the field marked as non-writeable. - No data validation is performed either. - - Args: - def_field_name_or_idx (LuxtronikDefinition | Base | int | str): - Definition, name, or register index to be used to search for the field. - It is also possible to pass the field itself. - value (int | List[int]): Value to set - """ - field = def_field_name_or_idx - if not isinstance(field, Base): - field = self.get(def_field_name_or_idx) - if field is not None: - field.value = value \ No newline at end of file + return None \ No newline at end of file diff --git a/tests/cfi/test_cfi_calculations.py b/tests/cfi/test_cfi_calculations.py index fd44cbed..97f3bb01 100644 --- a/tests/cfi/test_cfi_calculations.py +++ b/tests/cfi/test_cfi_calculations.py @@ -4,6 +4,7 @@ from luxtronik import Calculations from luxtronik.datatypes import Base +from luxtronik.definitions import LuxtronikDefinition class TestCalculations: @@ -13,20 +14,19 @@ def test_init(self): """Test cases for initialization""" calculations = Calculations() assert calculations.name == "calculation" - assert calculations.calculations == calculations._data def test_data(self): """Test cases for the data dictionary""" calculations = Calculations() - data = calculations.calculations + data = calculations.data # The Value must be a fields # The key can be an index assert isinstance(data[0], Base) - for k in data: - assert isinstance(k, int) + for d in data: + assert isinstance(d, LuxtronikDefinition) for v in data.values(): assert isinstance(v, Base) - for k, v in data.items(): - assert isinstance(k, int) + for d, v in data.items(): + assert isinstance(d, LuxtronikDefinition) assert isinstance(v, Base) diff --git a/tests/cfi/test_cfi_interface.py b/tests/cfi/test_cfi_interface.py index 755b9e59..aced441a 100644 --- a/tests/cfi/test_cfi_interface.py +++ b/tests/cfi/test_cfi_interface.py @@ -1,9 +1,10 @@ from luxtronik import ( - Parameters, - Calculations, - Visibilities, - LuxtronikSocketInterface, + LuxtronikSettings, + Parameters, + Calculations, + Visibilities, + LuxtronikSocketInterface, ) @@ -18,35 +19,63 @@ def test_parse(self): n = 2000 t = list(range(0, n + 1)) + parameters[0].write_pending = True lux._parse(parameters, t) p = parameters.get(n) assert p.name == f"unknown_parameter_{n}" assert p.raw == n + assert not p.write_pending + calculations[0].write_pending = True lux._parse(calculations, t) c = calculations.get(n) assert c.name == f"unknown_calculation_{n}" assert c.raw == n + assert not c.write_pending + visibilities[0].write_pending = True lux._parse(visibilities, t) v = visibilities.get(n) assert v.name == f"unknown_visibility_{n}" assert v.raw == n + assert not v.write_pending n = 10 t = list(range(0, n + 1)) + orig_preserve = LuxtronikSettings.preserve_last_read_value_on_fail + + LuxtronikSettings.preserve_last_read_value_on_fail = True + preserve = LuxtronikSettings.preserve_last_read_value_on_fail + for definition, field in parameters.data.items(): + field.write_pending = True lux._parse(parameters, t) - for definition, field in parameters.data.pairs(): - if definition.index > n: + for definition, field in parameters.data.items(): + value_available = definition.index > n + if value_available and not preserve: assert field.raw is None + assert field.write_pending == (value_available and preserve) + LuxtronikSettings.preserve_last_read_value_on_fail = False + preserve = LuxtronikSettings.preserve_last_read_value_on_fail + for definition, field in calculations.data.items(): + field.write_pending = True lux._parse(calculations, t) - for definition, field in calculations.data.pairs(): - if definition.index > n: + for definition, field in calculations.data.items(): + value_available = definition.index > n + if value_available and not preserve: assert field.raw is None + assert field.write_pending == (value_available and preserve) + LuxtronikSettings.preserve_last_read_value_on_fail = False + preserve = LuxtronikSettings.preserve_last_read_value_on_fail + for definition, field in visibilities.data.items(): + field.write_pending = True lux._parse(visibilities, t) - for definition, field in visibilities.data.pairs(): - if definition.index > n: - assert field.raw is None \ No newline at end of file + for definition, field in visibilities.data.items(): + value_available = definition.index > n + if value_available and not preserve: + assert field.raw is None + assert field.write_pending == (value_available and preserve) + + LuxtronikSettings.preserve_last_read_value_on_fail = orig_preserve \ No newline at end of file diff --git a/tests/cfi/test_cfi_parameters.py b/tests/cfi/test_cfi_parameters.py index 417e146c..8acb6f8b 100644 --- a/tests/cfi/test_cfi_parameters.py +++ b/tests/cfi/test_cfi_parameters.py @@ -4,6 +4,7 @@ from luxtronik import Parameters from luxtronik.datatypes import Base +from luxtronik.definitions import LuxtronikDefinition class TestParameters: @@ -13,28 +14,25 @@ def test_init(self): """Test cases for initialization""" parameters = Parameters() assert parameters.name == "parameter" - assert parameters.parameters == parameters._data assert parameters.safe - assert len(parameters.queue) == 0 parameters = Parameters(False) assert not parameters.safe - assert len(parameters.queue) == 0 def test_data(self): """Test cases for the data dictionary""" parameters = Parameters() - data = parameters.parameters + data = parameters.data # The Value must be a fields # The key can be an index assert isinstance(data[0], Base) - for k in data: - assert isinstance(k, int) + for d in data: + assert isinstance(d, LuxtronikDefinition) for v in data.values(): assert isinstance(v, Base) - for k, v in data.items(): - assert isinstance(k, int) + for d, v in data.items(): + assert isinstance(d, LuxtronikDefinition) assert isinstance(v, Base) def test_get(self): @@ -45,36 +43,32 @@ def test_get(self): assert parameters.get("0").name == s assert parameters.get(s).name == s - def test__lookup(self): - """Test cases for _lookup""" - parameters = Parameters() - s = "ID_Transfert_LuxNet" - assert parameters._lookup(0).name == s - assert parameters._lookup("0").name == s - assert parameters._lookup(s).name == s - - p0 = parameters._lookup(0) - assert parameters._lookup(0, True) == (0, p0) - assert parameters._lookup("0", True) == (0, p0) - assert parameters._lookup(s, True) == (0, p0) + p0 = parameters.get(0) + assert parameters[0] is p0 + assert parameters["0"] is p0 + assert parameters[s] is p0 # Look for a name which does not exist s = "ID_BarFoo" - assert parameters._lookup(s, True)[0] is None + assert parameters.get(s) is None # Look for something which is not an int and not a string j = 0.0 - assert parameters._lookup(j) is None + assert parameters.get(j) is None def test___iter__(self): """Test cases for __iter__""" parameters = Parameters() - for i, p in parameters: - if i == 0: + for d, p in parameters.items(): + if d.index == 0: assert p.name == "ID_Transfert_LuxNet" - elif i == 1: + assert d is parameters.data.def_dict.get(0) + assert p is parameters.get(0) + elif d.index == 1: assert p.name == "ID_Einst_WK_akt" + assert d is parameters.data.def_dict.get(1) + assert p is parameters.get(1) else: break @@ -84,18 +78,21 @@ def test_set(self): # Set something which does not exist parameters.set("BarFoo", 0) - assert len(parameters.queue) == 0 + assert parameters["BarFoo"] is None - # Set something which is not allowed to be set - parameters.set("ID_Transfert_LuxNet", 0) - assert len(parameters.queue) == 0 + # Set something which was previously (v0.3.14) not allowed to be set + parameters.set("ID_Transfert_LuxNet", 1) + assert parameters["ID_Transfert_LuxNet"].raw == 1 + assert parameters["ID_Transfert_LuxNet"].write_pending # Set something which is allowed to be set - parameters.set("ID_Einst_WK_akt", 0) - assert len(parameters.queue) == 1 + parameters.set("ID_Einst_WK_akt", 2) + assert parameters["ID_Einst_WK_akt"].raw == 20 + assert parameters["ID_Einst_WK_akt"].write_pending parameters = Parameters(safe=False) - # Set something which is not allowed to be set, but we are brave. - parameters.set("ID_Transfert_LuxNet", 0) - assert len(parameters.queue) == 1 + # Set something which was previously (v0.3.14) not allowed to be set, but we are brave. + parameters.set("ID_Transfert_LuxNet", 4) + assert parameters["ID_Transfert_LuxNet"].raw == 4 + assert parameters["ID_Transfert_LuxNet"].write_pending diff --git a/tests/cfi/test_cfi_vector.py b/tests/cfi/test_cfi_vector.py new file mode 100644 index 00000000..a97fa18b --- /dev/null +++ b/tests/cfi/test_cfi_vector.py @@ -0,0 +1,110 @@ +from luxtronik.datatypes import Base +from luxtronik.definitions import LuxtronikDefinitionsList +from luxtronik.cfi.vector import DataVectorConfig + + +############################################################################### +# Tests +############################################################################### + +def_list = [ + { + "index": 5, + "count": 1, + "names": ["field_5_bit1"], + "bit_offset": 0, + "bit_count": 1, + "type": Base, + "writeable": False, + }, + { + "index": 5, + "count": 1, + "names": ["field_5_bit2"], + "bit_offset": 1, + "bit_count": 3, + "type": Base, + "writeable": False, + }, + { + "index": 5, + "count": 1, + "names": ["field_5_all"], + "type": Base, + "writeable": False, + }, + { + "index": 7, + "count": 2, + "names": ["field_7"], + "type": Base, + "writeable": True, + }, + { + "index": 9, + "count": 2, + "names": ["field_9"], + "type": Base, + "writeable": True, + } +] +TEST_DEFINITIONS = LuxtronikDefinitionsList(def_list, 'foo', 100, 'INT32') + +FIELD_11_DICT = { + "index": 11, + "count": 1, + "names": ["field_11"], + "type": Base, + "writeable": True, +} +FIELD_12_DICT = { + "index": 12, + "count": 1, + "names": ["field_12"], + "type": Base, + "writeable": True, +} + +class DataVectorTest(DataVectorConfig): + name = 'foo' + definitions = TEST_DEFINITIONS + +class TestDataVector: + + def test_add(self): + data_vector = DataVectorTest.empty() + assert len(data_vector) == 0 + + # In case the definitions are added after the creation + data_vector.definitions.add(FIELD_11_DICT) + data_vector.definitions.add(FIELD_12_DICT) + + # Add available index + field = data_vector.add(11) + assert len(data_vector) == 1 + assert 11 in data_vector + assert field.name == 'field_11' + + # Add not available index (not existing) + field = data_vector.add(13) + assert 'field_6' not in data_vector + assert field is None + assert len(data_vector) == 1 + + # Re-add available index + field = data_vector.add(11) + assert len(data_vector) == 1 + assert field.name == 'field_11' + + # Add available field + field_12 = Base('field_12', False) + field = data_vector.add(field_12) + assert 12 in data_vector + assert len(data_vector) == 2 + assert field == field_12 + + # Re-add available field + field = data_vector.add(field_12) + assert field_12 in data_vector + assert len(data_vector) == 2 + assert field == field_12 diff --git a/tests/cfi/test_cfi_visibilities.py b/tests/cfi/test_cfi_visibilities.py index 8ecb6f72..aa5cbc19 100644 --- a/tests/cfi/test_cfi_visibilities.py +++ b/tests/cfi/test_cfi_visibilities.py @@ -4,6 +4,7 @@ from luxtronik import Visibilities from luxtronik.datatypes import Base +from luxtronik.definitions import LuxtronikDefinition class TestVisibilities: @@ -13,20 +14,19 @@ def test_init(self): """Test cases for initialization""" visibilities = Visibilities() assert visibilities.name == "visibility" - assert visibilities.visibilities == visibilities._data def test_data(self): """Test cases for the data dictionary""" visibilities = Visibilities() - data = visibilities.visibilities + data = visibilities.data # The Value must be a fields # The key can be an index assert isinstance(data[0], Base) - for k in data: - assert isinstance(k, int) + for d in data: + assert isinstance(d, LuxtronikDefinition) for v in data.values(): assert isinstance(v, Base) - for k, v in data.items(): - assert isinstance(k, int) + for d, v in data.items(): + assert isinstance(d, LuxtronikDefinition) assert isinstance(v, Base) diff --git a/tests/fake/fake_luxtronik.py b/tests/fake/fake_luxtronik.py index 8aaf38bc..bc9e639f 100644 --- a/tests/fake/fake_luxtronik.py +++ b/tests/fake/fake_luxtronik.py @@ -5,9 +5,9 @@ class FakeLuxtronik(Luxtronik): def __init__(self): LuxtronikAllData.__init__(self) - for idx, field in self.parameters: - field.raw = idx - for idx, field in self.calculations: - field.raw = idx - for idx, field in self.visibilities: - field.raw = idx \ No newline at end of file + for definition, field in self.parameters.items(): + field.raw = definition.index + for definition, field in self.calculations.items(): + field.raw = definition.index + for definition, field in self.visibilities.items(): + field.raw = definition.index \ No newline at end of file diff --git a/tests/shi/test_shi_contiguous.py b/tests/shi/test_shi_contiguous.py index 62a27d50..9dc7a72d 100644 --- a/tests/shi/test_shi_contiguous.py +++ b/tests/shi/test_shi_contiguous.py @@ -278,6 +278,16 @@ def test_get_data(self): data_arr = block.get_data_arr() assert data_arr is None + # Missing data (via gaps) + block = ContiguousDataBlock() + field_a.raw = [56, 57] + field_c.raw = [21, 22, 23] + block.add(def_a, field_a) + block.add(def_c, field_c) + + data_arr = block.get_data_arr() + assert data_arr is None + def test_repr(self): block = ContiguousDataBlock() text_empty = repr(block) diff --git a/tests/shi/test_shi_interface.py b/tests/shi/test_shi_interface.py index dd1596a6..c2c96cc9 100644 --- a/tests/shi/test_shi_interface.py +++ b/tests/shi/test_shi_interface.py @@ -1,6 +1,7 @@ import pytest from unittest.mock import patch +from luxtronik.common import LuxtronikSettings from luxtronik.constants import LUXTRONIK_VALUE_FUNCTION_NOT_AVAILABLE from luxtronik.datatypes import Base, Unknown from luxtronik.definitions import LuxtronikDefinition @@ -28,6 +29,10 @@ ) from tests.fake import FakeModbus +IDX_BLK = 0 +IDX_TLG = 1 +IDX_RNW = 2 + class TestLuxtronikSmartHomeData: @@ -244,8 +249,8 @@ def test_create_telegram(self): telegram = self.interface._create_telegram(block, "input", False) assert telegram is None - def test_create_telegrams(self): - blocks_list = [] + def create_contiguous_block_list(self): + block_list = [] blocks = ContiguousDataBlockList("holding", True) # block 1 @@ -260,86 +265,155 @@ def test_create_telegrams(self): # block 3 blocks.append_single(HOLDINGS_DEFINITIONS[10], HOLDINGS_DEFINITIONS[10].create_field()) - blocks_list.append(blocks) + block_list.append(blocks) blocks = ContiguousDataBlockList("holding", False) - # invalid block + # invalid block because of invalid data blocks.append_single(HOLDINGS_DEFINITIONS[12], HOLDINGS_DEFINITIONS[12].create_field()) + # block 4 field3 = HOLDINGS_DEFINITIONS[17].create_field() blocks.append_single(HOLDINGS_DEFINITIONS[17], field3) - blocks_list.append(blocks) + block_list.append(blocks) field3.raw = 17 - telegram_data = self.interface._create_telegrams(blocks_list) + assert len(block_list) == 2 + assert len(block_list[0]) == 3 + assert len(block_list[0][0]) == 2 + assert len(block_list[0][1]) == 1 + assert len(block_list[0][2]) == 1 + assert len(block_list[1]) == 2 + assert len(block_list[1][0]) == 1 + assert len(block_list[1][1]) == 1 + + return block_list + + def test_create_telegrams(self): + block_list = self.create_contiguous_block_list() + + telegram_data = self.interface._create_telegrams(block_list) assert len(telegram_data) == 4 + + # Note: telegram_data[block index][tuple index] + # Note: telegram_data[block index][IDX_BLK][part index] + # blocks - assert len(telegram_data[0][0]) == 2 - assert telegram_data[0][0].first_index == 10 - assert telegram_data[0][0].overall_count == 2 - assert len(telegram_data[1][0]) == 1 - assert telegram_data[1][0].first_index == 17 - assert telegram_data[1][0].overall_count == 1 - assert len(telegram_data[2][0]) == 1 - assert telegram_data[2][0].first_index == 10 - assert telegram_data[2][0].overall_count == 1 - assert len(telegram_data[3][0]) == 1 - assert telegram_data[3][0].first_index == 17 - assert telegram_data[3][0].overall_count == 1 + assert len(telegram_data[0][IDX_BLK]) == 2 + assert telegram_data[0][IDX_BLK].first_index == 10 + assert telegram_data[0][IDX_BLK].overall_count == 2 + assert len(telegram_data[1][IDX_BLK]) == 1 + assert telegram_data[1][IDX_BLK].first_index == 17 + assert telegram_data[1][IDX_BLK].overall_count == 1 + assert len(telegram_data[2][IDX_BLK]) == 1 + assert telegram_data[2][IDX_BLK].first_index == 10 + assert telegram_data[2][IDX_BLK].overall_count == 1 + assert len(telegram_data[3][IDX_BLK]) == 1 + assert telegram_data[3][IDX_BLK].first_index == 17 + assert telegram_data[3][IDX_BLK].overall_count == 1 # telegrams - assert telegram_data[0][1].count == 2 - assert telegram_data[1][1].count == 1 - assert telegram_data[2][1].count == 1 - assert telegram_data[3][1].count == 1 + assert telegram_data[0][IDX_TLG].count == 2 + assert telegram_data[1][IDX_TLG].count == 1 + assert telegram_data[2][IDX_TLG].count == 1 + assert telegram_data[3][IDX_TLG].count == 1 # read not write - assert telegram_data[0][2] - assert telegram_data[1][2] - assert telegram_data[2][2] - assert not telegram_data[3][2] + assert telegram_data[0][IDX_RNW] + assert telegram_data[1][IDX_RNW] + assert telegram_data[2][IDX_RNW] + assert not telegram_data[3][IDX_RNW] + + def test_integrate_data(self): + block_list = self.create_contiguous_block_list() + + telegram_data = self.interface._create_telegrams(block_list) # integrate - telegram_data[0][1].data = [18, 4] - telegram_data[1][1].data = [9] - telegram_data[2][1].data = [27] - telegram_data[3][0][0].field.write_pending = True + telegram_data[0][IDX_TLG].data = [18, 4] + telegram_data[0][IDX_BLK][0].field.write_pending = True + telegram_data[0][IDX_BLK][1].field.write_pending = False + telegram_data[1][IDX_TLG].data = [9] + telegram_data[2][IDX_TLG].data = [27] + telegram_data[3][IDX_BLK][0].field.write_pending = True valid = self.interface._integrate_data(telegram_data) assert valid # [index data, index for blocks, index for part] - assert telegram_data[0][0][0].field.raw == 18 - assert telegram_data[0][0][1].field.raw == 4 - assert telegram_data[1][0][0].field.raw == 9 - assert telegram_data[2][0][0].field.raw == 27 - assert not telegram_data[3][0][0].field.write_pending - assert telegram_data[3][0][0].field.raw == 17 # no update + assert telegram_data[0][IDX_BLK][0].field.raw == 18 + assert not telegram_data[0][IDX_BLK][0].field.write_pending + assert telegram_data[0][IDX_BLK][1].field.raw == 4 + assert not telegram_data[0][IDX_BLK][1].field.write_pending + assert telegram_data[1][IDX_BLK][0].field.raw == 9 + assert telegram_data[2][IDX_BLK][0].field.raw == 27 + assert telegram_data[3][IDX_BLK][0].field.raw == 17 # no update + assert not telegram_data[3][IDX_BLK][0].field.write_pending # integrate not available / None -> no error - telegram_data[0][1].data = [18, 4] - telegram_data[1][1].data = [LUXTRONIK_VALUE_FUNCTION_NOT_AVAILABLE] - telegram_data[2][1].data = [None] + telegram_data[0][IDX_TLG].data = [19, 5] + telegram_data[0][IDX_BLK][0].field.write_pending = True + telegram_data[1][IDX_TLG].data = [LUXTRONIK_VALUE_FUNCTION_NOT_AVAILABLE] + telegram_data[1][IDX_BLK][0].field.write_pending = True + telegram_data[2][IDX_TLG].data = [None] + telegram_data[2][IDX_BLK][0].field.write_pending = True + telegram_data[3][IDX_BLK][0].field.write_pending = True valid = self.interface._integrate_data(telegram_data) assert valid # [index data, index for blocks, index for part] - assert telegram_data[0][0][0].field.raw == 18 - assert telegram_data[0][0][1].field.raw == 4 - assert telegram_data[1][0][0].field.raw is None - assert telegram_data[2][0][0].field.raw is None - assert telegram_data[3][0][0].field.raw == 17 # no update + assert telegram_data[0][IDX_BLK][0].field.raw == 19 + assert not telegram_data[0][IDX_BLK][0].field.write_pending + assert telegram_data[0][IDX_BLK][1].field.raw == 5 + assert not telegram_data[0][IDX_BLK][1].field.write_pending + assert telegram_data[1][IDX_BLK][0].field.raw is None + assert not telegram_data[1][IDX_BLK][0].field.write_pending # update with none -> reset flag + assert telegram_data[2][IDX_BLK][0].field.raw is None + assert not telegram_data[2][IDX_BLK][0].field.write_pending # update with none -> reset flag + assert telegram_data[3][IDX_BLK][0].field.raw == 17 # no update + assert not telegram_data[3][IDX_BLK][0].field.write_pending + + orig_preserve = LuxtronikSettings.preserve_last_read_value_on_fail + LuxtronikSettings.preserve_last_read_value_on_fail = True # integrate too less -> error - telegram_data[0][1].data = [18] - telegram_data[1][1].data = [1] - telegram_data[2][1].data = [None] + telegram_data[0][IDX_TLG].data = [18] + telegram_data[0][IDX_BLK][0].field.write_pending = True + telegram_data[0][IDX_BLK][1].field.write_pending = True + telegram_data[1][IDX_TLG].data = [2] + telegram_data[1][IDX_BLK][0].field.write_pending = True + telegram_data[2][IDX_TLG].data = [None] valid = self.interface._integrate_data(telegram_data) assert not valid # [index data, index for blocks, index for part] - assert telegram_data[0][0][0].field.raw == 18 - assert telegram_data[0][0][1].field.raw == 4 # no update - assert telegram_data[1][0][0].field.raw == 1 - assert telegram_data[2][0][0].field.raw is None - assert telegram_data[3][0][0].field.raw == 17 # no update + assert telegram_data[0][IDX_BLK][0].field.raw == 19 # preserve -> no update + assert telegram_data[0][IDX_BLK][0].field.write_pending # preserve -> no update + assert telegram_data[0][IDX_BLK][1].field.raw == 5 # preserve -> no update + assert telegram_data[0][IDX_BLK][1].field.write_pending # preserve -> no update + assert telegram_data[1][IDX_BLK][0].field.raw == 2 + assert not telegram_data[1][IDX_BLK][0].field.write_pending + assert telegram_data[2][IDX_BLK][0].field.raw is None + assert telegram_data[3][IDX_BLK][0].field.raw == 17 # no update + + LuxtronikSettings.preserve_last_read_value_on_fail = False + + # integrate too less -> error + telegram_data[0][IDX_TLG].data = [18] + telegram_data[0][IDX_BLK][0].field.write_pending = True + telegram_data[0][IDX_BLK][1].field.write_pending = True + telegram_data[1][IDX_TLG].data = [2] + telegram_data[1][IDX_BLK][0].field.write_pending = True + telegram_data[2][IDX_TLG].data = [None] + valid = self.interface._integrate_data(telegram_data) + assert not valid + # [index data, index for blocks, index for part] + assert telegram_data[0][IDX_BLK][0].field.raw is None # no preserve -> update + assert not telegram_data[0][IDX_BLK][0].field.write_pending # no preserve -> update + assert telegram_data[0][IDX_BLK][1].field.raw is None # no preserve -> update + assert not telegram_data[0][IDX_BLK][1].field.write_pending # no preserve -> update + assert telegram_data[1][IDX_BLK][0].field.raw == 2 + assert not telegram_data[1][IDX_BLK][0].field.write_pending + assert telegram_data[2][IDX_BLK][0].field.raw is None + assert telegram_data[3][IDX_BLK][0].field.raw == 17 # no update + + LuxtronikSettings.preserve_last_read_value_on_fail = orig_preserve def test_prepare(self): definition = HOLDINGS_DEFINITIONS[2] @@ -1244,7 +1318,7 @@ def check_definitions(self, interface): for d in definitions: assert d.name in vector assert d in interface.holdings - for f in vector: + for f in vector.values(): assert f.name in definitions assert f.name in interface.holdings @@ -1255,7 +1329,7 @@ def check_definitions(self, interface): for d in definitions: assert d.name in vector assert d in interface.inputs - for f in vector: + for f in vector.values(): assert f.name in definitions assert f.name in interface.inputs diff --git a/tests/shi/test_shi_modbus.py b/tests/shi/test_shi_modbus.py index ba432418..1d0145ee 100644 --- a/tests/shi/test_shi_modbus.py +++ b/tests/shi/test_shi_modbus.py @@ -95,7 +95,6 @@ def test_no_connection(self): # Cannot connect to read holdings data = LuxtronikSmartHomeReadHoldingsTelegram(0, 1) result = self.modbus_interface.send(data) - print(data.data) assert not result # Cannot connect to write holdings diff --git a/tests/shi/test_shi_vector.py b/tests/shi/test_shi_vector.py index a232c32d..4cf149ea 100644 --- a/tests/shi/test_shi_vector.py +++ b/tests/shi/test_shi_vector.py @@ -5,23 +5,35 @@ from luxtronik.shi.holdings import Holdings from luxtronik.shi.inputs import Inputs -""" -The test was originally written for "False". -Since "True" is already checked in "test_definitions.py", -we continue to use "False" consistently here. -""" -Base.concatenate_multiple_data_chunks = False ############################################################################### # Tests ############################################################################### + +class TestType(Base): + """ + The test was originally written for "False". + Since "True" is already checked in "test_definitions.py", + we continue to use "False" consistently here. + """ + Base.concatenate_multiple_data_chunks = False + + @classmethod + def to_heatpump(cls, value): + return value + + @classmethod + def from_heatpump(cls, value): + return value + + def_list = [ { "index": 5, "count": 1, "names": ["field_5"], - "type": Base, + "type": TestType, "writeable": False, "since": "1.1", "until": "1.2", @@ -30,7 +42,7 @@ "index": 7, "count": 2, "names": ["field_7"], - "type": Base, + "type": TestType, "writeable": True, "since": "3.1", }, @@ -38,7 +50,7 @@ "index": 9, "count": 1, "names": ["field_9a"], - "type": Base, + "type": TestType, "writeable": True, "until": "1.3", }, @@ -46,7 +58,7 @@ "index": 9, "count": 2, "names": ["field_9"], - "type": Base, + "type": TestType, "writeable": True, "until": "3.3", }, @@ -54,7 +66,7 @@ "index": -1, "count": 1, "names": ["field_invalid"], - "type": Base, + "type": TestType, "writeable": True, "until": "3.3", }, @@ -82,17 +94,23 @@ def test_create(self): field = DataVectorTest.create_any_field(7) assert field.name == 'field_7' assert field.writeable - assert type(field) is Base + assert type(field) is TestType # create not available field field = DataVectorTest.create_any_field('BAR') assert field is None + # create field by def + field = DataVectorTest.create_any_field(TEST_DEFINITIONS._definitions[2]) + assert field.name == 'field_9a' + assert field.writeable + assert type(field) is TestType + # create versioned data vector data_vector = DataVectorTest(parse_version("1.2")) assert data_vector.version == (1, 2, 0, 0) assert len(data_vector) == 3 - assert len(data_vector._data.pairs()) == 3 + assert len(data_vector._data.pairs) == 3 assert not data_vector._read_blocks_up_to_date assert len(data_vector._read_blocks) == 0 @@ -100,7 +118,7 @@ def test_create(self): field = data_vector.create_field(5) assert field.name == 'field_5' assert not field.writeable - assert type(field) is Base + assert type(field) is TestType # create not available field (not available) field = data_vector.create_field(6) @@ -114,13 +132,13 @@ def test_create(self): field = data_vector.create_field(9) assert field.name == 'field_9' assert field.writeable - assert type(field) is Base + assert type(field) is TestType # create index-overloaded version-dependent field field = data_vector.create_field('field_9a') assert field.name == 'field_9a' assert field.writeable - assert type(field) is Base + assert type(field) is TestType # create versioned data vector data_vector = DataVectorTest(parse_version("3.0")) @@ -145,7 +163,7 @@ def test_create(self): field = data_vector.create_field(9) assert field.name == 'field_9' assert field.writeable - assert type(field) is Base + assert type(field) is TestType # create invalid field (not available) field = data_vector.create_field('field_invalid') @@ -192,7 +210,7 @@ def test_add(self): assert field.name == 'field_5' # Add available field - field_9 = Base('field_9', False) + field_9 = TestType('field_9', False) field = data_vector.add(field_9) assert 9 in data_vector assert len(data_vector) == 2 @@ -205,7 +223,7 @@ def test_add(self): assert field == field_9 # Add available field with same name - field_9_2 = Base('field_9', False) + field_9_2 = TestType('field_9', False) field = data_vector.add(field_9_2) assert field_9_2 not in data_vector assert len(data_vector) == 2 @@ -216,7 +234,7 @@ def test_add(self): field = data_vector.add(def_9a) assert def_9a in data_vector assert len(data_vector) == 3 - assert len(data_vector.data._pairs) == 3 + assert len(data_vector.data.pairs) == 3 assert field.name == 'field_9a' # Get via index (last added) @@ -252,13 +270,15 @@ def test_iter(self): for index, definition in enumerate(data_vector): if index == 0: assert definition.index == 5 - assert definition.name == 'field_5' + assert definition.name == "field_5" if index == 1: assert definition.index == 9 - assert definition.name == 'field_9a' + assert definition.name == "field_9a" if index == 2: assert definition.index == 9 - assert definition.name == 'field_9' + assert definition.name == "field_9" + if index == 3: + assert False for index, field in enumerate(data_vector.values()): if index == 0: @@ -267,20 +287,21 @@ def test_iter(self): assert field.name == 'field_9a' if index == 2: assert field.name == 'field_9' + if index == 3: + assert False for index, (definition, field) in enumerate(data_vector.items()): if index == 0: assert definition.index == 5 - assert definition.name == 'field_5' assert field.name == 'field_5' if index == 1: assert definition.index == 9 - assert definition.name == 'field_9a' assert field.name == 'field_9a' if index == 2: assert definition.index == 9 - assert definition.name == 'field_9' assert field.name == 'field_9' + if index == 3: + assert False def test_set(self): data_vector = DataVectorTest(parse_version("1.1.2")) @@ -406,7 +427,7 @@ def test_version_none(self): assert len(data_vector) == 3 data_vector.add(10) # field_9a alias assert len(data_vector) == 4 - assert len(data_vector._data._pairs) == 4 + assert len(data_vector.data.pairs) == 4 class TestHoldings: @@ -416,7 +437,6 @@ def test_init(self): """Test cases for initialization""" holdings = Holdings() assert holdings.name == "holding" - assert holdings.holdings == holdings._data class TestInputs: @@ -426,4 +446,3 @@ def test_init(self): """Test cases for initialization""" inputs = Inputs() assert inputs.name == "input" - assert inputs.inputs == inputs._data diff --git a/tests/test_LuxtronikData.py b/tests/test_LuxtronikData.py index 39ca2e52..f1e2bb62 100644 --- a/tests/test_LuxtronikData.py +++ b/tests/test_LuxtronikData.py @@ -65,9 +65,9 @@ def test_get_firmware_version(self): @pytest.mark.parametrize("vector, index, names", [ - ("para", 1106, ["ID_Einst_SilenceTimer_13", "Unknown_Parameter_1106"]), - ("para", 1109, ["ID_Einst_SilenceTimer_16", "Unknown_Parameter_1109"]), - ("calc", 232, ["Vapourisation_Temperature", "Unknown_Calculation_232"]), + ("para", 1106, ["ID_Einst_SilenceTimer_13"]), + ("para", 1109, ["ID_Einst_SilenceTimer_16"]), + ("calc", 232, ["Vapourisation_Temperature"]), ("calc", 241, ["HUP_PWM", "Circulation_Pump"]), ("visi", 182, ["ID_Visi_Heizung_Zeitschaltprogramm", "ID_Visi_Heizung_Zeitschlaltprogramm"]), ("visi", 326, ["Unknown_Visibility_326"]), diff --git a/tests/test_collections.py b/tests/test_collections.py index a1f41adc..3dee3e0c 100644 --- a/tests/test_collections.py +++ b/tests/test_collections.py @@ -1,4 +1,5 @@ + from luxtronik.collections import ( get_data_arr, integrate_data, @@ -226,39 +227,42 @@ def test_init(self): d = LuxtronikFieldsDictionary() assert type(d._def_lookup) is LuxtronikDefinitionsDictionary + assert d.def_dict is d._def_lookup assert type(d._field_lookup) is dict - assert len(d._field_lookup.values()) == 0 + assert d.field_dict is d._field_lookup assert type(d._pairs) is list - assert len(d._pairs) == 0 + assert d.pairs is d._pairs + assert len(d.field_dict) == 0 + assert len(d.pairs) == 0 def test_add(self): d = LuxtronikFieldsDictionary() assert len(d) == 0 - assert len(d.pairs()) == 0 + assert len(d.pairs) == 0 u = LuxtronikDefinition.unknown(1, "test", 0) f = u.create_field() d.add(u, f) assert len(d) == 1 - assert len(d._pairs) == 1 - assert d._pairs[0].definition is u - assert d._pairs[0].field is f + assert len(d.pairs) == 1 + assert d.pairs[0].definition is u + assert d.pairs[0].field is f u = LuxtronikDefinition.unknown(2, "test", 0) f = u.create_field() d.add(u, f) assert len(d) == 2 - assert len(d._pairs) == 2 - assert d._pairs[1].definition is u - assert d._pairs[1].field is f + assert len(d.pairs) == 2 + assert d.pairs[1].definition is u + assert d.pairs[1].field is f u = LuxtronikDefinition.unknown(0, "test", 0) f = u.create_field() d.add_sorted(u, f) assert len(d) == 3 assert len(d._pairs) == 3 - assert d._pairs[0].definition is u - assert d._pairs[0].field is f + assert d.pairs[0].definition is u + assert d.pairs[0].field is f def create_instance(self): d = LuxtronikFieldsDictionary() @@ -284,8 +288,8 @@ def create_instance(self): def test_len(self): d, _, _ = self.create_instance() # 3 different indices - assert len(d) == 3 - assert len(d.pairs()) == 4 + assert len(d) == 4 + assert len(d.pairs) == 4 def test_get_contains(self): d, u, f = self.create_instance() @@ -311,42 +315,55 @@ def test_get_contains(self): def test_iter(self): d, _, _ = self.create_instance() - for idx, key in enumerate(d): + for idx, d in enumerate(d): if idx == 0: - assert key == 1 + assert d.name == "unknown_test_1" + assert d.index == 1 if idx == 1: - assert key == 2 + assert d.name == "unknown_test_2" + assert d.index == 2 if idx == 2: - assert key == 3 + assert d.name == "base2" + assert d.index == 2 + if idx == 3: + assert d.name == "base3" + assert d.index == 3 def test_values(self): d, _, _ = self.create_instance() - for idx, value in enumerate(d.values()): + for idx, f in enumerate(d.values()): if idx == 0: - assert type(value) is Unknown - assert value.name == "unknown_test_1" + assert type(f) is Unknown + assert f.name == "unknown_test_1" if idx == 1: - assert type(value) is Base - assert value.name == "base2" + assert type(f) is Unknown + assert f.name == "unknown_test_2" if idx == 2: - assert type(value) is Base - assert value.name == "base3" + assert type(f) is Base + assert f.name == "base2" + if idx == 3: + assert type(f) is Base + assert f.name == "base3" def test_items(self): d, _, _ = self.create_instance() - for idx, (key, value) in enumerate(d.items()): + for idx, (d, f) in enumerate(d.items()): if idx == 0: - assert key == 1 - assert type(value) is Unknown - assert value.name == "unknown_test_1" + assert d.index == 1 + assert type(f) is Unknown + assert f.name == "unknown_test_1" if idx == 1: - assert key == 2 - assert type(value) is Base - assert value.name == "base2" + assert d.index == 2 + assert type(f) is Unknown + assert f.name == "unknown_test_2" if idx == 2: - assert key == 3 - assert type(value) is Base - assert value.name == "base3" + assert d.index == 2 + assert type(f) is Base + assert f.name == "base2" + if idx == 3: + assert d.index == 3 + assert type(f) is Base + assert f.name == "base3" class MyTestClass: pass diff --git a/tests/test_compatibility.py b/tests/test_compatibility.py index 4a0f80c3..30a922b8 100644 --- a/tests/test_compatibility.py +++ b/tests/test_compatibility.py @@ -2,1943 +2,2243 @@ # pylint: disable=too-few-public-methods,invalid-name,too-many-lines +import logging + from luxtronik import ( Calculations, Parameters, Visibilities, + Inputs, + Holdings, +) + +from luxtronik.datatypes import ( + Base, + BivalenceLevel, + Bool, + BufferType, + Celsius, + CelsiusInt16, + CelsiusUInt16, + Character, + ControlMode, + CoolingMode, + Count, + Energy, + Errorcode, + Flow, + Frequency, + FullVersion, + HeatPumpStatus, + HeatingMode, + HeatpumpCode, + HotWaterMode, + Hours, + Icon, + Kelvin, + KelvinInt16, + Level, + LevelMode, + LockMode, + LpcMode, + MainMenuStatusLine1, + MainMenuStatusLine2, + MainMenuStatusLine3, + MajorMinorVersion, + Minutes, + MixedCircuitMode, + ModeStatus, + OnOffMode, + OperationMode, + Percent2, + PoolMode, + Power, + PowerKW, + Pressure, + SecOperationMode, + Seconds, + SolarMode, + Speed, + SwitchoffFile, + TimeOfDay2, + TimerProgram, + Timestamp, + Unknown, + VentilationMode, + Version, + Voltage, ) +logging.disable(logging.CRITICAL) + + +class Pulses(Base): + pass + +class IPAddress(Base): + pass + class TestCompatibility: """Test suite for compatibilities""" def test_compatibilities(self): """Test cases for compatibilities""" + # Structure of entries: + # old_name: (old_index, old_type[, type_intentionally_changed]) + # + # old_name: Previously used but still supported name + # old_index: Index assigned to this name + # type_intentionally_changed: We also check type changes. + # If this optional flag is set to True, you can skip the type check + paras = { # Status of 0.3.14: - "ID_Transfert_LuxNet": 0, - "ID_Einst_WK_akt": 1, - "ID_Einst_BWS_akt": 2, - "ID_Ba_Hz_akt": 3, - "ID_Ba_Bw_akt": 4, - "ID_Ba_Al_akt": 5, - "ID_SU_FrkdHz": 6, - "ID_SU_FrkdBw": 7, - "ID_SU_FrkdAl": 8, - "ID_Einst_HReg_akt": 9, - "ID_Einst_HzHwMAt_akt": 10, - "ID_Einst_HzHwHKE_akt": 11, - "ID_Einst_HzHKRANH_akt": 12, - "ID_Einst_HzHKRABS_akt": 13, - "ID_Einst_HzMK1E_akt": 14, - "ID_Einst_HzMK1ANH_akt": 15, - "ID_Einst_HzMK1ABS_akt": 16, - "ID_Einst_HzFtRl_akt": 17, - "ID_Einst_HzFtMK1Vl_akt": 18, - "ID_Einst_SUBW_akt": 19, - "ID_Einst_BwTDI_akt_MO": 20, - "ID_Einst_BwTDI_akt_DI": 21, - "ID_Einst_BwTDI_akt_MI": 22, - "ID_Einst_BwTDI_akt_DO": 23, - "ID_Einst_BwTDI_akt_FR": 24, - "ID_Einst_BwTDI_akt_SA": 25, - "ID_Einst_BwTDI_akt_SO": 26, - "ID_Einst_BwTDI_akt_AL": 27, - "ID_Einst_AnlKonf_akt": 28, - "ID_Einst_Sprache_akt": 29, - "ID_Switchoff_Zahler": 30, - "ID_Switchoff_index": 31, - "ID_Einst_EvuTyp_akt": 32, - "ID_Einst_RFVEinb_akt": 33, - "ID_Einst_AbtZykMax_akt": 34, - "ID_Einst_HREinb_akt": 35, - "ID_Einst_ZWE1Art_akt": 36, - "ID_Einst_ZWE1Fkt_akt": 37, - "ID_Einst_ZWE2Art_akt": 38, - "ID_Einst_ZWE2Fkt_akt": 39, - "ID_Einst_BWBer_akt": 40, - "ID_Einst_En_Inst": 41, - "ID_Einst_MK1Typ_akt": 42, - "ID_Einst_ABTLuft_akt": 43, - "ID_Einst_TLAbt_akt": 44, - "ID_Einst_LAbtTime_akt": 45, - "ID_Einst_ASDTyp_akt": 46, - "ID_Einst_LGST_akt": 47, - "ID_Einst_BwWpTime_akt": 48, - "ID_Einst_Popt_akt": 49, - "ID_Einst_Kurzprog_akt": 50, - "ID_Timer_Kurzprog_akt": 51, - "ID_Einst_ManAbt_akt": 52, - "ID_Einst_Ahz_akt": 53, - "ID_Einst_TVL_Ahz_1": 54, - "ID_Einst_TVL_Ahz_2": 55, - "ID_Einst_TVL_Ahz_3": 56, - "ID_Einst_TVL_Ahz_4": 57, - "ID_Einst_TVL_Ahz_5": 58, - "ID_Einst_TVL_Ahz_6": 59, - "ID_Einst_TVL_Ahz_7": 60, - "ID_Einst_TVL_Ahz_8": 61, - "ID_Einst_TVL_Ahz_9": 62, - "ID_Einst_TVL_Ahz_10": 63, - "ID_Einst_TVL_Std_1": 64, - "ID_Einst_TVL_Std_2": 65, - "ID_Einst_TVL_Std_3": 66, - "ID_Einst_TVL_Std_4": 67, - "ID_Einst_TVL_Std_5": 68, - "ID_Einst_TVL_Std_6": 69, - "ID_Einst_TVL_Std_7": 70, - "ID_Einst_TVL_Std_8": 71, - "ID_Einst_TVL_Std_9": 72, - "ID_Einst_TVL_Std_10": 73, - "ID_Einst_BWS_Hyst_akt": 74, - "ID_Temp_TBW_BwHD_saved": 75, - "ID_Einst_ABT1_akt": 76, - "ID_Einst_LABTpaus_akt": 77, - "ID_AHZ_state_akt": 78, - "ID_Sollwert_TRL_HZ_AHZ": 79, - "ID_AHP_valid_records": 80, - "ID_Timer_AHZ_akt": 81, - "ID_Einst_BWTINP_akt": 82, - "ID_Einst_ZUPTYP_akt": 83, - "ID_Sollwert_TLG_max": 84, - "ID_Einst_BWZIP_akt": 85, - "ID_Einst_ERRmZWE_akt": 86, - "ID_Einst_TRBegr_akt": 87, - "ID_Einst_HRHyst_akt": 88, - "ID_Einst_TRErhmax_akt": 89, - "ID_Einst_ZWEFreig_akt": 90, - "ID_Einst_TAmax_akt": 91, - "ID_Einst_TAmin_akt": 92, - "ID_Einst_TWQmin_akt": 93, - "ID_Einst_THGmax_akt": 94, - "ID_Einst_FRGT2VD_akt": 95, - "ID_Einst_TV2VDBW_akt": 96, - "ID_Einst_SuAll_akt": 97, - "ID_Einst_TAbtEnd_akt": 98, - "ID_Einst_NrKlingel_akt": 99, - "ID_Einst_BWStyp_akt": 100, - "ID_Einst_ABT2_akt": 101, - "ID_Einst_UeVd_akt": 102, - "ID_Einst_RTyp_akt": 103, - "ID_Einst_AhpM_akt": 104, - "ID_Soll_BWS_akt": 105, - "ID_Timer_Password": 106, - "ID_Einst_Zugangscode": 107, - "ID_Einst_BA_Kuehl_akt": 108, - "ID_Sollwert_Kuehl1_akt": 109, - "ID_Einst_KuehlFreig_akt": 110, - "ID_Einst_TAbsMin_akt": 111, - "ID_TWQmin_saved": 112, - "ID_CWP_saved": 113, - "ID_Einst_Anode_akt": 114, - "ID_Timer_pexoff_akt": 115, - "ID_Einst_AnlPrio_Hzakt": 116, - "ID_Einst_AnlPrio_Bwakt": 117, - "ID_Einst_AnlPrio_Swakt": 118, - "ID_Ba_Sw_akt": 119, - "ID_Einst_RTypMK1_akt": 120, - "ID_Einst_RTypMK2_akt": 121, - "ID_Einst_TDC_Ein_akt": 122, - "ID_Einst_TDC_Aus_akt": 123, - "ID_Einst_TDC_Max_akt": 124, - "ID_Einst_HysHzExEn_akt": 125, - "ID_Einst_HysBwExEn_akt": 126, - "ID_Einst_ZWE3Art_akt": 127, - "ID_Einst_ZWE3Fkt_akt": 128, - "ID_Einst_HzSup_akt": 129, - "ID_Einst_MK2Typ_akt": 130, - "ID_Einst_KuTyp_akt": 131, - "ID_Sollwert_KuCft1_akt": 132, - "ID_Sollwert_KuCft2_akt": 133, - "ID_Sollwert_AtDif1_akt": 134, - "ID_Sollwert_AtDif2_akt": 135, - "ID_SU_FrkdSwb": 136, - "ID_Einst_SwbBer_akt": 137, - "ID_Einst_TV2VDSWB_akt": 138, - "ID_Einst_MinSwan_Time_akt": 139, - "ID_Einst_SuMk2_akt": 140, - "ID_Einst_HzMK2E_akt": 141, - "ID_Einst_HzMK2ANH_akt": 142, - "ID_Einst_HzMK2ABS_akt": 143, - "ID_Einst_HzMK2Hgr_akt": 144, - "ID_Einst_HzFtMK2Vl_akt": 145, - "ID_Temp_THG_BwHD_saved": 146, - "ID_Temp_TA_BwHD_saved": 147, - "ID_Einst_BwHup_akt": 148, - "ID_Einst_TVLmax_akt": 149, - "ID_Einst_MK1LzFaktor_akt": 150, - "ID_Einst_MK2LzFaktor_akt": 151, - "ID_Einst_MK1PerFaktor_akt": 152, - "ID_Einst_MK2PerFaktor_akt": 153, - "ID_Entl_Zyklus_akt": 154, - "ID_Einst_Entl_time_akt": 155, - "ID_Entl_Pause": 156, - "ID_Entl_timer": 157, - "ID_Einst_Entl_akt": 158, - "ID_Ahz_HLeist_confirmed": 159, - "ID_FirstInit_akt": 160, - "ID_Einst_SuAll_akt2": 161, - "ID_Einst_SuAllWo_zeit_0_0": 162, - "ID_Einst_SuAllWo_zeit_0_1": 163, - "ID_Einst_SuAllWo_zeit_1_0": 164, - "ID_Einst_SuAllWo_zeit_1_1": 165, - "ID_Einst_SuAllWo_zeit_2_0": 166, - "ID_Einst_SuAllWo_zeit_2_1": 167, - "ID_Einst_SuAll25_zeit_0_0": 168, - "ID_Einst_SuAll25_zeit_0_1": 169, - "ID_Einst_SuAll25_zeit_1_0": 170, - "ID_Einst_SuAll25_zeit_1_1": 171, - "ID_Einst_SuAll25_zeit_2_0": 172, - "ID_Einst_SuAll25_zeit_2_1": 173, - "ID_Einst_SuAll25_zeit_0_2": 174, - "ID_Einst_SuAll25_zeit_0_3": 175, - "ID_Einst_SuAll25_zeit_1_2": 176, - "ID_Einst_SuAll25_zeit_1_3": 177, - "ID_Einst_SuAll25_zeit_2_2": 178, - "ID_Einst_SuAll25_zeit_2_3": 179, - "ID_Einst_SuAllTg_zeit_0_0": 180, - "ID_Einst_SuAllTg_zeit_0_1": 181, - "ID_Einst_SuAllTg_zeit_1_0": 182, - "ID_Einst_SuAllTg_zeit_1_1": 183, - "ID_Einst_SuAllTg_zeit_2_0": 184, - "ID_Einst_SuAllTg_zeit_2_1": 185, - "ID_Einst_SuAllTg_zeit_0_2": 186, - "ID_Einst_SuAllTg_zeit_0_3": 187, - "ID_Einst_SuAllTg_zeit_1_2": 188, - "ID_Einst_SuAllTg_zeit_1_3": 189, - "ID_Einst_SuAllTg_zeit_2_2": 190, - "ID_Einst_SuAllTg_zeit_2_3": 191, - "ID_Einst_SuAllTg_zeit_0_4": 192, - "ID_Einst_SuAllTg_zeit_0_5": 193, - "ID_Einst_SuAllTg_zeit_1_4": 194, - "ID_Einst_SuAllTg_zeit_1_5": 195, - "ID_Einst_SuAllTg_zeit_2_4": 196, - "ID_Einst_SuAllTg_zeit_2_5": 197, - "ID_Einst_SuAllTg_zeit_0_6": 198, - "ID_Einst_SuAllTg_zeit_0_7": 199, - "ID_Einst_SuAllTg_zeit_1_6": 200, - "ID_Einst_SuAllTg_zeit_1_7": 201, - "ID_Einst_SuAllTg_zeit_2_6": 202, - "ID_Einst_SuAllTg_zeit_2_7": 203, - "ID_Einst_SuAllTg_zeit_0_8": 204, - "ID_Einst_SuAllTg_zeit_0_9": 205, - "ID_Einst_SuAllTg_zeit_1_8": 206, - "ID_Einst_SuAllTg_zeit_1_9": 207, - "ID_Einst_SuAllTg_zeit_2_8": 208, - "ID_Einst_SuAllTg_zeit_2_9": 209, - "ID_Einst_SuAllTg_zeit_0_10": 210, - "ID_Einst_SuAllTg_zeit_0_11": 211, - "ID_Einst_SuAllTg_zeit_1_10": 212, - "ID_Einst_SuAllTg_zeit_1_11": 213, - "ID_Einst_SuAllTg_zeit_2_10": 214, - "ID_Einst_SuAllTg_zeit_2_11": 215, - "ID_Einst_SuAllTg_zeit_0_12": 216, - "ID_Einst_SuAllTg_zeit_0_13": 217, - "ID_Einst_SuAllTg_zeit_1_12": 218, - "ID_Einst_SuAllTg_zeit_1_13": 219, - "ID_Einst_SuAllTg_zeit_2_12": 220, - "ID_Einst_SuAllTg_zeit_2_13": 221, - "ID_Einst_SuHkr_akt": 222, - "ID_Einst_SuHkrW0_zeit_0_0": 223, - "ID_Einst_SuHkrW0_zeit_0_1": 224, - "ID_Einst_SuHkrW0_zeit_1_0": 225, - "ID_Einst_SuHkrW0_zeit_1_1": 226, - "ID_Einst_SuHkrW0_zeit_2_0": 227, - "ID_Einst_SuHkrW0_zeit_2_1": 228, - "ID_Einst_SuHkr25_zeit_0_0": 229, - "ID_Einst_SuHkr25_zeit_0_1": 230, - "ID_Einst_SuHkr25_zeit_1_0": 231, - "ID_Einst_SuHkr25_zeit_1_1": 232, - "ID_Einst_SuHkr25_zeit_2_0": 233, - "ID_Einst_SuHkr25_zeit_2_1": 234, - "ID_Einst_SuHkr25_zeit_0_2": 235, - "ID_Einst_SuHkr25_zeit_0_3": 236, - "ID_Einst_SuHkr25_zeit_1_2": 237, - "ID_Einst_SuHkr25_zeit_1_3": 238, - "ID_Einst_SuHkr25_zeit_2_2": 239, - "ID_Einst_SuHkr25_zeit_2_3": 240, - "ID_Einst_SuHkrTG_zeit_0_0": 241, - "ID_Einst_SuHkrTG_zeit_0_1": 242, - "ID_Einst_SuHkrTG_zeit_1_0": 243, - "ID_Einst_SuHkrTG_zeit_1_1": 244, - "ID_Einst_SuHkrTG_zeit_2_0": 245, - "ID_Einst_SuHkrTG_zeit_2_1": 246, - "ID_Einst_SuHkrTG_zeit_0_2": 247, - "ID_Einst_SuHkrTG_zeit_0_3": 248, - "ID_Einst_SuHkrTG_zeit_1_2": 249, - "ID_Einst_SuHkrTG_zeit_1_3": 250, - "ID_Einst_SuHkrTG_zeit_2_2": 251, - "ID_Einst_SuHkrTG_zeit_2_3": 252, - "ID_Einst_SuHkrTG_zeit_0_4": 253, - "ID_Einst_SuHkrTG_zeit_0_5": 254, - "ID_Einst_SuHkrTG_zeit_1_4": 255, - "ID_Einst_SuHkrTG_zeit_1_5": 256, - "ID_Einst_SuHkrTG_zeit_2_4": 257, - "ID_Einst_SuHkrTG_zeit_2_5": 258, - "ID_Einst_SuHkrTG_zeit_0_6": 259, - "ID_Einst_SuHkrTG_zeit_0_7": 260, - "ID_Einst_SuHkrTG_zeit_1_6": 261, - "ID_Einst_SuHkrTG_zeit_1_7": 262, - "ID_Einst_SuHkrTG_zeit_2_6": 263, - "ID_Einst_SuHkrTG_zeit_2_7": 264, - "ID_Einst_SuHkrTG_zeit_0_8": 265, - "ID_Einst_SuHkrTG_zeit_0_9": 266, - "ID_Einst_SuHkrTG_zeit_1_8": 267, - "ID_Einst_SuHkrTG_zeit_1_9": 268, - "ID_Einst_SuHkrTG_zeit_2_8": 269, - "ID_Einst_SuHkrTG_zeit_2_9": 270, - "ID_Einst_SuHkrTG_zeit_0_10": 271, - "ID_Einst_SuHkrTG_zeit_0_11": 272, - "ID_Einst_SuHkrTG_zeit_1_10": 273, - "ID_Einst_SuHkrTG_zeit_1_11": 274, - "ID_Einst_SuHkrTG_zeit_2_10": 275, - "ID_Einst_SuHkrTG_zeit_2_11": 276, - "ID_Einst_SuHkrTG_zeit_0_12": 277, - "ID_Einst_SuHkrTG_zeit_0_13": 278, - "ID_Einst_SuHkrTG_zeit_1_12": 279, - "ID_Einst_SuHkrTG_zeit_1_13": 280, - "ID_Einst_SuHkrTG_zeit_2_12": 281, - "ID_Einst_SuHkrTG_zeit_2_13": 282, - "ID_Einst_SuMk1_akt": 283, - "ID_Einst_SuMk1W0_zeit_0_0": 284, - "ID_Einst_SuMk1W0_zeit_0_1": 285, - "ID_Einst_SuMk1W0_zeit_1_0": 286, - "ID_Einst_SuMk1W0_zeit_1_1": 287, - "ID_Einst_SuMk1W0_zeit_2_0": 288, - "ID_Einst_SuMk1W0_zeit_2_1": 289, - "ID_Einst_SuMk125_zeit_0_0": 290, - "ID_Einst_SuMk125_zeit_0_1": 291, - "ID_Einst_SuMk125_zeit_1_0": 292, - "ID_Einst_SuMk125_zeit_1_1": 293, - "ID_Einst_SuMk125_zeit_2_0": 294, - "ID_Einst_SuMk125_zeit_2_1": 295, - "ID_Einst_SuMk125_zeit_0_2": 296, - "ID_Einst_SuMk125_zeit_0_3": 297, - "ID_Einst_SuMk125_zeit_1_2": 298, - "ID_Einst_SuMk125_zeit_1_3": 299, - "ID_Einst_SuMk125_zeit_2_2": 300, - "ID_Einst_SuMk125_zeit_2_3": 301, - "ID_Einst_SuMk1TG_zeit_0_0": 302, - "ID_Einst_SuMk1TG_zeit_0_1": 303, - "ID_Einst_SuMk1TG_zeit_1_0": 304, - "ID_Einst_SuMk1TG_zeit_1_1": 305, - "ID_Einst_SuMk1TG_zeit_2_0": 306, - "ID_Einst_SuMk1TG_zeit_2_1": 307, - "ID_Einst_SuMk1TG_zeit_0_2": 308, - "ID_Einst_SuMk1TG_zeit_0_3": 309, - "ID_Einst_SuMk1TG_zeit_1_2": 310, - "ID_Einst_SuMk1TG_zeit_1_3": 311, - "ID_Einst_SuMk1TG_zeit_2_2": 312, - "ID_Einst_SuMk1TG_zeit_2_3": 313, - "ID_Einst_SuMk1TG_zeit_0_4": 314, - "ID_Einst_SuMk1TG_zeit_0_5": 315, - "ID_Einst_SuMk1TG_zeit_1_4": 316, - "ID_Einst_SuMk1TG_zeit_1_5": 317, - "ID_Einst_SuMk1TG_zeit_2_4": 318, - "ID_Einst_SuMk1TG_zeit_2_5": 319, - "ID_Einst_SuMk1TG_zeit_0_6": 320, - "ID_Einst_SuMk1TG_zeit_0_7": 321, - "ID_Einst_SuMk1TG_zeit_1_6": 322, - "ID_Einst_SuMk1TG_zeit_1_7": 323, - "ID_Einst_SuMk1TG_zeit_2_6": 324, - "ID_Einst_SuMk1TG_zeit_2_7": 325, - "ID_Einst_SuMk1TG_zeit_0_8": 326, - "ID_Einst_SuMk1TG_zeit_0_9": 327, - "ID_Einst_SuMk1TG_zeit_1_8": 328, - "ID_Einst_SuMk1TG_zeit_1_9": 329, - "ID_Einst_SuMk1TG_zeit_2_8": 330, - "ID_Einst_SuMk1TG_zeit_2_9": 331, - "ID_Einst_SuMk1TG_zeit_0_10": 332, - "ID_Einst_SuMk1TG_zeit_0_11": 333, - "ID_Einst_SuMk1TG_zeit_1_10": 334, - "ID_Einst_SuMk1TG_zeit_1_11": 335, - "ID_Einst_SuMk1TG_zeit_2_10": 336, - "ID_Einst_SuMk1TG_zeit_2_11": 337, - "ID_Einst_SuMk1TG_zeit_0_12": 338, - "ID_Einst_SuMk1TG_zeit_0_13": 339, - "ID_Einst_SuMk1TG_zeit_1_12": 340, - "ID_Einst_SuMk1TG_zeit_1_13": 341, - "ID_Einst_SuMk1TG_zeit_2_12": 342, - "ID_Einst_SuMk1TG_zeit_2_13": 343, - "ID_Einst_SuMk2_akt2": 344, - "ID_Einst_SuMk2Wo_zeit_0_0": 345, - "ID_Einst_SuMk2Wo_zeit_0_1": 346, - "ID_Einst_SuMk2Wo_zeit_1_0": 347, - "ID_Einst_SuMk2Wo_zeit_1_1": 348, - "ID_Einst_SuMk2Wo_zeit_2_0": 349, - "ID_Einst_SuMk2Wo_zeit_2_1": 350, - "ID_Einst_SuMk225_zeit_0_0": 351, - "ID_Einst_SuMk225_zeit_0_1": 352, - "ID_Einst_SuMk225_zeit_1_0": 353, - "ID_Einst_SuMk225_zeit_1_1": 354, - "ID_Einst_SuMk225_zeit_2_0": 355, - "ID_Einst_SuMk225_zeit_2_1": 356, - "ID_Einst_SuMk225_zeit_0_2": 357, - "ID_Einst_SuMk225_zeit_0_3": 358, - "ID_Einst_SuMk225_zeit_1_2": 359, - "ID_Einst_SuMk225_zeit_1_3": 360, - "ID_Einst_SuMk225_zeit_2_2": 361, - "ID_Einst_SuMk225_zeit_2_3": 362, - "ID_Einst_SuMk2Tg_zeit_0_0": 363, - "ID_Einst_SuMk2Tg_zeit_0_1": 364, - "ID_Einst_SuMk2Tg_zeit_1_0": 365, - "ID_Einst_SuMk2Tg_zeit_1_1": 366, - "ID_Einst_SuMk2Tg_zeit_2_0": 367, - "ID_Einst_SuMk2Tg_zeit_2_1": 368, - "ID_Einst_SuMk2Tg_zeit_0_2": 369, - "ID_Einst_SuMk2Tg_zeit_0_3": 370, - "ID_Einst_SuMk2Tg_zeit_1_2": 371, - "ID_Einst_SuMk2Tg_zeit_1_3": 372, - "ID_Einst_SuMk2Tg_zeit_2_2": 373, - "ID_Einst_SuMk2Tg_zeit_2_3": 374, - "ID_Einst_SuMk2Tg_zeit_0_4": 375, - "ID_Einst_SuMk2Tg_zeit_0_5": 376, - "ID_Einst_SuMk2Tg_zeit_1_4": 377, - "ID_Einst_SuMk2Tg_zeit_1_5": 378, - "ID_Einst_SuMk2Tg_zeit_2_4": 379, - "ID_Einst_SuMk2Tg_zeit_2_5": 380, - "ID_Einst_SuMk2Tg_zeit_0_6": 381, - "ID_Einst_SuMk2Tg_zeit_0_7": 382, - "ID_Einst_SuMk2Tg_zeit_1_6": 383, - "ID_Einst_SuMk2Tg_zeit_1_7": 384, - "ID_Einst_SuMk2Tg_zeit_2_6": 385, - "ID_Einst_SuMk2Tg_zeit_2_7": 386, - "ID_Einst_SuMk2Tg_zeit_0_8": 387, - "ID_Einst_SuMk2Tg_zeit_0_9": 388, - "ID_Einst_SuMk2Tg_zeit_1_8": 389, - "ID_Einst_SuMk2Tg_zeit_1_9": 390, - "ID_Einst_SuMk2Tg_zeit_2_8": 391, - "ID_Einst_SuMk2Tg_zeit_2_9": 392, - "ID_Einst_SuMk2Tg_zeit_0_10": 393, - "ID_Einst_SuMk2Tg_zeit_0_11": 394, - "ID_Einst_SuMk2Tg_zeit_1_10": 395, - "ID_Einst_SuMk2Tg_zeit_1_11": 396, - "ID_Einst_SuMk2Tg_zeit_2_10": 397, - "ID_Einst_SuMk2Tg_zeit_2_11": 398, - "ID_Einst_SuMk2Tg_zeit_0_12": 399, - "ID_Einst_SuMk2Tg_zeit_0_13": 400, - "ID_Einst_SuMk2Tg_zeit_1_12": 401, - "ID_Einst_SuMk2Tg_zeit_1_13": 402, - "ID_Einst_SuMk2Tg_zeit_2_12": 403, - "ID_Einst_SuMk2Tg_zeit_2_13": 404, - "ID_Einst_SUBW_akt2": 405, - "ID_Einst_SuBwWO_zeit_0_0": 406, - "ID_Einst_SuBwWO_zeit_0_1": 407, - "ID_Einst_SuBwWO_zeit_1_0": 408, - "ID_Einst_SuBwWO_zeit_1_1": 409, - "ID_Einst_SuBwWO_zeit_2_0": 410, - "ID_Einst_SuBwWO_zeit_2_1": 411, - "ID_Einst_SuBwWO_zeit_3_0": 412, - "ID_Einst_SuBwWO_zeit_3_1": 413, - "ID_Einst_SuBwWO_zeit_4_0": 414, - "ID_Einst_SuBwWO_zeit_4_1": 415, - "ID_Einst_SuBw25_zeit_0_0": 416, - "ID_Einst_SuBw25_zeit_0_1": 417, - "ID_Einst_SuBw25_zeit_1_0": 418, - "ID_Einst_SuBw25_zeit_1_1": 419, - "ID_Einst_SuBw25_zeit_2_0": 420, - "ID_Einst_SuBw25_zeit_2_1": 421, - "ID_Einst_SuBw25_zeit_3_0": 422, - "ID_Einst_SuBw25_zeit_3_1": 423, - "ID_Einst_SuBw25_zeit_4_0": 424, - "ID_Einst_SuBw25_zeit_4_1": 425, - "ID_Einst_SuBw25_zeit_0_2": 426, - "ID_Einst_SuBw25_zeit_0_3": 427, - "ID_Einst_SuBw25_zeit_1_2": 428, - "ID_Einst_SuBw25_zeit_1_3": 429, - "ID_Einst_SuBw25_zeit_2_2": 430, - "ID_Einst_SuBw25_zeit_2_3": 431, - "ID_Einst_SuBw25_zeit_3_2": 432, - "ID_Einst_SuBw25_zeit_3_3": 433, - "ID_Einst_SuBw25_zeit_4_2": 434, - "ID_Einst_SuBw25_zeit_4_3": 435, - "ID_Einst_SuBwTG_zeit_0_0": 436, - "ID_Einst_SuBwTG_zeit_0_1": 437, - "ID_Einst_SuBwTG_zeit_1_0": 438, - "ID_Einst_SuBwTG_zeit_1_1": 439, - "ID_Einst_SuBwTG_zeit_2_0": 440, - "ID_Einst_SuBwTG_zeit_2_1": 441, - "ID_Einst_SuBwTG_zeit_3_0": 442, - "ID_Einst_SuBwTG_zeit_3_1": 443, - "ID_Einst_SuBwTG_zeit_4_0": 444, - "ID_Einst_SuBwTG_zeit_4_1": 445, - "ID_Einst_SuBwTG_zeit_0_2": 446, - "ID_Einst_SuBwTG_zeit_0_3": 447, - "ID_Einst_SuBwTG_zeit_1_2": 448, - "ID_Einst_SuBwTG_zeit_1_3": 449, - "ID_Einst_SuBwTG_zeit_2_2": 450, - "ID_Einst_SuBwTG_zeit_2_3": 451, - "ID_Einst_SuBwTG_zeit_3_2": 452, - "ID_Einst_SuBwTG_zeit_3_3": 453, - "ID_Einst_SuBwTG_zeit_4_2": 454, - "ID_Einst_SuBwTG_zeit_4_3": 455, - "ID_Einst_SuBwTG_zeit_0_4": 456, - "ID_Einst_SuBwTG_zeit_0_5": 457, - "ID_Einst_SuBwTG_zeit_1_4": 458, - "ID_Einst_SuBwTG_zeit_1_5": 459, - "ID_Einst_SuBwTG_zeit_2_4": 460, - "ID_Einst_SuBwTG_zeit_2_5": 461, - "ID_Einst_SuBwTG_zeit_3_4": 462, - "ID_Einst_SuBwTG_zeit_3_5": 463, - "ID_Einst_SuBwTG_zeit_4_4": 464, - "ID_Einst_SuBwTG_zeit_4_5": 465, - "ID_Einst_SuBwTG_zeit_0_6": 466, - "ID_Einst_SuBwTG_zeit_0_7": 467, - "ID_Einst_SuBwTG_zeit_1_6": 468, - "ID_Einst_SuBwTG_zeit_1_7": 469, - "ID_Einst_SuBwTG_zeit_2_6": 470, - "ID_Einst_SuBwTG_zeit_2_7": 471, - "ID_Einst_SuBwTG_zeit_3_6": 472, - "ID_Einst_SuBwTG_zeit_3_7": 473, - "ID_Einst_SuBwTG_zeit_4_6": 474, - "ID_Einst_SuBwTG_zeit_4_7": 475, - "ID_Einst_SuBwTG_zeit_0_8": 476, - "ID_Einst_SuBwTG_zeit_0_9": 477, - "ID_Einst_SuBwTG_zeit_1_8": 478, - "ID_Einst_SuBwTG_zeit_1_9": 479, - "ID_Einst_SuBwTG_zeit_2_8": 480, - "ID_Einst_SuBwTG_zeit_2_9": 481, - "ID_Einst_SuBwTG_zeit_3_8": 482, - "ID_Einst_SuBwTG_zeit_3_9": 483, - "ID_Einst_SuBwTG_zeit_4_8": 484, - "ID_Einst_SuBwTG_zeit_4_9": 485, - "ID_Einst_SuBwTG_zeit_0_10": 486, - "ID_Einst_SuBwTG_zeit_0_11": 487, - "ID_Einst_SuBwTG_zeit_1_10": 488, - "ID_Einst_SuBwTG_zeit_1_11": 489, - "ID_Einst_SuBwTG_zeit_2_10": 490, - "ID_Einst_SuBwTG_zeit_2_11": 491, - "ID_Einst_SuBwTG_zeit_3_10": 492, - "ID_Einst_SuBwTG_zeit_3_11": 493, - "ID_Einst_SuBwTG_zeit_4_10": 494, - "ID_Einst_SuBwTG_zeit_4_11": 495, - "ID_Einst_SuBwTG_zeit_0_12": 496, - "ID_Einst_SuBwTG_zeit_0_13": 497, - "ID_Einst_SuBwTG_zeit_1_12": 498, - "ID_Einst_SuBwTG_zeit_1_13": 499, - "ID_Einst_SuBwTG_zeit_2_12": 500, - "ID_Einst_SuBwTG_zeit_2_13": 501, - "ID_Einst_SuBwTG_zeit_3_12": 502, - "ID_Einst_SuBwTG_zeit_3_13": 503, - "ID_Einst_SuBwTG_zeit_4_12": 504, - "ID_Einst_SuBwTG_zeit_4_13": 505, - "ID_Einst_SuZIP_akt": 506, - "ID_Einst_SuZIPWo_zeit_0_0": 507, - "ID_Einst_SuZIPWo_zeit_0_1": 508, - "ID_Einst_SuZIPWo_zeit_1_0": 509, - "ID_Einst_SuZIPWo_zeit_1_1": 510, - "ID_Einst_SuZIPWo_zeit_2_0": 511, - "ID_Einst_SuZIPWo_zeit_2_1": 512, - "ID_Einst_SuZIPWo_zeit_3_0": 513, - "ID_Einst_SuZIPWo_zeit_3_1": 514, - "ID_Einst_SuZIPWo_zeit_4_0": 515, - "ID_Einst_SuZIPWo_zeit_4_1": 516, - "ID_Einst_SuZIP25_zeit_0_0": 517, - "ID_Einst_SuZIP25_zeit_0_1": 518, - "ID_Einst_SuZIP25_zeit_1_0": 519, - "ID_Einst_SuZIP25_zeit_1_1": 520, - "ID_Einst_SuZIP25_zeit_2_0": 521, - "ID_Einst_SuZIP25_zeit_2_1": 522, - "ID_Einst_SuZIP25_zeit_3_0": 523, - "ID_Einst_SuZIP25_zeit_3_1": 524, - "ID_Einst_SuZIP25_zeit_4_0": 525, - "ID_Einst_SuZIP25_zeit_4_1": 526, - "ID_Einst_SuZIP25_zeit_0_2": 527, - "ID_Einst_SuZIP25_zeit_0_3": 528, - "ID_Einst_SuZIP25_zeit_1_2": 529, - "ID_Einst_SuZIP25_zeit_1_3": 530, - "ID_Einst_SuZIP25_zeit_2_2": 531, - "ID_Einst_SuZIP25_zeit_2_3": 532, - "ID_Einst_SuZIP25_zeit_3_2": 533, - "ID_Einst_SuZIP25_zeit_3_3": 534, - "ID_Einst_SuZIP25_zeit_4_2": 535, - "ID_Einst_SuZIP25_zeit_4_3": 536, - "ID_Einst_SuZIPTg_zeit_0_0": 537, - "ID_Einst_SuZIPTg_zeit_0_1": 538, - "ID_Einst_SuZIPTg_zeit_1_0": 539, - "ID_Einst_SuZIPTg_zeit_1_1": 540, - "ID_Einst_SuZIPTg_zeit_2_0": 541, - "ID_Einst_SuZIPTg_zeit_2_1": 542, - "ID_Einst_SuZIPTg_zeit_3_0": 543, - "ID_Einst_SuZIPTg_zeit_3_1": 544, - "ID_Einst_SuZIPTg_zeit_4_0": 545, - "ID_Einst_SuZIPTg_zeit_4_1": 546, - "ID_Einst_SuZIPTg_zeit_0_2": 547, - "ID_Einst_SuZIPTg_zeit_0_3": 548, - "ID_Einst_SuZIPTg_zeit_1_2": 549, - "ID_Einst_SuZIPTg_zeit_1_3": 550, - "ID_Einst_SuZIPTg_zeit_2_2": 551, - "ID_Einst_SuZIPTg_zeit_2_3": 552, - "ID_Einst_SuZIPTg_zeit_3_2": 553, - "ID_Einst_SuZIPTg_zeit_3_3": 554, - "ID_Einst_SuZIPTg_zeit_4_2": 555, - "ID_Einst_SuZIPTg_zeit_4_3": 556, - "ID_Einst_SuZIPTg_zeit_0_4": 557, - "ID_Einst_SuZIPTg_zeit_0_5": 558, - "ID_Einst_SuZIPTg_zeit_1_4": 559, - "ID_Einst_SuZIPTg_zeit_1_5": 560, - "ID_Einst_SuZIPTg_zeit_2_4": 561, - "ID_Einst_SuZIPTg_zeit_2_5": 562, - "ID_Einst_SuZIPTg_zeit_3_4": 563, - "ID_Einst_SuZIPTg_zeit_3_5": 564, - "ID_Einst_SuZIPTg_zeit_4_4": 565, - "ID_Einst_SuZIPTg_zeit_4_5": 566, - "ID_Einst_SuZIPTg_zeit_0_6": 567, - "ID_Einst_SuZIPTg_zeit_0_7": 568, - "ID_Einst_SuZIPTg_zeit_1_6": 569, - "ID_Einst_SuZIPTg_zeit_1_7": 570, - "ID_Einst_SuZIPTg_zeit_2_6": 571, - "ID_Einst_SuZIPTg_zeit_2_7": 572, - "ID_Einst_SuZIPTg_zeit_3_6": 573, - "ID_Einst_SuZIPTg_zeit_3_7": 574, - "ID_Einst_SuZIPTg_zeit_4_6": 575, - "ID_Einst_SuZIPTg_zeit_4_7": 576, - "ID_Einst_SuZIPTg_zeit_0_8": 577, - "ID_Einst_SuZIPTg_zeit_0_9": 578, - "ID_Einst_SuZIPTg_zeit_1_8": 579, - "ID_Einst_SuZIPTg_zeit_1_9": 580, - "ID_Einst_SuZIPTg_zeit_2_8": 581, - "ID_Einst_SuZIPTg_zeit_2_9": 582, - "ID_Einst_SuZIPTg_zeit_3_8": 583, - "ID_Einst_SuZIPTg_zeit_3_9": 584, - "ID_Einst_SuZIPTg_zeit_4_8": 585, - "ID_Einst_SuZIPTg_zeit_4_9": 586, - "ID_Einst_SuZIPTg_zeit_0_10": 587, - "ID_Einst_SuZIPTg_zeit_0_11": 588, - "ID_Einst_SuZIPTg_zeit_1_10": 589, - "ID_Einst_SuZIPTg_zeit_1_11": 590, - "ID_Einst_SuZIPTg_zeit_2_10": 591, - "ID_Einst_SuZIPTg_zeit_2_11": 592, - "ID_Einst_SuZIPTg_zeit_3_10": 593, - "ID_Einst_SuZIPTg_zeit_3_11": 594, - "ID_Einst_SuZIPTg_zeit_4_10": 595, - "ID_Einst_SuZIPTg_zeit_4_11": 596, - "ID_Einst_SuZIPTg_zeit_0_12": 597, - "ID_Einst_SuZIPTg_zeit_0_13": 598, - "ID_Einst_SuZIPTg_zeit_1_12": 599, - "ID_Einst_SuZIPTg_zeit_1_13": 600, - "ID_Einst_SuZIPTg_zeit_2_12": 601, - "ID_Einst_SuZIPTg_zeit_2_13": 602, - "ID_Einst_SuZIPTg_zeit_3_12": 603, - "ID_Einst_SuZIPTg_zeit_3_13": 604, - "ID_Einst_SuZIPTg_zeit_4_12": 605, - "ID_Einst_SuZIPTg_zeit_4_13": 606, - "ID_Einst_SuSwb_akt": 607, - "ID_Einst_SuSwbWo_zeit_0_0": 608, - "ID_Einst_SuSwbWo_zeit_0_1": 609, - "ID_Einst_SuSwbWo_zeit_1_0": 610, - "ID_Einst_SuSwbWo_zeit_1_1": 611, - "ID_Einst_SuSwbWo_zeit_2_0": 612, - "ID_Einst_SuSwbWo_zeit_2_1": 613, - "ID_Einst_SuSwb25_zeit_0_0": 614, - "ID_Einst_SuSwb25_zeit_0_1": 615, - "ID_Einst_SuSwb25_zeit_1_0": 616, - "ID_Einst_SuSwb25_zeit_1_1": 617, - "ID_Einst_SuSwb25_zeit_2_0": 618, - "ID_Einst_SuSwb25_zeit_2_1": 619, - "ID_Einst_SuSwb25_zeit_0_2": 620, - "ID_Einst_SuSwb25_zeit_0_3": 621, - "ID_Einst_SuSwb25_zeit_1_2": 622, - "ID_Einst_SuSwb25_zeit_1_3": 623, - "ID_Einst_SuSwb25_zeit_2_2": 624, - "ID_Einst_SuSwb25_zeit_2_3": 625, - "ID_Einst_SuSwbTg_zeit_0_0": 626, - "ID_Einst_SuSwbTg_zeit_0_1": 627, - "ID_Einst_SuSwbTg_zeit_1_0": 628, - "ID_Einst_SuSwbTg_zeit_1_1": 629, - "ID_Einst_SuSwbTg_zeit_2_0": 630, - "ID_Einst_SuSwbTg_zeit_2_1": 631, - "ID_Einst_SuSwbTg_zeit_0_2": 632, - "ID_Einst_SuSwbTg_zeit_0_3": 633, - "ID_Einst_SuSwbTg_zeit_1_2": 634, - "ID_Einst_SuSwbTg_zeit_1_3": 635, - "ID_Einst_SuSwbTg_zeit_2_2": 636, - "ID_Einst_SuSwbTg_zeit_2_3": 637, - "ID_Einst_SuSwbTg_zeit_0_4": 638, - "ID_Einst_SuSwbTg_zeit_0_5": 639, - "ID_Einst_SuSwbTg_zeit_1_4": 640, - "ID_Einst_SuSwbTg_zeit_1_5": 641, - "ID_Einst_SuSwbTg_zeit_2_4": 642, - "ID_Einst_SuSwbTg_zeit_2_5": 643, - "ID_Einst_SuSwbTg_zeit_0_6": 644, - "ID_Einst_SuSwbTg_zeit_0_7": 645, - "ID_Einst_SuSwbTg_zeit_1_6": 646, - "ID_Einst_SuSwbTg_zeit_1_7": 647, - "ID_Einst_SuSwbTg_zeit_2_6": 648, - "ID_Einst_SuSwbTg_zeit_2_7": 649, - "ID_Einst_SuSwbTg_zeit_0_8": 650, - "ID_Einst_SuSwbTg_zeit_0_9": 651, - "ID_Einst_SuSwbTg_zeit_1_8": 652, - "ID_Einst_SuSwbTg_zeit_1_9": 653, - "ID_Einst_SuSwbTg_zeit_2_8": 654, - "ID_Einst_SuSwbTg_zeit_2_9": 655, - "ID_Einst_SuSwbTg_zeit_0_10": 656, - "ID_Einst_SuSwbTg_zeit_0_11": 657, - "ID_Einst_SuSwbTg_zeit_1_10": 658, - "ID_Einst_SuSwbTg_zeit_1_11": 659, - "ID_Einst_SuSwbTg_zeit_2_10": 660, - "ID_Einst_SuSwbTg_zeit_2_11": 661, - "ID_Einst_SuSwbTg_zeit_0_12": 662, - "ID_Einst_SuSwbTg_zeit_0_13": 663, - "ID_Einst_SuSwbTg_zeit_1_12": 664, - "ID_Einst_SuSwbTg_zeit_1_13": 665, - "ID_Einst_SuSwbTg_zeit_2_12": 666, - "ID_Einst_SuSwbTg_zeit_2_13": 667, - "ID_Zaehler_BetrZeitWP": 668, - "ID_Zaehler_BetrZeitVD1": 669, - "ID_Zaehler_BetrZeitVD2": 670, - "ID_Zaehler_BetrZeitZWE1": 671, - "ID_Zaehler_BetrZeitZWE2": 672, - "ID_Zaehler_BetrZeitZWE3": 673, - "ID_Zaehler_BetrZeitImpVD1": 674, - "ID_Zaehler_BetrZeitImpVD2": 675, - "ID_Zaehler_BetrZeitEZMVD1": 676, - "ID_Zaehler_BetrZeitEZMVD2": 677, - "ID_Einst_Entl_Typ_0": 678, - "ID_Einst_Entl_Typ_1": 679, - "ID_Einst_Entl_Typ_2": 680, - "ID_Einst_Entl_Typ_3": 681, - "ID_Einst_Entl_Typ_4": 682, - "ID_Einst_Entl_Typ_5": 683, - "ID_Einst_Entl_Typ_6": 684, - "ID_Einst_Entl_Typ_7": 685, - "ID_Einst_Entl_Typ_8": 686, - "ID_Einst_Entl_Typ_9": 687, - "ID_Einst_Entl_Typ_10": 688, - "ID_Einst_Entl_Typ_11": 689, - "ID_Einst_Entl_Typ_12": 690, - "ID_Einst_Vorl_max_MK1": 691, - "ID_Einst_Vorl_max_MK2": 692, - "ID_SU_FrkdMK1": 693, - "ID_SU_FrkdMK2": 694, - "ID_Ba_Hz_MK1_akt": 695, - "ID_Ba_Hz_MK2_akt": 696, - "ID_Einst_Zirk_Ein_akt": 697, - "ID_Einst_Zirk_Aus_akt": 698, - "ID_Einst_Heizgrenze": 699, - "ID_Einst_Heizgrenze_Temp": 700, - "ID_VariablenIBNgespeichert": 701, - "ID_SchonIBNAssistant": 702, - "ID_Heizgrenze_0": 703, - "ID_Heizgrenze_1": 704, - "ID_Heizgrenze_2": 705, - "ID_Heizgrenze_3": 706, - "ID_Heizgrenze_4": 707, - "ID_Heizgrenze_5": 708, - "ID_Heizgrenze_6": 709, - "ID_Heizgrenze_7": 710, - "ID_Heizgrenze_8": 711, - "ID_Heizgrenze_9": 712, - "ID_Heizgrenze_10": 713, - "ID_Heizgrenze_11": 714, - "ID_SchemenIBNgewahlt": 715, - "ID_Switchoff_file_0_0": 716, - "ID_Switchoff_file_1_0": 717, - "ID_Switchoff_file_2_0": 718, - "ID_Switchoff_file_3_0": 719, - "ID_Switchoff_file_4_0": 720, - "ID_Switchoff_file_0_1": 721, - "ID_Switchoff_file_1_1": 722, - "ID_Switchoff_file_2_1": 723, - "ID_Switchoff_file_3_1": 724, - "ID_Switchoff_file_4_1": 725, - "ID_DauerDatenLoggerAktiv": 726, - "ID_Laufvar_Heizgrenze": 727, - "ID_Zaehler_BetrZeitHz": 728, - "ID_Zaehler_BetrZeitBW": 729, - "ID_Zaehler_BetrZeitKue": 730, - "ID_SU_FstdHz": 731, - "ID_SU_FstdBw": 732, - "ID_SU_FstdSwb": 733, - "ID_SU_FstdMK1": 734, - "ID_SU_FstdMK2": 735, - "ID_FerienAbsenkungHz": 736, - "ID_FerienAbsenkungMK1": 737, - "ID_FerienAbsenkungMK2": 738, - "ID_FerienModusAktivHz": 739, - "ID_FerienModusAktivBw": 740, - "ID_FerienModusAktivSwb": 741, - "ID_FerienModusAktivMk1": 742, - "ID_FerienModusAktivMk2": 743, - "ID_DisplayContrast_akt": 744, - "ID_Ba_Hz_saved": 745, - "ID_Ba_Bw_saved": 746, - "ID_Ba_Sw_saved": 747, - "ID_Ba_Hz_MK1_saved": 748, - "ID_Ba_Hz_MK2_saved": 749, - "ID_AdresseIP_akt": 750, - "ID_SubNetMask_akt": 751, - "ID_Add_Broadcast_akt": 752, - "ID_Add_StdGateway_akt": 753, - "ID_DHCPServerAktiv_akt": 754, - "ID_WebserverPasswort_1_akt": 755, - "ID_WebserverPasswort_2_akt": 756, - "ID_WebserverPasswort_3_akt": 757, - "ID_WebserverPasswort_4_akt": 758, - "ID_WebserverPasswort_5_akt": 759, - "ID_WebserverPasswort_6_akt": 760, - "ID_WebServerWerteBekommen": 761, - "ID_Einst_ParBetr_akt": 762, - "ID_Einst_WpAnz_akt": 763, - "ID_Einst_PhrTime_akt": 764, - "ID_Einst_HysPar_akt": 765, - "ID_IP_PB_Slave_0": 766, - "ID_IP_PB_Slave_1": 767, - "ID_IP_PB_Slave_2": 768, - "ID_IP_PB_Slave_3": 769, - "ID_IP_PB_Slave_4": 770, - "ID_IP_PB_Slave_5": 771, - "ID_Einst_BwHup_akt_backup": 772, - "ID_Einst_SuMk3_akt": 773, - "ID_Einst_HzMK3E_akt": 774, - "ID_Einst_HzMK3ANH_akt": 775, - "ID_Einst_HzMK3ABS_akt": 776, - "ID_Einst_HzMK3Hgr_akt": 777, - "ID_Einst_HzFtMK3Vl_akt": 778, - "ID_Ba_Hz_MK3_akt": 779, - "ID_Einst_MK3Typ_akt": 780, - "ID_Einst_RTypMK3_akt": 781, - "ID_Einst_MK3LzFaktor_akt": 782, - "ID_Einst_MK3PerFaktor_akt": 783, - "ID_FerienModusAktivMk3": 784, - "ID_SU_FrkdMK3": 785, - "ID_FerienAbsenkungMK3": 786, - "ID_SU_FstdMK3": 787, - "ID_Einst_SuMk3_akt2": 788, - "ID_Einst_SuMk3Wo_zeit_0_0": 789, - "ID_Einst_SuMk3Wo_zeit_0_1": 790, - "ID_Einst_SuMk3Wo_zeit_1_0": 791, - "ID_Einst_SuMk3Wo_zeit_1_1": 792, - "ID_Einst_SuMk3Wo_zeit_2_0": 793, - "ID_Einst_SuMk3Wo_zeit_2_1": 794, - "ID_Einst_SuMk325_zeit_0_0": 795, - "ID_Einst_SuMk325_zeit_0_1": 796, - "ID_Einst_SuMk325_zeit_1_0": 797, - "ID_Einst_SuMk325_zeit_1_1": 798, - "ID_Einst_SuMk325_zeit_2_0": 799, - "ID_Einst_SuMk325_zeit_2_1": 800, - "ID_Einst_SuMk325_zeit_0_2": 801, - "ID_Einst_SuMk325_zeit_0_3": 802, - "ID_Einst_SuMk325_zeit_1_2": 803, - "ID_Einst_SuMk325_zeit_1_3": 804, - "ID_Einst_SuMk325_zeit_2_2": 805, - "ID_Einst_SuMk325_zeit_2_3": 806, - "ID_Einst_SuMk3Tg_zeit_0_0": 807, - "ID_Einst_SuMk3Tg_zeit_0_1": 808, - "ID_Einst_SuMk3Tg_zeit_1_0": 809, - "ID_Einst_SuMk3Tg_zeit_1_1": 810, - "ID_Einst_SuMk3Tg_zeit_2_0": 811, - "ID_Einst_SuMk3Tg_zeit_2_1": 812, - "ID_Einst_SuMk3Tg_zeit_0_2": 813, - "ID_Einst_SuMk3Tg_zeit_0_3": 814, - "ID_Einst_SuMk3Tg_zeit_1_2": 815, - "ID_Einst_SuMk3Tg_zeit_1_3": 816, - "ID_Einst_SuMk3Tg_zeit_2_2": 817, - "ID_Einst_SuMk3Tg_zeit_2_3": 818, - "ID_Einst_SuMk3Tg_zeit_0_4": 819, - "ID_Einst_SuMk3Tg_zeit_0_5": 820, - "ID_Einst_SuMk3Tg_zeit_1_4": 821, - "ID_Einst_SuMk3Tg_zeit_1_5": 822, - "ID_Einst_SuMk3Tg_zeit_2_4": 823, - "ID_Einst_SuMk3Tg_zeit_2_5": 824, - "ID_Einst_SuMk3Tg_zeit_0_6": 825, - "ID_Einst_SuMk3Tg_zeit_0_7": 826, - "ID_Einst_SuMk3Tg_zeit_1_6": 827, - "ID_Einst_SuMk3Tg_zeit_1_7": 828, - "ID_Einst_SuMk3Tg_zeit_2_6": 829, - "ID_Einst_SuMk3Tg_zeit_2_7": 830, - "ID_Einst_SuMk3Tg_zeit_0_8": 831, - "ID_Einst_SuMk3Tg_zeit_0_9": 832, - "ID_Einst_SuMk3Tg_zeit_1_8": 833, - "ID_Einst_SuMk3Tg_zeit_1_9": 834, - "ID_Einst_SuMk3Tg_zeit_2_8": 835, - "ID_Einst_SuMk3Tg_zeit_2_9": 836, - "ID_Einst_SuMk3Tg_zeit_0_10": 837, - "ID_Einst_SuMk3Tg_zeit_0_11": 838, - "ID_Einst_SuMk3Tg_zeit_1_10": 839, - "ID_Einst_SuMk3Tg_zeit_1_11": 840, - "ID_Einst_SuMk3Tg_zeit_2_10": 841, - "ID_Einst_SuMk3Tg_zeit_2_11": 842, - "ID_Einst_SuMk3Tg_zeit_0_12": 843, - "ID_Einst_SuMk3Tg_zeit_0_13": 844, - "ID_Einst_SuMk3Tg_zeit_1_12": 845, - "ID_Einst_SuMk3Tg_zeit_1_13": 846, - "ID_Einst_SuMk3Tg_zeit_2_12": 847, - "ID_Einst_SuMk3Tg_zeit_2_13": 848, - "ID_Ba_Hz_MK3_saved": 849, - "ID_Einst_Kuhl_Zeit_Ein_akt": 850, - "ID_Einst_Kuhl_Zeit_Aus_akt": 851, - "ID_Waermemenge_Seit": 852, - "ID_Waermemenge_WQ": 853, - "ID_Waermemenge_Hz": 854, - "ID_Waermemenge_WQ_ges": 855, - "ID_Einst_Entl_Typ_13": 856, - "ID_Einst_Entl_Typ_14": 857, - "ID_Einst_Entl_Typ_15": 858, - "ID_Zaehler_BetrZeitSW": 859, - "ID_Einst_Fernwartung_akt": 860, - "ID_AdresseIPServ_akt": 861, - "ID_Einst_TA_EG_akt": 862, - "ID_Einst_TVLmax_EG_akt": 863, - "ID_Einst_Popt_Nachlauf_akt": 864, - "ID_FernwartungVertrag_akt": 865, - "ID_FernwartungAktuZeit": 866, - "ID_Einst_Effizienzpumpe_Nominal_akt": 867, - "ID_Einst_Effizienzpumpe_Minimal_akt": 868, - "ID_Einst_Effizienzpumpe_akt": 869, - "ID_Einst_Waermemenge_akt": 870, - "ID_Einst_Wm_Versorgung_Korrektur_akt": 871, - "ID_Einst_Wm_Auswertung_Korrektur_akt": 872, - "ID_SoftwareUpdateJetztGemacht_akt": 873, - "ID_WP_SerienNummer_DATUM": 874, - "ID_WP_SerienNummer_HEX": 875, - "ID_WP_SerienNummer_INDEX": 876, - "ID_ProgWerteWebSrvBeobarten": 877, - "ID_Waermemenge_BW": 878, - "ID_Waermemenge_SW": 879, - "ID_Waermemenge_Datum": 880, - "ID_Einst_Solar_akt": 881, - "ID_BSTD_Solar": 882, - "ID_Einst_TDC_Koll_Max_akt": 883, - "ID_Einst_Akt_Kuehlung_akt": 884, - "ID_Einst_Vorlauf_VBO_akt": 885, - "ID_Einst_KRHyst_akt": 886, - "ID_Einst_Akt_Kuehl_Speicher_min_akt": 887, - "ID_Einst_Akt_Kuehl_Freig_WQE_akt": 888, - "ID_NDAB_WW_Anzahl": 889, - "ID_NDS_WW_KD_Quitt": 890, - "ID_Einst_AbtZykMin_akt": 891, - "ID_Einst_VD2_Zeit_Min_akt": 892, - "ID_Einst_Hysterese_HR_verkuerzt_akt": 893, - "ID_Einst_BA_Lueftung_akt": 894, - "ID_Einst_SuLuf_akt": 895, - "ID_Einst_SuLufWo_zeit_0_0_0": 896, - "ID_Einst_SuLufWo_zeit_0_1_0": 897, - "ID_Einst_SuLufWo_zeit_0_2_0": 898, - "ID_Einst_SuLuf25_zeit_0_0_0": 899, - "ID_Einst_SuLuf25_zeit_0_1_0": 900, - "ID_Einst_SuLuf25_zeit_0_2_0": 901, - "ID_Einst_SuLuf25_zeit_0_0_2": 902, - "ID_Einst_SuLuf25_zeit_0_1_2": 903, - "ID_Einst_SuLuf25_zeit_0_2_2": 904, - "ID_Einst_SuLufTg_zeit_0_0_0": 905, - "ID_Einst_SuLufTg_zeit_0_1_0": 906, - "ID_Einst_SuLufTg_zeit_0_2_0": 907, - "ID_Einst_SuLufTg_zeit_0_0_2": 908, - "ID_Einst_SuLufTg_zeit_0_1_2": 909, - "ID_Einst_SuLufTg_zeit_0_2_2": 910, - "ID_Einst_SuLufTg_zeit_0_0_4": 911, - "ID_Einst_SuLufTg_zeit_0_1_4": 912, - "ID_Einst_SuLufTg_zeit_0_2_4": 913, - "ID_Einst_SuLufTg_zeit_0_0_6": 914, - "ID_Einst_SuLufTg_zeit_0_1_6": 915, - "ID_Einst_SuLufTg_zeit_0_2_6": 916, - "ID_Einst_SuLufTg_zeit_0_0_8": 917, - "ID_Einst_SuLufTg_zeit_0_1_8": 918, - "ID_Einst_SuLufTg_zeit_0_2_8": 919, - "ID_Einst_SuLufTg_zeit_0_0_10": 920, - "ID_Einst_SuLufTg_zeit_0_1_10": 921, - "ID_Einst_SuLufTg_zeit_0_2_10": 922, - "ID_Einst_SuLufTg_zeit_0_0_12": 923, - "ID_Einst_SuLufTg_zeit_0_1_12": 924, - "ID_Einst_SuLufTg_zeit_0_2_12": 925, - "ID_Einst_SuLufWo_zeit_1_0_0": 926, - "ID_Einst_SuLufWo_zeit_1_1_0": 927, - "ID_Einst_SuLufWo_zeit_1_2_0": 928, - "ID_Einst_SuLuf25_zeit_1_0_0": 929, - "ID_Einst_SuLuf25_zeit_1_1_0": 930, - "ID_Einst_SuLuf25_zeit_1_2_0": 931, - "ID_Einst_SuLuf25_zeit_1_0_2": 932, - "ID_Einst_SuLuf25_zeit_1_1_2": 933, - "ID_Einst_SuLuf25_zeit_1_2_2": 934, - "ID_Einst_SuLufTg_zeit_1_0_0": 935, - "ID_Einst_SuLufTg_zeit_1_1_0": 936, - "ID_Einst_SuLufTg_zeit_1_2_0": 937, - "ID_Einst_SuLufTg_zeit_1_0_2": 938, - "ID_Einst_SuLufTg_zeit_1_1_2": 939, - "ID_Einst_SuLufTg_zeit_1_2_2": 940, - "ID_Einst_SuLufTg_zeit_1_0_4": 941, - "ID_Einst_SuLufTg_zeit_1_1_4": 942, - "ID_Einst_SuLufTg_zeit_1_2_4": 943, - "ID_Einst_SuLufTg_zeit_1_0_6": 944, - "ID_Einst_SuLufTg_zeit_1_1_6": 945, - "ID_Einst_SuLufTg_zeit_1_2_6": 946, - "ID_Einst_SuLufTg_zeit_1_0_8": 947, - "ID_Einst_SuLufTg_zeit_1_1_8": 948, - "ID_Einst_SuLufTg_zeit_1_2_8": 949, - "ID_Einst_SuLufTg_zeit_1_0_10": 950, - "ID_Einst_SuLufTg_zeit_1_1_10": 951, - "ID_Einst_SuLufTg_zeit_1_2_10": 952, - "ID_Einst_SuLufTg_zeit_1_0_12": 953, - "ID_Einst_SuLufTg_zeit_1_1_12": 954, - "ID_Einst_SuLufTg_zeit_1_2_12": 955, - "ID_FerienModusAktivLueftung": 956, - "ID_Einst_BA_Lueftung_saved": 957, - "ID_SU_FrkdLueftung": 958, - "ID_SU_FstdLueftung": 959, - "ID_Einst_Luf_Feuchteschutz_akt": 960, - "ID_Einst_Luf_Reduziert_akt": 961, - "ID_Einst_Luf_Nennlueftung_akt": 962, - "ID_Einst_Luf_Intensivlueftung_akt": 963, - "ID_Timer_Fil_4Makt": 964, - "ID_Timer_Fil_WoAkt": 965, - "ID_Sollwert_KuCft3_akt": 966, - "ID_Sollwert_AtDif3_akt": 967, - "ID_Bitmaske_0": 968, - "ID_Einst_Lueftungsstufen": 969, - "ID_SysEin_Meldung_TDI": 970, - "ID_SysEin_Typ_WZW": 971, - "ID_Einst_GLT_aktiviert": 972, - "ID_Einst_BW_max": 973, - "ID_Einst_Sollwert_TRL_Kuehlen": 974, - "ID_Einst_Medium_Waermequelle": 975, - "ID_Einst_Photovoltaik_akt": 976, - "ID_Einst_Multispeicher_akt": 977, - "ID_Einst_PKuehlTime_akt": 978, - "ID_Einst_Minimale_Ruecklaufsolltemperatur": 979, - "ID_RBE_Einflussfaktor_RT_akt": 980, - "ID_RBE_Freigabe_Kuehlung_akt": 981, - "ID_RBE_Waermeverteilsystem_akt": 982, - "ID_RBE_Zeit_Heizstab_aktiv": 983, - "ID_SEC_ND_Alarmgrenze": 984, - "ID_SEC_HD_Alarmgrenze": 985, - "ID_SEC_Abtauendtemperatur": 986, - "ID_Einst_Min_RPM_BW": 987, - "ID_Einst_Luf_Feuchteschutz_Faktor_akt": 988, - "ID_Einst_Luf_Reduziert_Faktor_akt": 989, - "ID_Einst_Luf_Nennlueftung_Faktor_akt": 990, - "ID_Einst_Luf_Intensivlueftung_Faktor_akt": 991, - "ID_Einst_Freigabe_Zeit_ZWE": 992, - "ID_Einst_min_VL_Kuehl": 993, - "ID_Einst_Warmwasser_Nachheizung": 994, - "ID_Switchoff_file_LWD2_0_0": 995, - "ID_Switchoff_file_LWD2_1_0": 996, - "ID_Switchoff_file_LWD2_2_0": 997, - "ID_Switchoff_file_LWD2_3_0": 998, - "ID_Switchoff_file_LWD2_4_0": 999, - "ID_Switchoff_file_LWD2_0_1": 1000, - "ID_Switchoff_file_LWD2_1_1": 1001, - "ID_Switchoff_file_LWD2_2_1": 1002, - "ID_Switchoff_file_LWD2_3_1": 1003, - "ID_Switchoff_file_LWD2_4_1": 1004, - "ID_Switchoff_index_LWD2": 1005, - "ID_Einst_Effizienzpumpe_Nominal_2": 1006, - "ID_Einst_Effizienzpumpe_Minimal_2": 1007, - "ID_Einst_Wm_Versorgung_Korrektur_2": 1008, - "ID_Einst_Wm_Auswertung_Korrektur_2": 1009, - "ID_Einst_isTwin": 1010, - "ID_Einst_TAmin_2": 1011, - "ID_Einst_TVLmax_2": 1012, - "ID_Einst_TA_EG_2": 1013, - "ID_Einst_TVLmax_EG_2": 1014, - "ID_Waermemenge_Hz_2": 1015, - "ID_Waermemenge_BW_2": 1016, - "ID_Waermemenge_SW_2": 1017, - "ID_Waermemenge_Seit_2": 1018, - "ID_Einst_Entl_Typ_15_2": 1019, - "ID_Einst_WW_Nachheizung_max": 1020, - "ID_Einst_Kuhl_Zeit_Ein_RT": 1021, - "ID_Einst_ZWE1_Pos": 1022, - "ID_Einst_ZWE2_Pos": 1023, - "ID_Einst_ZWE3_Pos": 1024, - "ID_Einst_Leistung_ZWE": 1025, - "ID_WP_SN2_DATUM": 1026, - "ID_WP_SN2_HEX": 1027, - "ID_WP_SN2_INDEX": 1028, - "ID_CWP_saved2": 1029, - "ID_Einst_SmartGrid": 1030, - "ID_Einst_P155_HDS": 1031, - "ID_Einst_P155_PumpHeat_Max": 1032, - "ID_Einst_P155_PumpHeatCtrl": 1033, - "ID_Einst_P155_PumpDHWCtrl": 1034, - "ID_Einst_P155_PumpDHW_RPM": 1035, - "ID_Einst_P155_PumpPoolCtrl": 1036, - "ID_Einst_P155_PumpPool_RPM": 1037, - "ID_Einst_P155_PumpCool_RPM": 1038, - "ID_Einst_P155_PumpVBOCtrl": 1039, - "ID_Einst_P155_PumpVBO_RPM_C": 1040, - "ID_Einst_P155_PumpDHW_Max": 1041, - "ID_Einst_P155_PumpPool_Max": 1042, - "ID_Einst_P155_Sperrband_1": 1043, - "ID_Einst_P155_Leistungsfreigabe": 1044, - "ID_Einst_P155_DHW_Freq": 1045, - "ID_Einst_SWHUP": 1046, - "ID_Einst_P155_SWB_Freq": 1047, - "ID_Einst_MK1_Regelung": 1048, - "ID_Einst_MK2_Regelung": 1049, - "ID_Einst_MK3_Regelung": 1050, - "ID_Einst_PV_WW_Sperrzeit": 1051, - "ID_Einst_Warmwasser_extra": 1052, - "ID_Einst_Vorl_akt_Kuehl": 1053, - "ID_WP_SN3_DATUM": 1054, - "ID_WP_SN3_HEX": 1055, - "ID_WP_SN3_INDEX": 1056, - "ID_Einst_Vorlauf_ZUP": 1057, - "ID_Einst_Abtauen_im_Warmwasser": 1058, - "ID_Waermemenge_ZWE": 1059, - "ID_Waermemenge_Reset": 1060, - "ID_Waermemenge_Reset_2": 1061, - "ID_Einst_Brunnenpumpe_min": 1062, - "ID_Einst_Brunnenpumpe_max": 1063, - "ID_Einst_SmartHomeID": 1064, - "ID_Einst_SmartHK": 1065, - "ID_Einst_SmartMK1": 1066, - "ID_Einst_SmartMK2": 1067, - "ID_Einst_SmartMK3": 1068, - "ID_Einst_SmartWW": 1069, - "ID_Einst_SmartDefrost": 1070, - "ID_Einst_Empty1071": 1071, - "ID_Einst_MinVLMK1": 1072, - "ID_Einst_MinVLMK2": 1073, - "ID_Einst_MinVLMK3": 1074, - "ID_Einst_MaxVLMK1": 1075, - "ID_Einst_MaxVLMK2": 1076, - "ID_Einst_MaxVLMK3": 1077, - "ID_Einst_SmartPlusHz": 1078, - "ID_Einst_SmartMinusHz": 1079, - "ID_Einst_SmartPlusMK1": 1080, - "ID_Einst_SmartMinusMK1": 1081, - "ID_Einst_SmartPlusMK2": 1082, - "ID_Einst_SmartMinusMK2": 1083, - "ID_Einst_SmartPlusMK3": 1084, - "ID_Einst_SmartMinusMK3": 1085, - "Unknown_Parameter_1086": 1086, - "Unknown_Parameter_1087": 1087, - "Unknown_Parameter_1088": 1088, - "Unknown_Parameter_1089": 1089, - "Unknown_Parameter_1090": 1090, - "Unknown_Parameter_1091": 1091, - "Unknown_Parameter_1092": 1092, - "Unknown_Parameter_1093": 1093, - "Unknown_Parameter_1094": 1094, - "Unknown_Parameter_1095": 1095, - "Unknown_Parameter_1096": 1096, - "Unknown_Parameter_1097": 1097, - "Unknown_Parameter_1098": 1098, - "Unknown_Parameter_1099": 1099, - "Unknown_Parameter_1100": 1100, - "Unknown_Parameter_1101": 1101, - "Unknown_Parameter_1102": 1102, - "Unknown_Parameter_1103": 1103, - "Unknown_Parameter_1104": 1104, - "Unknown_Parameter_1105": 1105, - "Unknown_Parameter_1106": 1106, - "Unknown_Parameter_1107": 1107, - "Unknown_Parameter_1108": 1108, - "Unknown_Parameter_1109": 1109, - "Unknown_Parameter_1110": 1110, - "Unknown_Parameter_1111": 1111, - "Unknown_Parameter_1112": 1112, - "Unknown_Parameter_1113": 1113, - "Unknown_Parameter_1114": 1114, - "Unknown_Parameter_1115": 1115, - "Unknown_Parameter_1116": 1116, - "Unknown_Parameter_1117": 1117, - "Unknown_Parameter_1118": 1118, - "Unknown_Parameter_1119": 1119, - "Unknown_Parameter_1120": 1120, - "Unknown_Parameter_1121": 1121, - "Unknown_Parameter_1122": 1122, - "Unknown_Parameter_1123": 1123, - "Unknown_Parameter_1124": 1124, - "Unknown_Parameter_1125": 1125, + "ID_Transfert_LuxNet": (0, Unknown), + "ID_Einst_WK_akt": (1, Celsius), + "ID_Einst_BWS_akt": (2, Celsius), + "ID_Ba_Hz_akt": (3, HeatingMode), + "ID_Ba_Bw_akt": (4, HotWaterMode), + "ID_Ba_Al_akt": (5, Unknown), + "ID_SU_FrkdHz": (6, Unknown), + "ID_SU_FrkdBw": (7, Unknown), + "ID_SU_FrkdAl": (8, Unknown), + "ID_Einst_HReg_akt": (9, Unknown), + "ID_Einst_HzHwMAt_akt": (10, Unknown), + "ID_Einst_HzHwHKE_akt": (11, Celsius), + "ID_Einst_HzHKRANH_akt": (12, Celsius), + "ID_Einst_HzHKRABS_akt": (13, Celsius), + "ID_Einst_HzMK1E_akt": (14, Unknown), + "ID_Einst_HzMK1ANH_akt": (15, Unknown), + "ID_Einst_HzMK1ABS_akt": (16, Unknown), + "ID_Einst_HzFtRl_akt": (17, Unknown), + "ID_Einst_HzFtMK1Vl_akt": (18, Unknown), + "ID_Einst_SUBW_akt": (19, Unknown), + "ID_Einst_BwTDI_akt_MO": (20, Unknown), + "ID_Einst_BwTDI_akt_DI": (21, Unknown), + "ID_Einst_BwTDI_akt_MI": (22, Unknown), + "ID_Einst_BwTDI_akt_DO": (23, Unknown), + "ID_Einst_BwTDI_akt_FR": (24, Unknown), + "ID_Einst_BwTDI_akt_SA": (25, Unknown), + "ID_Einst_BwTDI_akt_SO": (26, Unknown), + "ID_Einst_BwTDI_akt_AL": (27, Unknown), + "ID_Einst_AnlKonf_akt": (28, Unknown), + "ID_Einst_Sprache_akt": (29, Unknown), + "ID_Switchoff_Zahler": (30, Unknown), + "ID_Switchoff_index": (31, Unknown), + "ID_Einst_EvuTyp_akt": (32, Unknown), + "ID_Einst_RFVEinb_akt": (33, Unknown), + "ID_Einst_AbtZykMax_akt": (34, Unknown), + "ID_Einst_HREinb_akt": (35, Unknown), + "ID_Einst_ZWE1Art_akt": (36, Unknown), + "ID_Einst_ZWE1Fkt_akt": (37, Unknown), + "ID_Einst_ZWE2Art_akt": (38, Unknown), + "ID_Einst_ZWE2Fkt_akt": (39, Unknown), + "ID_Einst_BWBer_akt": (40, Unknown), + "ID_Einst_En_Inst": (41, Unknown), + "ID_Einst_MK1Typ_akt": (42, Unknown), + "ID_Einst_ABTLuft_akt": (43, Unknown), + "ID_Einst_TLAbt_akt": (44, Unknown), + "ID_Einst_LAbtTime_akt": (45, Unknown), + "ID_Einst_ASDTyp_akt": (46, Unknown), + "ID_Einst_LGST_akt": (47, Unknown), + "ID_Einst_BwWpTime_akt": (48, Unknown), + "ID_Einst_Popt_akt": (49, Unknown), + "ID_Einst_Kurzprog_akt": (50, Unknown), + "ID_Timer_Kurzprog_akt": (51, Unknown), + "ID_Einst_ManAbt_akt": (52, Unknown), + "ID_Einst_Ahz_akt": (53, Unknown), + "ID_Einst_TVL_Ahz_1": (54, Unknown), + "ID_Einst_TVL_Ahz_2": (55, Unknown), + "ID_Einst_TVL_Ahz_3": (56, Unknown), + "ID_Einst_TVL_Ahz_4": (57, Unknown), + "ID_Einst_TVL_Ahz_5": (58, Unknown), + "ID_Einst_TVL_Ahz_6": (59, Unknown), + "ID_Einst_TVL_Ahz_7": (60, Unknown), + "ID_Einst_TVL_Ahz_8": (61, Unknown), + "ID_Einst_TVL_Ahz_9": (62, Unknown), + "ID_Einst_TVL_Ahz_10": (63, Unknown), + "ID_Einst_TVL_Std_1": (64, Unknown), + "ID_Einst_TVL_Std_2": (65, Unknown), + "ID_Einst_TVL_Std_3": (66, Unknown), + "ID_Einst_TVL_Std_4": (67, Unknown), + "ID_Einst_TVL_Std_5": (68, Unknown), + "ID_Einst_TVL_Std_6": (69, Unknown), + "ID_Einst_TVL_Std_7": (70, Unknown), + "ID_Einst_TVL_Std_8": (71, Unknown), + "ID_Einst_TVL_Std_9": (72, Unknown), + "ID_Einst_TVL_Std_10": (73, Unknown), + "ID_Einst_BWS_Hyst_akt": (74, Kelvin), + "ID_Temp_TBW_BwHD_saved": (75, Unknown), + "ID_Einst_ABT1_akt": (76, Unknown), + "ID_Einst_LABTpaus_akt": (77, Unknown), + "ID_AHZ_state_akt": (78, Unknown), + "ID_Sollwert_TRL_HZ_AHZ": (79, Celsius), + "ID_AHP_valid_records": (80, Unknown), + "ID_Timer_AHZ_akt": (81, Unknown), + "ID_Einst_BWTINP_akt": (82, Unknown), + "ID_Einst_ZUPTYP_akt": (83, Unknown), + "ID_Sollwert_TLG_max": (84, Unknown), + "ID_Einst_BWZIP_akt": (85, Unknown), + "ID_Einst_ERRmZWE_akt": (86, Unknown), + "ID_Einst_TRBegr_akt": (87, Unknown), + "ID_Einst_HRHyst_akt": (88, Unknown), + "ID_Einst_TRErhmax_akt": (89, Unknown), + "ID_Einst_ZWEFreig_akt": (90, Unknown), + "ID_Einst_TAmax_akt": (91, Unknown), + "ID_Einst_TAmin_akt": (92, Unknown), + "ID_Einst_TWQmin_akt": (93, Unknown), + "ID_Einst_THGmax_akt": (94, Unknown), + "ID_Einst_FRGT2VD_akt": (95, Unknown), + "ID_Einst_TV2VDBW_akt": (96, Unknown), + "ID_Einst_SuAll_akt": (97, Unknown), + "ID_Einst_TAbtEnd_akt": (98, Unknown), + "ID_Einst_NrKlingel_akt": (99, Unknown), + "ID_Einst_BWStyp_akt": (100, Unknown), + "ID_Einst_ABT2_akt": (101, Unknown), + "ID_Einst_UeVd_akt": (102, Unknown), + "ID_Einst_RTyp_akt": (103, Unknown), + "ID_Einst_AhpM_akt": (104, Unknown), + "ID_Soll_BWS_akt": (105, Celsius), + "ID_Timer_Password": (106, Unknown), + "ID_Einst_Zugangscode": (107, Unknown), + "ID_Einst_BA_Kuehl_akt": (108, CoolingMode), + "ID_Sollwert_Kuehl1_akt": (109, Unknown), + "ID_Einst_KuehlFreig_akt": (110, Celsius), + "ID_Einst_TAbsMin_akt": (111, Unknown), + "ID_TWQmin_saved": (112, Unknown), + "ID_CWP_saved": (113, Unknown), + "ID_Einst_Anode_akt": (114, Unknown), + "ID_Timer_pexoff_akt": (115, Unknown), + "ID_Einst_AnlPrio_Hzakt": (116, Unknown), + "ID_Einst_AnlPrio_Bwakt": (117, Unknown), + "ID_Einst_AnlPrio_Swakt": (118, Unknown), + "ID_Ba_Sw_akt": (119, PoolMode), + "ID_Einst_RTypMK1_akt": (120, Unknown), + "ID_Einst_RTypMK2_akt": (121, Unknown), + "ID_Einst_TDC_Ein_akt": (122, Kelvin), + "ID_Einst_TDC_Aus_akt": (123, Kelvin), + "ID_Einst_TDC_Max_akt": (124, Celsius), + "ID_Einst_HysHzExEn_akt": (125, Unknown), + "ID_Einst_HysBwExEn_akt": (126, Unknown), + "ID_Einst_ZWE3Art_akt": (127, Unknown), + "ID_Einst_ZWE3Fkt_akt": (128, Unknown), + "ID_Einst_HzSup_akt": (129, Unknown), + "ID_Einst_MK2Typ_akt": (130, Unknown), + "ID_Einst_KuTyp_akt": (131, Unknown), + "ID_Sollwert_KuCft1_akt": (132, Celsius), + "ID_Sollwert_KuCft2_akt": (133, Celsius), + "ID_Sollwert_AtDif1_akt": (134, Celsius), + "ID_Sollwert_AtDif2_akt": (135, Celsius), + "ID_SU_FrkdSwb": (136, Unknown), + "ID_Einst_SwbBer_akt": (137, Unknown), + "ID_Einst_TV2VDSWB_akt": (138, Unknown), + "ID_Einst_MinSwan_Time_akt": (139, Unknown), + "ID_Einst_SuMk2_akt": (140, Unknown), + "ID_Einst_HzMK2E_akt": (141, Unknown), + "ID_Einst_HzMK2ANH_akt": (142, Unknown), + "ID_Einst_HzMK2ABS_akt": (143, Unknown), + "ID_Einst_HzMK2Hgr_akt": (144, Unknown), + "ID_Einst_HzFtMK2Vl_akt": (145, Unknown), + "ID_Temp_THG_BwHD_saved": (146, Unknown), + "ID_Temp_TA_BwHD_saved": (147, Unknown), + "ID_Einst_BwHup_akt": (148, Unknown), + "ID_Einst_TVLmax_akt": (149, Unknown), + "ID_Einst_MK1LzFaktor_akt": (150, Unknown), + "ID_Einst_MK2LzFaktor_akt": (151, Unknown), + "ID_Einst_MK1PerFaktor_akt": (152, Unknown), + "ID_Einst_MK2PerFaktor_akt": (153, Unknown), + "ID_Entl_Zyklus_akt": (154, Unknown), + "ID_Einst_Entl_time_akt": (155, Unknown), + "ID_Entl_Pause": (156, Unknown), + "ID_Entl_timer": (157, Unknown), + "ID_Einst_Entl_akt": (158, Unknown), + "ID_Ahz_HLeist_confirmed": (159, Unknown), + "ID_FirstInit_akt": (160, Unknown), + "ID_Einst_SuAll_akt2": (161, Unknown), + "ID_Einst_SuAllWo_zeit_0_0": (162, Unknown), + "ID_Einst_SuAllWo_zeit_0_1": (163, Unknown), + "ID_Einst_SuAllWo_zeit_1_0": (164, Unknown), + "ID_Einst_SuAllWo_zeit_1_1": (165, Unknown), + "ID_Einst_SuAllWo_zeit_2_0": (166, Unknown), + "ID_Einst_SuAllWo_zeit_2_1": (167, Unknown), + "ID_Einst_SuAll25_zeit_0_0": (168, Unknown), + "ID_Einst_SuAll25_zeit_0_1": (169, Unknown), + "ID_Einst_SuAll25_zeit_1_0": (170, Unknown), + "ID_Einst_SuAll25_zeit_1_1": (171, Unknown), + "ID_Einst_SuAll25_zeit_2_0": (172, Unknown), + "ID_Einst_SuAll25_zeit_2_1": (173, Unknown), + "ID_Einst_SuAll25_zeit_0_2": (174, Unknown), + "ID_Einst_SuAll25_zeit_0_3": (175, Unknown), + "ID_Einst_SuAll25_zeit_1_2": (176, Unknown), + "ID_Einst_SuAll25_zeit_1_3": (177, Unknown), + "ID_Einst_SuAll25_zeit_2_2": (178, Unknown), + "ID_Einst_SuAll25_zeit_2_3": (179, Unknown), + "ID_Einst_SuAllTg_zeit_0_0": (180, Unknown), + "ID_Einst_SuAllTg_zeit_0_1": (181, Unknown), + "ID_Einst_SuAllTg_zeit_1_0": (182, Unknown), + "ID_Einst_SuAllTg_zeit_1_1": (183, Unknown), + "ID_Einst_SuAllTg_zeit_2_0": (184, Unknown), + "ID_Einst_SuAllTg_zeit_2_1": (185, Unknown), + "ID_Einst_SuAllTg_zeit_0_2": (186, Unknown), + "ID_Einst_SuAllTg_zeit_0_3": (187, Unknown), + "ID_Einst_SuAllTg_zeit_1_2": (188, Unknown), + "ID_Einst_SuAllTg_zeit_1_3": (189, Unknown), + "ID_Einst_SuAllTg_zeit_2_2": (190, Unknown), + "ID_Einst_SuAllTg_zeit_2_3": (191, Unknown), + "ID_Einst_SuAllTg_zeit_0_4": (192, Unknown), + "ID_Einst_SuAllTg_zeit_0_5": (193, Unknown), + "ID_Einst_SuAllTg_zeit_1_4": (194, Unknown), + "ID_Einst_SuAllTg_zeit_1_5": (195, Unknown), + "ID_Einst_SuAllTg_zeit_2_4": (196, Unknown), + "ID_Einst_SuAllTg_zeit_2_5": (197, Unknown), + "ID_Einst_SuAllTg_zeit_0_6": (198, Unknown), + "ID_Einst_SuAllTg_zeit_0_7": (199, Unknown), + "ID_Einst_SuAllTg_zeit_1_6": (200, Unknown), + "ID_Einst_SuAllTg_zeit_1_7": (201, Unknown), + "ID_Einst_SuAllTg_zeit_2_6": (202, Unknown), + "ID_Einst_SuAllTg_zeit_2_7": (203, Unknown), + "ID_Einst_SuAllTg_zeit_0_8": (204, Unknown), + "ID_Einst_SuAllTg_zeit_0_9": (205, Unknown), + "ID_Einst_SuAllTg_zeit_1_8": (206, Unknown), + "ID_Einst_SuAllTg_zeit_1_9": (207, Unknown), + "ID_Einst_SuAllTg_zeit_2_8": (208, Unknown), + "ID_Einst_SuAllTg_zeit_2_9": (209, Unknown), + "ID_Einst_SuAllTg_zeit_0_10": (210, Unknown), + "ID_Einst_SuAllTg_zeit_0_11": (211, Unknown), + "ID_Einst_SuAllTg_zeit_1_10": (212, Unknown), + "ID_Einst_SuAllTg_zeit_1_11": (213, Unknown), + "ID_Einst_SuAllTg_zeit_2_10": (214, Unknown), + "ID_Einst_SuAllTg_zeit_2_11": (215, Unknown), + "ID_Einst_SuAllTg_zeit_0_12": (216, Unknown), + "ID_Einst_SuAllTg_zeit_0_13": (217, Unknown), + "ID_Einst_SuAllTg_zeit_1_12": (218, Unknown), + "ID_Einst_SuAllTg_zeit_1_13": (219, Unknown), + "ID_Einst_SuAllTg_zeit_2_12": (220, Unknown), + "ID_Einst_SuAllTg_zeit_2_13": (221, Unknown), + "ID_Einst_SuHkr_akt": (222, Unknown), + "ID_Einst_SuHkrW0_zeit_0_0": (223, Unknown), + "ID_Einst_SuHkrW0_zeit_0_1": (224, Unknown), + "ID_Einst_SuHkrW0_zeit_1_0": (225, Unknown), + "ID_Einst_SuHkrW0_zeit_1_1": (226, Unknown), + "ID_Einst_SuHkrW0_zeit_2_0": (227, Unknown), + "ID_Einst_SuHkrW0_zeit_2_1": (228, Unknown), + "ID_Einst_SuHkr25_zeit_0_0": (229, Unknown), + "ID_Einst_SuHkr25_zeit_0_1": (230, Unknown), + "ID_Einst_SuHkr25_zeit_1_0": (231, Unknown), + "ID_Einst_SuHkr25_zeit_1_1": (232, Unknown), + "ID_Einst_SuHkr25_zeit_2_0": (233, Unknown), + "ID_Einst_SuHkr25_zeit_2_1": (234, Unknown), + "ID_Einst_SuHkr25_zeit_0_2": (235, Unknown), + "ID_Einst_SuHkr25_zeit_0_3": (236, Unknown), + "ID_Einst_SuHkr25_zeit_1_2": (237, Unknown), + "ID_Einst_SuHkr25_zeit_1_3": (238, Unknown), + "ID_Einst_SuHkr25_zeit_2_2": (239, Unknown), + "ID_Einst_SuHkr25_zeit_2_3": (240, Unknown), + "ID_Einst_SuHkrTG_zeit_0_0": (241, Unknown), + "ID_Einst_SuHkrTG_zeit_0_1": (242, Unknown), + "ID_Einst_SuHkrTG_zeit_1_0": (243, Unknown), + "ID_Einst_SuHkrTG_zeit_1_1": (244, Unknown), + "ID_Einst_SuHkrTG_zeit_2_0": (245, Unknown), + "ID_Einst_SuHkrTG_zeit_2_1": (246, Unknown), + "ID_Einst_SuHkrTG_zeit_0_2": (247, Unknown), + "ID_Einst_SuHkrTG_zeit_0_3": (248, Unknown), + "ID_Einst_SuHkrTG_zeit_1_2": (249, Unknown), + "ID_Einst_SuHkrTG_zeit_1_3": (250, Unknown), + "ID_Einst_SuHkrTG_zeit_2_2": (251, Unknown), + "ID_Einst_SuHkrTG_zeit_2_3": (252, Unknown), + "ID_Einst_SuHkrTG_zeit_0_4": (253, Unknown), + "ID_Einst_SuHkrTG_zeit_0_5": (254, Unknown), + "ID_Einst_SuHkrTG_zeit_1_4": (255, Unknown), + "ID_Einst_SuHkrTG_zeit_1_5": (256, Unknown), + "ID_Einst_SuHkrTG_zeit_2_4": (257, Unknown), + "ID_Einst_SuHkrTG_zeit_2_5": (258, Unknown), + "ID_Einst_SuHkrTG_zeit_0_6": (259, Unknown), + "ID_Einst_SuHkrTG_zeit_0_7": (260, Unknown), + "ID_Einst_SuHkrTG_zeit_1_6": (261, Unknown), + "ID_Einst_SuHkrTG_zeit_1_7": (262, Unknown), + "ID_Einst_SuHkrTG_zeit_2_6": (263, Unknown), + "ID_Einst_SuHkrTG_zeit_2_7": (264, Unknown), + "ID_Einst_SuHkrTG_zeit_0_8": (265, Unknown), + "ID_Einst_SuHkrTG_zeit_0_9": (266, Unknown), + "ID_Einst_SuHkrTG_zeit_1_8": (267, Unknown), + "ID_Einst_SuHkrTG_zeit_1_9": (268, Unknown), + "ID_Einst_SuHkrTG_zeit_2_8": (269, Unknown), + "ID_Einst_SuHkrTG_zeit_2_9": (270, Unknown), + "ID_Einst_SuHkrTG_zeit_0_10": (271, Unknown), + "ID_Einst_SuHkrTG_zeit_0_11": (272, Unknown), + "ID_Einst_SuHkrTG_zeit_1_10": (273, Unknown), + "ID_Einst_SuHkrTG_zeit_1_11": (274, Unknown), + "ID_Einst_SuHkrTG_zeit_2_10": (275, Unknown), + "ID_Einst_SuHkrTG_zeit_2_11": (276, Unknown), + "ID_Einst_SuHkrTG_zeit_0_12": (277, Unknown), + "ID_Einst_SuHkrTG_zeit_0_13": (278, Unknown), + "ID_Einst_SuHkrTG_zeit_1_12": (279, Unknown), + "ID_Einst_SuHkrTG_zeit_1_13": (280, Unknown), + "ID_Einst_SuHkrTG_zeit_2_12": (281, Unknown), + "ID_Einst_SuHkrTG_zeit_2_13": (282, Unknown), + "ID_Einst_SuMk1_akt": (283, Unknown), + "ID_Einst_SuMk1W0_zeit_0_0": (284, Unknown), + "ID_Einst_SuMk1W0_zeit_0_1": (285, Unknown), + "ID_Einst_SuMk1W0_zeit_1_0": (286, Unknown), + "ID_Einst_SuMk1W0_zeit_1_1": (287, Unknown), + "ID_Einst_SuMk1W0_zeit_2_0": (288, Unknown), + "ID_Einst_SuMk1W0_zeit_2_1": (289, Unknown), + "ID_Einst_SuMk125_zeit_0_0": (290, Unknown), + "ID_Einst_SuMk125_zeit_0_1": (291, Unknown), + "ID_Einst_SuMk125_zeit_1_0": (292, Unknown), + "ID_Einst_SuMk125_zeit_1_1": (293, Unknown), + "ID_Einst_SuMk125_zeit_2_0": (294, Unknown), + "ID_Einst_SuMk125_zeit_2_1": (295, Unknown), + "ID_Einst_SuMk125_zeit_0_2": (296, Unknown), + "ID_Einst_SuMk125_zeit_0_3": (297, Unknown), + "ID_Einst_SuMk125_zeit_1_2": (298, Unknown), + "ID_Einst_SuMk125_zeit_1_3": (299, Unknown), + "ID_Einst_SuMk125_zeit_2_2": (300, Unknown), + "ID_Einst_SuMk125_zeit_2_3": (301, Unknown), + "ID_Einst_SuMk1TG_zeit_0_0": (302, Unknown), + "ID_Einst_SuMk1TG_zeit_0_1": (303, Unknown), + "ID_Einst_SuMk1TG_zeit_1_0": (304, Unknown), + "ID_Einst_SuMk1TG_zeit_1_1": (305, Unknown), + "ID_Einst_SuMk1TG_zeit_2_0": (306, Unknown), + "ID_Einst_SuMk1TG_zeit_2_1": (307, Unknown), + "ID_Einst_SuMk1TG_zeit_0_2": (308, Unknown), + "ID_Einst_SuMk1TG_zeit_0_3": (309, Unknown), + "ID_Einst_SuMk1TG_zeit_1_2": (310, Unknown), + "ID_Einst_SuMk1TG_zeit_1_3": (311, Unknown), + "ID_Einst_SuMk1TG_zeit_2_2": (312, Unknown), + "ID_Einst_SuMk1TG_zeit_2_3": (313, Unknown), + "ID_Einst_SuMk1TG_zeit_0_4": (314, Unknown), + "ID_Einst_SuMk1TG_zeit_0_5": (315, Unknown), + "ID_Einst_SuMk1TG_zeit_1_4": (316, Unknown), + "ID_Einst_SuMk1TG_zeit_1_5": (317, Unknown), + "ID_Einst_SuMk1TG_zeit_2_4": (318, Unknown), + "ID_Einst_SuMk1TG_zeit_2_5": (319, Unknown), + "ID_Einst_SuMk1TG_zeit_0_6": (320, Unknown), + "ID_Einst_SuMk1TG_zeit_0_7": (321, Unknown), + "ID_Einst_SuMk1TG_zeit_1_6": (322, Unknown), + "ID_Einst_SuMk1TG_zeit_1_7": (323, Unknown), + "ID_Einst_SuMk1TG_zeit_2_6": (324, Unknown), + "ID_Einst_SuMk1TG_zeit_2_7": (325, Unknown), + "ID_Einst_SuMk1TG_zeit_0_8": (326, Unknown), + "ID_Einst_SuMk1TG_zeit_0_9": (327, Unknown), + "ID_Einst_SuMk1TG_zeit_1_8": (328, Unknown), + "ID_Einst_SuMk1TG_zeit_1_9": (329, Unknown), + "ID_Einst_SuMk1TG_zeit_2_8": (330, Unknown), + "ID_Einst_SuMk1TG_zeit_2_9": (331, Unknown), + "ID_Einst_SuMk1TG_zeit_0_10": (332, Unknown), + "ID_Einst_SuMk1TG_zeit_0_11": (333, Unknown), + "ID_Einst_SuMk1TG_zeit_1_10": (334, Unknown), + "ID_Einst_SuMk1TG_zeit_1_11": (335, Unknown), + "ID_Einst_SuMk1TG_zeit_2_10": (336, Unknown), + "ID_Einst_SuMk1TG_zeit_2_11": (337, Unknown), + "ID_Einst_SuMk1TG_zeit_0_12": (338, Unknown), + "ID_Einst_SuMk1TG_zeit_0_13": (339, Unknown), + "ID_Einst_SuMk1TG_zeit_1_12": (340, Unknown), + "ID_Einst_SuMk1TG_zeit_1_13": (341, Unknown), + "ID_Einst_SuMk1TG_zeit_2_12": (342, Unknown), + "ID_Einst_SuMk1TG_zeit_2_13": (343, Unknown), + "ID_Einst_SuMk2_akt2": (344, Unknown), + "ID_Einst_SuMk2Wo_zeit_0_0": (345, Unknown), + "ID_Einst_SuMk2Wo_zeit_0_1": (346, Unknown), + "ID_Einst_SuMk2Wo_zeit_1_0": (347, Unknown), + "ID_Einst_SuMk2Wo_zeit_1_1": (348, Unknown), + "ID_Einst_SuMk2Wo_zeit_2_0": (349, Unknown), + "ID_Einst_SuMk2Wo_zeit_2_1": (350, Unknown), + "ID_Einst_SuMk225_zeit_0_0": (351, Unknown), + "ID_Einst_SuMk225_zeit_0_1": (352, Unknown), + "ID_Einst_SuMk225_zeit_1_0": (353, Unknown), + "ID_Einst_SuMk225_zeit_1_1": (354, Unknown), + "ID_Einst_SuMk225_zeit_2_0": (355, Unknown), + "ID_Einst_SuMk225_zeit_2_1": (356, Unknown), + "ID_Einst_SuMk225_zeit_0_2": (357, Unknown), + "ID_Einst_SuMk225_zeit_0_3": (358, Unknown), + "ID_Einst_SuMk225_zeit_1_2": (359, Unknown), + "ID_Einst_SuMk225_zeit_1_3": (360, Unknown), + "ID_Einst_SuMk225_zeit_2_2": (361, Unknown), + "ID_Einst_SuMk225_zeit_2_3": (362, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_0": (363, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_1": (364, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_0": (365, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_1": (366, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_0": (367, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_1": (368, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_2": (369, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_3": (370, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_2": (371, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_3": (372, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_2": (373, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_3": (374, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_4": (375, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_5": (376, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_4": (377, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_5": (378, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_4": (379, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_5": (380, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_6": (381, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_7": (382, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_6": (383, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_7": (384, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_6": (385, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_7": (386, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_8": (387, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_9": (388, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_8": (389, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_9": (390, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_8": (391, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_9": (392, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_10": (393, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_11": (394, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_10": (395, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_11": (396, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_10": (397, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_11": (398, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_12": (399, Unknown), + "ID_Einst_SuMk2Tg_zeit_0_13": (400, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_12": (401, Unknown), + "ID_Einst_SuMk2Tg_zeit_1_13": (402, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_12": (403, Unknown), + "ID_Einst_SuMk2Tg_zeit_2_13": (404, Unknown), + "ID_Einst_SUBW_akt2": (405, Unknown), + "ID_Einst_SuBwWO_zeit_0_0": (406, Unknown), + "ID_Einst_SuBwWO_zeit_0_1": (407, Unknown), + "ID_Einst_SuBwWO_zeit_1_0": (408, Unknown), + "ID_Einst_SuBwWO_zeit_1_1": (409, Unknown), + "ID_Einst_SuBwWO_zeit_2_0": (410, Unknown), + "ID_Einst_SuBwWO_zeit_2_1": (411, Unknown), + "ID_Einst_SuBwWO_zeit_3_0": (412, Unknown), + "ID_Einst_SuBwWO_zeit_3_1": (413, Unknown), + "ID_Einst_SuBwWO_zeit_4_0": (414, Unknown), + "ID_Einst_SuBwWO_zeit_4_1": (415, Unknown), + "ID_Einst_SuBw25_zeit_0_0": (416, Unknown), + "ID_Einst_SuBw25_zeit_0_1": (417, Unknown), + "ID_Einst_SuBw25_zeit_1_0": (418, Unknown), + "ID_Einst_SuBw25_zeit_1_1": (419, Unknown), + "ID_Einst_SuBw25_zeit_2_0": (420, Unknown), + "ID_Einst_SuBw25_zeit_2_1": (421, Unknown), + "ID_Einst_SuBw25_zeit_3_0": (422, Unknown), + "ID_Einst_SuBw25_zeit_3_1": (423, Unknown), + "ID_Einst_SuBw25_zeit_4_0": (424, Unknown), + "ID_Einst_SuBw25_zeit_4_1": (425, Unknown), + "ID_Einst_SuBw25_zeit_0_2": (426, Unknown), + "ID_Einst_SuBw25_zeit_0_3": (427, Unknown), + "ID_Einst_SuBw25_zeit_1_2": (428, Unknown), + "ID_Einst_SuBw25_zeit_1_3": (429, Unknown), + "ID_Einst_SuBw25_zeit_2_2": (430, Unknown), + "ID_Einst_SuBw25_zeit_2_3": (431, Unknown), + "ID_Einst_SuBw25_zeit_3_2": (432, Unknown), + "ID_Einst_SuBw25_zeit_3_3": (433, Unknown), + "ID_Einst_SuBw25_zeit_4_2": (434, Unknown), + "ID_Einst_SuBw25_zeit_4_3": (435, Unknown), + "ID_Einst_SuBwTG_zeit_0_0": (436, Unknown), + "ID_Einst_SuBwTG_zeit_0_1": (437, Unknown), + "ID_Einst_SuBwTG_zeit_1_0": (438, Unknown), + "ID_Einst_SuBwTG_zeit_1_1": (439, Unknown), + "ID_Einst_SuBwTG_zeit_2_0": (440, Unknown), + "ID_Einst_SuBwTG_zeit_2_1": (441, Unknown), + "ID_Einst_SuBwTG_zeit_3_0": (442, Unknown), + "ID_Einst_SuBwTG_zeit_3_1": (443, Unknown), + "ID_Einst_SuBwTG_zeit_4_0": (444, Unknown), + "ID_Einst_SuBwTG_zeit_4_1": (445, Unknown), + "ID_Einst_SuBwTG_zeit_0_2": (446, Unknown), + "ID_Einst_SuBwTG_zeit_0_3": (447, Unknown), + "ID_Einst_SuBwTG_zeit_1_2": (448, Unknown), + "ID_Einst_SuBwTG_zeit_1_3": (449, Unknown), + "ID_Einst_SuBwTG_zeit_2_2": (450, Unknown), + "ID_Einst_SuBwTG_zeit_2_3": (451, Unknown), + "ID_Einst_SuBwTG_zeit_3_2": (452, Unknown), + "ID_Einst_SuBwTG_zeit_3_3": (453, Unknown), + "ID_Einst_SuBwTG_zeit_4_2": (454, Unknown), + "ID_Einst_SuBwTG_zeit_4_3": (455, Unknown), + "ID_Einst_SuBwTG_zeit_0_4": (456, Unknown), + "ID_Einst_SuBwTG_zeit_0_5": (457, Unknown), + "ID_Einst_SuBwTG_zeit_1_4": (458, Unknown), + "ID_Einst_SuBwTG_zeit_1_5": (459, Unknown), + "ID_Einst_SuBwTG_zeit_2_4": (460, Unknown), + "ID_Einst_SuBwTG_zeit_2_5": (461, Unknown), + "ID_Einst_SuBwTG_zeit_3_4": (462, Unknown), + "ID_Einst_SuBwTG_zeit_3_5": (463, Unknown), + "ID_Einst_SuBwTG_zeit_4_4": (464, Unknown), + "ID_Einst_SuBwTG_zeit_4_5": (465, Unknown), + "ID_Einst_SuBwTG_zeit_0_6": (466, Unknown), + "ID_Einst_SuBwTG_zeit_0_7": (467, Unknown), + "ID_Einst_SuBwTG_zeit_1_6": (468, Unknown), + "ID_Einst_SuBwTG_zeit_1_7": (469, Unknown), + "ID_Einst_SuBwTG_zeit_2_6": (470, Unknown), + "ID_Einst_SuBwTG_zeit_2_7": (471, Unknown), + "ID_Einst_SuBwTG_zeit_3_6": (472, Unknown), + "ID_Einst_SuBwTG_zeit_3_7": (473, Unknown), + "ID_Einst_SuBwTG_zeit_4_6": (474, Unknown), + "ID_Einst_SuBwTG_zeit_4_7": (475, Unknown), + "ID_Einst_SuBwTG_zeit_0_8": (476, Unknown), + "ID_Einst_SuBwTG_zeit_0_9": (477, Unknown), + "ID_Einst_SuBwTG_zeit_1_8": (478, Unknown), + "ID_Einst_SuBwTG_zeit_1_9": (479, Unknown), + "ID_Einst_SuBwTG_zeit_2_8": (480, Unknown), + "ID_Einst_SuBwTG_zeit_2_9": (481, Unknown), + "ID_Einst_SuBwTG_zeit_3_8": (482, Unknown), + "ID_Einst_SuBwTG_zeit_3_9": (483, Unknown), + "ID_Einst_SuBwTG_zeit_4_8": (484, Unknown), + "ID_Einst_SuBwTG_zeit_4_9": (485, Unknown), + "ID_Einst_SuBwTG_zeit_0_10": (486, Unknown), + "ID_Einst_SuBwTG_zeit_0_11": (487, Unknown), + "ID_Einst_SuBwTG_zeit_1_10": (488, Unknown), + "ID_Einst_SuBwTG_zeit_1_11": (489, Unknown), + "ID_Einst_SuBwTG_zeit_2_10": (490, Unknown), + "ID_Einst_SuBwTG_zeit_2_11": (491, Unknown), + "ID_Einst_SuBwTG_zeit_3_10": (492, Unknown), + "ID_Einst_SuBwTG_zeit_3_11": (493, Unknown), + "ID_Einst_SuBwTG_zeit_4_10": (494, Unknown), + "ID_Einst_SuBwTG_zeit_4_11": (495, Unknown), + "ID_Einst_SuBwTG_zeit_0_12": (496, Unknown), + "ID_Einst_SuBwTG_zeit_0_13": (497, Unknown), + "ID_Einst_SuBwTG_zeit_1_12": (498, Unknown), + "ID_Einst_SuBwTG_zeit_1_13": (499, Unknown), + "ID_Einst_SuBwTG_zeit_2_12": (500, Unknown), + "ID_Einst_SuBwTG_zeit_2_13": (501, Unknown), + "ID_Einst_SuBwTG_zeit_3_12": (502, Unknown), + "ID_Einst_SuBwTG_zeit_3_13": (503, Unknown), + "ID_Einst_SuBwTG_zeit_4_12": (504, Unknown), + "ID_Einst_SuBwTG_zeit_4_13": (505, Unknown), + "ID_Einst_SuZIP_akt": (506, Unknown), + "ID_Einst_SuZIPWo_zeit_0_0": (507, Unknown), + "ID_Einst_SuZIPWo_zeit_0_1": (508, Unknown), + "ID_Einst_SuZIPWo_zeit_1_0": (509, Unknown), + "ID_Einst_SuZIPWo_zeit_1_1": (510, Unknown), + "ID_Einst_SuZIPWo_zeit_2_0": (511, Unknown), + "ID_Einst_SuZIPWo_zeit_2_1": (512, Unknown), + "ID_Einst_SuZIPWo_zeit_3_0": (513, Unknown), + "ID_Einst_SuZIPWo_zeit_3_1": (514, Unknown), + "ID_Einst_SuZIPWo_zeit_4_0": (515, Unknown), + "ID_Einst_SuZIPWo_zeit_4_1": (516, Unknown), + "ID_Einst_SuZIP25_zeit_0_0": (517, Unknown), + "ID_Einst_SuZIP25_zeit_0_1": (518, Unknown), + "ID_Einst_SuZIP25_zeit_1_0": (519, Unknown), + "ID_Einst_SuZIP25_zeit_1_1": (520, Unknown), + "ID_Einst_SuZIP25_zeit_2_0": (521, Unknown), + "ID_Einst_SuZIP25_zeit_2_1": (522, Unknown), + "ID_Einst_SuZIP25_zeit_3_0": (523, Unknown), + "ID_Einst_SuZIP25_zeit_3_1": (524, Unknown), + "ID_Einst_SuZIP25_zeit_4_0": (525, Unknown), + "ID_Einst_SuZIP25_zeit_4_1": (526, Unknown), + "ID_Einst_SuZIP25_zeit_0_2": (527, Unknown), + "ID_Einst_SuZIP25_zeit_0_3": (528, Unknown), + "ID_Einst_SuZIP25_zeit_1_2": (529, Unknown), + "ID_Einst_SuZIP25_zeit_1_3": (530, Unknown), + "ID_Einst_SuZIP25_zeit_2_2": (531, Unknown), + "ID_Einst_SuZIP25_zeit_2_3": (532, Unknown), + "ID_Einst_SuZIP25_zeit_3_2": (533, Unknown), + "ID_Einst_SuZIP25_zeit_3_3": (534, Unknown), + "ID_Einst_SuZIP25_zeit_4_2": (535, Unknown), + "ID_Einst_SuZIP25_zeit_4_3": (536, Unknown), + "ID_Einst_SuZIPTg_zeit_0_0": (537, Unknown), + "ID_Einst_SuZIPTg_zeit_0_1": (538, Unknown), + "ID_Einst_SuZIPTg_zeit_1_0": (539, Unknown), + "ID_Einst_SuZIPTg_zeit_1_1": (540, Unknown), + "ID_Einst_SuZIPTg_zeit_2_0": (541, Unknown), + "ID_Einst_SuZIPTg_zeit_2_1": (542, Unknown), + "ID_Einst_SuZIPTg_zeit_3_0": (543, Unknown), + "ID_Einst_SuZIPTg_zeit_3_1": (544, Unknown), + "ID_Einst_SuZIPTg_zeit_4_0": (545, Unknown), + "ID_Einst_SuZIPTg_zeit_4_1": (546, Unknown), + "ID_Einst_SuZIPTg_zeit_0_2": (547, Unknown), + "ID_Einst_SuZIPTg_zeit_0_3": (548, Unknown), + "ID_Einst_SuZIPTg_zeit_1_2": (549, Unknown), + "ID_Einst_SuZIPTg_zeit_1_3": (550, Unknown), + "ID_Einst_SuZIPTg_zeit_2_2": (551, Unknown), + "ID_Einst_SuZIPTg_zeit_2_3": (552, Unknown), + "ID_Einst_SuZIPTg_zeit_3_2": (553, Unknown), + "ID_Einst_SuZIPTg_zeit_3_3": (554, Unknown), + "ID_Einst_SuZIPTg_zeit_4_2": (555, Unknown), + "ID_Einst_SuZIPTg_zeit_4_3": (556, Unknown), + "ID_Einst_SuZIPTg_zeit_0_4": (557, Unknown), + "ID_Einst_SuZIPTg_zeit_0_5": (558, Unknown), + "ID_Einst_SuZIPTg_zeit_1_4": (559, Unknown), + "ID_Einst_SuZIPTg_zeit_1_5": (560, Unknown), + "ID_Einst_SuZIPTg_zeit_2_4": (561, Unknown), + "ID_Einst_SuZIPTg_zeit_2_5": (562, Unknown), + "ID_Einst_SuZIPTg_zeit_3_4": (563, Unknown), + "ID_Einst_SuZIPTg_zeit_3_5": (564, Unknown), + "ID_Einst_SuZIPTg_zeit_4_4": (565, Unknown), + "ID_Einst_SuZIPTg_zeit_4_5": (566, Unknown), + "ID_Einst_SuZIPTg_zeit_0_6": (567, Unknown), + "ID_Einst_SuZIPTg_zeit_0_7": (568, Unknown), + "ID_Einst_SuZIPTg_zeit_1_6": (569, Unknown), + "ID_Einst_SuZIPTg_zeit_1_7": (570, Unknown), + "ID_Einst_SuZIPTg_zeit_2_6": (571, Unknown), + "ID_Einst_SuZIPTg_zeit_2_7": (572, Unknown), + "ID_Einst_SuZIPTg_zeit_3_6": (573, Unknown), + "ID_Einst_SuZIPTg_zeit_3_7": (574, Unknown), + "ID_Einst_SuZIPTg_zeit_4_6": (575, Unknown), + "ID_Einst_SuZIPTg_zeit_4_7": (576, Unknown), + "ID_Einst_SuZIPTg_zeit_0_8": (577, Unknown), + "ID_Einst_SuZIPTg_zeit_0_9": (578, Unknown), + "ID_Einst_SuZIPTg_zeit_1_8": (579, Unknown), + "ID_Einst_SuZIPTg_zeit_1_9": (580, Unknown), + "ID_Einst_SuZIPTg_zeit_2_8": (581, Unknown), + "ID_Einst_SuZIPTg_zeit_2_9": (582, Unknown), + "ID_Einst_SuZIPTg_zeit_3_8": (583, Unknown), + "ID_Einst_SuZIPTg_zeit_3_9": (584, Unknown), + "ID_Einst_SuZIPTg_zeit_4_8": (585, Unknown), + "ID_Einst_SuZIPTg_zeit_4_9": (586, Unknown), + "ID_Einst_SuZIPTg_zeit_0_10": (587, Unknown), + "ID_Einst_SuZIPTg_zeit_0_11": (588, Unknown), + "ID_Einst_SuZIPTg_zeit_1_10": (589, Unknown), + "ID_Einst_SuZIPTg_zeit_1_11": (590, Unknown), + "ID_Einst_SuZIPTg_zeit_2_10": (591, Unknown), + "ID_Einst_SuZIPTg_zeit_2_11": (592, Unknown), + "ID_Einst_SuZIPTg_zeit_3_10": (593, Unknown), + "ID_Einst_SuZIPTg_zeit_3_11": (594, Unknown), + "ID_Einst_SuZIPTg_zeit_4_10": (595, Unknown), + "ID_Einst_SuZIPTg_zeit_4_11": (596, Unknown), + "ID_Einst_SuZIPTg_zeit_0_12": (597, Unknown), + "ID_Einst_SuZIPTg_zeit_0_13": (598, Unknown), + "ID_Einst_SuZIPTg_zeit_1_12": (599, Unknown), + "ID_Einst_SuZIPTg_zeit_1_13": (600, Unknown), + "ID_Einst_SuZIPTg_zeit_2_12": (601, Unknown), + "ID_Einst_SuZIPTg_zeit_2_13": (602, Unknown), + "ID_Einst_SuZIPTg_zeit_3_12": (603, Unknown), + "ID_Einst_SuZIPTg_zeit_3_13": (604, Unknown), + "ID_Einst_SuZIPTg_zeit_4_12": (605, Unknown), + "ID_Einst_SuZIPTg_zeit_4_13": (606, Unknown), + "ID_Einst_SuSwb_akt": (607, Unknown), + "ID_Einst_SuSwbWo_zeit_0_0": (608, Unknown), + "ID_Einst_SuSwbWo_zeit_0_1": (609, Unknown), + "ID_Einst_SuSwbWo_zeit_1_0": (610, Unknown), + "ID_Einst_SuSwbWo_zeit_1_1": (611, Unknown), + "ID_Einst_SuSwbWo_zeit_2_0": (612, Unknown), + "ID_Einst_SuSwbWo_zeit_2_1": (613, Unknown), + "ID_Einst_SuSwb25_zeit_0_0": (614, Unknown), + "ID_Einst_SuSwb25_zeit_0_1": (615, Unknown), + "ID_Einst_SuSwb25_zeit_1_0": (616, Unknown), + "ID_Einst_SuSwb25_zeit_1_1": (617, Unknown), + "ID_Einst_SuSwb25_zeit_2_0": (618, Unknown), + "ID_Einst_SuSwb25_zeit_2_1": (619, Unknown), + "ID_Einst_SuSwb25_zeit_0_2": (620, Unknown), + "ID_Einst_SuSwb25_zeit_0_3": (621, Unknown), + "ID_Einst_SuSwb25_zeit_1_2": (622, Unknown), + "ID_Einst_SuSwb25_zeit_1_3": (623, Unknown), + "ID_Einst_SuSwb25_zeit_2_2": (624, Unknown), + "ID_Einst_SuSwb25_zeit_2_3": (625, Unknown), + "ID_Einst_SuSwbTg_zeit_0_0": (626, Unknown), + "ID_Einst_SuSwbTg_zeit_0_1": (627, Unknown), + "ID_Einst_SuSwbTg_zeit_1_0": (628, Unknown), + "ID_Einst_SuSwbTg_zeit_1_1": (629, Unknown), + "ID_Einst_SuSwbTg_zeit_2_0": (630, Unknown), + "ID_Einst_SuSwbTg_zeit_2_1": (631, Unknown), + "ID_Einst_SuSwbTg_zeit_0_2": (632, Unknown), + "ID_Einst_SuSwbTg_zeit_0_3": (633, Unknown), + "ID_Einst_SuSwbTg_zeit_1_2": (634, Unknown), + "ID_Einst_SuSwbTg_zeit_1_3": (635, Unknown), + "ID_Einst_SuSwbTg_zeit_2_2": (636, Unknown), + "ID_Einst_SuSwbTg_zeit_2_3": (637, Unknown), + "ID_Einst_SuSwbTg_zeit_0_4": (638, Unknown), + "ID_Einst_SuSwbTg_zeit_0_5": (639, Unknown), + "ID_Einst_SuSwbTg_zeit_1_4": (640, Unknown), + "ID_Einst_SuSwbTg_zeit_1_5": (641, Unknown), + "ID_Einst_SuSwbTg_zeit_2_4": (642, Unknown), + "ID_Einst_SuSwbTg_zeit_2_5": (643, Unknown), + "ID_Einst_SuSwbTg_zeit_0_6": (644, Unknown), + "ID_Einst_SuSwbTg_zeit_0_7": (645, Unknown), + "ID_Einst_SuSwbTg_zeit_1_6": (646, Unknown), + "ID_Einst_SuSwbTg_zeit_1_7": (647, Unknown), + "ID_Einst_SuSwbTg_zeit_2_6": (648, Unknown), + "ID_Einst_SuSwbTg_zeit_2_7": (649, Unknown), + "ID_Einst_SuSwbTg_zeit_0_8": (650, Unknown), + "ID_Einst_SuSwbTg_zeit_0_9": (651, Unknown), + "ID_Einst_SuSwbTg_zeit_1_8": (652, Unknown), + "ID_Einst_SuSwbTg_zeit_1_9": (653, Unknown), + "ID_Einst_SuSwbTg_zeit_2_8": (654, Unknown), + "ID_Einst_SuSwbTg_zeit_2_9": (655, Unknown), + "ID_Einst_SuSwbTg_zeit_0_10": (656, Unknown), + "ID_Einst_SuSwbTg_zeit_0_11": (657, Unknown), + "ID_Einst_SuSwbTg_zeit_1_10": (658, Unknown), + "ID_Einst_SuSwbTg_zeit_1_11": (659, Unknown), + "ID_Einst_SuSwbTg_zeit_2_10": (660, Unknown), + "ID_Einst_SuSwbTg_zeit_2_11": (661, Unknown), + "ID_Einst_SuSwbTg_zeit_0_12": (662, Unknown), + "ID_Einst_SuSwbTg_zeit_0_13": (663, Unknown), + "ID_Einst_SuSwbTg_zeit_1_12": (664, Unknown), + "ID_Einst_SuSwbTg_zeit_1_13": (665, Unknown), + "ID_Einst_SuSwbTg_zeit_2_12": (666, Unknown), + "ID_Einst_SuSwbTg_zeit_2_13": (667, Unknown), + "ID_Zaehler_BetrZeitWP": (668, Unknown), + "ID_Zaehler_BetrZeitVD1": (669, Unknown), + "ID_Zaehler_BetrZeitVD2": (670, Unknown), + "ID_Zaehler_BetrZeitZWE1": (671, Unknown), + "ID_Zaehler_BetrZeitZWE2": (672, Unknown), + "ID_Zaehler_BetrZeitZWE3": (673, Unknown), + "ID_Zaehler_BetrZeitImpVD1": (674, Unknown), + "ID_Zaehler_BetrZeitImpVD2": (675, Unknown), + "ID_Zaehler_BetrZeitEZMVD1": (676, Unknown), + "ID_Zaehler_BetrZeitEZMVD2": (677, Unknown), + "ID_Einst_Entl_Typ_0": (678, Unknown), + "ID_Einst_Entl_Typ_1": (679, Unknown), + "ID_Einst_Entl_Typ_2": (680, Unknown), + "ID_Einst_Entl_Typ_3": (681, Unknown), + "ID_Einst_Entl_Typ_4": (682, Unknown), + "ID_Einst_Entl_Typ_5": (683, Unknown), + "ID_Einst_Entl_Typ_6": (684, Unknown), + "ID_Einst_Entl_Typ_7": (685, Unknown), + "ID_Einst_Entl_Typ_8": (686, Unknown), + "ID_Einst_Entl_Typ_9": (687, Unknown), + "ID_Einst_Entl_Typ_10": (688, Unknown), + "ID_Einst_Entl_Typ_11": (689, Unknown), + "ID_Einst_Entl_Typ_12": (690, Unknown), + "ID_Einst_Vorl_max_MK1": (691, Unknown), + "ID_Einst_Vorl_max_MK2": (692, Unknown), + "ID_SU_FrkdMK1": (693, Unknown), + "ID_SU_FrkdMK2": (694, Unknown), + "ID_Ba_Hz_MK1_akt": (695, Unknown), + "ID_Ba_Hz_MK2_akt": (696, Unknown), + "ID_Einst_Zirk_Ein_akt": (697, Unknown), + "ID_Einst_Zirk_Aus_akt": (698, Unknown), + "ID_Einst_Heizgrenze": (699, Unknown), + "ID_Einst_Heizgrenze_Temp": (700, Celsius), + "ID_VariablenIBNgespeichert": (701, Unknown), + "ID_SchonIBNAssistant": (702, Unknown), + "ID_Heizgrenze_0": (703, Unknown), + "ID_Heizgrenze_1": (704, Unknown), + "ID_Heizgrenze_2": (705, Unknown), + "ID_Heizgrenze_3": (706, Unknown), + "ID_Heizgrenze_4": (707, Unknown), + "ID_Heizgrenze_5": (708, Unknown), + "ID_Heizgrenze_6": (709, Unknown), + "ID_Heizgrenze_7": (710, Unknown), + "ID_Heizgrenze_8": (711, Unknown), + "ID_Heizgrenze_9": (712, Unknown), + "ID_Heizgrenze_10": (713, Unknown), + "ID_Heizgrenze_11": (714, Unknown), + "ID_SchemenIBNgewahlt": (715, Unknown), + "ID_Switchoff_file_0_0": (716, Unknown), + "ID_Switchoff_file_1_0": (717, Unknown), + "ID_Switchoff_file_2_0": (718, Unknown), + "ID_Switchoff_file_3_0": (719, Unknown), + "ID_Switchoff_file_4_0": (720, Unknown), + "ID_Switchoff_file_0_1": (721, Unknown), + "ID_Switchoff_file_1_1": (722, Unknown), + "ID_Switchoff_file_2_1": (723, Unknown), + "ID_Switchoff_file_3_1": (724, Unknown), + "ID_Switchoff_file_4_1": (725, Unknown), + "ID_DauerDatenLoggerAktiv": (726, Unknown), + "ID_Laufvar_Heizgrenze": (727, Unknown), + "ID_Zaehler_BetrZeitHz": (728, Unknown), + "ID_Zaehler_BetrZeitBW": (729, Unknown), + "ID_Zaehler_BetrZeitKue": (730, Unknown), + "ID_SU_FstdHz": (731, Unknown), + "ID_SU_FstdBw": (732, Unknown), + "ID_SU_FstdSwb": (733, Unknown), + "ID_SU_FstdMK1": (734, Unknown), + "ID_SU_FstdMK2": (735, Unknown), + "ID_FerienAbsenkungHz": (736, Unknown), + "ID_FerienAbsenkungMK1": (737, Unknown), + "ID_FerienAbsenkungMK2": (738, Unknown), + "ID_FerienModusAktivHz": (739, Unknown), + "ID_FerienModusAktivBw": (740, Unknown), + "ID_FerienModusAktivSwb": (741, Unknown), + "ID_FerienModusAktivMk1": (742, Unknown), + "ID_FerienModusAktivMk2": (743, Unknown), + "ID_DisplayContrast_akt": (744, Unknown), + "ID_Ba_Hz_saved": (745, Unknown), + "ID_Ba_Bw_saved": (746, Unknown), + "ID_Ba_Sw_saved": (747, Unknown), + "ID_Ba_Hz_MK1_saved": (748, Unknown), + "ID_Ba_Hz_MK2_saved": (749, Unknown), + "ID_AdresseIP_akt": (750, Unknown), + "ID_SubNetMask_akt": (751, Unknown), + "ID_Add_Broadcast_akt": (752, Unknown), + "ID_Add_StdGateway_akt": (753, Unknown), + "ID_DHCPServerAktiv_akt": (754, Unknown), + "ID_WebserverPasswort_1_akt": (755, Unknown), + "ID_WebserverPasswort_2_akt": (756, Unknown), + "ID_WebserverPasswort_3_akt": (757, Unknown), + "ID_WebserverPasswort_4_akt": (758, Unknown), + "ID_WebserverPasswort_5_akt": (759, Unknown), + "ID_WebserverPasswort_6_akt": (760, Unknown), + "ID_WebServerWerteBekommen": (761, Unknown), + "ID_Einst_ParBetr_akt": (762, Unknown), + "ID_Einst_WpAnz_akt": (763, Unknown), + "ID_Einst_PhrTime_akt": (764, Unknown), + "ID_Einst_HysPar_akt": (765, Unknown), + "ID_IP_PB_Slave_0": (766, Unknown), + "ID_IP_PB_Slave_1": (767, Unknown), + "ID_IP_PB_Slave_2": (768, Unknown), + "ID_IP_PB_Slave_3": (769, Unknown), + "ID_IP_PB_Slave_4": (770, Unknown), + "ID_IP_PB_Slave_5": (771, Unknown), + "ID_Einst_BwHup_akt_backup": (772, Unknown), + "ID_Einst_SuMk3_akt": (773, Unknown), + "ID_Einst_HzMK3E_akt": (774, Unknown), + "ID_Einst_HzMK3ANH_akt": (775, Unknown), + "ID_Einst_HzMK3ABS_akt": (776, Unknown), + "ID_Einst_HzMK3Hgr_akt": (777, Unknown), + "ID_Einst_HzFtMK3Vl_akt": (778, Unknown), + "ID_Ba_Hz_MK3_akt": (779, MixedCircuitMode), + "ID_Einst_MK3Typ_akt": (780, Unknown), + "ID_Einst_RTypMK3_akt": (781, Unknown), + "ID_Einst_MK3LzFaktor_akt": (782, Unknown), + "ID_Einst_MK3PerFaktor_akt": (783, Unknown), + "ID_FerienModusAktivMk3": (784, Unknown), + "ID_SU_FrkdMK3": (785, Unknown), + "ID_FerienAbsenkungMK3": (786, Unknown), + "ID_SU_FstdMK3": (787, Unknown), + "ID_Einst_SuMk3_akt2": (788, Unknown), + "ID_Einst_SuMk3Wo_zeit_0_0": (789, Unknown), + "ID_Einst_SuMk3Wo_zeit_0_1": (790, Unknown), + "ID_Einst_SuMk3Wo_zeit_1_0": (791, Unknown), + "ID_Einst_SuMk3Wo_zeit_1_1": (792, Unknown), + "ID_Einst_SuMk3Wo_zeit_2_0": (793, Unknown), + "ID_Einst_SuMk3Wo_zeit_2_1": (794, Unknown), + "ID_Einst_SuMk325_zeit_0_0": (795, Unknown), + "ID_Einst_SuMk325_zeit_0_1": (796, Unknown), + "ID_Einst_SuMk325_zeit_1_0": (797, Unknown), + "ID_Einst_SuMk325_zeit_1_1": (798, Unknown), + "ID_Einst_SuMk325_zeit_2_0": (799, Unknown), + "ID_Einst_SuMk325_zeit_2_1": (800, Unknown), + "ID_Einst_SuMk325_zeit_0_2": (801, Unknown), + "ID_Einst_SuMk325_zeit_0_3": (802, Unknown), + "ID_Einst_SuMk325_zeit_1_2": (803, Unknown), + "ID_Einst_SuMk325_zeit_1_3": (804, Unknown), + "ID_Einst_SuMk325_zeit_2_2": (805, Unknown), + "ID_Einst_SuMk325_zeit_2_3": (806, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_0": (807, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_1": (808, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_0": (809, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_1": (810, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_0": (811, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_1": (812, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_2": (813, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_3": (814, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_2": (815, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_3": (816, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_2": (817, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_3": (818, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_4": (819, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_5": (820, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_4": (821, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_5": (822, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_4": (823, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_5": (824, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_6": (825, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_7": (826, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_6": (827, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_7": (828, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_6": (829, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_7": (830, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_8": (831, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_9": (832, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_8": (833, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_9": (834, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_8": (835, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_9": (836, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_10": (837, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_11": (838, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_10": (839, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_11": (840, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_10": (841, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_11": (842, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_12": (843, Unknown), + "ID_Einst_SuMk3Tg_zeit_0_13": (844, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_12": (845, Unknown), + "ID_Einst_SuMk3Tg_zeit_1_13": (846, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_12": (847, Unknown), + "ID_Einst_SuMk3Tg_zeit_2_13": (848, Unknown), + "ID_Ba_Hz_MK3_saved": (849, Unknown), + "ID_Einst_Kuhl_Zeit_Ein_akt": (850, Hours), + "ID_Einst_Kuhl_Zeit_Aus_akt": (851, Hours), + "ID_Waermemenge_Seit": (852, Unknown), + "ID_Waermemenge_WQ": (853, Unknown), + "ID_Waermemenge_Hz": (854, Unknown), + "ID_Waermemenge_WQ_ges": (855, Unknown), + "ID_Einst_Entl_Typ_13": (856, Unknown), + "ID_Einst_Entl_Typ_14": (857, Unknown), + "ID_Einst_Entl_Typ_15": (858, Unknown), + "ID_Zaehler_BetrZeitSW": (859, Unknown), + "ID_Einst_Fernwartung_akt": (860, Unknown), + "ID_AdresseIPServ_akt": (861, Unknown), + "ID_Einst_TA_EG_akt": (862, Unknown), + "ID_Einst_TVLmax_EG_akt": (863, Unknown), + "ID_Einst_Popt_Nachlauf_akt": (864, Unknown), + "ID_FernwartungVertrag_akt": (865, Unknown), + "ID_FernwartungAktuZeit": (866, Unknown), + "ID_Einst_Effizienzpumpe_Nominal_akt": (867, Unknown), + "ID_Einst_Effizienzpumpe_Minimal_akt": (868, Unknown), + "ID_Einst_Effizienzpumpe_akt": (869, Unknown), + "ID_Einst_Waermemenge_akt": (870, Unknown), + "ID_Einst_Wm_Versorgung_Korrektur_akt": (871, Unknown), + "ID_Einst_Wm_Auswertung_Korrektur_akt": (872, Unknown), + "ID_SoftwareUpdateJetztGemacht_akt": (873, Unknown), + "ID_WP_SerienNummer_DATUM": (874, Unknown), + "ID_WP_SerienNummer_HEX": (875, Unknown), + "ID_WP_SerienNummer_INDEX": (876, Unknown), + "ID_ProgWerteWebSrvBeobarten": (877, Unknown), + "ID_Waermemenge_BW": (878, Unknown), + "ID_Waermemenge_SW": (879, Unknown), + "ID_Waermemenge_Datum": (880, Unknown), + "ID_Einst_Solar_akt": (881, SolarMode), + "ID_BSTD_Solar": (882, Unknown), + "ID_Einst_TDC_Koll_Max_akt": (883, Celsius), + "ID_Einst_Akt_Kuehlung_akt": (884, Unknown), + "ID_Einst_Vorlauf_VBO_akt": (885, Unknown), + "ID_Einst_KRHyst_akt": (886, Unknown), + "ID_Einst_Akt_Kuehl_Speicher_min_akt": (887, Unknown), + "ID_Einst_Akt_Kuehl_Freig_WQE_akt": (888, Unknown), + "ID_NDAB_WW_Anzahl": (889, Unknown), + "ID_NDS_WW_KD_Quitt": (890, Unknown), + "ID_Einst_AbtZykMin_akt": (891, Unknown), + "ID_Einst_VD2_Zeit_Min_akt": (892, Unknown), + "ID_Einst_Hysterese_HR_verkuerzt_akt": (893, Unknown), + "ID_Einst_BA_Lueftung_akt": (894, VentilationMode), + "ID_Einst_SuLuf_akt": (895, Unknown), + "ID_Einst_SuLufWo_zeit_0_0_0": (896, Unknown), + "ID_Einst_SuLufWo_zeit_0_1_0": (897, Unknown), + "ID_Einst_SuLufWo_zeit_0_2_0": (898, Unknown), + "ID_Einst_SuLuf25_zeit_0_0_0": (899, Unknown), + "ID_Einst_SuLuf25_zeit_0_1_0": (900, Unknown), + "ID_Einst_SuLuf25_zeit_0_2_0": (901, Unknown), + "ID_Einst_SuLuf25_zeit_0_0_2": (902, Unknown), + "ID_Einst_SuLuf25_zeit_0_1_2": (903, Unknown), + "ID_Einst_SuLuf25_zeit_0_2_2": (904, Unknown), + "ID_Einst_SuLufTg_zeit_0_0_0": (905, Unknown), + "ID_Einst_SuLufTg_zeit_0_1_0": (906, Unknown), + "ID_Einst_SuLufTg_zeit_0_2_0": (907, Unknown), + "ID_Einst_SuLufTg_zeit_0_0_2": (908, Unknown), + "ID_Einst_SuLufTg_zeit_0_1_2": (909, Unknown), + "ID_Einst_SuLufTg_zeit_0_2_2": (910, Unknown), + "ID_Einst_SuLufTg_zeit_0_0_4": (911, Unknown), + "ID_Einst_SuLufTg_zeit_0_1_4": (912, Unknown), + "ID_Einst_SuLufTg_zeit_0_2_4": (913, Unknown), + "ID_Einst_SuLufTg_zeit_0_0_6": (914, Unknown), + "ID_Einst_SuLufTg_zeit_0_1_6": (915, Unknown), + "ID_Einst_SuLufTg_zeit_0_2_6": (916, Unknown), + "ID_Einst_SuLufTg_zeit_0_0_8": (917, Unknown), + "ID_Einst_SuLufTg_zeit_0_1_8": (918, Unknown), + "ID_Einst_SuLufTg_zeit_0_2_8": (919, Unknown), + "ID_Einst_SuLufTg_zeit_0_0_10": (920, Unknown), + "ID_Einst_SuLufTg_zeit_0_1_10": (921, Unknown), + "ID_Einst_SuLufTg_zeit_0_2_10": (922, Unknown), + "ID_Einst_SuLufTg_zeit_0_0_12": (923, Unknown), + "ID_Einst_SuLufTg_zeit_0_1_12": (924, Unknown), + "ID_Einst_SuLufTg_zeit_0_2_12": (925, Unknown), + "ID_Einst_SuLufWo_zeit_1_0_0": (926, Unknown), + "ID_Einst_SuLufWo_zeit_1_1_0": (927, Unknown), + "ID_Einst_SuLufWo_zeit_1_2_0": (928, Unknown), + "ID_Einst_SuLuf25_zeit_1_0_0": (929, Unknown), + "ID_Einst_SuLuf25_zeit_1_1_0": (930, Unknown), + "ID_Einst_SuLuf25_zeit_1_2_0": (931, Unknown), + "ID_Einst_SuLuf25_zeit_1_0_2": (932, Unknown), + "ID_Einst_SuLuf25_zeit_1_1_2": (933, Unknown), + "ID_Einst_SuLuf25_zeit_1_2_2": (934, Unknown), + "ID_Einst_SuLufTg_zeit_1_0_0": (935, Unknown), + "ID_Einst_SuLufTg_zeit_1_1_0": (936, Unknown), + "ID_Einst_SuLufTg_zeit_1_2_0": (937, Unknown), + "ID_Einst_SuLufTg_zeit_1_0_2": (938, Unknown), + "ID_Einst_SuLufTg_zeit_1_1_2": (939, Unknown), + "ID_Einst_SuLufTg_zeit_1_2_2": (940, Unknown), + "ID_Einst_SuLufTg_zeit_1_0_4": (941, Unknown), + "ID_Einst_SuLufTg_zeit_1_1_4": (942, Unknown), + "ID_Einst_SuLufTg_zeit_1_2_4": (943, Unknown), + "ID_Einst_SuLufTg_zeit_1_0_6": (944, Unknown), + "ID_Einst_SuLufTg_zeit_1_1_6": (945, Unknown), + "ID_Einst_SuLufTg_zeit_1_2_6": (946, Unknown), + "ID_Einst_SuLufTg_zeit_1_0_8": (947, Unknown), + "ID_Einst_SuLufTg_zeit_1_1_8": (948, Unknown), + "ID_Einst_SuLufTg_zeit_1_2_8": (949, Unknown), + "ID_Einst_SuLufTg_zeit_1_0_10": (950, Unknown), + "ID_Einst_SuLufTg_zeit_1_1_10": (951, Unknown), + "ID_Einst_SuLufTg_zeit_1_2_10": (952, Unknown), + "ID_Einst_SuLufTg_zeit_1_0_12": (953, Unknown), + "ID_Einst_SuLufTg_zeit_1_1_12": (954, Unknown), + "ID_Einst_SuLufTg_zeit_1_2_12": (955, Unknown), + "ID_FerienModusAktivLueftung": (956, Unknown), + "ID_Einst_BA_Lueftung_saved": (957, Unknown), + "ID_SU_FrkdLueftung": (958, Unknown), + "ID_SU_FstdLueftung": (959, Unknown), + "ID_Einst_Luf_Feuchteschutz_akt": (960, Unknown), + "ID_Einst_Luf_Reduziert_akt": (961, Unknown), + "ID_Einst_Luf_Nennlueftung_akt": (962, Unknown), + "ID_Einst_Luf_Intensivlueftung_akt": (963, Unknown), + "ID_Timer_Fil_4Makt": (964, Unknown), + "ID_Timer_Fil_WoAkt": (965, Unknown), + "ID_Sollwert_KuCft3_akt": (966, Celsius), + "ID_Sollwert_AtDif3_akt": (967, Celsius), + "ID_Bitmaske_0": (968, Unknown), + "ID_Einst_Lueftungsstufen": (969, Unknown), + "ID_SysEin_Meldung_TDI": (970, Unknown), + "ID_SysEin_Typ_WZW": (971, Unknown), + "ID_Einst_GLT_aktiviert": (972, Unknown), + "ID_Einst_BW_max": (973, Unknown), + "ID_Einst_Sollwert_TRL_Kuehlen": (974, Unknown), + "ID_Einst_Medium_Waermequelle": (975, Unknown), + "ID_Einst_Photovoltaik_akt": (976, Unknown), + "ID_Einst_Multispeicher_akt": (977, Unknown), + "ID_Einst_PKuehlTime_akt": (978, Unknown), + "ID_Einst_Minimale_Ruecklaufsolltemperatur": (979, Unknown), + "ID_RBE_Einflussfaktor_RT_akt": (980, Unknown), + "ID_RBE_Freigabe_Kuehlung_akt": (981, Unknown), + "ID_RBE_Waermeverteilsystem_akt": (982, Unknown), + "ID_RBE_Zeit_Heizstab_aktiv": (983, Unknown), + "ID_SEC_ND_Alarmgrenze": (984, Unknown), + "ID_SEC_HD_Alarmgrenze": (985, Unknown), + "ID_SEC_Abtauendtemperatur": (986, Unknown), + "ID_Einst_Min_RPM_BW": (987, Unknown), + "ID_Einst_Luf_Feuchteschutz_Faktor_akt": (988, Unknown), + "ID_Einst_Luf_Reduziert_Faktor_akt": (989, Unknown), + "ID_Einst_Luf_Nennlueftung_Faktor_akt": (990, Unknown), + "ID_Einst_Luf_Intensivlueftung_Faktor_akt": (991, Unknown), + "ID_Einst_Freigabe_Zeit_ZWE": (992, Unknown), + "ID_Einst_min_VL_Kuehl": (993, Unknown), + "ID_Einst_Warmwasser_Nachheizung": (994, Unknown), + "ID_Switchoff_file_LWD2_0_0": (995, Unknown), + "ID_Switchoff_file_LWD2_1_0": (996, Unknown), + "ID_Switchoff_file_LWD2_2_0": (997, Unknown), + "ID_Switchoff_file_LWD2_3_0": (998, Unknown), + "ID_Switchoff_file_LWD2_4_0": (999, Unknown), + "ID_Switchoff_file_LWD2_0_1": (1000, Unknown), + "ID_Switchoff_file_LWD2_1_1": (1001, Unknown), + "ID_Switchoff_file_LWD2_2_1": (1002, Unknown), + "ID_Switchoff_file_LWD2_3_1": (1003, Unknown), + "ID_Switchoff_file_LWD2_4_1": (1004, Unknown), + "ID_Switchoff_index_LWD2": (1005, Unknown), + "ID_Einst_Effizienzpumpe_Nominal_2": (1006, Unknown), + "ID_Einst_Effizienzpumpe_Minimal_2": (1007, Unknown), + "ID_Einst_Wm_Versorgung_Korrektur_2": (1008, Unknown), + "ID_Einst_Wm_Auswertung_Korrektur_2": (1009, Unknown), + "ID_Einst_isTwin": (1010, Unknown), + "ID_Einst_TAmin_2": (1011, Unknown), + "ID_Einst_TVLmax_2": (1012, Unknown), + "ID_Einst_TA_EG_2": (1013, Unknown), + "ID_Einst_TVLmax_EG_2": (1014, Unknown), + "ID_Waermemenge_Hz_2": (1015, Unknown), + "ID_Waermemenge_BW_2": (1016, Unknown), + "ID_Waermemenge_SW_2": (1017, Unknown), + "ID_Waermemenge_Seit_2": (1018, Unknown), + "ID_Einst_Entl_Typ_15_2": (1019, Unknown), + "ID_Einst_WW_Nachheizung_max": (1020, Unknown), + "ID_Einst_Kuhl_Zeit_Ein_RT": (1021, Unknown), + "ID_Einst_ZWE1_Pos": (1022, Unknown), + "ID_Einst_ZWE2_Pos": (1023, Unknown), + "ID_Einst_ZWE3_Pos": (1024, Unknown), + "ID_Einst_Leistung_ZWE": (1025, Unknown), + "ID_WP_SN2_DATUM": (1026, Unknown), + "ID_WP_SN2_HEX": (1027, Unknown), + "ID_WP_SN2_INDEX": (1028, Unknown), + "ID_CWP_saved2": (1029, Unknown), + "ID_Einst_SmartGrid": (1030, Unknown), + "ID_Einst_P155_HDS": (1031, Unknown), + "ID_Einst_P155_PumpHeat_Max": (1032, Unknown), + "ID_Einst_P155_PumpHeatCtrl": (1033, Unknown), + "ID_Einst_P155_PumpDHWCtrl": (1034, Unknown), + "ID_Einst_P155_PumpDHW_RPM": (1035, Unknown), + "ID_Einst_P155_PumpPoolCtrl": (1036, Unknown), + "ID_Einst_P155_PumpPool_RPM": (1037, Unknown), + "ID_Einst_P155_PumpCool_RPM": (1038, Unknown), + "ID_Einst_P155_PumpVBOCtrl": (1039, Unknown), + "ID_Einst_P155_PumpVBO_RPM_C": (1040, Unknown), + "ID_Einst_P155_PumpDHW_Max": (1041, Unknown), + "ID_Einst_P155_PumpPool_Max": (1042, Unknown), + "ID_Einst_P155_Sperrband_1": (1043, Unknown), + "ID_Einst_P155_Leistungsfreigabe": (1044, Unknown), + "ID_Einst_P155_DHW_Freq": (1045, Unknown), + "ID_Einst_SWHUP": (1046, Unknown), + "ID_Einst_P155_SWB_Freq": (1047, Unknown), + "ID_Einst_MK1_Regelung": (1048, Unknown), + "ID_Einst_MK2_Regelung": (1049, Unknown), + "ID_Einst_MK3_Regelung": (1050, Unknown), + "ID_Einst_PV_WW_Sperrzeit": (1051, Unknown), + "ID_Einst_Warmwasser_extra": (1052, Unknown), + "ID_Einst_Vorl_akt_Kuehl": (1053, Unknown), + "ID_WP_SN3_DATUM": (1054, Unknown), + "ID_WP_SN3_HEX": (1055, Unknown), + "ID_WP_SN3_INDEX": (1056, Unknown), + "ID_Einst_Vorlauf_ZUP": (1057, Unknown), + "ID_Einst_Abtauen_im_Warmwasser": (1058, Unknown), + "ID_Waermemenge_ZWE": (1059, Unknown), + "ID_Waermemenge_Reset": (1060, Unknown), + "ID_Waermemenge_Reset_2": (1061, Unknown), + "ID_Einst_Brunnenpumpe_min": (1062, Unknown), + "ID_Einst_Brunnenpumpe_max": (1063, Unknown), + "ID_Einst_SmartHomeID": (1064, Unknown), + "ID_Einst_SmartHK": (1065, Unknown), + "ID_Einst_SmartMK1": (1066, Unknown), + "ID_Einst_SmartMK2": (1067, Unknown), + "ID_Einst_SmartMK3": (1068, Unknown), + "ID_Einst_SmartWW": (1069, Unknown), + "ID_Einst_SmartDefrost": (1070, Unknown), + "ID_Einst_Empty1071": (1071, Unknown), + "ID_Einst_MinVLMK1": (1072, Unknown), + "ID_Einst_MinVLMK2": (1073, Unknown), + "ID_Einst_MinVLMK3": (1074, Unknown), + "ID_Einst_MaxVLMK1": (1075, Unknown), + "ID_Einst_MaxVLMK2": (1076, Unknown), + "ID_Einst_MaxVLMK3": (1077, Unknown), + "ID_Einst_SmartPlusHz": (1078, Unknown), + "ID_Einst_SmartMinusHz": (1079, Unknown), + "ID_Einst_SmartPlusMK1": (1080, Unknown), + "ID_Einst_SmartMinusMK1": (1081, Unknown), + "ID_Einst_SmartPlusMK2": (1082, Unknown), + "ID_Einst_SmartMinusMK2": (1083, Unknown), + "ID_Einst_SmartPlusMK3": (1084, Unknown), + "ID_Einst_SmartMinusMK3": (1085, Unknown), + "Unknown_Parameter_1086": (1086, Unknown), + "Unknown_Parameter_1087": (1087, Unknown), + "Unknown_Parameter_1088": (1088, Unknown), + "Unknown_Parameter_1089": (1089, Unknown), + "Unknown_Parameter_1090": (1090, Unknown), + "Unknown_Parameter_1091": (1091, Unknown), + "Unknown_Parameter_1092": (1092, Unknown), + "Unknown_Parameter_1093": (1093, Unknown), + "Unknown_Parameter_1094": (1094, Unknown), + "Unknown_Parameter_1095": (1095, Unknown), + "Unknown_Parameter_1096": (1096, Unknown), + "Unknown_Parameter_1097": (1097, Unknown), + "Unknown_Parameter_1098": (1098, Unknown), + "Unknown_Parameter_1099": (1099, Unknown), + "Unknown_Parameter_1100": (1100, Unknown), + "Unknown_Parameter_1101": (1101, Unknown), + "Unknown_Parameter_1102": (1102, Unknown), + "Unknown_Parameter_1103": (1103, Unknown), + "Unknown_Parameter_1104": (1104, Unknown), + "Unknown_Parameter_1105": (1105, Unknown), + "Unknown_Parameter_1106": (1106, Unknown), + "Unknown_Parameter_1107": (1107, Unknown), + "Unknown_Parameter_1108": (1108, Unknown), + "Unknown_Parameter_1109": (1109, Unknown), + "Unknown_Parameter_1110": (1110, Unknown), + "Unknown_Parameter_1111": (1111, Unknown), + "Unknown_Parameter_1112": (1112, Unknown), + "Unknown_Parameter_1113": (1113, Unknown), + "Unknown_Parameter_1114": (1114, Unknown), + "Unknown_Parameter_1115": (1115, Unknown), + "Unknown_Parameter_1116": (1116, Unknown), + "Unknown_Parameter_1117": (1117, Unknown), + "Unknown_Parameter_1118": (1118, Unknown), + "Unknown_Parameter_1119": (1119, Unknown), + "Unknown_Parameter_1120": (1120, Unknown), + "Unknown_Parameter_1121": (1121, Unknown), + "Unknown_Parameter_1122": (1122, Unknown), + "Unknown_Parameter_1123": (1123, Unknown), + "Unknown_Parameter_1124": (1124, Unknown), + "Unknown_Parameter_1125": (1125, Unknown), # New in 'main' branch: - "SILENT_MODE": 1087, - "ID_Einst_SuSilence": 1092, - "ID_Einst_SilenceTimer_0": 1093, - "ID_Einst_SilenceTimer_1": 1094, - "ID_Einst_SilenceTimer_2": 1095, - "ID_Einst_SilenceTimer_3": 1096, - "ID_Einst_SilenceTimer_4": 1097, - "ID_Einst_SilenceTimer_5": 1098, - "ID_Einst_SilenceTimer_6": 1099, - "ID_Einst_SilenceTimer_7": 1100, - "ID_Einst_SilenceTimer_8": 1101, - "ID_Einst_SilenceTimer_9": 1102, - "ID_Einst_SilenceTimer_10": 1103, - "ID_Einst_SilenceTimer_11": 1104, - "ID_Einst_SilenceTimer_12": 1105, - "ID_Einst_SilenceTimer_13": 1106, - "ID_Einst_SilenceTimer_14": 1107, - "ID_Einst_SilenceTimer_15": 1108, - "ID_Einst_SilenceTimer_16": 1109, - "ID_Einst_SilenceTimer_17": 1110, - "ID_Einst_SilenceTimer_18": 1111, - "ID_Einst_SilenceTimer_19": 1112, - "ID_Einst_SilenceTimer_20": 1113, - "LAST_DEFROST_TIMESTAMP": 1119, - "Unknown_Parameter_1126": 1126, - "Unknown_Parameter_1127": 1127, - "Unknown_Parameter_1128": 1128, - "Unknown_Parameter_1129": 1129, - "Unknown_Parameter_1130": 1130, - "Unknown_Parameter_1131": 1131, - "Unknown_Parameter_1132": 1132, - "Unknown_Parameter_1133": 1133, - "Unknown_Parameter_1134": 1134, - "Unknown_Parameter_1135": 1135, - "Unknown_Parameter_1136": 1136, - "HEAT_ENERGY_INPUT": 1136, - "Unknown_Parameter_1137": 1137, - "DHW_ENERGY_INPUT": 1137, - "Unknown_Parameter_1138": 1138, - "Unknown_Parameter_1139": 1139, - "COOLING_ENERGY_INPUT": 1139, - "Unknown_Parameter_1140": 1140, - "SECOND_HEAT_GENERATOR_AMOUNT_COUNTER": 1140, - "Unknown_Parameter_1141": 1141, - "Unknown_Parameter_1142": 1142, - "Unknown_Parameter_1143": 1143, - "Unknown_Parameter_1144": 1144, - "Unknown_Parameter_1145": 1145, - "Unknown_Parameter_1146": 1146, - "Unknown_Parameter_1147": 1147, - "Unknown_Parameter_1148": 1148, - "HEATING_TARGET_TEMP_ROOM_THERMOSTAT": 1148, - "Unknown_Parameter_1149": 1149, - "Unknown_Parameter_1150": 1150, - "Unknown_Parameter_1151": 1151, - "Unknown_Parameter_1152": 1152, - "Unknown_Parameter_1153": 1153, - "Unknown_Parameter_1154": 1154, - "Unknown_Parameter_1155": 1155, - "Unknown_Parameter_1156": 1156, - "Unknown_Parameter_1157": 1157, - "Unknown_Parameter_1158": 1158, - "POWER_LIMIT_SWITCH": 1158, - "Unknown_Parameter_1159": 1159, - "POWER_LIMIT_VALUE": 1159, + "SILENT_MODE": (1087, OnOffMode), + "ID_Einst_SuSilence": (1092, TimerProgram), + "ID_Einst_SilenceTimer_0": (1093, TimeOfDay2), + "ID_Einst_SilenceTimer_1": (1094, TimeOfDay2), + "ID_Einst_SilenceTimer_2": (1095, TimeOfDay2), + "ID_Einst_SilenceTimer_3": (1096, TimeOfDay2), + "ID_Einst_SilenceTimer_4": (1097, TimeOfDay2), + "ID_Einst_SilenceTimer_5": (1098, TimeOfDay2), + "ID_Einst_SilenceTimer_6": (1099, TimeOfDay2), + "ID_Einst_SilenceTimer_7": (1100, TimeOfDay2), + "ID_Einst_SilenceTimer_8": (1101, TimeOfDay2), + "ID_Einst_SilenceTimer_9": (1102, TimeOfDay2), + "ID_Einst_SilenceTimer_10": (1103, TimeOfDay2), + "ID_Einst_SilenceTimer_11": (1104, TimeOfDay2), + "ID_Einst_SilenceTimer_12": (1105, TimeOfDay2), + "ID_Einst_SilenceTimer_13": (1106, TimeOfDay2), + "ID_Einst_SilenceTimer_14": (1107, TimeOfDay2), + "ID_Einst_SilenceTimer_15": (1108, TimeOfDay2), + "ID_Einst_SilenceTimer_16": (1109, TimeOfDay2), + "ID_Einst_SilenceTimer_17": (1110, TimeOfDay2), + "ID_Einst_SilenceTimer_18": (1111, TimeOfDay2), + "ID_Einst_SilenceTimer_19": (1112, TimeOfDay2), + "ID_Einst_SilenceTimer_20": (1113, TimeOfDay2), + "LAST_DEFROST_TIMESTAMP": (1119, Timestamp), + "Unknown_Parameter_1126": (1126, Unknown), + "Unknown_Parameter_1127": (1127, Unknown), + "Unknown_Parameter_1128": (1128, Unknown), + "Unknown_Parameter_1129": (1129, Unknown), + "Unknown_Parameter_1130": (1130, Unknown), + "Unknown_Parameter_1131": (1131, Unknown), + "Unknown_Parameter_1132": (1132, Unknown), + "Unknown_Parameter_1133": (1133, Unknown), + "Unknown_Parameter_1134": (1134, Unknown), + "Unknown_Parameter_1135": (1135, Unknown), + "Unknown_Parameter_1136": (1136, Unknown), + "HEAT_ENERGY_INPUT": (1136, Energy), + "Unknown_Parameter_1137": (1137, Unknown), + "DHW_ENERGY_INPUT": (1137, Energy), + "Unknown_Parameter_1138": (1138, Unknown), + "Unknown_Parameter_1139": (1139, Unknown), + "COOLING_ENERGY_INPUT": (1139, Energy), + "Unknown_Parameter_1140": (1140, Unknown), + "SECOND_HEAT_GENERATOR_AMOUNT_COUNTER": (1140, Unknown), + "Unknown_Parameter_1141": (1141, Unknown), + "Unknown_Parameter_1142": (1142, Unknown), + "Unknown_Parameter_1143": (1143, Unknown), + "Unknown_Parameter_1144": (1144, Unknown), + "Unknown_Parameter_1145": (1145, Unknown), + "Unknown_Parameter_1146": (1146, Unknown), + "Unknown_Parameter_1147": (1147, Unknown), + "Unknown_Parameter_1148": (1148, Unknown), + "HEATING_TARGET_TEMP_ROOM_THERMOSTAT": (1148, Celsius), + "Unknown_Parameter_1149": (1149, Unknown), + "Unknown_Parameter_1150": (1150, Unknown), + "Unknown_Parameter_1151": (1151, Unknown), + "Unknown_Parameter_1152": (1152, Unknown), + "Unknown_Parameter_1153": (1153, Unknown), + "Unknown_Parameter_1154": (1154, Unknown), + "Unknown_Parameter_1155": (1155, Unknown), + "Unknown_Parameter_1156": (1156, Unknown), + "Unknown_Parameter_1157": (1157, Unknown), + "Unknown_Parameter_1158": (1158, Unknown), + "POWER_LIMIT_SWITCH": (1158, Unknown), + "Unknown_Parameter_1159": (1159, Unknown), + "POWER_LIMIT_VALUE": (1159, Unknown), } calcs = { # Status of 0.3.14: - "Unknown_Calculation_0": 0, - "Unknown_Calculation_1": 1, - "Unknown_Calculation_2": 2, - "Unknown_Calculation_3": 3, - "Unknown_Calculation_4": 4, - "Unknown_Calculation_5": 5, - "Unknown_Calculation_6": 6, - "Unknown_Calculation_7": 7, - "Unknown_Calculation_8": 8, - "Unknown_Calculation_9": 9, - "ID_WEB_Temperatur_TVL": 10, - "ID_WEB_Temperatur_TRL": 11, - "ID_WEB_Sollwert_TRL_HZ": 12, - "ID_WEB_Temperatur_TRL_ext": 13, - "ID_WEB_Temperatur_THG": 14, - "ID_WEB_Temperatur_TA": 15, - "ID_WEB_Mitteltemperatur": 16, - "ID_WEB_Temperatur_TBW": 17, - "ID_WEB_Einst_BWS_akt": 18, - "ID_WEB_Temperatur_TWE": 19, - "ID_WEB_Temperatur_TWA": 20, - "ID_WEB_Temperatur_TFB1": 21, - "ID_WEB_Sollwert_TVL_MK1": 22, - "ID_WEB_Temperatur_RFV": 23, - "ID_WEB_Temperatur_TFB2": 24, - "ID_WEB_Sollwert_TVL_MK2": 25, - "ID_WEB_Temperatur_TSK": 26, - "ID_WEB_Temperatur_TSS": 27, - "ID_WEB_Temperatur_TEE": 28, - "ID_WEB_ASDin": 29, - "ID_WEB_BWTin": 30, - "ID_WEB_EVUin": 31, - "ID_WEB_HDin": 32, - "ID_WEB_MOTin": 33, - "ID_WEB_NDin": 34, - "ID_WEB_PEXin": 35, - "ID_WEB_SWTin": 36, - "ID_WEB_AVout": 37, - "ID_WEB_BUPout": 38, - "ID_WEB_HUPout": 39, - "ID_WEB_MA1out": 40, - "ID_WEB_MZ1out": 41, - "ID_WEB_VENout": 42, - "ID_WEB_VBOout": 43, - "ID_WEB_VD1out": 44, - "ID_WEB_VD2out": 45, - "ID_WEB_ZIPout": 46, - "ID_WEB_ZUPout": 47, - "ID_WEB_ZW1out": 48, - "ID_WEB_ZW2SSTout": 49, - "ID_WEB_ZW3SSTout": 50, - "ID_WEB_FP2out": 51, - "ID_WEB_SLPout": 52, - "ID_WEB_SUPout": 53, - "ID_WEB_MZ2out": 54, - "ID_WEB_MA2out": 55, - "ID_WEB_Zaehler_BetrZeitVD1": 56, - "ID_WEB_Zaehler_BetrZeitImpVD1": 57, - "ID_WEB_Zaehler_BetrZeitVD2": 58, - "ID_WEB_Zaehler_BetrZeitImpVD2": 59, - "ID_WEB_Zaehler_BetrZeitZWE1": 60, - "ID_WEB_Zaehler_BetrZeitZWE2": 61, - "ID_WEB_Zaehler_BetrZeitZWE3": 62, - "ID_WEB_Zaehler_BetrZeitWP": 63, - "ID_WEB_Zaehler_BetrZeitHz": 64, - "ID_WEB_Zaehler_BetrZeitBW": 65, - "ID_WEB_Zaehler_BetrZeitKue": 66, - "ID_WEB_Time_WPein_akt": 67, - "ID_WEB_Time_ZWE1_akt": 68, - "ID_WEB_Time_ZWE2_akt": 69, - "ID_WEB_Timer_EinschVerz": 70, - "ID_WEB_Time_SSPAUS_akt": 71, - "ID_WEB_Time_SSPEIN_akt": 72, - "ID_WEB_Time_VDStd_akt": 73, - "ID_WEB_Time_HRM_akt": 74, - "ID_WEB_Time_HRW_akt": 75, - "ID_WEB_Time_LGS_akt": 76, - "ID_WEB_Time_SBW_akt": 77, - "ID_WEB_Code_WP_akt": 78, - "ID_WEB_BIV_Stufe_akt": 79, - "ID_WEB_WP_BZ_akt": 80, - "ID_WEB_AdresseIP_akt": 91, - "ID_WEB_SubNetMask_akt": 92, - "ID_WEB_Add_Broadcast": 93, - "ID_WEB_Add_StdGateway": 94, - "ID_WEB_ERROR_Time0": 95, - "ID_WEB_ERROR_Time1": 96, - "ID_WEB_ERROR_Time2": 97, - "ID_WEB_ERROR_Time3": 98, - "ID_WEB_ERROR_Time4": 99, - "ID_WEB_ERROR_Nr0": 100, - "ID_WEB_ERROR_Nr1": 101, - "ID_WEB_ERROR_Nr2": 102, - "ID_WEB_ERROR_Nr3": 103, - "ID_WEB_ERROR_Nr4": 104, - "ID_WEB_AnzahlFehlerInSpeicher": 105, - "ID_WEB_Switchoff_file_Nr0": 106, - "ID_WEB_Switchoff_file_Nr1": 107, - "ID_WEB_Switchoff_file_Nr2": 108, - "ID_WEB_Switchoff_file_Nr3": 109, - "ID_WEB_Switchoff_file_Nr4": 110, - "ID_WEB_Switchoff_file_Time0": 111, - "ID_WEB_Switchoff_file_Time1": 112, - "ID_WEB_Switchoff_file_Time2": 113, - "ID_WEB_Switchoff_file_Time3": 114, - "ID_WEB_Switchoff_file_Time4": 115, - "ID_WEB_Comfort_exists": 116, - "ID_WEB_HauptMenuStatus_Zeile1": 117, - "ID_WEB_HauptMenuStatus_Zeile2": 118, - "ID_WEB_HauptMenuStatus_Zeile3": 119, - "ID_WEB_HauptMenuStatus_Zeit": 120, - "ID_WEB_HauptMenuAHP_Stufe": 121, - "ID_WEB_HauptMenuAHP_Temp": 122, - "ID_WEB_HauptMenuAHP_Zeit": 123, - "ID_WEB_SH_BWW": 124, - "ID_WEB_SH_HZ": 125, - "ID_WEB_SH_MK1": 126, - "ID_WEB_SH_MK2": 127, - "ID_WEB_Einst_Kurzrpgramm": 128, - "ID_WEB_StatusSlave_1": 129, - "ID_WEB_StatusSlave_2": 130, - "ID_WEB_StatusSlave_3": 131, - "ID_WEB_StatusSlave_4": 132, - "ID_WEB_StatusSlave_5": 133, - "ID_WEB_AktuelleTimeStamp": 134, - "ID_WEB_SH_MK3": 135, - "ID_WEB_Sollwert_TVL_MK3": 136, - "ID_WEB_Temperatur_TFB3": 137, - "ID_WEB_MZ3out": 138, - "ID_WEB_MA3out": 139, - "ID_WEB_FP3out": 140, - "ID_WEB_Time_AbtIn": 141, - "ID_WEB_Temperatur_RFV2": 142, - "ID_WEB_Temperatur_RFV3": 143, - "ID_WEB_SH_SW": 144, - "ID_WEB_Zaehler_BetrZeitSW": 145, - "ID_WEB_FreigabKuehl": 146, - "ID_WEB_AnalogIn": 147, - "ID_WEB_SonderZeichen": 148, - "ID_WEB_SH_ZIP": 149, - "ID_WEB_WebsrvProgrammWerteBeobarten": 150, - "ID_WEB_WMZ_Heizung": 151, - "ID_WEB_WMZ_Brauchwasser": 152, - "ID_WEB_WMZ_Schwimmbad": 153, - "ID_WEB_WMZ_Seit": 154, - "ID_WEB_WMZ_Durchfluss": 155, - "ID_WEB_AnalogOut1": 156, - "ID_WEB_AnalogOut2": 157, - "ID_WEB_Time_Heissgas": 158, - "ID_WEB_Temp_Lueftung_Zuluft": 159, - "ID_WEB_Temp_Lueftung_Abluft": 160, - "ID_WEB_Zaehler_BetrZeitSolar": 161, - "ID_WEB_AnalogOut3": 162, - "ID_WEB_AnalogOut4": 163, - "ID_WEB_Out_VZU": 164, - "ID_WEB_Out_VAB": 165, - "ID_WEB_Out_VSK": 166, - "ID_WEB_Out_FRH": 167, - "ID_WEB_AnalogIn2": 168, - "ID_WEB_AnalogIn3": 169, - "ID_WEB_SAXin": 170, - "ID_WEB_SPLin": 171, - "ID_WEB_Compact_exists": 172, - "ID_WEB_Durchfluss_WQ": 173, - "ID_WEB_LIN_exists": 174, - "ID_WEB_LIN_ANSAUG_VERDAMPFER": 175, - "ID_WEB_LIN_ANSAUG_VERDICHTER": 176, - "ID_WEB_LIN_VDH": 177, - "ID_WEB_LIN_UH": 178, - "ID_WEB_LIN_UH_Soll": 179, - "ID_WEB_LIN_HD": 180, - "ID_WEB_LIN_ND": 181, - "ID_WEB_LIN_VDH_out": 182, - "ID_WEB_HZIO_PWM": 183, - "ID_WEB_HZIO_VEN": 184, - "ID_WEB_HZIO_EVU2": 185, - "ID_WEB_HZIO_STB": 186, - "ID_WEB_SEC_Qh_Soll": 187, - "ID_WEB_SEC_Qh_Ist": 188, - "ID_WEB_SEC_TVL_Soll": 189, - "ID_WEB_SEC_Software": 190, - "ID_WEB_SEC_BZ": 191, - "ID_WEB_SEC_VWV": 192, - "ID_WEB_SEC_VD": 193, - "ID_WEB_SEC_VerdEVI": 194, - "ID_WEB_SEC_AnsEVI": 195, - "ID_WEB_SEC_UEH_EVI": 196, - "ID_WEB_SEC_UEH_EVI_S": 197, - "ID_WEB_SEC_KondTemp": 198, - "ID_WEB_SEC_FlussigEx": 199, - "ID_WEB_SEC_UK_EEV": 200, - "ID_WEB_SEC_EVI_Druck": 201, - "ID_WEB_SEC_U_Inv": 202, - "ID_WEB_Temperatur_THG_2": 203, - "ID_WEB_Temperatur_TWE_2": 204, - "ID_WEB_LIN_ANSAUG_VERDAMPFER_2": 205, - "ID_WEB_LIN_ANSAUG_VERDICHTER_2": 206, - "ID_WEB_LIN_VDH_2": 207, - "ID_WEB_LIN_UH_2": 208, - "ID_WEB_LIN_UH_Soll_2": 209, - "ID_WEB_LIN_HD_2": 210, - "ID_WEB_LIN_ND_2": 211, - "ID_WEB_HDin_2": 212, - "ID_WEB_AVout_2": 213, - "ID_WEB_VBOout_2": 214, - "ID_WEB_VD1out_2": 215, - "ID_WEB_LIN_VDH_out_2": 216, - "ID_WEB_Switchoff2_file_Nr0": 217, - "ID_WEB_Switchoff2_file_Nr1": 218, - "ID_WEB_Switchoff2_file_Nr2": 219, - "ID_WEB_Switchoff2_file_Nr3": 220, - "ID_WEB_Switchoff2_file_Nr4": 221, - "ID_WEB_Switchoff2_file_Time0": 222, - "ID_WEB_Switchoff2_file_Time1": 223, - "ID_WEB_Switchoff2_file_Time2": 224, - "ID_WEB_Switchoff2_file_Time3": 225, - "ID_WEB_Switchoff2_file_Time4": 226, - "ID_WEB_RBE_RT_Ist": 227, - "ID_WEB_RBE_RT_Soll": 228, - "ID_WEB_Temperatur_BW_oben": 229, - "ID_WEB_Code_WP_akt_2": 230, - "ID_WEB_Freq_VD": 231, - "Unknown_Calculation_232": 232, - "Unknown_Calculation_233": 233, - "Unknown_Calculation_234": 234, - "Unknown_Calculation_235": 235, - "Unknown_Calculation_236": 236, - "Unknown_Calculation_237": 237, - "Unknown_Calculation_238": 238, - "Unknown_Calculation_239": 239, - "Unknown_Calculation_240": 240, - "Circulation_Pump": 241, - "Unknown_Calculation_242": 242, - "Unknown_Calculation_243": 243, - "Unknown_Calculation_244": 244, - "Unknown_Calculation_245": 245, - "Unknown_Calculation_246": 246, - "Unknown_Calculation_247": 247, - "Unknown_Calculation_248": 248, - "Unknown_Calculation_249": 249, - "Unknown_Calculation_250": 250, - "Unknown_Calculation_251": 251, - "Unknown_Calculation_252": 252, - "Unknown_Calculation_253": 253, - "Flow_Rate_254": 254, - "Unknown_Calculation_255": 255, - "Unknown_Calculation_256": 256, - "Heat_Output": 257, - "Unknown_Calculation_258": 258, - "Unknown_Calculation_259": 259, + "Unknown_Calculation_0": (0, Unknown), + "Unknown_Calculation_1": (1, Unknown), + "Unknown_Calculation_2": (2, Unknown), + "Unknown_Calculation_3": (3, Unknown), + "Unknown_Calculation_4": (4, Unknown), + "Unknown_Calculation_5": (5, Unknown), + "Unknown_Calculation_6": (6, Unknown), + "Unknown_Calculation_7": (7, Unknown), + "Unknown_Calculation_8": (8, Unknown), + "Unknown_Calculation_9": (9, Unknown), + "ID_WEB_Temperatur_TVL": (10, Celsius), + "ID_WEB_Temperatur_TRL": (11, Celsius), + "ID_WEB_Sollwert_TRL_HZ": (12, Celsius), + "ID_WEB_Temperatur_TRL_ext": (13, Celsius), + "ID_WEB_Temperatur_THG": (14, Celsius), + "ID_WEB_Temperatur_TA": (15, Celsius), + "ID_WEB_Mitteltemperatur": (16, Celsius), + "ID_WEB_Temperatur_TBW": (17, Celsius), + "ID_WEB_Einst_BWS_akt": (18, Celsius), + "ID_WEB_Temperatur_TWE": (19, Celsius), + "ID_WEB_Temperatur_TWA": (20, Celsius), + "ID_WEB_Temperatur_TFB1": (21, Celsius), + "ID_WEB_Sollwert_TVL_MK1": (22, Celsius), + "ID_WEB_Temperatur_RFV": (23, Celsius), + "ID_WEB_Temperatur_TFB2": (24, Celsius), + "ID_WEB_Sollwert_TVL_MK2": (25, Celsius), + "ID_WEB_Temperatur_TSK": (26, Celsius), + "ID_WEB_Temperatur_TSS": (27, Celsius), + "ID_WEB_Temperatur_TEE": (28, Celsius), + "ID_WEB_ASDin": (29, Bool), + "ID_WEB_BWTin": (30, Bool), + "ID_WEB_EVUin": (31, Bool), + "ID_WEB_HDin": (32, Bool), + "ID_WEB_MOTin": (33, Bool), + "ID_WEB_NDin": (34, Bool), + "ID_WEB_PEXin": (35, Bool), + "ID_WEB_SWTin": (36, Bool), + "ID_WEB_AVout": (37, Bool), + "ID_WEB_BUPout": (38, Bool), + "ID_WEB_HUPout": (39, Bool), + "ID_WEB_MA1out": (40, Bool), + "ID_WEB_MZ1out": (41, Bool), + "ID_WEB_VENout": (42, Bool), + "ID_WEB_VBOout": (43, Bool), + "ID_WEB_VD1out": (44, Bool), + "ID_WEB_VD2out": (45, Bool), + "ID_WEB_ZIPout": (46, Bool), + "ID_WEB_ZUPout": (47, Bool), + "ID_WEB_ZW1out": (48, Bool), + "ID_WEB_ZW2SSTout": (49, Bool), + "ID_WEB_ZW3SSTout": (50, Bool), + "ID_WEB_FP2out": (51, Bool), + "ID_WEB_SLPout": (52, Bool), + "ID_WEB_SUPout": (53, Bool), + "ID_WEB_MZ2out": (54, Bool), + "ID_WEB_MA2out": (55, Bool), + "ID_WEB_Zaehler_BetrZeitVD1": (56, Seconds), + "ID_WEB_Zaehler_BetrZeitImpVD1": (57, Pulses, True), # obsolete type -> type change allowed + "ID_WEB_Zaehler_BetrZeitVD2": (58, Seconds), + "ID_WEB_Zaehler_BetrZeitImpVD2": (59, Pulses, True), # obsolete type -> type change allowed + "ID_WEB_Zaehler_BetrZeitZWE1": (60, Seconds), + "ID_WEB_Zaehler_BetrZeitZWE2": (61, Seconds), + "ID_WEB_Zaehler_BetrZeitZWE3": (62, Seconds), + "ID_WEB_Zaehler_BetrZeitWP": (63, Seconds), + "ID_WEB_Zaehler_BetrZeitHz": (64, Seconds), + "ID_WEB_Zaehler_BetrZeitBW": (65, Seconds), + "ID_WEB_Zaehler_BetrZeitKue": (66, Seconds), + "ID_WEB_Time_WPein_akt": (67, Seconds), + "ID_WEB_Time_ZWE1_akt": (68, Seconds), + "ID_WEB_Time_ZWE2_akt": (69, Seconds), + "ID_WEB_Timer_EinschVerz": (70, Seconds), + "ID_WEB_Time_SSPAUS_akt": (71, Seconds), + "ID_WEB_Time_SSPEIN_akt": (72, Seconds), + "ID_WEB_Time_VDStd_akt": (73, Seconds), + "ID_WEB_Time_HRM_akt": (74, Seconds), + "ID_WEB_Time_HRW_akt": (75, Seconds), + "ID_WEB_Time_LGS_akt": (76, Seconds), + "ID_WEB_Time_SBW_akt": (77, Seconds), + "ID_WEB_Code_WP_akt": (78, HeatpumpCode), + "ID_WEB_BIV_Stufe_akt": (79, BivalenceLevel), + "ID_WEB_WP_BZ_akt": (80, OperationMode), + "ID_WEB_SoftStand": (81, Version), + "ID_WEB_AdresseIP_akt": (91, IPAddress, True), # obsolete type -> type change allowed + "ID_WEB_SubNetMask_akt": (92, IPAddress, True), # obsolete type -> type change allowed + "ID_WEB_Add_Broadcast": (93, IPAddress, True), # obsolete type -> type change allowed + "ID_WEB_Add_StdGateway": (94, IPAddress, True), # obsolete type -> type change allowed + "ID_WEB_ERROR_Time0": (95, Timestamp), + "ID_WEB_ERROR_Time1": (96, Timestamp), + "ID_WEB_ERROR_Time2": (97, Timestamp), + "ID_WEB_ERROR_Time3": (98, Timestamp), + "ID_WEB_ERROR_Time4": (99, Timestamp), + "ID_WEB_ERROR_Nr0": (100, Errorcode), + "ID_WEB_ERROR_Nr1": (101, Errorcode), + "ID_WEB_ERROR_Nr2": (102, Errorcode), + "ID_WEB_ERROR_Nr3": (103, Errorcode), + "ID_WEB_ERROR_Nr4": (104, Errorcode), + "ID_WEB_AnzahlFehlerInSpeicher": (105, Count), + "ID_WEB_Switchoff_file_Nr0": (106, SwitchoffFile), + "ID_WEB_Switchoff_file_Nr1": (107, SwitchoffFile), + "ID_WEB_Switchoff_file_Nr2": (108, SwitchoffFile), + "ID_WEB_Switchoff_file_Nr3": (109, SwitchoffFile), + "ID_WEB_Switchoff_file_Nr4": (110, SwitchoffFile), + "ID_WEB_Switchoff_file_Time0": (111, Timestamp), + "ID_WEB_Switchoff_file_Time1": (112, Timestamp), + "ID_WEB_Switchoff_file_Time2": (113, Timestamp), + "ID_WEB_Switchoff_file_Time3": (114, Timestamp), + "ID_WEB_Switchoff_file_Time4": (115, Timestamp), + "ID_WEB_Comfort_exists": (116, Bool), + "ID_WEB_HauptMenuStatus_Zeile1": (117, MainMenuStatusLine1), + "ID_WEB_HauptMenuStatus_Zeile2": (118, MainMenuStatusLine2), + "ID_WEB_HauptMenuStatus_Zeile3": (119, MainMenuStatusLine3), + "ID_WEB_HauptMenuStatus_Zeit": (120, Seconds), + "ID_WEB_HauptMenuAHP_Stufe": (121, Level), + "ID_WEB_HauptMenuAHP_Temp": (122, Celsius), + "ID_WEB_HauptMenuAHP_Zeit": (123, Seconds), + "ID_WEB_SH_BWW": (124, Bool), + "ID_WEB_SH_HZ": (125, Icon), + "ID_WEB_SH_MK1": (126, Icon), + "ID_WEB_SH_MK2": (127, Icon), + "ID_WEB_Einst_Kurzrpgramm": (128, Unknown), + "ID_WEB_StatusSlave_1": (129, Unknown), + "ID_WEB_StatusSlave_2": (130, Unknown), + "ID_WEB_StatusSlave_3": (131, Unknown), + "ID_WEB_StatusSlave_4": (132, Unknown), + "ID_WEB_StatusSlave_5": (133, Unknown), + "ID_WEB_AktuelleTimeStamp": (134, Timestamp), + "ID_WEB_SH_MK3": (135, Icon), + "ID_WEB_Sollwert_TVL_MK3": (136, Celsius), + "ID_WEB_Temperatur_TFB3": (137, Celsius), + "ID_WEB_MZ3out": (138, Bool), + "ID_WEB_MA3out": (139, Bool), + "ID_WEB_FP3out": (140, Bool), + "ID_WEB_Time_AbtIn": (141, Seconds), + "ID_WEB_Temperatur_RFV2": (142, Celsius), + "ID_WEB_Temperatur_RFV3": (143, Celsius), + "ID_WEB_SH_SW": (144, Icon), + "ID_WEB_Zaehler_BetrZeitSW": (145, Unknown), + "ID_WEB_FreigabKuehl": (146, Bool), + "ID_WEB_AnalogIn": (147, Voltage), + "ID_WEB_SonderZeichen": (148, Unknown), + "ID_WEB_SH_ZIP": (149, Icon), + "ID_WEB_WebsrvProgrammWerteBeobarten": (150, Icon), + "ID_WEB_WMZ_Heizung": (151, Energy), + "ID_WEB_WMZ_Brauchwasser": (152, Energy), + "ID_WEB_WMZ_Schwimmbad": (153, Energy), + "ID_WEB_WMZ_Seit": (154, Energy), + "ID_WEB_WMZ_Durchfluss": (155, Flow), + "ID_WEB_AnalogOut1": (156, Voltage), + "ID_WEB_AnalogOut2": (157, Voltage), + "ID_WEB_Time_Heissgas": (158, Seconds), + "ID_WEB_Temp_Lueftung_Zuluft": (159, Celsius), + "ID_WEB_Temp_Lueftung_Abluft": (160, Celsius), + "ID_WEB_Zaehler_BetrZeitSolar": (161, Seconds), + "ID_WEB_AnalogOut3": (162, Voltage), + "ID_WEB_AnalogOut4": (163, Voltage), + "ID_WEB_Out_VZU": (164, Voltage), + "ID_WEB_Out_VAB": (165, Voltage), + "ID_WEB_Out_VSK": (166, Bool), + "ID_WEB_Out_FRH": (167, Bool), + "ID_WEB_AnalogIn2": (168, Voltage), + "ID_WEB_AnalogIn3": (169, Voltage), + "ID_WEB_SAXin": (170, Bool), + "ID_WEB_SPLin": (171, Bool), + "ID_WEB_Compact_exists": (172, Bool), + "ID_WEB_Durchfluss_WQ": (173, Flow), + "ID_WEB_LIN_exists": (174, Bool), + "ID_WEB_LIN_ANSAUG_VERDAMPFER": (175, Celsius), + "ID_WEB_LIN_ANSAUG_VERDICHTER": (176, Celsius), + "ID_WEB_LIN_VDH": (177, Celsius), + "ID_WEB_LIN_UH": (178, Kelvin), + "ID_WEB_LIN_UH_Soll": (179, Kelvin), + "ID_WEB_LIN_HD": (180, Pressure), + "ID_WEB_LIN_ND": (181, Pressure), + "ID_WEB_LIN_VDH_out": (182, Bool), + "ID_WEB_HZIO_PWM": (183, Percent2), + "ID_WEB_HZIO_VEN": (184, Speed), + "ID_WEB_HZIO_EVU2": (185, Unknown), + "ID_WEB_HZIO_STB": (186, Bool), + "ID_WEB_SEC_Qh_Soll": (187, Energy), + "ID_WEB_SEC_Qh_Ist": (188, Energy), + "ID_WEB_SEC_TVL_Soll": (189, Celsius), + "ID_WEB_SEC_Software": (190, Unknown), + "ID_WEB_SEC_BZ": (191, SecOperationMode), + "ID_WEB_SEC_VWV": (192, Unknown), + "ID_WEB_SEC_VD": (193, Speed), + "ID_WEB_SEC_VerdEVI": (194, Celsius), + "ID_WEB_SEC_AnsEVI": (195, Celsius), + "ID_WEB_SEC_UEH_EVI": (196, Kelvin), + "ID_WEB_SEC_UEH_EVI_S": (197, Kelvin), + "ID_WEB_SEC_KondTemp": (198, Celsius), + "ID_WEB_SEC_FlussigEx": (199, Celsius), + "ID_WEB_SEC_UK_EEV": (200, Celsius), + "ID_WEB_SEC_EVI_Druck": (201, Pressure), + "ID_WEB_SEC_U_Inv": (202, Voltage), + "ID_WEB_Temperatur_THG_2": (203, Celsius), + "ID_WEB_Temperatur_TWE_2": (204, Celsius), + "ID_WEB_LIN_ANSAUG_VERDAMPFER_2": (205, Celsius), + "ID_WEB_LIN_ANSAUG_VERDICHTER_2": (206, Celsius), + "ID_WEB_LIN_VDH_2": (207, Celsius), + "ID_WEB_LIN_UH_2": (208, Kelvin), + "ID_WEB_LIN_UH_Soll_2": (209, Kelvin), + "ID_WEB_LIN_HD_2": (210, Pressure), + "ID_WEB_LIN_ND_2": (211, Pressure), + "ID_WEB_HDin_2": (212, Bool), + "ID_WEB_AVout_2": (213, Bool), + "ID_WEB_VBOout_2": (214, Bool), + "ID_WEB_VD1out_2": (215, Bool), + "ID_WEB_LIN_VDH_out_2": (216, Bool), + "ID_WEB_Switchoff2_file_Nr0": (217, SwitchoffFile), + "ID_WEB_Switchoff2_file_Nr1": (218, SwitchoffFile), + "ID_WEB_Switchoff2_file_Nr2": (219, SwitchoffFile), + "ID_WEB_Switchoff2_file_Nr3": (220, SwitchoffFile), + "ID_WEB_Switchoff2_file_Nr4": (221, SwitchoffFile), + "ID_WEB_Switchoff2_file_Time0": (222, Timestamp), + "ID_WEB_Switchoff2_file_Time1": (223, Timestamp), + "ID_WEB_Switchoff2_file_Time2": (224, Timestamp), + "ID_WEB_Switchoff2_file_Time3": (225, Timestamp), + "ID_WEB_Switchoff2_file_Time4": (226, Timestamp), + "ID_WEB_RBE_RT_Ist": (227, Celsius), + "ID_WEB_RBE_RT_Soll": (228, Celsius), + "ID_WEB_Temperatur_BW_oben": (229, Celsius), + "ID_WEB_Code_WP_akt_2": (230, HeatpumpCode), + "ID_WEB_Freq_VD": (231, Frequency), + "Unknown_Calculation_232": (232, Unknown), + "Unknown_Calculation_233": (233, Unknown), + "Unknown_Calculation_234": (234, Unknown), + "Unknown_Calculation_235": (235, Unknown), + "Unknown_Calculation_236": (236, Unknown), + "Unknown_Calculation_237": (237, Unknown), + "Unknown_Calculation_238": (238, Unknown), + "Unknown_Calculation_239": (239, Unknown), + "Unknown_Calculation_240": (240, Unknown), + "Circulation_Pump": (241, Percent2), + "Unknown_Calculation_242": (242, Unknown), + "Unknown_Calculation_243": (243, Unknown), + "Unknown_Calculation_244": (244, Unknown), + "Unknown_Calculation_245": (245, Unknown), + "Unknown_Calculation_246": (246, Unknown), + "Unknown_Calculation_247": (247, Unknown), + "Unknown_Calculation_248": (248, Unknown), + "Unknown_Calculation_249": (249, Unknown), + "Unknown_Calculation_250": (250, Unknown), + "Unknown_Calculation_251": (251, Unknown), + "Unknown_Calculation_252": (252, Unknown), + "Unknown_Calculation_253": (253, Unknown), + "Flow_Rate_254": (254, Flow), + "Unknown_Calculation_255": (255, Unknown), + "Unknown_Calculation_256": (256, Unknown), + "Heat_Output": (257, Power), + "Unknown_Calculation_258": (258, Unknown), + "Unknown_Calculation_259": (259, Unknown), # New in 'main' branch: - "ID_WEB_SoftStand_0": 81, - "ID_WEB_SoftStand_1": 82, - "ID_WEB_SoftStand_2": 83, - "ID_WEB_SoftStand_3": 84, - "ID_WEB_SoftStand_4": 85, - "ID_WEB_SoftStand_5": 86, - "ID_WEB_SoftStand_6": 87, - "ID_WEB_SoftStand_7": 88, - "ID_WEB_SoftStand_8": 89, - "ID_WEB_SoftStand_9": 90, - "Vapourisation_Temperature": 232, - "Liquefaction_Temperature": 233, - "ID_WEB_Freq_VD_Soll": 236, - "ID_WEB_Freq_VD_Min": 237, - "ID_WEB_Freq_VD_Max": 238, - "VBO_Temp_Spread_Soll": 239, - "VBO_Temp_Spread_Ist": 240, - "HUP_PWM": 241, - "HUP_Temp_Spread_Soll": 242, - "HUP_Temp_Spread_Ist": 243, - "RBE_Version": 258, - "Unknown_Calculation_260": 260, - "Unknown_Calculation_261": 261, - "Unknown_Calculation_262": 262, - "Unknown_Calculation_263": 263, - "Unknown_Calculation_264": 264, - "Unknown_Calculation_265": 265, - "Unknown_Calculation_266": 266, - "Desired_Room_Temperature": 267, - "AC_Power_Input": 268, + "ID_WEB_SoftStand_0": (81, Character), + "ID_WEB_SoftStand_1": (82, Character), + "ID_WEB_SoftStand_2": (83, Character), + "ID_WEB_SoftStand_3": (84, Character), + "ID_WEB_SoftStand_4": (85, Character), + "ID_WEB_SoftStand_5": (86, Character), + "ID_WEB_SoftStand_6": (87, Character), + "ID_WEB_SoftStand_7": (88, Character), + "ID_WEB_SoftStand_8": (89, Character), + "ID_WEB_SoftStand_9": (90, Character), + "Vapourisation_Temperature": (232, Celsius), + "Liquefaction_Temperature": (233, Celsius), + "ID_WEB_Freq_VD_Soll": (236, Frequency), + "ID_WEB_Freq_VD_Min": (237, Frequency), + "ID_WEB_Freq_VD_Max": (238, Frequency), + "VBO_Temp_Spread_Soll": (239, Kelvin), + "VBO_Temp_Spread_Ist": (240, Kelvin), + "HUP_PWM": (241, Percent2), + "HUP_Temp_Spread_Soll": (242, Kelvin), + "HUP_Temp_Spread_Ist": (243, Kelvin), + "RBE_Version": (258, MajorMinorVersion), + "Unknown_Calculation_260": (260, Unknown), + "Unknown_Calculation_261": (261, Unknown), + "Unknown_Calculation_262": (262, Unknown), + "Unknown_Calculation_263": (263, Unknown), + "Unknown_Calculation_264": (264, Unknown), + "Unknown_Calculation_265": (265, Unknown), + "Unknown_Calculation_266": (266, Unknown), + "Desired_Room_Temperature": (267, Celsius), + "AC_Power_Input": (268, Power), } - # Note: "ID_WEB_SoftStand" tested in "test_get_firmware_version()" visis = { # Status of 0.3.14: - "ID_Visi_NieAnzeigen": 0, - "ID_Visi_ImmerAnzeigen": 1, - "ID_Visi_Heizung": 2, - "ID_Visi_Brauwasser": 3, - "ID_Visi_Schwimmbad": 4, - "ID_Visi_Kuhlung": 5, - "ID_Visi_Lueftung": 6, - "ID_Visi_MK1": 7, - "ID_Visi_MK2": 8, - "ID_Visi_ThermDesinfekt": 9, - "ID_Visi_Zirkulation": 10, - "ID_Visi_KuhlTemp_SolltempMK1": 11, - "ID_Visi_KuhlTemp_SolltempMK2": 12, - "ID_Visi_KuhlTemp_ATDiffMK1": 13, - "ID_Visi_KuhlTemp_ATDiffMK2": 14, - "ID_Visi_Service_Information": 15, - "ID_Visi_Service_Einstellung": 16, - "ID_Visi_Service_Sprache": 17, - "ID_Visi_Service_DatumUhrzeit": 18, - "ID_Visi_Service_Ausheiz": 19, - "ID_Visi_Service_Anlagenkonfiguration": 20, - "ID_Visi_Service_IBNAssistant": 21, - "ID_Visi_Service_ParameterIBNZuruck": 22, - "ID_Visi_Temp_Vorlauf": 23, - "ID_Visi_Temp_Rucklauf": 24, - "ID_Visi_Temp_RL_Soll": 25, - "ID_Visi_Temp_Ruecklext": 26, - "ID_Visi_Temp_Heissgas": 27, - "ID_Visi_Temp_Aussent": 28, - "ID_Visi_Temp_BW_Ist": 29, - "ID_Visi_Temp_BW_Soll": 30, - "ID_Visi_Temp_WQ_Ein": 31, - "ID_Visi_Temp_Kaltekreis": 32, - "ID_Visi_Temp_MK1_Vorlauf": 33, - "ID_Visi_Temp_MK1VL_Soll": 34, - "ID_Visi_Temp_Raumstation": 35, - "ID_Visi_Temp_MK2_Vorlauf": 36, - "ID_Visi_Temp_MK2VL_Soll": 37, - "ID_Visi_Temp_Solarkoll": 38, - "ID_Visi_Temp_Solarsp": 39, - "ID_Visi_Temp_Ext_Energ": 40, - "ID_Visi_IN_ASD": 41, - "ID_Visi_IN_BWT": 42, - "ID_Visi_IN_EVU": 43, - "ID_Visi_IN_HD": 44, - "ID_Visi_IN_MOT": 45, - "ID_Visi_IN_ND": 46, - "ID_Visi_IN_PEX": 47, - "ID_Visi_IN_SWT": 48, - "ID_Visi_OUT_Abtauventil": 49, - "ID_Visi_OUT_BUP": 50, - "ID_Visi_OUT_FUP1": 51, - "ID_Visi_OUT_HUP": 52, - "ID_Visi_OUT_Mischer1Auf": 53, - "ID_Visi_OUT_Mischer1Zu": 54, - "ID_Visi_OUT_Ventilation": 55, - "ID_Visi_OUT_Ventil_BOSUP": 56, - "ID_Visi_OUT_Verdichter1": 57, - "ID_Visi_OUT_Verdichter2": 58, - "ID_Visi_OUT_ZIP": 59, - "ID_Visi_OUT_ZUP": 60, - "ID_Visi_OUT_ZWE1": 61, - "ID_Visi_OUT_ZWE2_SST": 62, - "ID_Visi_OUT_ZWE3": 63, - "ID_Visi_OUT_FUP2": 64, - "ID_Visi_OUT_SLP": 65, - "ID_Visi_OUT_SUP": 66, - "ID_Visi_OUT_Mischer2Auf": 67, - "ID_Visi_OUT_Mischer2Zu": 68, - "ID_Visi_AblaufZ_WP_Seit": 69, - "ID_Visi_AblaufZ_ZWE1_seit": 70, - "ID_Visi_AblaufZ_ZWE2_seit": 71, - "ID_Visi_AblaufZ_ZWE3_seit": 72, - "ID_Visi_AblaufZ_Netzeinv": 73, - "ID_Visi_AblaufZ_SSP_Zeit1": 74, - "ID_Visi_AblaufZ_VD_Stand": 75, - "ID_Visi_AblaufZ_HRM_Zeit": 76, - "ID_Visi_AblaufZ_HRW_Zeit": 77, - "ID_Visi_AblaufZ_TDI_seit": 78, - "ID_Visi_AblaufZ_Sperre_BW": 79, - "ID_Visi_Bst_BStdVD1": 80, - "ID_Visi_Bst_ImpVD1": 81, - "ID_Visi_Bst_dEZVD1": 82, - "ID_Visi_Bst_BStdVD2": 83, - "ID_Visi_Bst_ImpVD2": 84, - "ID_Visi_Bst_dEZVD2": 85, - "ID_Visi_Bst_BStdZWE1": 86, - "ID_Visi_Bst_BStdZWE2": 87, - "ID_Visi_Bst_BStdZWE3": 88, - "ID_Visi_Bst_BStdWP": 89, - "ID_Visi_Text_Kurzprogramme": 90, - "ID_Visi_Text_Zwangsheizung": 91, - "ID_Visi_Text_Zwangsbrauchwasser": 92, - "ID_Visi_Text_Abtauen": 93, - "ID_Visi_EinstTemp_RucklBegr": 94, - "ID_Visi_EinstTemp_HystereseHR": 95, - "ID_Visi_EinstTemp_TRErhmax": 96, - "ID_Visi_EinstTemp_Freig2VD": 97, - "ID_Visi_EinstTemp_FreigZWE": 98, - "ID_Visi_EinstTemp_Tluftabt": 99, - "ID_Visi_EinstTemp_TDISolltemp": 100, - "ID_Visi_EinstTemp_HystereseBW": 101, - "ID_Visi_EinstTemp_Vorl2VDBW": 102, - "ID_Visi_EinstTemp_TAussenmax": 103, - "ID_Visi_EinstTemp_TAussenmin": 104, - "ID_Visi_EinstTemp_TWQmin": 105, - "ID_Visi_EinstTemp_THGmax": 106, - "ID_Visi_EinstTemp_TLABTEnde": 107, - "ID_Visi_EinstTemp_Absenkbis": 108, - "ID_Visi_EinstTemp_Vorlaufmax": 109, - "ID_Visi_EinstTemp_TDiffEin": 110, - "ID_Visi_EinstTemp_TDiffAus": 111, - "ID_Visi_EinstTemp_TDiffmax": 112, - "ID_Visi_EinstTemp_TEEHeizung": 113, - "ID_Visi_EinstTemp_TEEBrauchw": 114, - "ID_Visi_EinstTemp_Vorl2VDSW": 115, - "ID_Visi_EinstTemp_VLMaxMk1": 116, - "ID_Visi_EinstTemp_VLMaxMk2": 117, - "ID_Visi_Priori_Brauchwasser": 118, - "ID_Visi_Priori_Heizung": 119, - "ID_Visi_Priori_Schwimmbad": 120, - "ID_Visi_SysEin_EVUSperre": 121, - "ID_Visi_SysEin_Raumstation": 122, - "ID_Visi_SysEin_Einbindung": 123, - "ID_Visi_SysEin_Mischkreis1": 124, - "ID_Visi_SysEin_Mischkreis2": 125, - "ID_Visi_SysEin_ZWE1Art": 126, - "ID_Visi_SysEin_ZWE1Fkt": 127, - "ID_Visi_SysEin_ZWE2Art": 128, - "ID_Visi_SysEin_ZWE2Fkt": 129, - "ID_Visi_SysEin_ZWE3Art": 130, - "ID_Visi_SysEin_ZWE3Fkt": 131, - "ID_Visi_SysEin_Stoerung": 132, - "ID_Visi_SysEin_Brauchwasser1": 133, - "ID_Visi_SysEin_Brauchwasser2": 134, - "ID_Visi_SysEin_Brauchwasser3": 135, - "ID_Visi_SysEin_Brauchwasser4": 136, - "ID_Visi_SysEin_Brauchwasser5": 137, - "ID_Visi_SysEin_BWWPmax": 138, - "ID_Visi_SysEin_Abtzykmax": 139, - "ID_Visi_SysEin_Luftabt": 140, - "ID_Visi_SysEin_LuftAbtmax": 141, - "ID_Visi_SysEin_Abtauen1": 142, - "ID_Visi_SysEin_Abtauen2": 143, - "ID_Visi_SysEin_Pumpenoptim": 144, - "ID_Visi_SysEin_Zusatzpumpe": 145, - "ID_Visi_SysEin_Zugang": 146, - "ID_Visi_SysEin_SoledrDurchf": 147, - "ID_Visi_SysEin_UberwachungVD": 148, - "ID_Visi_SysEin_RegelungHK": 149, - "ID_Visi_SysEin_RegelungMK1": 150, - "ID_Visi_SysEin_RegelungMK2": 151, - "ID_Visi_SysEin_Kuhlung": 152, - "ID_Visi_SysEin_Ausheizen": 153, - "ID_Visi_SysEin_ElektrAnode": 154, - "ID_Visi_SysEin_SWBBer": 155, - "ID_Visi_SysEin_SWBMin": 156, - "ID_Visi_SysEin_Heizung": 157, - "ID_Visi_SysEin_PeriodeMk1": 158, - "ID_Visi_SysEin_LaufzeitMk1": 159, - "ID_Visi_SysEin_PeriodeMk2": 160, - "ID_Visi_SysEin_LaufzeitMk2": 161, - "ID_Visi_SysEin_Heizgrenze": 162, - "ID_Visi_Enlt_HUP": 163, - "ID_Visi_Enlt_ZUP": 164, - "ID_Visi_Enlt_BUP": 165, - "ID_Visi_Enlt_Ventilator_BOSUP": 166, - "ID_Visi_Enlt_MA1": 167, - "ID_Visi_Enlt_MZ1": 168, - "ID_Visi_Enlt_ZIP": 169, - "ID_Visi_Enlt_MA2": 170, - "ID_Visi_Enlt_MZ2": 171, - "ID_Visi_Enlt_SUP": 172, - "ID_Visi_Enlt_SLP": 173, - "ID_Visi_Enlt_FP2": 174, - "ID_Visi_Enlt_Laufzeit": 175, - "ID_Visi_Anlgkonf_Heizung": 176, - "ID_Visi_Anlgkonf_Brauchwarmwasser": 177, - "ID_Visi_Anlgkonf_Schwimmbad": 178, - "ID_Visi_Heizung_Betriebsart": 179, - "ID_Visi_Heizung_TemperaturPlusMinus": 180, - "ID_Visi_Heizung_Heizkurven": 181, - "ID_Visi_Heizung_Zeitschlaltprogramm": 182, - "ID_Visi_Heizung_Heizgrenze": 183, - "ID_Visi_Mitteltemperatur": 184, - "ID_Visi_Dataenlogger": 185, - "ID_Visi_Sprachen_DEUTSCH": 186, - "ID_Visi_Sprachen_ENGLISH": 187, - "ID_Visi_Sprachen_FRANCAIS": 188, - "ID_Visi_Sprachen_NORWAY": 189, - "ID_Visi_Sprachen_TCHECH": 190, - "ID_Visi_Sprachen_ITALIANO": 191, - "ID_Visi_Sprachen_NEDERLANDS": 192, - "ID_Visi_Sprachen_SVENSKA": 193, - "ID_Visi_Sprachen_POLSKI": 194, - "ID_Visi_Sprachen_MAGYARUL": 195, - "ID_Visi_ErrorUSBspeichern": 196, - "ID_Visi_Bst_BStdHz": 197, - "ID_Visi_Bst_BStdBW": 198, - "ID_Visi_Bst_BStdKue": 199, - "ID_Visi_Service_Systemsteuerung": 200, - "ID_Visi_Service_Systemsteuerung_Contrast": 201, - "ID_Visi_Service_Systemsteuerung_Webserver": 202, - "ID_Visi_Service_Systemsteuerung_IPAdresse": 203, - "ID_Visi_Service_Systemsteuerung_Fernwartung": 204, - "ID_Visi_Paralleleschaltung": 205, - "ID_Visi_SysEin_Paralleleschaltung": 206, - "ID_Visi_Sprachen_DANSK": 207, - "ID_Visi_Sprachen_PORTUGES": 208, - "ID_Visi_Heizkurve_Heizung": 209, - "ID_Visi_SysEin_Mischkreis3": 210, - "ID_Visi_MK3": 211, - "ID_Visi_Temp_MK3_Vorlauf": 212, - "ID_Visi_Temp_MK3VL_Soll": 213, - "ID_Visi_OUT_Mischer3Auf": 214, - "ID_Visi_OUT_Mischer3Zu": 215, - "ID_Visi_SysEin_RegelungMK3": 216, - "ID_Visi_SysEin_PeriodeMk3": 217, - "ID_Visi_SysEin_LaufzeitMk3": 218, - "ID_Visi_SysEin_Kuhl_Zeit_Ein": 219, - "ID_Visi_SysEin_Kuhl_Zeit_Aus": 220, - "ID_Visi_AblaufZ_AbtauIn": 221, - "ID_Visi_Waermemenge_WS": 222, - "ID_Visi_Waermemenge_WQ": 223, - "ID_Visi_Enlt_MA3": 224, - "ID_Visi_Enlt_MZ3": 225, - "ID_Visi_Enlt_FP3": 226, - "ID_Visi_OUT_FUP3": 227, - "ID_Visi_Temp_Raumstation2": 228, - "ID_Visi_Temp_Raumstation3": 229, - "ID_Visi_Bst_BStdSW": 230, - "ID_Visi_Sprachen_LITAUISCH": 231, - "ID_Visi_Sprachen_ESTNICH": 232, - "ID_Visi_SysEin_Fernwartung": 233, - "ID_Visi_Sprachen_SLOVENISCH": 234, - "ID_Visi_EinstTemp_TA_EG": 235, - "ID_Visi_Einst_TVLmax_EG": 236, - "ID_Visi_SysEin_PoptNachlauf": 237, - "ID_Visi_RFV_K_Kuehlin": 238, - "ID_Visi_SysEin_EffizienzpumpeNom": 239, - "ID_Visi_SysEin_EffizienzpumpeMin": 240, - "ID_Visi_SysEin_Effizienzpumpe": 241, - "ID_Visi_SysEin_Waermemenge": 242, - "ID_Visi_Service_WMZ_Effizienz": 243, - "ID_Visi_SysEin_Wm_Versorgung_Korrektur": 244, - "ID_Visi_SysEin_Wm_Auswertung_Korrektur": 245, - "ID_Visi_IN_AnalogIn": 246, - "ID_Visi_Eins_SN_Eingabe": 247, - "ID_Visi_OUT_Analog_1": 248, - "ID_Visi_OUT_Analog_2": 249, - "ID_Visi_Solar": 250, - "ID_Visi_SysEin_Solar": 251, - "ID_Visi_EinstTemp_TDiffKollmax": 252, - "ID_Visi_AblaufZ_HG_Sperre": 253, - "ID_Visi_SysEin_Akt_Kuehlung": 254, - "ID_Visi_SysEin_Vorlauf_VBO": 255, - "ID_Visi_Einst_KRHyst": 256, - "ID_Visi_Einst_Akt_Kuehl_Speicher_min": 257, - "ID_Visi_Einst_Akt_Kuehl_Freig_WQE": 258, - "ID_Visi_SysEin_AbtZykMin": 259, - "ID_Visi_SysEin_VD2_Zeit_Min": 260, - "ID_Visi_EinstTemp_Hysterese_HR_verkuerzt": 261, - "ID_Visi_Einst_Luf_Feuchteschutz_akt": 262, - "ID_Visi_Einst_Luf_Reduziert_akt": 263, - "ID_Visi_Einst_Luf_Nennlueftung_akt": 264, - "ID_Visi_Einst_Luf_Intensivlueftung_akt": 265, - "ID_Visi_Temperatur_Lueftung_Zuluft": 266, - "ID_Visi_Temperatur_Lueftung_Abluft": 267, - "ID_Visi_OUT_Analog_3": 268, - "ID_Visi_OUT_Analog_4": 269, - "ID_Visi_IN_Analog_2": 270, - "ID_Visi_IN_Analog_3": 271, - "ID_Visi_IN_SAX": 272, - "ID_Visi_OUT_VZU": 273, - "ID_Visi_OUT_VAB": 274, - "ID_Visi_OUT_VSK": 275, - "ID_Visi_OUT_FRH": 276, - "ID_Visi_KuhlTemp_SolltempMK3": 277, - "ID_Visi_KuhlTemp_ATDiffMK3": 278, - "ID_Visi_IN_SPL": 279, - "ID_Visi_SysEin_Lueftungsstufen": 280, - "ID_Visi_SysEin_Meldung_TDI": 281, - "ID_Visi_SysEin_Typ_WZW": 282, - "ID_Visi_BACnet": 283, - "ID_Visi_Sprachen_SLOWAKISCH": 284, - "ID_Visi_Sprachen_LETTISCH": 285, - "ID_Visi_Sprachen_FINNISCH": 286, - "ID_Visi_Kalibrierung_LWD": 287, - "ID_Visi_IN_Durchfluss": 288, - "ID_Visi_LIN_ANSAUG_VERDICHTER": 289, - "ID_Visi_LIN_VDH": 290, - "ID_Visi_LIN_UH": 291, - "ID_Visi_LIN_Druck": 292, - "ID_Visi_Einst_Sollwert_TRL_Kuehlen": 293, - "ID_Visi_Entl_ExVentil": 294, - "ID_Visi_Einst_Medium_Waermequelle": 295, - "ID_Visi_Einst_Multispeicher": 296, - "ID_Visi_Einst_Minimale_Ruecklaufsolltemperatur": 297, - "ID_Visi_Einst_PKuehlTime": 298, - "ID_Visi_Sprachen_TUERKISCH": 299, - "ID_Visi_RBE": 300, - "ID_Visi_Einst_Luf_Stufen_Faktor": 301, - "ID_Visi_Freigabe_Zeit_ZWE": 302, - "ID_Visi_Einst_min_VL_Kuehl": 303, - "ID_Visi_ZWE1": 304, - "ID_Visi_ZWE2": 305, - "ID_Visi_ZWE3": 306, - "ID_Visi_SEC": 307, - "ID_Visi_HZIO": 308, - "ID_Visi_WPIO": 309, - "ID_Visi_LIN_ANSAUG_VERDAMPFER": 310, - "ID_Visi_LIN_MULTI1": 311, - "ID_Visi_LIN_MULTI2": 312, - "ID_Visi_Einst_Leistung_ZWE": 313, - "ID_Visi_Sprachen_ESPANOL": 314, - "ID_Visi_Temp_BW_oben": 315, - "ID_Visi_MAXIO": 316, - "ID_Visi_OUT_Abtauwunsch": 317, - "ID_Visi_SmartGrid": 318, - "ID_Visi_Drehzahlgeregelt": 319, - "ID_Visi_P155_Inverter": 320, - "ID_Visi_Leistungsfreigabe": 321, - "ID_Visi_Einst_Vorl_akt_Kuehl": 322, - "ID_Visi_Einst_Abtauen_im_Warmwasser": 323, - "ID_Visi_Waermemenge_ZWE": 324, - "Unknown_Visibility_325": 325, - "Unknown_Visibility_326": 326, - "Unknown_Visibility_327": 327, - "Unknown_Visibility_328": 328, - "Unknown_Visibility_329": 329, - "Unknown_Visibility_330": 330, - "Unknown_Visibility_331": 331, - "Unknown_Visibility_332": 332, - "Unknown_Visibility_333": 333, - "Unknown_Visibility_334": 334, - "Unknown_Visibility_335": 335, - "Unknown_Visibility_336": 336, - "Unknown_Visibility_337": 337, - "Unknown_Visibility_338": 338, - "Unknown_Visibility_339": 339, - "Unknown_Visibility_340": 340, - "Unknown_Visibility_341": 341, - "Unknown_Visibility_342": 342, - "Unknown_Visibility_343": 343, - "Unknown_Visibility_344": 344, - "Unknown_Visibility_345": 345, - "Unknown_Visibility_346": 346, - "Unknown_Visibility_347": 347, - "Unknown_Visibility_348": 348, - "Unknown_Visibility_349": 349, - "Unknown_Visibility_350": 350, - "Unknown_Visibility_351": 351, - "Unknown_Visibility_352": 352, - "Unknown_Visibility_353": 353, - "Unknown_Visibility_354": 354, - # New in 'main' branch: - "ID_Visi_Heizung_Zeitschaltprogramm": 182, - "Unknown_Visibility_355": 355, - "Unknown_Visibility_356": 356, - "Unknown_Visibility_357": 357, - "ELECTRICAL_POWER_LIMITATION_SWITCH": 357, - "Unknown_Visibility_358": 358, - "Unknown_Visibility_359": 359, - "Unknown_Visibility_360": 360, - "Unknown_Visibility_361": 361, - "Unknown_Visibility_362": 362, - "Unknown_Visibility_363": 363, - "Unknown_Visibility_364": 364, - "Unknown_Visibility_365": 365, - "Unknown_Visibility_366": 366, - "Unknown_Visibility_367": 367, - "Unknown_Visibility_368": 368, - "Unknown_Visibility_369": 369, - "Unknown_Visibility_370": 370, - "Unknown_Visibility_371": 371, - "Unknown_Visibility_372": 372, - "Unknown_Visibility_373": 373, - "Unknown_Visibility_374": 374, - "Unknown_Visibility_375": 375, - "Unknown_Visibility_376": 376, - "Unknown_Visibility_377": 377, - "Unknown_Visibility_378": 378, - "Unknown_Visibility_379": 379, + "ID_Visi_NieAnzeigen": (0, Unknown), + "ID_Visi_ImmerAnzeigen": (1, Unknown), + "ID_Visi_Heizung": (2, Unknown), + "ID_Visi_Brauwasser": (3, Unknown), + "ID_Visi_Schwimmbad": (4, Unknown), + "ID_Visi_Kuhlung": (5, Unknown), + "ID_Visi_Lueftung": (6, Unknown), + "ID_Visi_MK1": (7, Unknown), + "ID_Visi_MK2": (8, Unknown), + "ID_Visi_ThermDesinfekt": (9, Unknown), + "ID_Visi_Zirkulation": (10, Unknown), + "ID_Visi_KuhlTemp_SolltempMK1": (11, Unknown), + "ID_Visi_KuhlTemp_SolltempMK2": (12, Unknown), + "ID_Visi_KuhlTemp_ATDiffMK1": (13, Unknown), + "ID_Visi_KuhlTemp_ATDiffMK2": (14, Unknown), + "ID_Visi_Service_Information": (15, Unknown), + "ID_Visi_Service_Einstellung": (16, Unknown), + "ID_Visi_Service_Sprache": (17, Unknown), + "ID_Visi_Service_DatumUhrzeit": (18, Unknown), + "ID_Visi_Service_Ausheiz": (19, Unknown), + "ID_Visi_Service_Anlagenkonfiguration": (20, Unknown), + "ID_Visi_Service_IBNAssistant": (21, Unknown), + "ID_Visi_Service_ParameterIBNZuruck": (22, Unknown), + "ID_Visi_Temp_Vorlauf": (23, Unknown), + "ID_Visi_Temp_Rucklauf": (24, Unknown), + "ID_Visi_Temp_RL_Soll": (25, Unknown), + "ID_Visi_Temp_Ruecklext": (26, Unknown), + "ID_Visi_Temp_Heissgas": (27, Unknown), + "ID_Visi_Temp_Aussent": (28, Unknown), + "ID_Visi_Temp_BW_Ist": (29, Unknown), + "ID_Visi_Temp_BW_Soll": (30, Unknown), + "ID_Visi_Temp_WQ_Ein": (31, Unknown), + "ID_Visi_Temp_Kaltekreis": (32, Unknown), + "ID_Visi_Temp_MK1_Vorlauf": (33, Unknown), + "ID_Visi_Temp_MK1VL_Soll": (34, Unknown), + "ID_Visi_Temp_Raumstation": (35, Unknown), + "ID_Visi_Temp_MK2_Vorlauf": (36, Unknown), + "ID_Visi_Temp_MK2VL_Soll": (37, Unknown), + "ID_Visi_Temp_Solarkoll": (38, Unknown), + "ID_Visi_Temp_Solarsp": (39, Unknown), + "ID_Visi_Temp_Ext_Energ": (40, Unknown), + "ID_Visi_IN_ASD": (41, Unknown), + "ID_Visi_IN_BWT": (42, Unknown), + "ID_Visi_IN_EVU": (43, Unknown), + "ID_Visi_IN_HD": (44, Unknown), + "ID_Visi_IN_MOT": (45, Unknown), + "ID_Visi_IN_ND": (46, Unknown), + "ID_Visi_IN_PEX": (47, Unknown), + "ID_Visi_IN_SWT": (48, Unknown), + "ID_Visi_OUT_Abtauventil": (49, Unknown), + "ID_Visi_OUT_BUP": (50, Unknown), + "ID_Visi_OUT_FUP1": (51, Unknown), + "ID_Visi_OUT_HUP": (52, Unknown), + "ID_Visi_OUT_Mischer1Auf": (53, Unknown), + "ID_Visi_OUT_Mischer1Zu": (54, Unknown), + "ID_Visi_OUT_Ventilation": (55, Unknown), + "ID_Visi_OUT_Ventil_BOSUP": (56, Unknown), + "ID_Visi_OUT_Verdichter1": (57, Unknown), + "ID_Visi_OUT_Verdichter2": (58, Unknown), + "ID_Visi_OUT_ZIP": (59, Unknown), + "ID_Visi_OUT_ZUP": (60, Unknown), + "ID_Visi_OUT_ZWE1": (61, Unknown), + "ID_Visi_OUT_ZWE2_SST": (62, Unknown), + "ID_Visi_OUT_ZWE3": (63, Unknown), + "ID_Visi_OUT_FUP2": (64, Unknown), + "ID_Visi_OUT_SLP": (65, Unknown), + "ID_Visi_OUT_SUP": (66, Unknown), + "ID_Visi_OUT_Mischer2Auf": (67, Unknown), + "ID_Visi_OUT_Mischer2Zu": (68, Unknown), + "ID_Visi_AblaufZ_WP_Seit": (69, Unknown), + "ID_Visi_AblaufZ_ZWE1_seit": (70, Unknown), + "ID_Visi_AblaufZ_ZWE2_seit": (71, Unknown), + "ID_Visi_AblaufZ_ZWE3_seit": (72, Unknown), + "ID_Visi_AblaufZ_Netzeinv": (73, Unknown), + "ID_Visi_AblaufZ_SSP_Zeit1": (74, Unknown), + "ID_Visi_AblaufZ_VD_Stand": (75, Unknown), + "ID_Visi_AblaufZ_HRM_Zeit": (76, Unknown), + "ID_Visi_AblaufZ_HRW_Zeit": (77, Unknown), + "ID_Visi_AblaufZ_TDI_seit": (78, Unknown), + "ID_Visi_AblaufZ_Sperre_BW": (79, Unknown), + "ID_Visi_Bst_BStdVD1": (80, Unknown), + "ID_Visi_Bst_ImpVD1": (81, Unknown), + "ID_Visi_Bst_dEZVD1": (82, Unknown), + "ID_Visi_Bst_BStdVD2": (83, Unknown), + "ID_Visi_Bst_ImpVD2": (84, Unknown), + "ID_Visi_Bst_dEZVD2": (85, Unknown), + "ID_Visi_Bst_BStdZWE1": (86, Unknown), + "ID_Visi_Bst_BStdZWE2": (87, Unknown), + "ID_Visi_Bst_BStdZWE3": (88, Unknown), + "ID_Visi_Bst_BStdWP": (89, Unknown), + "ID_Visi_Text_Kurzprogramme": (90, Unknown), + "ID_Visi_Text_Zwangsheizung": (91, Unknown), + "ID_Visi_Text_Zwangsbrauchwasser": (92, Unknown), + "ID_Visi_Text_Abtauen": (93, Unknown), + "ID_Visi_EinstTemp_RucklBegr": (94, Unknown), + "ID_Visi_EinstTemp_HystereseHR": (95, Unknown), + "ID_Visi_EinstTemp_TRErhmax": (96, Unknown), + "ID_Visi_EinstTemp_Freig2VD": (97, Unknown), + "ID_Visi_EinstTemp_FreigZWE": (98, Unknown), + "ID_Visi_EinstTemp_Tluftabt": (99, Unknown), + "ID_Visi_EinstTemp_TDISolltemp": (100, Unknown), + "ID_Visi_EinstTemp_HystereseBW": (101, Unknown), + "ID_Visi_EinstTemp_Vorl2VDBW": (102, Unknown), + "ID_Visi_EinstTemp_TAussenmax": (103, Unknown), + "ID_Visi_EinstTemp_TAussenmin": (104, Unknown), + "ID_Visi_EinstTemp_TWQmin": (105, Unknown), + "ID_Visi_EinstTemp_THGmax": (106, Unknown), + "ID_Visi_EinstTemp_TLABTEnde": (107, Unknown), + "ID_Visi_EinstTemp_Absenkbis": (108, Unknown), + "ID_Visi_EinstTemp_Vorlaufmax": (109, Unknown), + "ID_Visi_EinstTemp_TDiffEin": (110, Unknown), + "ID_Visi_EinstTemp_TDiffAus": (111, Unknown), + "ID_Visi_EinstTemp_TDiffmax": (112, Unknown), + "ID_Visi_EinstTemp_TEEHeizung": (113, Unknown), + "ID_Visi_EinstTemp_TEEBrauchw": (114, Unknown), + "ID_Visi_EinstTemp_Vorl2VDSW": (115, Unknown), + "ID_Visi_EinstTemp_VLMaxMk1": (116, Unknown), + "ID_Visi_EinstTemp_VLMaxMk2": (117, Unknown), + "ID_Visi_Priori_Brauchwasser": (118, Unknown), + "ID_Visi_Priori_Heizung": (119, Unknown), + "ID_Visi_Priori_Schwimmbad": (120, Unknown), + "ID_Visi_SysEin_EVUSperre": (121, Unknown), + "ID_Visi_SysEin_Raumstation": (122, Unknown), + "ID_Visi_SysEin_Einbindung": (123, Unknown), + "ID_Visi_SysEin_Mischkreis1": (124, Unknown), + "ID_Visi_SysEin_Mischkreis2": (125, Unknown), + "ID_Visi_SysEin_ZWE1Art": (126, Unknown), + "ID_Visi_SysEin_ZWE1Fkt": (127, Unknown), + "ID_Visi_SysEin_ZWE2Art": (128, Unknown), + "ID_Visi_SysEin_ZWE2Fkt": (129, Unknown), + "ID_Visi_SysEin_ZWE3Art": (130, Unknown), + "ID_Visi_SysEin_ZWE3Fkt": (131, Unknown), + "ID_Visi_SysEin_Stoerung": (132, Unknown), + "ID_Visi_SysEin_Brauchwasser1": (133, Unknown), + "ID_Visi_SysEin_Brauchwasser2": (134, Unknown), + "ID_Visi_SysEin_Brauchwasser3": (135, Unknown), + "ID_Visi_SysEin_Brauchwasser4": (136, Unknown), + "ID_Visi_SysEin_Brauchwasser5": (137, Unknown), + "ID_Visi_SysEin_BWWPmax": (138, Unknown), + "ID_Visi_SysEin_Abtzykmax": (139, Unknown), + "ID_Visi_SysEin_Luftabt": (140, Unknown), + "ID_Visi_SysEin_LuftAbtmax": (141, Unknown), + "ID_Visi_SysEin_Abtauen1": (142, Unknown), + "ID_Visi_SysEin_Abtauen2": (143, Unknown), + "ID_Visi_SysEin_Pumpenoptim": (144, Unknown), + "ID_Visi_SysEin_Zusatzpumpe": (145, Unknown), + "ID_Visi_SysEin_Zugang": (146, Unknown), + "ID_Visi_SysEin_SoledrDurchf": (147, Unknown), + "ID_Visi_SysEin_UberwachungVD": (148, Unknown), + "ID_Visi_SysEin_RegelungHK": (149, Unknown), + "ID_Visi_SysEin_RegelungMK1": (150, Unknown), + "ID_Visi_SysEin_RegelungMK2": (151, Unknown), + "ID_Visi_SysEin_Kuhlung": (152, Unknown), + "ID_Visi_SysEin_Ausheizen": (153, Unknown), + "ID_Visi_SysEin_ElektrAnode": (154, Unknown), + "ID_Visi_SysEin_SWBBer": (155, Unknown), + "ID_Visi_SysEin_SWBMin": (156, Unknown), + "ID_Visi_SysEin_Heizung": (157, Unknown), + "ID_Visi_SysEin_PeriodeMk1": (158, Unknown), + "ID_Visi_SysEin_LaufzeitMk1": (159, Unknown), + "ID_Visi_SysEin_PeriodeMk2": (160, Unknown), + "ID_Visi_SysEin_LaufzeitMk2": (161, Unknown), + "ID_Visi_SysEin_Heizgrenze": (162, Unknown), + "ID_Visi_Enlt_HUP": (163, Unknown), + "ID_Visi_Enlt_ZUP": (164, Unknown), + "ID_Visi_Enlt_BUP": (165, Unknown), + "ID_Visi_Enlt_Ventilator_BOSUP": (166, Unknown), + "ID_Visi_Enlt_MA1": (167, Unknown), + "ID_Visi_Enlt_MZ1": (168, Unknown), + "ID_Visi_Enlt_ZIP": (169, Unknown), + "ID_Visi_Enlt_MA2": (170, Unknown), + "ID_Visi_Enlt_MZ2": (171, Unknown), + "ID_Visi_Enlt_SUP": (172, Unknown), + "ID_Visi_Enlt_SLP": (173, Unknown), + "ID_Visi_Enlt_FP2": (174, Unknown), + "ID_Visi_Enlt_Laufzeit": (175, Unknown), + "ID_Visi_Anlgkonf_Heizung": (176, Unknown), + "ID_Visi_Anlgkonf_Brauchwarmwasser": (177, Unknown), + "ID_Visi_Anlgkonf_Schwimmbad": (178, Unknown), + "ID_Visi_Heizung_Betriebsart": (179, Unknown), + "ID_Visi_Heizung_TemperaturPlusMinus": (180, Unknown), + "ID_Visi_Heizung_Heizkurven": (181, Unknown), + "ID_Visi_Heizung_Zeitschlaltprogramm": (182, Unknown), + "ID_Visi_Heizung_Heizgrenze": (183, Unknown), + "ID_Visi_Mitteltemperatur": (184, Unknown), + "ID_Visi_Dataenlogger": (185, Unknown), + "ID_Visi_Sprachen_DEUTSCH": (186, Unknown), + "ID_Visi_Sprachen_ENGLISH": (187, Unknown), + "ID_Visi_Sprachen_FRANCAIS": (188, Unknown), + "ID_Visi_Sprachen_NORWAY": (189, Unknown), + "ID_Visi_Sprachen_TCHECH": (190, Unknown), + "ID_Visi_Sprachen_ITALIANO": (191, Unknown), + "ID_Visi_Sprachen_NEDERLANDS": (192, Unknown), + "ID_Visi_Sprachen_SVENSKA": (193, Unknown), + "ID_Visi_Sprachen_POLSKI": (194, Unknown), + "ID_Visi_Sprachen_MAGYARUL": (195, Unknown), + "ID_Visi_ErrorUSBspeichern": (196, Unknown), + "ID_Visi_Bst_BStdHz": (197, Unknown), + "ID_Visi_Bst_BStdBW": (198, Unknown), + "ID_Visi_Bst_BStdKue": (199, Unknown), + "ID_Visi_Service_Systemsteuerung": (200, Unknown), + "ID_Visi_Service_Systemsteuerung_Contrast": (201, Unknown), + "ID_Visi_Service_Systemsteuerung_Webserver": (202, Unknown), + "ID_Visi_Service_Systemsteuerung_IPAdresse": (203, Unknown), + "ID_Visi_Service_Systemsteuerung_Fernwartung": (204, Unknown), + "ID_Visi_Paralleleschaltung": (205, Unknown), + "ID_Visi_SysEin_Paralleleschaltung": (206, Unknown), + "ID_Visi_Sprachen_DANSK": (207, Unknown), + "ID_Visi_Sprachen_PORTUGES": (208, Unknown), + "ID_Visi_Heizkurve_Heizung": (209, Unknown), + "ID_Visi_SysEin_Mischkreis3": (210, Unknown), + "ID_Visi_MK3": (211, Unknown), + "ID_Visi_Temp_MK3_Vorlauf": (212, Unknown), + "ID_Visi_Temp_MK3VL_Soll": (213, Unknown), + "ID_Visi_OUT_Mischer3Auf": (214, Unknown), + "ID_Visi_OUT_Mischer3Zu": (215, Unknown), + "ID_Visi_SysEin_RegelungMK3": (216, Unknown), + "ID_Visi_SysEin_PeriodeMk3": (217, Unknown), + "ID_Visi_SysEin_LaufzeitMk3": (218, Unknown), + "ID_Visi_SysEin_Kuhl_Zeit_Ein": (219, Unknown), + "ID_Visi_SysEin_Kuhl_Zeit_Aus": (220, Unknown), + "ID_Visi_AblaufZ_AbtauIn": (221, Unknown), + "ID_Visi_Waermemenge_WS": (222, Unknown), + "ID_Visi_Waermemenge_WQ": (223, Unknown), + "ID_Visi_Enlt_MA3": (224, Unknown), + "ID_Visi_Enlt_MZ3": (225, Unknown), + "ID_Visi_Enlt_FP3": (226, Unknown), + "ID_Visi_OUT_FUP3": (227, Unknown), + "ID_Visi_Temp_Raumstation2": (228, Unknown), + "ID_Visi_Temp_Raumstation3": (229, Unknown), + "ID_Visi_Bst_BStdSW": (230, Unknown), + "ID_Visi_Sprachen_LITAUISCH": (231, Unknown), + "ID_Visi_Sprachen_ESTNICH": (232, Unknown), + "ID_Visi_SysEin_Fernwartung": (233, Unknown), + "ID_Visi_Sprachen_SLOVENISCH": (234, Unknown), + "ID_Visi_EinstTemp_TA_EG": (235, Unknown), + "ID_Visi_Einst_TVLmax_EG": (236, Unknown), + "ID_Visi_SysEin_PoptNachlauf": (237, Unknown), + "ID_Visi_RFV_K_Kuehlin": (238, Unknown), + "ID_Visi_SysEin_EffizienzpumpeNom": (239, Unknown), + "ID_Visi_SysEin_EffizienzpumpeMin": (240, Unknown), + "ID_Visi_SysEin_Effizienzpumpe": (241, Unknown), + "ID_Visi_SysEin_Waermemenge": (242, Unknown), + "ID_Visi_Service_WMZ_Effizienz": (243, Unknown), + "ID_Visi_SysEin_Wm_Versorgung_Korrektur": (244, Unknown), + "ID_Visi_SysEin_Wm_Auswertung_Korrektur": (245, Unknown), + "ID_Visi_IN_AnalogIn": (246, Unknown), + "ID_Visi_Eins_SN_Eingabe": (247, Unknown), + "ID_Visi_OUT_Analog_1": (248, Unknown), + "ID_Visi_OUT_Analog_2": (249, Unknown), + "ID_Visi_Solar": (250, Unknown), + "ID_Visi_SysEin_Solar": (251, Unknown), + "ID_Visi_EinstTemp_TDiffKollmax": (252, Unknown), + "ID_Visi_AblaufZ_HG_Sperre": (253, Unknown), + "ID_Visi_SysEin_Akt_Kuehlung": (254, Unknown), + "ID_Visi_SysEin_Vorlauf_VBO": (255, Unknown), + "ID_Visi_Einst_KRHyst": (256, Unknown), + "ID_Visi_Einst_Akt_Kuehl_Speicher_min": (257, Unknown), + "ID_Visi_Einst_Akt_Kuehl_Freig_WQE": (258, Unknown), + "ID_Visi_SysEin_AbtZykMin": (259, Unknown), + "ID_Visi_SysEin_VD2_Zeit_Min": (260, Unknown), + "ID_Visi_EinstTemp_Hysterese_HR_verkuerzt": (261, Unknown), + "ID_Visi_Einst_Luf_Feuchteschutz_akt": (262, Unknown), + "ID_Visi_Einst_Luf_Reduziert_akt": (263, Unknown), + "ID_Visi_Einst_Luf_Nennlueftung_akt": (264, Unknown), + "ID_Visi_Einst_Luf_Intensivlueftung_akt": (265, Unknown), + "ID_Visi_Temperatur_Lueftung_Zuluft": (266, Unknown), + "ID_Visi_Temperatur_Lueftung_Abluft": (267, Unknown), + "ID_Visi_OUT_Analog_3": (268, Unknown), + "ID_Visi_OUT_Analog_4": (269, Unknown), + "ID_Visi_IN_Analog_2": (270, Unknown), + "ID_Visi_IN_Analog_3": (271, Unknown), + "ID_Visi_IN_SAX": (272, Unknown), + "ID_Visi_OUT_VZU": (273, Unknown), + "ID_Visi_OUT_VAB": (274, Unknown), + "ID_Visi_OUT_VSK": (275, Unknown), + "ID_Visi_OUT_FRH": (276, Unknown), + "ID_Visi_KuhlTemp_SolltempMK3": (277, Unknown), + "ID_Visi_KuhlTemp_ATDiffMK3": (278, Unknown), + "ID_Visi_IN_SPL": (279, Unknown), + "ID_Visi_SysEin_Lueftungsstufen": (280, Unknown), + "ID_Visi_SysEin_Meldung_TDI": (281, Unknown), + "ID_Visi_SysEin_Typ_WZW": (282, Unknown), + "ID_Visi_BACnet": (283, Unknown), + "ID_Visi_Sprachen_SLOWAKISCH": (284, Unknown), + "ID_Visi_Sprachen_LETTISCH": (285, Unknown), + "ID_Visi_Sprachen_FINNISCH": (286, Unknown), + "ID_Visi_Kalibrierung_LWD": (287, Unknown), + "ID_Visi_IN_Durchfluss": (288, Unknown), + "ID_Visi_LIN_ANSAUG_VERDICHTER": (289, Unknown), + "ID_Visi_LIN_VDH": (290, Unknown), + "ID_Visi_LIN_UH": (291, Unknown), + "ID_Visi_LIN_Druck": (292, Unknown), + "ID_Visi_Einst_Sollwert_TRL_Kuehlen": (293, Unknown), + "ID_Visi_Entl_ExVentil": (294, Unknown), + "ID_Visi_Einst_Medium_Waermequelle": (295, Unknown), + "ID_Visi_Einst_Multispeicher": (296, Unknown), + "ID_Visi_Einst_Minimale_Ruecklaufsolltemperatur": (297, Unknown), + "ID_Visi_Einst_PKuehlTime": (298, Unknown), + "ID_Visi_Sprachen_TUERKISCH": (299, Unknown), + "ID_Visi_RBE": (300, Unknown), + "ID_Visi_Einst_Luf_Stufen_Faktor": (301, Unknown), + "ID_Visi_Freigabe_Zeit_ZWE": (302, Unknown), + "ID_Visi_Einst_min_VL_Kuehl": (303, Unknown), + "ID_Visi_ZWE1": (304, Unknown), + "ID_Visi_ZWE2": (305, Unknown), + "ID_Visi_ZWE3": (306, Unknown), + "ID_Visi_SEC": (307, Unknown), + "ID_Visi_HZIO": (308, Unknown), + "ID_Visi_WPIO": (309, Unknown), + "ID_Visi_LIN_ANSAUG_VERDAMPFER": (310, Unknown), + "ID_Visi_LIN_MULTI1": (311, Unknown), + "ID_Visi_LIN_MULTI2": (312, Unknown), + "ID_Visi_Einst_Leistung_ZWE": (313, Unknown), + "ID_Visi_Sprachen_ESPANOL": (314, Unknown), + "ID_Visi_Temp_BW_oben": (315, Unknown), + "ID_Visi_MAXIO": (316, Unknown), + "ID_Visi_OUT_Abtauwunsch": (317, Unknown), + "ID_Visi_SmartGrid": (318, Unknown), + "ID_Visi_Drehzahlgeregelt": (319, Unknown), + "ID_Visi_P155_Inverter": (320, Unknown), + "ID_Visi_Leistungsfreigabe": (321, Unknown), + "ID_Visi_Einst_Vorl_akt_Kuehl": (322, Unknown), + "ID_Visi_Einst_Abtauen_im_Warmwasser": (323, Unknown), + "ID_Visi_Waermemenge_ZWE": (324, Unknown), + "Unknown_Visibility_325": (325, Unknown), + "Unknown_Visibility_326": (326, Unknown), + "Unknown_Visibility_327": (327, Unknown), + "Unknown_Visibility_328": (328, Unknown), + "Unknown_Visibility_329": (329, Unknown), + "Unknown_Visibility_330": (330, Unknown), + "Unknown_Visibility_331": (331, Unknown), + "Unknown_Visibility_332": (332, Unknown), + "Unknown_Visibility_333": (333, Unknown), + "Unknown_Visibility_334": (334, Unknown), + "Unknown_Visibility_335": (335, Unknown), + "Unknown_Visibility_336": (336, Unknown), + "Unknown_Visibility_337": (337, Unknown), + "Unknown_Visibility_338": (338, Unknown), + "Unknown_Visibility_339": (339, Unknown), + "Unknown_Visibility_340": (340, Unknown), + "Unknown_Visibility_341": (341, Unknown), + "Unknown_Visibility_342": (342, Unknown), + "Unknown_Visibility_343": (343, Unknown), + "Unknown_Visibility_344": (344, Unknown), + "Unknown_Visibility_345": (345, Unknown), + "Unknown_Visibility_346": (346, Unknown), + "Unknown_Visibility_347": (347, Unknown), + "Unknown_Visibility_348": (348, Unknown), + "Unknown_Visibility_349": (349, Unknown), + "Unknown_Visibility_350": (350, Unknown), + "Unknown_Visibility_351": (351, Unknown), + "Unknown_Visibility_352": (352, Unknown), + "Unknown_Visibility_353": (353, Unknown), + "Unknown_Visibility_354": (354, Unknown), # Bug in v0.3.14 visibilities parse method - "Unknown_Parameter_355": 355, - "Unknown_Parameter_356": 356, - "Unknown_Parameter_357": 357, - "Unknown_Parameter_358": 358, - "Unknown_Parameter_359": 359, - "Unknown_Parameter_360": 360, - "Unknown_Parameter_361": 361, - "Unknown_Parameter_362": 362, - "Unknown_Parameter_363": 363, - "Unknown_Parameter_364": 364, - "Unknown_Parameter_365": 365, - "Unknown_Parameter_366": 366, - "Unknown_Parameter_367": 367, - "Unknown_Parameter_368": 368, - "Unknown_Parameter_369": 369, - "Unknown_Parameter_370": 370, - "Unknown_Parameter_371": 371, - "Unknown_Parameter_372": 372, - "Unknown_Parameter_373": 373, - "Unknown_Parameter_374": 374, - "Unknown_Parameter_375": 375, - "Unknown_Parameter_376": 376, - "Unknown_Parameter_377": 377, - "Unknown_Parameter_378": 378, - "Unknown_Parameter_379": 379, + "Unknown_Parameter_355": (355, Unknown), + "Unknown_Parameter_356": (356, Unknown), + "Unknown_Parameter_357": (357, Unknown), + "Unknown_Parameter_358": (358, Unknown), + "Unknown_Parameter_359": (359, Unknown), + "Unknown_Parameter_360": (360, Unknown), + "Unknown_Parameter_361": (361, Unknown), + "Unknown_Parameter_362": (362, Unknown), + "Unknown_Parameter_363": (363, Unknown), + "Unknown_Parameter_364": (364, Unknown), + "Unknown_Parameter_365": (365, Unknown), + "Unknown_Parameter_366": (366, Unknown), + "Unknown_Parameter_367": (367, Unknown), + "Unknown_Parameter_368": (368, Unknown), + "Unknown_Parameter_369": (369, Unknown), + "Unknown_Parameter_370": (370, Unknown), + "Unknown_Parameter_371": (371, Unknown), + "Unknown_Parameter_372": (372, Unknown), + "Unknown_Parameter_373": (373, Unknown), + "Unknown_Parameter_374": (374, Unknown), + "Unknown_Parameter_375": (375, Unknown), + "Unknown_Parameter_376": (376, Unknown), + "Unknown_Parameter_377": (377, Unknown), + "Unknown_Parameter_378": (378, Unknown), + "Unknown_Parameter_379": (379, Unknown), + # New in 'main' branch: + "ID_Visi_Heizung_Zeitschaltprogramm": (182, Unknown), + "Unknown_Visibility_355": (355, Unknown), + "Unknown_Visibility_356": (356, Unknown), + "Unknown_Visibility_357": (357, Unknown), + "ELECTRICAL_POWER_LIMITATION_SWITCH": (357, Unknown), + "Unknown_Visibility_358": (358, Unknown), + "Unknown_Visibility_359": (359, Unknown), + "Unknown_Visibility_360": (360, Unknown), + "Unknown_Visibility_361": (361, Unknown), + "Unknown_Visibility_362": (362, Unknown), + "Unknown_Visibility_363": (363, Unknown), + "Unknown_Visibility_364": (364, Unknown), + "Unknown_Visibility_365": (365, Unknown), + "Unknown_Visibility_366": (366, Unknown), + "Unknown_Visibility_367": (367, Unknown), + "Unknown_Visibility_368": (368, Unknown), + "Unknown_Visibility_369": (369, Unknown), + "Unknown_Visibility_370": (370, Unknown), + "Unknown_Visibility_371": (371, Unknown), + "Unknown_Visibility_372": (372, Unknown), + "Unknown_Visibility_373": (373, Unknown), + "Unknown_Visibility_374": (374, Unknown), + "Unknown_Visibility_375": (375, Unknown), + "Unknown_Visibility_376": (376, Unknown), + "Unknown_Visibility_377": (377, Unknown), + "Unknown_Visibility_378": (378, Unknown), + "Unknown_Visibility_379": (379, Unknown), + } + + inputs = { + "heatpump_vd1_status": (0, Bool), + "heatpump_vd2_status": (0, Bool), + "heatpump_zwe1_status": (0, Bool), + "heatpump_zwe2_status": (0, Bool), + "heatpump_zwe3_status": (0, Bool), + "heatpump_status": (0, HeatPumpStatus), + "operation_mode": (2, OperationMode), + "heating_status": (3, ModeStatus), + "hot_water_status": (4, ModeStatus), + "dhw_status": (4, ModeStatus), + "cooling_status": (6, ModeStatus), + "pool_heating_status": (7, ModeStatus), + "return_line_temp": (100, CelsiusUInt16), + "return_line_target": (101, CelsiusUInt16), + "return_line_ext": (102, CelsiusUInt16), + "return_line_limit": (103, CelsiusInt16), + "return_line_min_target": (104, CelsiusInt16), + "flow_line_temp": (105, CelsiusUInt16), + "room_temperature": (106, CelsiusInt16), + "heating_limit": (107, CelsiusInt16), + "outside_temp": (108, CelsiusInt16), + "outside_temp_average": (109, CelsiusInt16), + "heat_source_input": (110, CelsiusInt16), + "heat_source_output": (111, CelsiusInt16), + "max_flow_temp": (112, CelsiusUInt16), + "unknown_input_113": (113, Unknown), + "hot_water_temp": (120, CelsiusInt16), + "dhw_temp": (120, CelsiusInt16), + "hot_water_target": (121, CelsiusUInt16), + "dhw_target": (121, CelsiusUInt16), + "hot_water_min": (122, CelsiusInt16), + "dhw_min": (122, CelsiusInt16), + "hot_water_max": (123, CelsiusInt16), + "dhw_max": (123, CelsiusInt16), + "hot_water_limit": (124, CelsiusInt16), + "dhw_limit": (124, CelsiusInt16), + "mc1_temp": (140, CelsiusInt16), + "mc1_target": (141, CelsiusInt16), + "mc1_min": (142, CelsiusInt16), + "mc1_max": (143, CelsiusInt16), + "mc2_temp": (150, CelsiusInt16), + "mc2_target": (151, CelsiusInt16), + "mc2_min": (152, CelsiusInt16), + "mc2_max": (153, CelsiusInt16), + "mc3_temp": (160, CelsiusInt16), + "mc3_target": (161, CelsiusInt16), + "mc3_min": (162, CelsiusInt16), + "mc3_max": (163, CelsiusInt16), + "error_number": (201, Errorcode), + "buffer_type": (202, BufferType), + "min_off_time": (203, Minutes), + "min_run_time": (204, Minutes), + "cooling_configured": (205, OnOffMode), + "pool_heating_configured": (206, OnOffMode), + "cooling_release": (207, OnOffMode), + "heating_power_actual": (300, PowerKW), + "electric_power_actual": (301, PowerKW), + "electric_power_min_predicted": (302, PowerKW), + "electric_energy_total": (310, Energy), + "electric_energy_heating": (312, Energy), + "electric_energy_dhw": (314, Energy), + "electric_energy_cooling": (316, Energy), + "electric_energy_pool": (318, Energy), + "thermal_energy_total": (320, Energy), + "thermal_energy_heating": (322, Energy), + "thermal_energy_dhw": (324, Energy), + "thermal_energy_cooling": (326, Energy), + "thermal_energy_pool": (328, Energy), + "unknown_input_350": (350, Unknown), + "unknown_input_351": (351, Unknown), + "unknown_input_352": (352, Unknown), + "unknown_input_353": (353, Unknown), + "unknown_input_354": (354, Unknown), + "unknown_input_355": (355, Unknown), + "unknown_input_356": (356, Unknown), + "unknown_input_360": (360, Unknown), + "unknown_input_361": (361, Unknown), + "version": (400, FullVersion), + "unknown_input_404": (404, Unknown), + "unknown_input_405": (405, Unknown), + "unknown_input_406": (406, Unknown), + "unknown_input_407": (407, Unknown), + "unknown_input_408": (408, Unknown), + "unknown_input_409": (409, Unknown), + "unknown_input_410": (410, Unknown), + "unknown_input_411": (411, Unknown), + "unknown_input_412": (412, Unknown), + "unknown_input_413": (413, Unknown), + "unknown_input_416": (416, Unknown), + "unknown_input_417": (417, Unknown), + "unknown_input_500": (500, Unknown), + "unknown_input_501": (501, Unknown), + "unknown_input_502": (502, Unknown), } - values = [[paras, Parameters(), "paras"], [calcs, Calculations(), "calcs"], [visis, Visibilities(), "visis"]] + holdings = { + # New in 'main' branch: + "heating_mode": (0, ControlMode), + "heating_setpoint": (1, CelsiusUInt16), + "heating_offset": (2, KelvinInt16), + "heating_level": (3, LevelMode), + "hot_water_mode": (5, ControlMode), + "dhw_mode": (5, ControlMode), + "hot_water_setpoint": (6, CelsiusUInt16), + "dhw_setpoint": (6, CelsiusUInt16), + "hot_water_offset": (7, KelvinInt16), + "dhw_offset": (7, KelvinInt16), + "hot_water_level": (8, LevelMode), + "dhw_level": (8, LevelMode), + "mc1_heat_mode": (10, ControlMode), + "mc1_heat_setpoint": (11, CelsiusUInt16), + "mc1_heat_offset": (12, KelvinInt16), + "mc1_heat_level": (13, LevelMode), + "mc1_cool_mode": (15, ControlMode), + "mc1_cool_setpoint": (16, CelsiusUInt16), + "mc1_cool_offset": (17, KelvinInt16), + "mc2_heat_mode": (20, ControlMode), + "mc2_heat_setpoint": (21, CelsiusUInt16), + "mc2_heat_offset": (22, KelvinInt16), + "mc2_heat_level": (23, LevelMode), + "mc2_cool_mode": (25, ControlMode), + "mc2_cool_setpoint": (26, CelsiusUInt16), + "mc2_cool_offset": (27, KelvinInt16), + "mc3_heat_mode": (30, ControlMode), + "mc3_heat_setpoint": (31, CelsiusUInt16), + "mc3_heat_offset": (32, KelvinInt16), + "mc3_heat_level": (33, LevelMode), + "mc3_cool_mode": (35, ControlMode), + "mc3_cool_setpoint": (36, CelsiusUInt16), + "mc3_cool_offset": (37, KelvinInt16), + "lpc_mode": (40, LpcMode), + "pc_limit": (41, PowerKW), + "lock_heating": (50, LockMode), + "lock_hot_water": (51, LockMode), + "lock_cooling": (52, LockMode), + "lock_swimming_pool": (53, LockMode), + "unknown_holding_60": (60, Unknown), + "heat_overall_mode": (65, ControlMode), + "heat_overall_offset": (66, KelvinInt16), + "heat_overall_level": (67, LevelMode), + "circulation": (70, OnOffMode), + "hot_water_extra": (71, OnOffMode), + } + + values = [ + [paras, Parameters(), "paras"], + [calcs, Calculations(), "calcs"], + [visis, Visibilities(), "visis"], + [inputs, Inputs(), "inputs"], + [holdings, Holdings(), "holdings"], + ] # First, we check if we can find all entries of the above dicts. - ok = True + all_ok = True for mapping, data_vector, caption in values: - print_caption = True - for old_name, old_idx in mapping.items(): - cur_idx, new_name = data_vector._name_lookup(old_name) - cur_name = data_vector.get(old_idx).name - if cur_idx != old_idx or (new_name is not None and new_name != cur_name): - # We do not use assert here, in order to catch all incompatibilities at once. - if print_caption: - print(f"### Incompatibilities - {caption}:") - print_caption = False - print(f'"{old_name}" is not registered for {old_idx}: "{cur_name}",') - ok = False - assert ok, "Found incompatibilities. Please consider to add them to compatibilities.py" + obsolete_found = [] + old_not_found = [] + old_idx_wrong = [] + old_type_changed_info = [] + old_type_changed_err = [] + + for old_name, (old_idx, old_type, *old_type_changed) in mapping.items(): + # using * old_type_changed is a list with all residual elements + old_type_changed = True if len(old_type_changed) > 0 and old_type_changed[0] else False + + # Try to get the definition of the "old name" + try: + def_by_name = data_vector.definitions.get(old_name) + except Exception: + def_by_name = None + old_found = def_by_name is not None + old_is_obsolete = old_name in data_vector._obsolete + + # Check names + # We do not use assert here, in order to catch all incompatibilities at once. + if old_found and old_is_obsolete: + obsolete_found.append(f"{old_name} marked as obsolete, but a definition was found!") + continue + + if not old_found and not old_is_obsolete: + old_not_found.append(f"No definition found for {old_name} with index {old_idx} and type {old_type.__name__}") + continue + + if old_found: + if old_idx != def_by_name.index: + old_idx_wrong.append(f"Index of {old_name} changed from {old_idx} to {def_by_name.index}") + continue + + #if old_name != def_by_name.name: + # new name available -> no error + + # we allow type changes if we already use a name, but the type is still unknown + type_change_allowed = old_type_changed or (not old_name.lower().startswith("unknown_") and old_type == Unknown) + if old_type != def_by_name.field_type: + if type_change_allowed: + old_type_changed_info.append(f"Type of {old_name} changed from {old_type.__name__} to {def_by_name.field_type.__name__}") + else: + old_type_changed_err.append(f"Type of {old_name} changed from {old_type.__name__} to {def_by_name.field_type.__name__}") + + ok = not obsolete_found and not old_not_found \ + and not old_idx_wrong and not old_type_changed_err + do_print = not ok or len(old_type_changed_info) > 0 + + if do_print: + print(f"############################## Incompatibilities - {caption}:") + if obsolete_found: + print("############################## obsolete") + for err in obsolete_found: + print(err) + if old_not_found: + print("############################## not found") + for err in old_not_found: + print(err) + if old_idx_wrong: + print("############################## idx wrong") + for err in old_idx_wrong: + print(err) + if old_type_changed_err: + print("############################## type change error") + for err in old_type_changed_err: + print(err) + if old_type_changed_info: + print("############################## type change info") + for err in old_type_changed_info: + print(err) + + all_ok &= ok + assert all_ok, "Found incompatibilities. Please consider to add them to compatibilities.py" # Second, we check if all names are present in the above dicts. - ok = True + all_ok = True for mapping, data_vector, caption in values: - print_caption = True - for definition in data_vector.definitions: + missing = [] + + for definition, field in data_vector.items(): for name in definition.names: + + # Check existing entries + # We do not use assert here, in order to catch all incompatibilities at once. + # The output can be copied to the dicts above if name not in mapping: - # We do not use assert here, in order to catch all incompatibilities at once. - # The output can be copied to the dicts above - if print_caption: - print(f"### Missing - {caption}:") - print_caption = False - print(f'"{name}": {definition.index},') - ok = False - assert ok, "Found missing entries. Please consider to add them to the test suite." \ No newline at end of file + missing.append(f'"{name}": ({definition.index}, {definition.field_type.__name__}),') + + ok = not missing + do_print = not ok + + if do_print: + print(f"############################## Missing - {caption}:") + if missing: + for err in missing: + print(err) + + all_ok &= ok + assert all_ok, "Found missing entries. Please consider to add them to the test suite." \ No newline at end of file diff --git a/tests/test_data_vector.py b/tests/test_data_vector.py index 9a13632e..f12ea2f5 100644 --- a/tests/test_data_vector.py +++ b/tests/test_data_vector.py @@ -28,7 +28,7 @@ class TestDataVector: @pytest.mark.parametrize("name, exception_expected", [ ("foo", False), - ("bar", True), + ("bar", False), ("baz", True), ("qux", False), ]) diff --git a/tests/test_datatypes.py b/tests/test_datatypes.py index 5da5cc7e..8139d201 100644 --- a/tests/test_datatypes.py +++ b/tests/test_datatypes.py @@ -4,12 +4,6 @@ import datetime -from luxtronik.constants import ( - LUXTRONIK_NAME_CHECK_NONE, - LUXTRONIK_NAME_CHECK_PREFERRED, - LUXTRONIK_NAME_CHECK_OBSOLETE, -) - from luxtronik.datatypes import ( Base, BitMaskBase, @@ -60,6 +54,7 @@ TimerProgram, TimeOfDay, TimeOfDay2, + Version, ) @@ -83,6 +78,7 @@ def test_init(self): a = Base("base") assert a.name == "base" assert a.writeable is False + assert a.unit is None b = Base("base", writeable=True) assert b.name == "base" @@ -121,14 +117,6 @@ def test_empty_name(self): except Exception: pass - def test_check_name(self): - """Test cases for check_name() function""" - base = Base(["foo", "bar"]) - - assert base.check_name("foo") == LUXTRONIK_NAME_CHECK_PREFERRED - assert base.check_name("bar") == LUXTRONIK_NAME_CHECK_OBSOLETE - assert base.check_name("baz") == LUXTRONIK_NAME_CHECK_NONE - def test_value_property(self): """Test case for value property""" @@ -188,6 +176,8 @@ def test_eq(self): d = Bool("bool") assert c != d + assert a != "b" + def test_lt(self): """Test cases for __lt__ function""" @@ -212,6 +202,7 @@ def test_init(self): assert a.name == "selection_base" assert not a.codes assert len(a.codes) == 0 + assert a.unit is None def test_options(self): """Test cases for options property""" @@ -231,6 +222,7 @@ def test_to_heatpump(self): """Test cases for to_heatpump function""" a = SelectionBase("") + assert a.to_heatpump("") is None assert a.to_heatpump("a") is None assert a.to_heatpump("Unknown_214") == 214 assert a.to_heatpump("unknown_215") == 215 @@ -260,6 +252,7 @@ def test_init(self): assert a.name == "selection_base_child" assert a.codes assert len(a.codes) == 3 + assert a.unit is None def test_options(self): """Test cases for options property""" @@ -301,6 +294,7 @@ def test_init(self): assert a.name == "bitmask_base" assert not a.bit_values assert len(a.bit_values) == 0 + assert a.unit is None def test_bits(self): """Test cases for bits property""" @@ -323,6 +317,7 @@ def test_to_heatpump(self): """Test cases for to_heatpump function""" a = BitMaskBase("") + assert a.to_heatpump("") is None assert a.to_heatpump("a") is None assert a.to_heatpump(1) is None assert a.to_heatpump(None) is None @@ -418,6 +413,7 @@ def test_to_heatpump(self): a = ScalingBaseTest("") assert a.to_heatpump(1) == 1 assert a.to_heatpump(42) == 42 + assert a.to_heatpump(12.0) == 12 class ScalingBaseChild(ScalingBase): @@ -444,6 +440,7 @@ def test_from_heatpump(self): assert a.from_heatpump(1) == 13 assert a.from_heatpump(2) == 26 assert a.from_heatpump(-4) == -52 + assert a.from_heatpump(None) is None def test_to_heatpump(self): """Test cases for to_heatpump function""" @@ -497,6 +494,7 @@ def test_init(self): assert a.name == "celsius" assert a.datatype_class == "temperature" assert a.datatype_unit == "°C" + assert a.unit == "°C" def test_from_heatpump(self): """Test cases for from_heatpump function""" @@ -518,6 +516,8 @@ def test_to_heatpump(self): assert Celsius.to_heatpump(-1) == -10 assert Celsius.to_heatpump(-1.1) == -11 + assert Celsius.to_heatpump(None) is None + class TestBool: """Test suite for Bool datatype""" @@ -529,18 +529,28 @@ def test_init(self): assert a.name == "bool" assert a.datatype_class == "boolean" assert a.datatype_unit is None + assert a.unit is None def test_from_heatpump(self): """Test cases for from_heatpump function""" assert Bool.from_heatpump(0) is False assert Bool.from_heatpump(1) is True + assert Bool.from_heatpump(None) is None def test_to_heatpump(self): """Test cases for to_heatpump function""" + class BoolExcept: + def __bool__(self): + return "x" + assert Bool.to_heatpump(False) == 0 assert Bool.to_heatpump(True) == 1 + assert Bool.to_heatpump(None) == 0 + assert Bool.to_heatpump("1") == 1 + assert Bool.to_heatpump("abc") == 1 + assert Bool.to_heatpump(BoolExcept()) is None class TestFrequency: @@ -553,6 +563,7 @@ def test_init(self): assert a.name == "frequency" assert a.datatype_class == "frequency" assert a.datatype_unit == "Hz" + assert a.unit == "Hz" class TestSeconds: @@ -565,6 +576,7 @@ def test_init(self): assert a.name == "seconds" assert a.datatype_class == "timespan" assert a.datatype_unit == "s" + assert a.unit == "s" class TestIPv4Address: @@ -577,6 +589,7 @@ def test_init(self): assert a.name == "ipv4_address" assert a.datatype_class == "ipv4_address" assert a.datatype_unit is None + assert a.unit is None def test_from_heatpump(self): """Test cases for from_heatpump function""" @@ -586,6 +599,7 @@ def test_from_heatpump(self): assert IPv4Address.from_heatpump(-1062731775) == "192.168.0.1" assert IPv4Address.from_heatpump(-256) == "255.255.255.0" assert IPv4Address.from_heatpump(-1) == "255.255.255.255" + assert IPv4Address.from_heatpump(None) is None def test_to_heatpump(self): """Test cases for to_heatpump function""" @@ -595,6 +609,8 @@ def test_to_heatpump(self): assert IPv4Address.to_heatpump("192.168.0.1") == -1062731775 assert IPv4Address.to_heatpump("255.255.255.0") == -256 assert IPv4Address.to_heatpump("255.255.255.255") == -1 + assert IPv4Address.to_heatpump(1) is None + assert IPv4Address.to_heatpump(None) is None class TestTimestamp: @@ -607,6 +623,7 @@ def test_init(self): assert a.name == "timestamp" assert a.datatype_class == "timestamp" assert a.datatype_unit is None + assert a.unit is None def test_from_heatpump(self): """Test cases for from_heatpump function""" @@ -620,12 +637,14 @@ def test_from_heatpump(self): # pylint: disable=fixme # TODO Consider to drop microseconds when dealing with this datatype? b = datetime.datetime.now() - assert a.from_heatpump(datetime.datetime.timestamp(b)) == b + assert a.from_heatpump(datetime.datetime.timestamp(b)) is None def test_to_heatpump(self): """Test cases for to_heatpump function""" a = Timestamp("") + assert a.to_heatpump(None) is None + assert a.to_heatpump("a") is None assert a.to_heatpump(datetime.datetime.fromtimestamp(0)) == 0 assert a.to_heatpump(datetime.datetime.fromtimestamp(1)) == 1 # pylint: disable=fixme @@ -670,6 +689,9 @@ def test_to_heatpump(self): assert Kelvin.to_heatpump(1) == 10 assert Kelvin.to_heatpump(1.1) == 11 + assert Kelvin.to_heatpump(None) is None + assert Kelvin.to_heatpump("0") == 0 + assert Kelvin.to_heatpump("b") is None class TestPressure: @@ -696,6 +718,9 @@ def test_to_heatpump(self): assert Pressure.to_heatpump(1) == 100 assert Pressure.to_heatpump(1.01) == 101 + assert Pressure.to_heatpump(None) is None + assert Pressure.to_heatpump("1") == 100 + assert Pressure.to_heatpump("c") is None class TestPercent: @@ -723,6 +748,10 @@ def test_percent_to_heatpump(self): assert Percent.to_heatpump(1) == 10 assert Percent.to_heatpump(1.1) == 11 + assert Percent.to_heatpump(None) is None + assert Percent.to_heatpump("2") == 20 + assert Percent.to_heatpump("d") is None + class TestPercent2: """Test suite for Percent2 datatype""" @@ -747,6 +776,10 @@ def test_to_heatpump(self): assert Percent2.to_heatpump(10) == 10 assert Percent2.to_heatpump(11) == 11 + assert Percent2.to_heatpump(None) is None + assert Percent2.to_heatpump("3") is None + assert Percent2.to_heatpump("e") is None + class TestSpeed: """Test suite for Speed datatype""" @@ -797,6 +830,10 @@ def test_to_heatpump(self): assert a.to_heatpump(1.5) == 15 assert a.to_heatpump(5.6) == 56 + assert a.to_heatpump(None) is None + assert a.to_heatpump("4") == 40 + assert a.to_heatpump("f") is None + class TestEnergy: """Test suite for Energy datatype""" @@ -823,6 +860,10 @@ def test_energy_to_heatpump(self): assert Energy.to_heatpump(1) == 10 assert Energy.to_heatpump(1.1) == 11 + assert Energy.to_heatpump(None) is None + assert Energy.to_heatpump("5") == 50 + assert Energy.to_heatpump("g") is None + class TestVoltage: """Test suite for Voltage datatype""" @@ -849,6 +890,10 @@ def test_voltage_to_heatpump(self): assert Voltage.to_heatpump(1) == 10 assert Voltage.to_heatpump(1.1) == 11 + assert Voltage.to_heatpump(None) is None + assert Voltage.to_heatpump("6") == 60 + assert Voltage.to_heatpump("h") is None + class TestHours: """Test suite for Hours datatype""" @@ -875,6 +920,10 @@ def test_hours_to_heatpump(self): assert Hours.to_heatpump(1) == 10 assert Hours.to_heatpump(1.1) == 11 + assert Hours.to_heatpump(None) is None + assert Hours.to_heatpump("7") == 70 + assert Hours.to_heatpump("i") is None + class TestHours2: """Test suite for Hours2 datatype""" @@ -901,6 +950,10 @@ def test_hours2_to_heatpump(self): assert Hours2.to_heatpump(2) == 2 assert Hours2.to_heatpump(5) == 8 + assert Hours2.to_heatpump(None) is None + assert Hours2.to_heatpump("8") is None + assert Hours2.to_heatpump("i") is None + class TestMinutes: """Test suite for Minutes datatype""" @@ -950,6 +1003,24 @@ def test_init(self): assert a.datatype_unit is None +class TestVersion: + """Test suite for Version datatype""" + + def test_init(self): + """Test cases for initialization""" + + a = Version("ver") + assert a.name == "ver" + assert a.datatype_class == "version" + assert a.datatype_unit is None + + def test_from_heatpump(self): + + assert Version.from_heatpump([3, 1, 4]) == '\x03\x01\x04' + assert Version.from_heatpump(None) is None + assert Version.from_heatpump("a") is None + + class TestCharacter: """Test suite for Character datatype""" @@ -970,6 +1041,8 @@ def test_from_heatpump(self): assert Character.from_heatpump(56) == "8" assert Character.from_heatpump(48) == "0" + assert Character.from_heatpump(None) is None + class TestMajorMinorVersion: """Test suite for MajorMinorVersion datatype""" @@ -995,6 +1068,8 @@ def test_from_heatpump(self): assert MajorMinorVersion.from_heatpump(12) == "0.12" assert MajorMinorVersion.from_heatpump(-1) == "0" + assert MajorMinorVersion.from_heatpump(None) is None + class TestFullVersion: """Test suite for FullVersion datatype""" @@ -1009,9 +1084,10 @@ def test_init(self): def test_from_heatpump(self): """Test cases for from_heatpump function""" - assert FullVersion.from_heatpump(112) == "0" - assert FullVersion.from_heatpump(0) == "0" - assert FullVersion.from_heatpump([0, 12]) == "0" + assert FullVersion.from_heatpump(None) is None + assert FullVersion.from_heatpump(112) is None + assert FullVersion.from_heatpump(0) is None + assert FullVersion.from_heatpump([0, 12]) is None assert FullVersion.from_heatpump([0, 12, 3]) == "0.12.3" class TestIcon: @@ -1372,6 +1448,8 @@ def test_timeofday_conversion(self): """Test cases for from_heatpump function""" assert TimeOfDay.from_heatpump(None) is None + assert TimeOfDay.to_heatpump(None) is None + assert TimeOfDay.to_heatpump(1) is None check_pair(TimeOfDay, 7 * 3600 + 30 * 60, "7:30") check_pair(TimeOfDay, 7 * 3600 + 30 * 60 + 50, "7:30:50") @@ -1396,6 +1474,8 @@ def test_timeofday_conversion(self): """Test cases for from_heatpump function""" assert TimeOfDay2.from_heatpump(None) is None + assert TimeOfDay2.to_heatpump(None) is None + assert TimeOfDay2.to_heatpump(1) is None check_pair(TimeOfDay2, ((19 * 60) << 16) + 7 * 60 + 30, "7:30-19:00") check_pair(TimeOfDay2, ((19 * 60 + 30) << 16) + 5 * 60 + 23, "5:23-19:30") diff --git a/tests/test_socket_interaction.py b/tests/test_socket_interaction.py index bf0a1577..34e8ebdf 100644 --- a/tests/test_socket_interaction.py +++ b/tests/test_socket_interaction.py @@ -34,7 +34,7 @@ def check_data_vector(self, data_vector): fct = fake_calculation_value elif type(data_vector) is Visibilities: fct = fake_visibility_value - for d, f in data_vector.data.pairs(): + for d, f in data_vector.items(): # get raw data raw = [fct(idx) for idx in range(d.index, d.index + d.count)] temp_field = d.create_field() @@ -49,8 +49,8 @@ def clear_luxtronik_data(self, lux): self.clear_data_vector(lux.visibilities) def clear_data_vector(self, data_vector): - for idx, entry in data_vector: - entry.raw = 0 + for d, f in data_vector.items(): + f.raw = 0 def test_luxtronik_socket_interface(self): host = "my_heatpump" @@ -96,21 +96,29 @@ def test_luxtronik_socket_interface(self): # Finally, writing p = Parameters() - p.queue = {0: 100, 1: 200} + p[1].raw = 100 + p[1].write_pending = True + p[2].raw = 200 + p[2].write_pending = True lux.write(p) s = FakeSocket.last_instance - assert s.written_values[0] == 100 - assert s.written_values[1] == 200 - assert len(p.queue) == 0 + assert s.written_values[1] == 100 + assert s.written_values[2] == 200 + assert not p[1].write_pending + assert not p[2].write_pending p = Parameters() - p.queue = {2: 300, 3: "test"} + p[3].raw = 300 + p[3].write_pending = True + p[4].raw = "test" + p[4].write_pending = True d = lux.write_and_read(p) s = FakeSocket.last_instance - assert s.written_values[2] == 300 + assert s.written_values[3] == 300 # Make sure that the non-int value is not written: - assert 3 not in s.written_values - assert len(p.queue) == 0 + assert 4 not in s.written_values + assert not p[3].write_pending + assert not p[4].write_pending assert self.check_luxtronik_data(d) def test_luxtronik(self): @@ -141,16 +149,18 @@ def test_luxtronik(self): ########################## # Test the write routine # ########################## - lux.parameters.queue = {0: 500} + lux.parameters[1].raw = 500 + lux.parameters[1].write_pending = True lux.write() s = FakeSocket.last_instance - assert s.written_values[0] == 500 + assert s.written_values[1] == 500 p = Parameters() - p.queue = {1: 501} + p[2].raw = 501 + p[2].write_pending = True lux.write(p) s = FakeSocket.last_instance - assert s.written_values[1] == 501 + assert s.written_values[2] == 501 # lux.write() and lux.write(p) should not read: assert self.check_luxtronik_data(lux, False) @@ -158,22 +168,24 @@ def test_luxtronik(self): ################################### # Test the write_and_read routine # ################################### - lux.parameters.queue = {2: 502} + lux.parameters[3].raw = 502 + lux.parameters[3].write_pending = True lux.write_and_read() # Currently write_and_read triggers two separate connections/operations s = FakeSocket.prev_instance - assert s.written_values[2] == 502 + assert s.written_values[3] == 502 # Now, the values should be read assert self.check_luxtronik_data(lux) self.clear_luxtronik_data(lux) - p.queue = {3: 503} + p[4].raw = 503 + p[4].write_pending = True lux.write_and_read(p) # Currently write_and_read triggers two separate connections/operations s = FakeSocket.prev_instance - assert s.written_values[3] == 503 + assert s.written_values[4] == 503 # Now, the values should be read assert self.check_luxtronik_data(lux)