diff --git a/README.md b/README.md index 9fe3e2b..25a360d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,29 @@ -# python-thermia-online-api -A Python API for Thermia heat pumps using https://online.thermia.se +# Thermia Online API +### A Python API for Thermia heat pumps using https://online.thermia.se + +## Available properties within ThermiaWaterHeater class: +| Property | Description | +| --- | --- | +| `name` | Name of the Water Heater | +| `id` | Unique ID of the Water Heater Thermia generates | +| `is_online` | Boolean value indicating if the Water Heater is online or not | +| `last_online` | DateTime string indicating the last time the Water Heater was online | +| `has_indoor_temperature_sensor` | Boolean value indicating if the Water Heater has an indoor temperature sensor | +| `indoor_temperature` | Indoor temperature in Celsius, if `has_indoor_temperature_sensor` is False, this value is the same as `heat_temperature` | +| `is_outdoor_temp_sensor_functioning` | Boolean value indicating if the Water Heater has an outdoor temperature sensor | +| `outdoor_temperature` | Outdoor temperature in Celsius | +| `is_hot_water_active` | Boolean value indicating if the Water Heater is heating water | +| `hot_water_temperature` | Hot water temperature in Celsius | +| `heat_temperature` | Water Pump heating target temperature in Celsius | +| `heat_min_temperature_value` | Minimum temperature value possible for Water Heater to set | +| `heat_max_temperature_value` | Maximum temperature value possible for Water Heater to set | +| `heat_temperature_step` | Step value for temperature setting | +| `operation_mode` | Current operation mode of the Water Heater | +| `available_operation_modes` | List of available operation modes for the Water Heater | + +## Available functions within ThermiaWaterHeater class: +| Function | Description | +| --- | --- | +| `refetch_data` | Refetch all data from Thermia for Water Heater | +| `set_temperature` | Set the target temperature for the Water Heater | +| `set_operation_mode` | Set the operation mode for the Water Heater | \ No newline at end of file diff --git a/ThermiaOnlineAPI/api/ThermiaAPI.py b/ThermiaOnlineAPI/api/ThermiaAPI.py index 9345923..e09ca96 100644 --- a/ThermiaOnlineAPI/api/ThermiaAPI.py +++ b/ThermiaOnlineAPI/api/ThermiaAPI.py @@ -10,9 +10,9 @@ THERMIA_API_CONFIG_URL = "https://online.thermia.se/api/configuration" -SET_REGISTER_VALUES = { - "set_temperature": 50, - "set_operation_mode": 51, +REGISTER_VALUES = { + "temperature": 50, + "operation_mode": 51, } class ThermiaAPI(): @@ -32,7 +32,7 @@ def get_devices(self): request = requests.get(url, headers=DEFAULT_REQUEST_HEADERS) status = request.status_code LOGGER.info("Fetching devices. " + str(status)) - + if status != 200: LOGGER.error("Error fetching devices. " + str(status)) return [] @@ -65,6 +65,28 @@ def get_device_status(self, device): return request.json() + def get_temperature_status(self, device): + self.__check_token_validity() + + url = self.configuration['apiBaseUrl'] + "/api/v1/Registers/Installations/" + str(device['id']) + "/Groups/REG_GROUP_TEMPERATURES" + request = requests.get(url, headers=DEFAULT_REQUEST_HEADERS) + status = request.status_code + + if status != 200: + LOGGER.error("Error in getting device's operation mode. " + str(status)) + return None + + data = [d for d in request.json() if d['registerIndex'] == REGISTER_VALUES['temperature']] + + if len(data) == 0: + return None + + return { + "minValue": data[0]['minValue'], + "maxValue": data[0]['maxValue'], + "step": data[0]['step'], + } + def get_operation_mode(self, device): self.__check_token_validity() @@ -76,10 +98,13 @@ def get_operation_mode(self, device): LOGGER.error("Error in getting device's operation mode. " + str(status)) return None - data = request.json()[0] + data = [d for d in request.json() if d['registerIndex'] == REGISTER_VALUES['operation_mode']] + + if len(data) == 0: + return None - current_operation_mode = int(data.get("registerValue")) - operation_modes_data = data.get("valueNames") + current_operation_mode = int(data[0].get("registerValue")) + operation_modes_data = data[0].get("valueNames") if operation_modes_data is not None: operation_modes = list(map(lambda values: values.get("name").split("REG_VALUE_OPERATION_MODE_")[1], operation_modes_data)) @@ -91,13 +116,13 @@ def get_operation_mode(self, device): return None def set_temperature(self, device: ThermiaWaterHeater, temperature): - self.__set_register_value(device, SET_REGISTER_VALUES["set_temperature"], temperature) + self.__set_register_value(device, REGISTER_VALUES["temperature"], temperature) def set_operation_mode(self, device: ThermiaWaterHeater, mode): operation_mode_int = device.available_operation_modes.index(mode) - self.__set_register_value(device, SET_REGISTER_VALUES["set_operation_mode"], operation_mode_int) + self.__set_register_value(device, REGISTER_VALUES["operation_mode"], operation_mode_int) - def __set_register_value(self, device: ThermiaWaterHeater, register_index: SET_REGISTER_VALUES, register_value: int): + def __set_register_value(self, device: ThermiaWaterHeater, register_index: REGISTER_VALUES, register_value: int): self.__check_token_validity() url = self.configuration['apiBaseUrl'] + "/api/v1/Registers/Installations/" + str(device.id) + "/Registers" diff --git a/ThermiaOnlineAPI/model/WaterHeater.py b/ThermiaOnlineAPI/model/WaterHeater.py index 6b8b549..dcc2888 100644 --- a/ThermiaOnlineAPI/model/WaterHeater.py +++ b/ThermiaOnlineAPI/model/WaterHeater.py @@ -14,6 +14,7 @@ def __init__(self, device_data: json, api_interface: "ThermiaAPI"): self.__api_interface = api_interface self.__info = None self.__status = None + self.__temperature_state = None self.__operation_mode_state = None self.refetch_data() @@ -21,16 +22,19 @@ def __init__(self, device_data: json, api_interface: "ThermiaAPI"): def refetch_data(self): self.__info = self.__api_interface.get_device_info(self.__device_data) self.__status = self.__api_interface.get_device_status(self.__device_data) + self.__temperature_state = self.__api_interface.get_temperature_status(self.__device_data) self.__operation_mode_state = self.__api_interface.get_operation_mode(self.__device_data) def set_temperature(self, temperature: int): LOGGER.info("Setting temperature to " + str(temperature)) self.__api_interface.set_temperature(self, temperature) + self.__status["heatingEffect"] = temperature # update local state before refetching data self.refetch_data() def set_operation_mode(self, mode: str): LOGGER.info("Setting operation mode to " + str(mode)) self.__api_interface.set_operation_mode(self, mode) + self.__operation_mode_state["current"] = mode # update local state before refetching data self.refetch_data() @property @@ -77,6 +81,18 @@ def hot_water_temperature(self): def heat_temperature(self): return self.__status.get("heatingEffect") + @property + def heat_min_temperature_value(self): + return self.__temperature_state.get("minValue") + + @property + def heat_max_temperature_value(self): + return self.__temperature_state.get("maxValue") + + @property + def heat_temperature_step(self): + return self.__temperature_state.get("step") + @property def operation_mode(self): return self.__operation_mode_state["current"] diff --git a/example.py b/example.py index d16eeac..d9d42ca 100644 --- a/example.py +++ b/example.py @@ -20,9 +20,14 @@ print("Is Hot Water Active: " + str(water_heater.is_hot_water_active)) print("Hot Water Temperature: " + str(water_heater.hot_water_temperature)) print("Heat Temperature: " + str(water_heater.heat_temperature)) +print("Heat Min Temperature Value: " + str(water_heater.heat_min_temperature_value)) +print("Heat Max Temperature Value: " + str(water_heater.heat_max_temperature_value)) +print("Heat Temperature Step: " + str(water_heater.heat_temperature_step)) print("Operation Mode: " + str(water_heater.operation_mode)) print("Available Operation Modes: " + str(water_heater.available_operation_modes)) +print("\n") + water_heater.set_temperature(19) water_heater.set_operation_mode("COMPRESSOR") diff --git a/setup.py b/setup.py index 2583e89..2c056e4 100644 --- a/setup.py +++ b/setup.py @@ -1,11 +1,18 @@ from distutils.core import setup +from pathlib import Path + +# read the contents of your README file +current_directory = Path(__file__).parent +long_description = (current_directory / "README.md").read_text() setup( name='ThermiaOnlineAPI', packages=['ThermiaOnlineAPI', 'ThermiaOnlineAPI.api', 'ThermiaOnlineAPI.model'], - version='1.3', + version='1.4', license='GPL-3.0', description='A Python API for Thermia heat pumps using https://online.thermia.se', + long_description=long_description, + long_description_content_type='text/markdown', author='Krisjanis Lejejs', author_email='krisjanis.lejejs@gmail.com', url='https://github.com/klejejs/python-thermia-online-api',