From d03078cfd421966ebf2398d560c5222f36085cb7 Mon Sep 17 00:00:00 2001 From: SMKRV Date: Sun, 24 Nov 2024 17:55:39 +0300 Subject: [PATCH] Release v2.0.0 --- custom_components/ha_text_ai/coordinator.py | 16 +++- custom_components/ha_text_ai/sensor.py | 97 +++++++++++---------- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/custom_components/ha_text_ai/coordinator.py b/custom_components/ha_text_ai/coordinator.py index 705a00f..9773ce6 100644 --- a/custom_components/ha_text_ai/coordinator.py +++ b/custom_components/ha_text_ai/coordinator.py @@ -19,7 +19,7 @@ class HATextAICoordinator(DataUpdateCoordinator): hass: HomeAssistant, client: Any, model: str, - update_interval: int, # Изменен тип на int + update_interval: int, instance_name: str, max_tokens: int = 1000, temperature: float = 0.7, @@ -27,15 +27,14 @@ class HATextAICoordinator(DataUpdateCoordinator): is_anthropic: bool = False, ) -> None: """Initialize coordinator.""" - # Преобразуем update_interval в timedelta update_interval_td = timedelta(seconds=update_interval) super().__init__( hass, _LOGGER, name=f"HA Text AI {instance_name}", - update_interval=update_interval_td, # Передаем timedelta - ) + update_interval=update_interval_td, + ) self.instance_name = instance_name self.client = client @@ -68,6 +67,15 @@ class HATextAICoordinator(DataUpdateCoordinator): self.last_response = None self.endpoint_status = "initialized" + self.last_response = { + "timestamp": dt_util.utcnow().isoformat(), + "question": "", + "response": "", + "model": model, + "instance": instance_name, + "error": None + } + @property def is_processing(self) -> bool: """Return True if currently processing a request.""" diff --git a/custom_components/ha_text_ai/sensor.py b/custom_components/ha_text_ai/sensor.py index 5b8599e..a1ef7ce 100644 --- a/custom_components/ha_text_ai/sensor.py +++ b/custom_components/ha_text_ai/sensor.py @@ -106,12 +106,12 @@ class HATextAISensor(CoordinatorEntity, SensorEntity): @property def native_value(self) -> StateType: """Return the native value of the sensor.""" - if self.coordinator.data is None: + if not self.coordinator.data: return STATE_DISCONNECTED - state = self.coordinator.data.get("state", STATE_READY) - self._current_state = state - return state + status = self.coordinator.data.get("status", STATE_READY) + self._current_state = status + return status @property def icon(self) -> str: @@ -133,48 +133,52 @@ class HATextAISensor(CoordinatorEntity, SensorEntity): ATTR_LAST_ERROR: self._last_error, } - if self.coordinator.data: - data = self.coordinator.data + if not self.coordinator.data: + return attributes - # Основные атрибуты - for attr in [ - ATTR_TOTAL_RESPONSES, - ATTR_AVG_RESPONSE_TIME, - ATTR_LAST_REQUEST_TIME, - ATTR_IS_PROCESSING, - ATTR_IS_RATE_LIMITED, - ATTR_IS_MAINTENANCE, - ATTR_API_VERSION, - ATTR_ENDPOINT_STATUS, - ATTR_PERFORMANCE_METRICS, - ATTR_HISTORY_SIZE, - ATTR_UPTIME, - ATTR_SYSTEM_PROMPT, + data = self.coordinator.data + + # Основные атрибуты + for attr in [ + ATTR_TOTAL_RESPONSES, + ATTR_AVG_RESPONSE_TIME, + ATTR_LAST_REQUEST_TIME, + ATTR_IS_PROCESSING, + ATTR_IS_RATE_LIMITED, + ATTR_IS_MAINTENANCE, + ATTR_API_VERSION, + ATTR_ENDPOINT_STATUS, + ATTR_PERFORMANCE_METRICS, + ATTR_HISTORY_SIZE, + ATTR_UPTIME, + ATTR_SYSTEM_PROMPT, + ]: + value = data.get(attr) + if value is not None: + attributes[attr] = value + + # Метрики + metrics = data.get("metrics", {}) + if isinstance(metrics, dict): + for metric in [ + METRIC_TOTAL_TOKENS, + METRIC_PROMPT_TOKENS, + METRIC_COMPLETION_TOKENS, + METRIC_SUCCESSFUL_REQUESTS, + METRIC_FAILED_REQUESTS, + METRIC_AVERAGE_LATENCY, + METRIC_MAX_LATENCY, + METRIC_MIN_LATENCY, ]: - if attr in data: - attributes[attr] = data[attr] + value = metrics.get(metric) + if value is not None: + attributes[metric] = value - # Метрики - if "metrics" in data: - metrics = data["metrics"] - for metric in [ - METRIC_TOTAL_TOKENS, - METRIC_PROMPT_TOKENS, - METRIC_COMPLETION_TOKENS, - METRIC_SUCCESSFUL_REQUESTS, - METRIC_FAILED_REQUESTS, - METRIC_AVERAGE_LATENCY, - METRIC_MAX_LATENCY, - METRIC_MIN_LATENCY, - ]: - if metric in metrics: - attributes[metric] = metrics[metric] - - # Последний ответ - if "last_response" in data: - last_response = data["last_response"] - attributes[ATTR_RESPONSE] = last_response.get("response", "") - attributes[ATTR_QUESTION] = last_response.get("question", "") + # Последний ответ + last_response = data.get("last_response", {}) + if isinstance(last_response, dict): + attributes[ATTR_RESPONSE] = last_response.get("response", "") + attributes[ATTR_QUESTION] = last_response.get("question", "") return attributes @@ -185,7 +189,7 @@ class HATextAISensor(CoordinatorEntity, SensorEntity): def _handle_coordinator_update(self) -> None: """Handle updated data from the coordinator.""" - if self.coordinator.data is None: + if not self.coordinator.data: self._current_state = STATE_DISCONNECTED self.async_write_ha_state() return @@ -208,8 +212,9 @@ class HATextAISensor(CoordinatorEntity, SensorEntity): self._current_state = STATE_READY # Обновляем метрики - if "metrics" in data: - self._error_count = data["metrics"].get("total_errors", self._error_count) + metrics = data.get("metrics", {}) + if isinstance(metrics, dict): + self._error_count = metrics.get("total_errors", self._error_count) self._last_update = data.get("last_update")