????JFIF??x?x????'
Server IP : 79.136.114.73 / Your IP : 216.73.216.227 Web Server : Apache/2.4.7 (Ubuntu) PHP/5.5.9-1ubuntu4.29 OpenSSL/1.0.1f System : Linux b8009 3.13.0-170-generic #220-Ubuntu SMP Thu May 9 12:40:49 UTC 2019 x86_64 User : www-data ( 33) PHP Version : 5.5.9-1ubuntu4.29 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /home/b8009/thermia/ThermiaOnlineAPI-2.17/ThermiaOnlineAPI/api/ |
Upload File : |
import logging from collections import ChainMap from datetime import datetime import requests from ThermiaOnlineAPI.const import ( REG_GROUP_HOT_WATER, REG_GROUP_OPERATIONAL_OPERATION, REG_GROUP_OPERATIONAL_STATUS, REG_GROUP_OPERATIONAL_TIME, REG_GROUP_TEMPERATURES, REGISTER_GROUPS, THERMIA_API_CONFIG_URLS_BY_API_TYPE, THERMIA_INSTALLATION_PATH, ) from ..exceptions.AuthenticationException import AuthenticationException from ..exceptions.NetworkException import NetworkException from ..model.HeatPump import ThermiaHeatPump _LOGGER = logging.getLogger(__name__) class ThermiaAPI: def __init__(self, email, password, api_type): self.__email = email self.__password = password self.__token = None self.__token_valid_to = None self.__default_request_headers = { "Authorization": "Bearer ", "Content-Type": "application/json", } if api_type not in THERMIA_API_CONFIG_URLS_BY_API_TYPE: raise ValueError("Unknown device type: " + api_type) self.__api_config_url = THERMIA_API_CONFIG_URLS_BY_API_TYPE[api_type] self.configuration = self.__fetch_configuration() self.authenticated = self.__authenticate() def get_devices(self): self.__check_token_validity() url = self.configuration["apiBaseUrl"] + "/api/v1/InstallationsInfo/own" request = requests.get(url, headers=self.__default_request_headers) status = request.status_code if status != 200: _LOGGER.error("Error fetching devices. " + str(status)) return [] return request.json() def get_device_by_id(self, device_id: str): self.__check_token_validity() devices = self.get_devices() device = [d for d in devices if str(d["id"]) == device_id] if len(device) != 1: _LOGGER.error("Error getting device by id: " + str(device_id)) return None return device[0] def get_device_info(self, device_id: str): self.__check_token_validity() url = self.configuration["apiBaseUrl"] + "/api/v1/installations/" + device_id request = requests.get(url, headers=self.__default_request_headers) status = request.status_code if status != 200: _LOGGER.error("Error fetching device info. " + str(status)) return None return request.json() def get_device_status(self, device_id: str): self.__check_token_validity() url = ( self.configuration["apiBaseUrl"] + "/api/v1/installationstatus/" + device_id + "/status" ) request = requests.get(url, headers=self.__default_request_headers) status = request.status_code if status != 200: _LOGGER.error("Error fetching device status. " + str(status)) return None return request.json() def get_all_alarms(self, device_id: str): self.__check_token_validity() url = ( self.configuration["apiBaseUrl"] + "/api/v1/installation/" + str(device_id) + "/events?onlyActiveAlarms=false" ) request = requests.get(url, headers=self.__default_request_headers) status = request.status_code if status != 200: _LOGGER.error("Error in getting device's alarms. " + str(status)) return None return request.json() def get_historical_data_registers(self, device_id: str): self.__check_token_validity() url = ( self.configuration["apiBaseUrl"] + "/api/v1/DataHistory/installation/" + str(device_id) ) request = requests.get(url, headers=self.__default_request_headers) status = request.status_code if status != 200: _LOGGER.error("Error in historical data registers. " + str(status)) return None return request.json() def get_historical_data( self, device_id: str, register_id, start_date_str, end_date_str ): self.__check_token_validity() url = ( self.configuration["apiBaseUrl"] + "/api/v1/datahistory/installation/" + str(device_id) + "/register/" + str(register_id) + "/minute?periodStart=" + start_date_str + "&periodEnd=" + end_date_str ) request = requests.get(url, headers=self.__default_request_headers) status = request.status_code if status != 200: _LOGGER.error( "Error in historical data for specific register. " + str(status) ) return None return request.json() def get__group_temperatures(self, device_id: str): return self.__get_register_group(device_id, REG_GROUP_TEMPERATURES) def get__group_operational_status(self, device_id: str): register_data = self.__get_register_group( device_id, REG_GROUP_OPERATIONAL_STATUS ) data = [ d for d in register_data if d["registerName"] == "REG_OPERATIONAL_STATUS_PRIO1" ] if len(data) != 1: # Operation operational status not supported return None data = data[0] current_operation_mode_value = int(data.get("registerValue")) operation_modes_data = data.get("valueNames") if operation_modes_data is not None: operation_modes_map = map( lambda values: { values.get("value"): values.get("name").split("REG_VALUE_STATUS_")[ 1 ], }, operation_modes_data, ) operation_modes_list = list(operation_modes_map) operation_modes = ChainMap(*operation_modes_list) current_operation_mode = [ name for value, name in operation_modes.items() if value == current_operation_mode_value ] if len(current_operation_mode) != 1: # Something has gone wrong or operation mode not supported return None return { "current": current_operation_mode[0], "available": operation_modes, "isReadOnly": data["isReadOnly"], } return None def get__group_operational_time(self, device_id: str): return self.__get_register_group(device_id, REG_GROUP_OPERATIONAL_TIME) def get_group_operational_operation(self, device: ThermiaHeatPump): register_data = self.__get_register_group( device.id, REG_GROUP_OPERATIONAL_OPERATION ) data = [d for d in register_data if d["registerName"] == "REG_OPERATIONMODE"] if len(data) != 1: # Operation mode not supported return None data = data[0] device.set_register_index_operation_mode(data["registerIndex"]) current_operation_mode_value = int(data.get("registerValue")) operation_modes_data = data.get("valueNames") if operation_modes_data is not None: operation_modes_map = map( lambda values: { values.get("value"): values.get("name").split( "REG_VALUE_OPERATION_MODE_" )[1], }, operation_modes_data, ) operation_modes_list = list(operation_modes_map) operation_modes = ChainMap(*operation_modes_list) current_operation_mode = [ name for value, name in operation_modes.items() if value == current_operation_mode_value ] if len(current_operation_mode) != 1: # Something has gone wrong or operation mode not supported return None return { "current": current_operation_mode[0], "available": operation_modes, "isReadOnly": data["isReadOnly"], } return None def get_group_hot_water(self, device: ThermiaHeatPump): register_data = self.__get_register_group(device.id, REG_GROUP_HOT_WATER) data = [d for d in register_data if d["registerName"] == "REG_HOT_WATER_STATUS"] if len(data) == 0: # Hot water switch not supported return None data = data[0] device.set_register_index_hot_water_switch(data["registerIndex"]) current_switch_state = int(data.get("registerValue")) switch_states_data = data.get("valueNames") if switch_states_data is not None and len(switch_states_data) == 2: return current_switch_state return None def set_temperature(self, device: ThermiaHeatPump, temperature): device_temperature_register_index = device.get_register_indexes()["temperature"] if device_temperature_register_index is None: _LOGGER.error( "Error setting device's temperature. No temperature register index." ) return self.__set_register_value( device, device_temperature_register_index, temperature ) def set_operation_mode(self, device: ThermiaHeatPump, mode): if device.is_operation_mode_read_only: _LOGGER.error( "Error setting device's operation mode. Operation mode is read only." ) return operation_mode_int = None for value, name in device.available_operation_mode_map.items(): if name == mode: operation_mode_int = value if operation_mode_int is None: _LOGGER.error( "Error setting device's operation mode. Invalid operation mode." ) return device_operation_mode_register_index = device.get_register_indexes()[ "operation_mode" ] if device_operation_mode_register_index is None: _LOGGER.error( "Error setting device's operation mode. No operation mode register index." ) return self.__set_register_value( device, device_operation_mode_register_index, operation_mode_int ) def set_hot_water_switch_state( self, device: ThermiaHeatPump, state: int ): # 0 - off, 1 - on device_hot_water_switch_state_register_index = device.get_register_indexes()[ "hot_water_switch" ] if device_hot_water_switch_state_register_index is None: _LOGGER.error( "Error setting device's hot water switch state. No hot water switch register index." ) return self.__set_register_value( device, device_hot_water_switch_state_register_index, state ) def __get_register_group(self, device_id: str, register_group: REGISTER_GROUPS): self.__check_token_validity() url = ( self.configuration["apiBaseUrl"] + THERMIA_INSTALLATION_PATH + str(device_id) + "/Groups/" + register_group ) request = requests.get(url, headers=self.__default_request_headers) status = request.status_code if status != 200: _LOGGER.error( "Error in getting device's register group: " + register_group + ", Status: " + str(status) ) return None return request.json() def __set_register_value( self, device: ThermiaHeatPump, register_index: int, register_value: int ): self.__check_token_validity() url = ( self.configuration["apiBaseUrl"] + THERMIA_INSTALLATION_PATH + str(device.id) + "/Registers" ) body = { "registerIndex": register_index, "registerValue": register_value, "clientUuid": "api-client-uuid", } request = requests.post(url, headers=self.__default_request_headers, json=body) status = request.status_code if status != 200: _LOGGER.error( "Error setting register " + str(register_index) + " value. " + str(status) ) def __fetch_configuration(self): request = requests.get(self.__api_config_url) status = request.status_code if status != 200: _LOGGER.error("Error fetching API configuration. " + str(status)) raise NetworkException("Error fetching API configuration.", status) return request.json() def __authenticate(self): auth_url = self.configuration["authApiBaseUrl"] + "/api/v1/Jwt/login" json = { "userName": self.__email, "password": self.__password, "rememberMe": True, } request_auth = requests.post(auth_url, json=json) status = request_auth.status_code if status != 200: _LOGGER.error( "Authentication request failed, please check credentials. " + str(status) ) raise AuthenticationException( "Authentication request failed, please check credentials.", status ) auth_data = request_auth.json() token_valid_to = auth_data.get("tokenValidToUtc").split(".")[0] datetime_object = datetime.strptime(token_valid_to, "%Y-%m-%dT%H:%M:%S") token_valid_to = datetime_object.timestamp() self.__token = auth_data.get("token") self.__token_valid_to = token_valid_to self.__default_request_headers = { "Authorization": "Bearer " + self.__token, "Content-Type": "application/json", } _LOGGER.info("Authentication was successful, token set.") return True def __check_token_validity(self): if ( self.__token_valid_to is None or self.__token_valid_to < datetime.now().timestamp() ): _LOGGER.info("Token expired, re-authenticating.") self.authenticated = self.__authenticate()