Controllers.climate
Контроллер датчика температуры и влажности.
Взаимодействует с API Яндекс Умного дома для получения показаний температуры и влажности с климатического датчика.
1#!/usr/bin/env python3 2""" 3Контроллер датчика температуры и влажности. 4 5Взаимодействует с API Яндекс Умного дома для получения показаний 6температуры и влажности с климатического датчика. 7""" 8 9import time 10 11import requests 12from langfuse import observe 13from loguru import logger 14 15from Controllers.controller import Controller 16from DataSources import YandexDataSource 17 18 19class ClimateController(Controller, YandexDataSource): 20 """Контроллер для датчика температуры и влажности Яндекс Умного дома. 21 22 Получает состояние датчика (температуру, влажность, онлайн-статус) 23 через Yandex IoT API с повторными попытками при ошибках. 24 25 Attributes: 26 device_id: Идентификатор устройства в Яндекс Умном доме. 27 round_digits: Кортеж из количества знаков для округления (температура, влажность, запасной). 28 state_retry_count: Количество попыток получения состояния. 29 state_retry_delay: Задержка между попытками в секундах. 30 state: Последнее полученное состояние датчика. 31 """ 32 33 _default_round_digits = (0, 2, 0) 34 35 def __init__( 36 self, 37 device_id, 38 api_key, 39 round_digits=None, 40 state_retry_count=3, 41 state_retry_delay=2, 42 ): 43 """Инициализирует контроллер датчика температуры. 44 45 Args: 46 device_id: Идентификатор устройства в Яндекс Умном доме. 47 api_key: Токен авторизации Yandex IoT API. 48 round_digits: Кортеж с количеством знаков после запятой. 49 state_retry_count: Количество попыток получения состояния. 50 state_retry_delay: Задержка между попытками в секундах. 51 """ 52 53 self.device_id = device_id 54 55 Controller.__init__(self) 56 YandexDataSource.__init__(self, api_key) 57 58 self.round_digits = round_digits or self._default_round_digits 59 self.state_retry_count = state_retry_count 60 self.state_retry_delay = state_retry_delay 61 self.state = self.get_state() 62 63 def __str__(self): 64 """Возвращает строковое представление состояния датчика. 65 66 Returns: 67 str: Строка вида "Название: 25°C, влажность 40%". 68 """ 69 name = self.state.get("name", "Датчик") 70 temperature = round(self.state.get("temperature", 0), self.round_digits[0]) 71 temperature = int(temperature) if self.round_digits[0] == 0 else temperature 72 humidity = round(self.state.get("humidity", 0), self.round_digits[0]) 73 humidity = int(humidity) if self.round_digits[0] == 0 else humidity 74 return f"{name}: {temperature}°C, влажность {humidity}%" 75 76 @observe(name="Функция для получения состояния датчика температуры и влажности") 77 def get_state(self): 78 """Получает состояние датчика температуры и влажности через Yandex IoT API. 79 80 Выполняет GET-запрос к API Яндекс Умного дома с повторными 81 попытками. Разбирает capabilities и properties устройства. 82 83 Returns: 84 dict: Словарь с ключами device_id, name, online, power, 85 temperature, humidity. При ошибках возвращает значения по умолчанию. 86 """ 87 88 for attempt in range(self.state_retry_count): 89 try: 90 response = requests.get( 91 self.url + f"/{self.device_id}", 92 headers=self.yandex_headers, 93 timeout=10, 94 ) 95 response.raise_for_status() 96 97 device = response.json() 98 99 state = { 100 "device_id": self.device_id, 101 "name": device.get("name", ""), 102 "online": device.get("state", "unknown"), 103 } 104 105 # Обрабатываем capabilities и properties как в первой функции 106 for capability in device.get("capabilities", []): 107 if capability.get("type") == "devices.capabilities.on_off": 108 state["power"] = capability.get("state", {}).get("value", False) 109 110 for property in device.get("properties", []): 111 prop_type = property.get("type") 112 value = property.get("state", {}).get("value") 113 114 if prop_type == "devices.properties.float": 115 parameters = property.get("parameters", {}) 116 instance = parameters.get("instance", "") 117 118 if "temperature" in instance: 119 state["temperature"] = value 120 elif "humidity" in instance: 121 state["humidity"] = value 122 123 self.state = state 124 return state 125 except requests.exceptions.RequestException as e: 126 logger.error(f"Попытка {attempt + 1}/{self.state_retry_count}: {e}") 127 if attempt < self.state_retry_count - 1: 128 time.sleep(self.state_retry_delay) 129 130 self.state = { 131 "device_id": self.device_id, 132 "name": "", 133 "online": "unknown", 134 "power": False, 135 "temperature": 0, 136 "humidity": 0, 137 } 138 logger.error( 139 f"Не удалось получить состояние датчика после {self.state_retry_count} попыток" 140 ) 141 return self.state
20class ClimateController(Controller, YandexDataSource): 21 """Контроллер для датчика температуры и влажности Яндекс Умного дома. 22 23 Получает состояние датчика (температуру, влажность, онлайн-статус) 24 через Yandex IoT API с повторными попытками при ошибках. 25 26 Attributes: 27 device_id: Идентификатор устройства в Яндекс Умном доме. 28 round_digits: Кортеж из количества знаков для округления (температура, влажность, запасной). 29 state_retry_count: Количество попыток получения состояния. 30 state_retry_delay: Задержка между попытками в секундах. 31 state: Последнее полученное состояние датчика. 32 """ 33 34 _default_round_digits = (0, 2, 0) 35 36 def __init__( 37 self, 38 device_id, 39 api_key, 40 round_digits=None, 41 state_retry_count=3, 42 state_retry_delay=2, 43 ): 44 """Инициализирует контроллер датчика температуры. 45 46 Args: 47 device_id: Идентификатор устройства в Яндекс Умном доме. 48 api_key: Токен авторизации Yandex IoT API. 49 round_digits: Кортеж с количеством знаков после запятой. 50 state_retry_count: Количество попыток получения состояния. 51 state_retry_delay: Задержка между попытками в секундах. 52 """ 53 54 self.device_id = device_id 55 56 Controller.__init__(self) 57 YandexDataSource.__init__(self, api_key) 58 59 self.round_digits = round_digits or self._default_round_digits 60 self.state_retry_count = state_retry_count 61 self.state_retry_delay = state_retry_delay 62 self.state = self.get_state() 63 64 def __str__(self): 65 """Возвращает строковое представление состояния датчика. 66 67 Returns: 68 str: Строка вида "Название: 25°C, влажность 40%". 69 """ 70 name = self.state.get("name", "Датчик") 71 temperature = round(self.state.get("temperature", 0), self.round_digits[0]) 72 temperature = int(temperature) if self.round_digits[0] == 0 else temperature 73 humidity = round(self.state.get("humidity", 0), self.round_digits[0]) 74 humidity = int(humidity) if self.round_digits[0] == 0 else humidity 75 return f"{name}: {temperature}°C, влажность {humidity}%" 76 77 @observe(name="Функция для получения состояния датчика температуры и влажности") 78 def get_state(self): 79 """Получает состояние датчика температуры и влажности через Yandex IoT API. 80 81 Выполняет GET-запрос к API Яндекс Умного дома с повторными 82 попытками. Разбирает capabilities и properties устройства. 83 84 Returns: 85 dict: Словарь с ключами device_id, name, online, power, 86 temperature, humidity. При ошибках возвращает значения по умолчанию. 87 """ 88 89 for attempt in range(self.state_retry_count): 90 try: 91 response = requests.get( 92 self.url + f"/{self.device_id}", 93 headers=self.yandex_headers, 94 timeout=10, 95 ) 96 response.raise_for_status() 97 98 device = response.json() 99 100 state = { 101 "device_id": self.device_id, 102 "name": device.get("name", ""), 103 "online": device.get("state", "unknown"), 104 } 105 106 # Обрабатываем capabilities и properties как в первой функции 107 for capability in device.get("capabilities", []): 108 if capability.get("type") == "devices.capabilities.on_off": 109 state["power"] = capability.get("state", {}).get("value", False) 110 111 for property in device.get("properties", []): 112 prop_type = property.get("type") 113 value = property.get("state", {}).get("value") 114 115 if prop_type == "devices.properties.float": 116 parameters = property.get("parameters", {}) 117 instance = parameters.get("instance", "") 118 119 if "temperature" in instance: 120 state["temperature"] = value 121 elif "humidity" in instance: 122 state["humidity"] = value 123 124 self.state = state 125 return state 126 except requests.exceptions.RequestException as e: 127 logger.error(f"Попытка {attempt + 1}/{self.state_retry_count}: {e}") 128 if attempt < self.state_retry_count - 1: 129 time.sleep(self.state_retry_delay) 130 131 self.state = { 132 "device_id": self.device_id, 133 "name": "", 134 "online": "unknown", 135 "power": False, 136 "temperature": 0, 137 "humidity": 0, 138 } 139 logger.error( 140 f"Не удалось получить состояние датчика после {self.state_retry_count} попыток" 141 ) 142 return self.state
Контроллер для датчика температуры и влажности Яндекс Умного дома.
Получает состояние датчика (температуру, влажность, онлайн-статус) через Yandex IoT API с повторными попытками при ошибках.
Attributes: device_id: Идентификатор устройства в Яндекс Умном доме. round_digits: Кортеж из количества знаков для округления (температура, влажность, запасной). state_retry_count: Количество попыток получения состояния. state_retry_delay: Задержка между попытками в секундах. state: Последнее полученное состояние датчика.
36 def __init__( 37 self, 38 device_id, 39 api_key, 40 round_digits=None, 41 state_retry_count=3, 42 state_retry_delay=2, 43 ): 44 """Инициализирует контроллер датчика температуры. 45 46 Args: 47 device_id: Идентификатор устройства в Яндекс Умном доме. 48 api_key: Токен авторизации Yandex IoT API. 49 round_digits: Кортеж с количеством знаков после запятой. 50 state_retry_count: Количество попыток получения состояния. 51 state_retry_delay: Задержка между попытками в секундах. 52 """ 53 54 self.device_id = device_id 55 56 Controller.__init__(self) 57 YandexDataSource.__init__(self, api_key) 58 59 self.round_digits = round_digits or self._default_round_digits 60 self.state_retry_count = state_retry_count 61 self.state_retry_delay = state_retry_delay 62 self.state = self.get_state()
Инициализирует контроллер датчика температуры.
Args: device_id: Идентификатор устройства в Яндекс Умном доме. api_key: Токен авторизации Yandex IoT API. round_digits: Кортеж с количеством знаков после запятой. state_retry_count: Количество попыток получения состояния. state_retry_delay: Задержка между попытками в секундах.
77 @observe(name="Функция для получения состояния датчика температуры и влажности") 78 def get_state(self): 79 """Получает состояние датчика температуры и влажности через Yandex IoT API. 80 81 Выполняет GET-запрос к API Яндекс Умного дома с повторными 82 попытками. Разбирает capabilities и properties устройства. 83 84 Returns: 85 dict: Словарь с ключами device_id, name, online, power, 86 temperature, humidity. При ошибках возвращает значения по умолчанию. 87 """ 88 89 for attempt in range(self.state_retry_count): 90 try: 91 response = requests.get( 92 self.url + f"/{self.device_id}", 93 headers=self.yandex_headers, 94 timeout=10, 95 ) 96 response.raise_for_status() 97 98 device = response.json() 99 100 state = { 101 "device_id": self.device_id, 102 "name": device.get("name", ""), 103 "online": device.get("state", "unknown"), 104 } 105 106 # Обрабатываем capabilities и properties как в первой функции 107 for capability in device.get("capabilities", []): 108 if capability.get("type") == "devices.capabilities.on_off": 109 state["power"] = capability.get("state", {}).get("value", False) 110 111 for property in device.get("properties", []): 112 prop_type = property.get("type") 113 value = property.get("state", {}).get("value") 114 115 if prop_type == "devices.properties.float": 116 parameters = property.get("parameters", {}) 117 instance = parameters.get("instance", "") 118 119 if "temperature" in instance: 120 state["temperature"] = value 121 elif "humidity" in instance: 122 state["humidity"] = value 123 124 self.state = state 125 return state 126 except requests.exceptions.RequestException as e: 127 logger.error(f"Попытка {attempt + 1}/{self.state_retry_count}: {e}") 128 if attempt < self.state_retry_count - 1: 129 time.sleep(self.state_retry_delay) 130 131 self.state = { 132 "device_id": self.device_id, 133 "name": "", 134 "online": "unknown", 135 "power": False, 136 "temperature": 0, 137 "humidity": 0, 138 } 139 logger.error( 140 f"Не удалось получить состояние датчика после {self.state_retry_count} попыток" 141 ) 142 return self.state
Получает состояние датчика температуры и влажности через Yandex IoT API.
Выполняет GET-запрос к API Яндекс Умного дома с повторными попытками. Разбирает capabilities и properties устройства.
Returns: dict: Словарь с ключами device_id, name, online, power, temperature, humidity. При ошибках возвращает значения по умолчанию.