From e3b2b3e5994f4f8d28753175fa82e48049b5ca54 Mon Sep 17 00:00:00 2001 From: Guzz-T Date: Mon, 15 Sep 2025 23:22:15 +0200 Subject: [PATCH 1/4] Add new data-types used in the smart-home-interface --- luxtronik/datatypes.py | 99 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/luxtronik/datatypes.py b/luxtronik/datatypes.py index c7ee504..9561098 100755 --- a/luxtronik/datatypes.py +++ b/luxtronik/datatypes.py @@ -846,6 +846,105 @@ def to_heatpump(cls, value): return val +class HeatPumpState(SelectionBase): + """HeatPumpState datatype, converts from and to list of HeatPumpState codes.""" + + datatype_class = "selection" + + codes = { + 0: "Idle", # Heatpump is idle + 1: "Running", # Heatpump is running + } + +class ModeState(SelectionBase): + """ModeState datatype, converts from and to list of ModeState codes.""" + + datatype_class = "selection" + + codes = { + 0: "Disabled", # Heating / Hot water is disabled + 1: "No request", # Heating / Hot water currently not requested + 2: "Requested", # Heating / Hot water requested but currently not running + 3: "Running", # Heating / Hot water running + } + +class ControlMode(SelectionBase): + """ControlMode datatype, converts from and to list of ControlMode codes.""" + + datatype_class = "selection" + + codes = { + 0: "Off", # System value is used + 1: "Setpoint", # Setpoint register value is used + 2: "Offset", # System values + offset register value is used + 3: "Level", + } + + +class LpcMode(SelectionBase): + """LpcMode datatype, converts from and to list of LpcMode codes.""" + + datatype_class = "selection" + + codes = { + 0: "No-Limit", + 1: "Soft-Limit", + 2: "Hard-Limit", + } + + +class LockMode(SelectionBase): + """LockMode datatype, converts from and to list of LockMode codes.""" + + datatype_class = "selection" + + codes = { + 0: "Unlocked / Off", + 1: "Locked / On", + } + +class OnOffMode(SelectionBase): + """OnOffMode datatype, converts from and to list of OnOffMode codes.""" + + datatype_class = "selection" + + codes = { + 0: "Off", # Function deactivated + 1: "On", # Function activated + } + +class LevelMode(SelectionBase): + """LevelMode datatype, converts from and to list of LevelMode codes.""" + + datatype_class = "selection" + + codes = { + 0: "Normal", # No correction + 1: "Increased", # Increase the temperature by the values within the SHI-settings + 2: "Increased", # Increase the temperature by the values within the SHI-settings + 3: "Decreased", # Decrease the temperature by the values within the SHI-settings + } + +class PowerLimit(ScalingBase): + """PowerLimit datatype, converts from and to PowerLimit.""" + + datatype_class = "power" + datatype_unit = "kW" + scaling_factor = 0.1 + + +class FullVersion(Base): + """FullVersion datatype, converts from and to a RBEVersion""" + + datatype_class = "version" + + @classmethod + def from_heatpump(cls, value): + if isinstance(value, list) and len(value) >= 3: + return f"{value[0]}.{value[1]}.{value[2]}" + else: + return "0" + class Unknown(Base): """Unknown datatype, fallback for unknown data.""" From c33dc9358b7699a15fea687bae266f832182649c Mon Sep 17 00:00:00 2001 From: Guzz-T Date: Mon, 15 Sep 2025 23:24:11 +0200 Subject: [PATCH 2/4] Add smart-home-interface field definitions --- luxtronik/definitions/holdings.py | 394 ++++++++++++++ luxtronik/definitions/inputs.py | 843 ++++++++++++++++++++++++++++++ 2 files changed, 1237 insertions(+) create mode 100644 luxtronik/definitions/holdings.py create mode 100644 luxtronik/definitions/inputs.py diff --git a/luxtronik/definitions/holdings.py b/luxtronik/definitions/holdings.py new file mode 100644 index 0000000..665299f --- /dev/null +++ b/luxtronik/definitions/holdings.py @@ -0,0 +1,394 @@ +""" +Constant list containing the complete holdings definitions. +""" +from luxtronik.datatypes import ( + Celsius, + ControlMode, + Kelvin, + LevelMode, + LockMode, + LpcMode, + OnOffMode, + PowerLimit, +) + +HOLDINGS_DEFINITIONS_LIST = [ + { + "index": 0, + "count": 1, + "names": ["heating_mode"], + "type": ControlMode, + "writeable": True, + "since": "3.90.1", + "description": "Operating mode of the heating function", + }, + { + "index": 1, + "count": 1, + "names": ["heating_setpoint"], + "type": Celsius, + "writeable": True, + "range": {"min": 15, "max": 75}, + "since": "3.90.1", + "description": "Desired target temperature for heating in °C", + }, + { + "index": 2, + "count": 1, + "names": ["heating_offset"], + "type": Kelvin, + "writeable": True, + "range": {"min": 0, "max": 20}, + "since": "3.90.1", + "description": "Temperature correction in Kelvin for heating", + }, + { + "index": 3, + "count": 1, + "names": ["heating_level"], + "type": LevelMode, + "writeable": True, + "since": "3.92.0", + "description": "Increase or decrease the temperature by the SHI-offsets-setting", + }, + { + "index": 5, + "count": 1, + "names": ["hot_water_mode"], + "type": ControlMode, + "writeable": True, + "since": "3.90.1", + "description": "Operating mode of the hot water system", + }, + { + "index": 6, + "count": 1, + "names": ["hot_water_setpoint"], + "type": Celsius, + "writeable": True, + "range": {"min": 30, "max": 75}, + "since": "3.90.1", + "description": "Target temperature for hot water in °C", + }, + { + "index": 7, + "count": 1, + "names": ["hot_water_offset"], + "type": Kelvin, + "writeable": True, + "range": {"min": 0, "max": 20}, + "since": "3.90.1", + "description": "Temperature correction in Kelvin for hot water", + }, + { + "index": 8, + "count": 1, + "names": ["hot_water_level"], + "type": LevelMode, + "writeable": True, + "since": "3.92.0", + "description": "Increase or decrease the temperature by the SHI-offsets-setting", + }, + { + "index": 10, + "count": 1, + "names": ["MK1_heat_mode"], + "type": ControlMode, + "writeable": True, + "since": "3.90.1", + "description": "Operating mode for heating circuit 1", + }, + { + "index": 11, + "count": 1, + "names": ["MK1_heat_setpoint"], + "type": Celsius, + "writeable": True, + "range": {"min": 20, "max": 65}, + "since": "3.90.1", + "description": "Target temperature for heating circuit 1 in °C", + }, + { + "index": 12, + "count": 1, + "names": ["MK1_heat_offset"], + "type": Kelvin, + "writeable": True, + "range": {"min": 0, "max": 5}, + "since": "3.90.1", + "description": "Temperature correction in Kelvin for heating circuit 1", + }, + { + "index": 13, + "count": 1, + "names": ["MK1_heat_level"], + "type": LevelMode, + "writeable": True, + "since": "3.92.0", + "description": "Increase or decrease the temperature by the SHI-offsets-setting", + }, + { + "index": 15, + "count": 1, + "names": ["MK1_cool_mode"], + "type": ControlMode, + "writeable": True, + "since": "3.90.1", + "description": "Operating mode for cooling circuit 1", + }, + { + "index": 16, + "count": 1, + "names": ["MK1_cool_setpoint"], + "type": Celsius, + "writeable": True, + "range": {"min": 5, "max": 25}, + "since": "3.90.1", + "description": "Target temperature for cooling circuit 1 in °C", + }, + { + "index": 17, + "count": 1, + "names": ["MK1_cool_offset"], + "type": Kelvin, + "writeable": True, + "range": {"min": 0, "max": 5}, + "since": "3.90.1", + "description": "Temperature correction in Kelvin for cooling circuit 1", + }, + { + "index": 20, + "count": 1, + "names": ["MK2_heat_mode"], + "type": ControlMode, + "writeable": True, + "since": "3.90.1", + "description": "Operating mode for heating circuit 2", + }, + { + "index": 21, + "count": 1, + "names": ["MK2_heat_setpoint"], + "type": Celsius, + "writeable": True, + "range": {"min": 20, "max": 65}, + "since": "3.90.1", + "description": "Target temperature for heating circuit 2 in °C", + }, + { + "index": 22, + "count": 1, + "names": ["MK2_heat_offset"], + "type": Kelvin, + "writeable": True, + "range": {"min": 0, "max": 5}, + "since": "3.90.1", + "description": "Temperature correction in Kelvin for heating circuit 2", + }, + { + "index": 23, + "count": 1, + "names": ["MK2_heat_level"], + "type": LevelMode, + "writeable": True, + "since": "3.92.0", + "description": "Increase or decrease the temperature by the SHI-offsets-setting", + }, + { + "index": 25, + "count": 1, + "names": ["MK2_cool_mode"], + "type": ControlMode, + "writeable": True, + "since": "3.90.1", + "description": "Operating mode for cooling circuit 2", + }, + { + "index": 26, + "count": 1, + "names": ["MK2_cool_setpoint"], + "type": Celsius, + "writeable": True, + "range": {"min": 5, "max": 25}, + "since": "3.90.1", + "description": "Target temperature for cooling circuit 2 in °C", + }, + { + "index": 27, + "count": 1, + "names": ["MK2_cool_offset"], + "type": Kelvin, + "writeable": True, + "range": {"min": 0, "max": 5}, + "since": "3.90.1", + "description": "Temperature correction in Kelvin for cooling circuit 2", + }, + { + "index": 30, + "count": 1, + "names": ["MK3_heat_mode"], + "type": ControlMode, + "writeable": True, + "since": "3.90.1", + "description": "Operating mode for heating circuit 3", + }, + { + "index": 31, + "count": 1, + "names": ["MK3_heat_setpoint"], + "type": Celsius, + "writeable": True, + "range": {"min": 20, "max": 65}, + "since": "3.90.1", + "description": "Target temperature for heating circuit 3 in °C", + }, + { + "index": 32, + "count": 1, + "names": ["MK3_heat_offset"], + "type": Kelvin, + "writeable": True, + "range": {"min": 0, "max": 5}, + "since": "3.90.1", + "description": "Temperature correction in Kelvin for heating circuit 3", + }, + { + "index": 33, + "count": 1, + "names": ["MK3_heat_level"], + "type": LevelMode, + "writeable": True, + "since": "3.92.0", + "description": "Increase or decrease the temperature by the SHI-offsets-setting", + }, + { + "index": 35, + "count": 1, + "names": ["MK3_cool_mode"], + "type": ControlMode, + "writeable": True, + "since": "3.90.1", + "description": "Operating mode for cooling circuit 3", + }, + { + "index": 36, + "count": 1, + "names": ["MK3_cool_setpoint"], + "type": Celsius, + "writeable": True, + "range": {"min": 5, "max": 25}, + "since": "3.90.1", + "description": "Target temperature for cooling circuit 3 in °C", + }, + { + "index": 37, + "count": 1, + "names": ["MK3_cool_offset"], + "type": Kelvin, + "writeable": True, + "range": {"min": 0, "max": 5}, + "since": "3.90.1", + "description": "Temperature correction in Kelvin for cooling circuit 3", + }, + { + "index": 40, + "count": 1, + "names": ["LPC_mode"], + "type": LpcMode, + "writeable": True, + "since": "3.90.1", + "description": "Operating mode of the load power control", + }, + { + "index": 41, + "count": 1, + "names": ["PC_limit"], + "type": PowerLimit, + "writeable": True, + "range": {"min": 0, "max": 30}, + "since": "3.90.1", + "description": "Maximum power limit", + }, + { + "index": 50, + "count": 1, + "names": ["lock_heating"], + "type": LockMode, + "writeable": True, + "since": "3.92.0", + "description": "Lock state for heating", + }, + { + "index": 51, + "count": 1, + "names": ["lock_hot_water"], + "type": LockMode, + "writeable": True, + "since": "3.92.0", + "description": "Lock state for hot water", + }, + { + "index": 52, + "count": 1, + "names": ["lock_cooling"], + "type": LockMode, + "writeable": True, + "since": "3.90.1", + "description": "Lock state for cooling", + }, + { + "index": 53, + "count": 1, + "names": ["lock_swimming_pool"], + "type": LockMode, + "writeable": True, + "since": "3.90.1", + "description": "Lock state for the swimming pool function", + }, + { + "index": 65, + "count": 1, + "names": ["heat_overall_mode"], + "type": ControlMode, + "writeable": True, + "since": "3.92.0", + "description": "Operating mode of all heating functions (no setpoint available)", + }, + { + "index": 66, + "count": 1, + "names": ["heat_overall_offset"], + "type": Kelvin, + "writeable": True, + "range": {"min": 0, "max": 20}, + "since": "3.92.0", + "description": "Temperature correction in Kelvin for all heating functions", + }, + { + "index": 67, + "count": 1, + "names": ["heat_overall_level"], + "type": LevelMode, + "writeable": True, + "since": "3.92.0", + "description": "Increase or decrease all temperatures by the SHI-offsets-setting", + }, + { + "index": 70, + "count": 1, + "names": ["circulation"], + "type": OnOffMode, + "writeable": True, + "since": "3.92.0", + "description": "When set to ON, the circulation pump is activated, but only if no time schedule is configured for it.", + }, + { + "index": 71, + "count": 1, + "names": ["hot_water_extra"], + "type": OnOffMode, + "writeable": True, + "since": "3.92.0", + "description": "When set to ON, the hot water heating is activated and will run until the maximum temperature is reached.", + }, +] diff --git a/luxtronik/definitions/inputs.py b/luxtronik/definitions/inputs.py new file mode 100644 index 0000000..c23cac5 --- /dev/null +++ b/luxtronik/definitions/inputs.py @@ -0,0 +1,843 @@ +""" +Constant list containing the complete inputs definitions. +""" +from luxtronik.datatypes import ( + Celsius, + Energy, + FullVersion, + HeatPumpState, + ModeState, + OperationMode, + Unknown, +) + +INPUTS_DEFINITIONS_LIST = [ + { + "index": 0, + "count": 1, + "names": ["Heatpump_state"], + "type": HeatPumpState, + "writeable": False, + "since": "3.90.1", + "description": "Current operating state of the heat pump", + }, + { + "index": 2, + "count": 1, + "names": ["Operation_mode"], + "type": OperationMode, + "writeable": False, + "since": "3.90.1", + "description": "Overall operation mode of the system", + }, + { + "index": 3, + "count": 1, + "names": ["Heating_state"], + "type": ModeState, + "writeable": False, + "since": "3.90.1", + "description": "Current state of the heating function", + }, + { + "index": 4, + "count": 1, + "names": ["Hot_water_state"], + "type": ModeState, + "writeable": False, + "since": "3.90.1", + "description": "Current state of the hot water function", + }, + { + "index": 6, + "count": 1, + "names": ["Unknown_Input_6"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 7, + "count": 1, + "names": ["Unknown_Input_7"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 100, + "count": 1, + "names": ["TRL"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Current return line temperature", + }, + { + "index": 101, + "count": 1, + "names": ["TRL_target"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Target return line temperature", + }, + { + "index": 102, + "count": 1, + "names": ["TRL_ext"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "External return line temperature sensor reading", + }, + { + "index": 103, + "count": 1, + "names": ["TRL_limit"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Maximum allowed return line temperature", + }, + { + "index": 104, + "count": 1, + "names": ["TRL_min_target"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Minimum target return line temperature", + }, + { + "index": 105, + "count": 1, + "names": ["TVL"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Current flow line temperature", + }, + { + "index": 106, + "count": 1, + "names": ["Unknown_Input_106"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 107, + "count": 1, + "names": ["Inside_temp"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Measured indoor temperature", + }, + { + "index": 108, + "count": 1, + "names": ["Outside_temp"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Measured outdoor temperature", + }, + { + "index": 109, + "count": 1, + "names": ["Unknown_Input_109"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 110, + "count": 1, + "names": ["Unknown_Input_110"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 111, + "count": 1, + "names": ["Unknown_Input_111"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 112, + "count": 1, + "names": ["Unknown_Input_112"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 113, + "count": 1, + "names": ["Unknown_Input_113"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 120, + "count": 1, + "names": ["Hot_water_temp"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Current hot water temperature", + }, + { + "index": 121, + "count": 1, + "names": ["Hot_water_target"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Target hot water temperature", + }, + { + "index": 122, + "count": 1, + "names": ["Hot_water_min"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Minimum hot water temperature", + }, + { + "index": 123, + "count": 1, + "names": ["Hot_water_max"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Maximum hot water temperature", + }, + { + "index": 124, + "count": 1, + "names": ["Unknown_Input_124"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – possibly hot water idle/running indicator", + }, + { + "index": 140, + "count": 1, + "names": ["MK1_heat_temp"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Current heating circuit 1 temperature", + }, + { + "index": 141, + "count": 1, + "names": ["MK1_heat_target"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Target heating circuit 1 temperature", + }, + { + "index": 142, + "count": 1, + "names": ["MK1_heat_min"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Minimum heating circuit 1 temperature", + }, + { + "index": 143, + "count": 1, + "names": ["MK1_heat_max"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Maximum heating circuit 1 temperature", + }, + { + "index": 150, + "count": 1, + "names": ["MK2_heat_temp"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Current heating circuit 2 temperature", + }, + { + "index": 151, + "count": 1, + "names": ["MK2_heat_target"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Target heating circuit 2 temperature", + }, + { + "index": 152, + "count": 1, + "names": ["MK2_heat_min"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Minimum heating circuit 2 temperature", + }, + { + "index": 153, + "count": 1, + "names": ["MK2_heat_max"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Maximum heating circuit 2 temperature", + }, + { + "index": 160, + "count": 1, + "names": ["MK3_heat_temp"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Current heating circuit 3 temperature", + }, + { + "index": 161, + "count": 1, + "names": ["MK3_heat_target"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Target heating circuit 3 temperature", + }, + { + "index": 162, + "count": 1, + "names": ["MK3_heat_min"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Minimum heating circuit 3 temperature", + }, + { + "index": 163, + "count": 1, + "names": ["MK3_heat_max"], + "type": Celsius, + "writeable": False, + "since": "3.90.1", + "description": "Maximum heating circuit 3 temperature", + }, + { + "index": 201, + "count": 1, + "names": ["Unknown_Input_201"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 202, + "count": 1, + "names": ["Unknown_Input_202"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 203, + "count": 1, + "names": ["Unknown_Input_203"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 204, + "count": 1, + "names": ["Unknown_Input_204"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 205, + "count": 1, + "names": ["Unknown_Input_205"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 206, + "count": 1, + "names": ["Unknown_Input_206"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 207, + "count": 1, + "names": ["Unknown_Input_207"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 300, + "count": 1, + "names": ["Unknown_Input_300"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 301, + "count": 1, + "names": ["Unknown_Input_301"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 302, + "count": 1, + "names": ["Unknown_Input_302"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 310, + "count": 1, + "names": ["Unknown_Input_310"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 311, + "count": 1, + "names": ["Total_power_consumption"], + "type": Energy, + "writeable": False, + "since": "3.90.1", + "description": "Total electrical energy consumption", + }, + { + "index": 312, + "count": 1, + "names": ["Unknown_Input_312"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 313, + "count": 1, + "names": ["Heat_power_consumption"], + "type": Energy, + "writeable": False, + "since": "3.90.1", + "description": "Electrical energy consumption for heating", + }, + { + "index": 314, + "count": 1, + "names": ["Unknown_Input_314"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 315, + "count": 1, + "names": ["Hot_water_power_consumption"], + "type": Energy, + "writeable": False, + "since": "3.90.1", + "description": "Electrical energy consumption for hot water", + }, + { + "index": 316, + "count": 1, + "names": ["Unknown_Input_316"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 317, + "count": 1, + "names": ["Unknown_Input_317"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 318, + "count": 1, + "names": ["Unknown_Input_318"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 319, + "count": 1, + "names": ["Unknown_Input_319"], + "type": Unknown, + "writeable": False, + "since": "3.90.1", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 320, + "count": 1, + "names": ["Unknown_Input_320"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 321, + "count": 1, + "names": ["Unknown_Input_321"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 322, + "count": 1, + "names": ["Unknown_Input_322"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 323, + "count": 1, + "names": ["Unknown_Input_323"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 324, + "count": 1, + "names": ["Unknown_Input_324"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 325, + "count": 1, + "names": ["Unknown_Input_325"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 326, + "count": 1, + "names": ["Unknown_Input_326"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 327, + "count": 1, + "names": ["Unknown_Input_327"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 328, + "count": 1, + "names": ["Unknown_Input_328"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 329, + "count": 1, + "names": ["Unknown_Input_329"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 350, + "count": 1, + "names": ["Unknown_Input_350"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 351, + "count": 1, + "names": ["Unknown_Input_351"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 352, + "count": 1, + "names": ["Unknown_Input_352"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 353, + "count": 1, + "names": ["Unknown_Input_353"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 354, + "count": 1, + "names": ["Unknown_Input_354"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 355, + "count": 1, + "names": ["Unknown_Input_355"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 356, + "count": 1, + "names": ["Unknown_Input_356"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 360, + "count": 1, + "names": ["Unknown_Input_360"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 361, + "count": 1, + "names": ["Unknown_Input_361"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 400, + "count": 3, + "names": ["Version"], + "type": FullVersion, + "writeable": False, + "since": "3.90.1", + "description": "Full firmware version information", + }, + { + "index": 404, + "count": 1, + "names": ["Unknown_Input_404"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 405, + "count": 1, + "names": ["Unknown_Input_405"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 406, + "count": 1, + "names": ["Unknown_Input_406"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 407, + "count": 1, + "names": ["Unknown_Input_407"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 408, + "count": 1, + "names": ["Unknown_Input_408"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 409, + "count": 1, + "names": ["Unknown_Input_409"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 410, + "count": 1, + "names": ["Unknown_Input_410"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 411, + "count": 1, + "names": ["Unknown_Input_411"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 412, + "count": 1, + "names": ["Unknown_Input_412"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 413, + "count": 1, + "names": ["Unknown_Input_413"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 416, + "count": 1, + "names": ["Unknown_Input_416"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 417, + "count": 1, + "names": ["Unknown_Input_417"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 500, + "count": 1, + "names": ["Unknown_Input_500"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 501, + "count": 1, + "names": ["Unknown_Input_501"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, + { + "index": 502, + "count": 1, + "names": ["Unknown_Input_502"], + "type": Unknown, + "writeable": False, + "since": "3.92.0", + "description": "TODO: Function unknown – requires further analysis", + }, +] From f8a11e335b68ec12140b5399cdfbd5aba9f7a385 Mon Sep 17 00:00:00 2001 From: Guzz-T Date: Mon, 15 Sep 2025 23:43:38 +0200 Subject: [PATCH 3/4] Add tests for new data types --- tests/test_datatypes.py | 46 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/test_datatypes.py b/tests/test_datatypes.py index 2643c36..b309ab7 100644 --- a/tests/test_datatypes.py +++ b/tests/test_datatypes.py @@ -21,6 +21,7 @@ Percent2, Speed, Power, + PowerLimit, Energy, Voltage, Hours, @@ -31,6 +32,7 @@ Count, Character, MajorMinorVersion, + FullVersion, Icon, HeatingMode, CoolingMode, @@ -589,6 +591,32 @@ def test_init(self): assert a.datatype_class == "power" assert a.datatype_unit == "W" +class TestPowerLimit: + """Test suite for PowerLimit datatype""" + + def test_init(self): + """Test cases for initialization""" + + a = PowerLimit("power_limit") + assert a.name == "power_limit" + assert a.datatype_class == "power" + assert a.datatype_unit == "kW" + + def test_from_heatpump(self): + """Test cases for from_heatpump function""" + + a = PowerLimit("") + assert a.from_heatpump(15) == 1.5 + assert a.from_heatpump(525) == 52.5 + assert a.from_heatpump(None) is None + + def test_to_heatpump(self): + """Test cases for to_heatpump function""" + + a = PowerLimit("") + assert a.to_heatpump(1.5) == 15 + assert a.to_heatpump(5.6) == 56 + class TestEnergy: """Test suite for Energy datatype""" @@ -787,6 +815,24 @@ def test_from_heatpump(self): assert MajorMinorVersion.from_heatpump(12) == "0.12" assert MajorMinorVersion.from_heatpump(-1) == "0" +class TestFullVersion: + """Test suite for FullVersion datatype""" + + def test_init(self): + """Test cases for initialization""" + + a = FullVersion("full_version") + assert a.name == "full_version" + assert a.datatype_class == "version" + assert a.datatype_unit is None + + 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([0, 12, 3]) == "0.12.3" class TestIcon: """Test suite for Icon datatype""" From 49e75eb3fd2e00c6c4066024e18cbf7169d75af2 Mon Sep 17 00:00:00 2001 From: Guzz-T Date: Mon, 22 Sep 2025 21:58:41 +0200 Subject: [PATCH 4/4] Refine some smart-home-interface comments and descriptions --- luxtronik/datatypes.py | 25 ++++++++++++++++--------- luxtronik/definitions/holdings.py | 7 ++++++- luxtronik/definitions/inputs.py | 7 ++++++- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/luxtronik/datatypes.py b/luxtronik/datatypes.py index 9561098..501012f 100755 --- a/luxtronik/datatypes.py +++ b/luxtronik/datatypes.py @@ -877,7 +877,8 @@ class ControlMode(SelectionBase): 0: "Off", # System value is used 1: "Setpoint", # Setpoint register value is used 2: "Offset", # System values + offset register value is used - 3: "Level", + 3: "Level", # System values + smart-home-interface-settings + # register value is used } @@ -887,9 +888,9 @@ class LpcMode(SelectionBase): datatype_class = "selection" codes = { - 0: "No-Limit", - 1: "Soft-Limit", - 2: "Hard-Limit", + 0: "No limit", + 1: "Soft limit", + 2: "Hard limit", } @@ -899,8 +900,8 @@ class LockMode(SelectionBase): datatype_class = "selection" codes = { - 0: "Unlocked / Off", - 1: "Locked / On", + 0: "Off", # Function is not locked + 1: "On", # Function is locked } class OnOffMode(SelectionBase): @@ -920,9 +921,15 @@ class LevelMode(SelectionBase): codes = { 0: "Normal", # No correction - 1: "Increased", # Increase the temperature by the values within the SHI-settings - 2: "Increased", # Increase the temperature by the values within the SHI-settings - 3: "Decreased", # Decrease the temperature by the values within the SHI-settings + 1: "Increased", # Increase the temperature by the values + # within the smart-home-interface-settings + # TODO: Function unknown – requires further analysis + 2: "Increased2", # Increase the temperature by the values + # within the smart-home-interface-settings + # TODO: Function unknown – requires further analysis + 3: "Decreased", # Decrease the temperature by the values + # within the smart-home-interface-settings + # TODO: Function unknown – requires further analysis } class PowerLimit(ScalingBase): diff --git a/luxtronik/definitions/holdings.py b/luxtronik/definitions/holdings.py index 665299f..08bc2be 100644 --- a/luxtronik/definitions/holdings.py +++ b/luxtronik/definitions/holdings.py @@ -1,5 +1,10 @@ """ -Constant list containing the complete holdings definitions. +Constant list containing all 'holdings' definitions +used by the Smart Home Interface (SHI) of the Luxtronik controller. + +Unlike the setting registers, these SHI register are volatile and intended for +communication with smart home systems. 'Holding' registers are readable +and writable and are used to control the heat pump externally. """ from luxtronik.datatypes import ( Celsius, diff --git a/luxtronik/definitions/inputs.py b/luxtronik/definitions/inputs.py index c23cac5..b61e62e 100644 --- a/luxtronik/definitions/inputs.py +++ b/luxtronik/definitions/inputs.py @@ -1,5 +1,10 @@ """ -Constant list containing the complete inputs definitions. +Constant list containing all 'inputs' definitions +used by the Smart Home Interface (SHI) of the Luxtronik controller. + +Unlike the setting registers, these SHI register are volatile and intended for +communication with smart home systems. 'Input' register are read-only +and are used for display or to control other devices. """ from luxtronik.datatypes import ( Celsius,