meteocat 0.1.25 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/.github/workflows/release.yml +33 -33
  2. package/.pre-commit-config.yaml +37 -37
  3. package/.releaserc +23 -23
  4. package/.releaserc.toml +14 -14
  5. package/AUTHORS.md +12 -12
  6. package/CHANGELOG.md +430 -401
  7. package/README.md +40 -40
  8. package/custom_components/meteocat/__init__.py +136 -107
  9. package/custom_components/meteocat/condition.py +28 -28
  10. package/custom_components/meteocat/config_flow.py +199 -192
  11. package/custom_components/meteocat/const.py +55 -55
  12. package/custom_components/meteocat/coordinator.py +194 -195
  13. package/custom_components/meteocat/entity.py +98 -98
  14. package/custom_components/meteocat/helpers.py +42 -42
  15. package/custom_components/meteocat/manifest.json +12 -12
  16. package/custom_components/meteocat/options_flow.py +71 -71
  17. package/custom_components/meteocat/sensor.py +325 -303
  18. package/custom_components/meteocat/strings.json +25 -25
  19. package/custom_components/meteocat/translations/ca.json +25 -25
  20. package/custom_components/meteocat/translations/en.json +25 -25
  21. package/custom_components/meteocat/translations/es.json +25 -25
  22. package/custom_components/meteocat/version.py +2 -2
  23. package/filetree.py +48 -48
  24. package/filetree.txt +46 -46
  25. package/hacs.json +5 -5
  26. package/package.json +22 -22
  27. package/poetry.lock +3210 -3216
  28. package/pyproject.toml +64 -64
  29. package/releaserc.json +17 -17
  30. package/requirements.test.txt +3 -3
  31. package/setup.cfg +64 -64
  32. package/setup.py +10 -10
  33. package/tests/bandit.yaml +17 -17
  34. package/tests/conftest.py +19 -19
  35. package/tests/test_init.py +9 -9
@@ -1,195 +1,194 @@
1
- from __future__ import annotations
2
-
3
- import os
4
- import json
5
- import logging
6
- from datetime import timedelta
7
- from typing import Dict
8
-
9
- from homeassistant.core import HomeAssistant
10
- from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
11
- from homeassistant.exceptions import ConfigEntryNotReady
12
-
13
- from meteocatpy.data import MeteocatStationData
14
- from meteocatpy.forecast import MeteocatForecast
15
- from meteocatpy.exceptions import (
16
- BadRequestError,
17
- ForbiddenError,
18
- TooManyRequestsError,
19
- InternalServerError,
20
- UnknownAPIError,
21
- )
22
-
23
- from .const import DOMAIN
24
-
25
- _LOGGER = logging.getLogger(__name__)
26
-
27
- # Valores predeterminados para los intervalos de actualización
28
- DEFAULT_SENSOR_UPDATE_INTERVAL = timedelta(minutes=90)
29
- DEFAULT_ENTITY_UPDATE_INTERVAL = timedelta(hours=12)
30
-
31
- def save_json_to_file(data: dict, filename="station_data.json"):
32
- """Guardar datos JSON en un archivo para análisis."""
33
- try:
34
- # Crear la carpeta 'files' si no existe
35
- output_folder = os.path.join(os.path.dirname(__file__), "files")
36
- os.makedirs(output_folder, exist_ok=True)
37
-
38
- # Ruta completa del archivo
39
- output_file = os.path.join(output_folder, filename)
40
-
41
- # Guardar los datos en el archivo
42
- with open(output_file, "w", encoding="utf-8") as f:
43
- json.dump(data, f, ensure_ascii=False, indent=4)
44
-
45
- _LOGGER.info(f"Archivo JSON guardado en: {output_file}")
46
- except Exception as e:
47
- _LOGGER.error(f"Error al guardar el archivo JSON: {e}")
48
-
49
- class MeteocatSensorCoordinator(DataUpdateCoordinator):
50
- """Coordinator para manejar la actualización de datos de los sensores."""
51
-
52
- def __init__(
53
- self,
54
- hass: HomeAssistant,
55
- entry_data: dict,
56
- update_interval: timedelta = DEFAULT_SENSOR_UPDATE_INTERVAL,
57
- ):
58
- """
59
- Inicializa el coordinador de sensores de Meteocat.
60
-
61
- Args:
62
- hass (HomeAssistant): Instancia de Home Assistant.
63
- entry_data (dict): Datos de configuración obtenidos de core.config_entries.
64
- update_interval (timedelta): Intervalo de actualización.
65
- """
66
- self.api_key = entry_data["api_key"] # Usamos la API key de la configuración
67
- self.town_name = entry_data["town_name"] # Usamos el nombre del municipio
68
- self.town_id = entry_data["town_id"] # Usamos el ID del municipio
69
- self.station_name = entry_data["station_name"] # Usamos el nombre de la estación
70
- self.station_id = entry_data["station_id"] # Usamos el ID de la estación
71
- self.variable_name = entry_data["variable_name"] # Usamos el nombre de la variable
72
- self.variable_id = entry_data["variable_id"] # Usamos el ID de la variable
73
- self.meteocat_station_data = MeteocatStationData(self.api_key)
74
-
75
- super().__init__(
76
- hass,
77
- _LOGGER,
78
- name=f"{DOMAIN} Sensor Coordinator",
79
- update_interval=update_interval,
80
- )
81
-
82
- async def _async_update_data(self) -> Dict:
83
- """Actualiza los datos de los sensores desde la API de Meteocat."""
84
- try:
85
- # Obtener datos desde la API
86
- data = await self.meteocat_station_data.get_station_data(self.station_id)
87
- _LOGGER.debug("Datos de sensores actualizados exitosamente: %s", data)
88
-
89
- # Guardar los datos en un archivo JSON
90
- save_json_to_file(data)
91
-
92
- return data
93
- except ForbiddenError as err:
94
- _LOGGER.error(
95
- "Acceso denegado al obtener datos de sensores (Station ID: %s): %s",
96
- self.station_id,
97
- err,
98
- )
99
- raise ConfigEntryNotReady from err
100
- except TooManyRequestsError as err:
101
- _LOGGER.warning(
102
- "Límite de solicitudes alcanzado al obtener datos de sensores (Station ID: %s): %s",
103
- self.station_id,
104
- err,
105
- )
106
- raise ConfigEntryNotReady from err
107
- except (BadRequestError, InternalServerError, UnknownAPIError) as err:
108
- _LOGGER.error(
109
- "Error al obtener datos de sensores (Station ID: %s): %s",
110
- self.station_id,
111
- err,
112
- )
113
- raise
114
- except Exception as err:
115
- _LOGGER.exception(
116
- "Error inesperado al obtener datos de sensores (Station ID: %s): %s",
117
- self.station_id,
118
- err,
119
- )
120
- raise
121
-
122
-
123
- class MeteocatEntityCoordinator(DataUpdateCoordinator):
124
- """Coordinator para manejar la actualización de datos de las entidades de predicción."""
125
-
126
- def __init__(
127
- self,
128
- hass: HomeAssistant,
129
- entry_data: dict,
130
- update_interval: timedelta = DEFAULT_ENTITY_UPDATE_INTERVAL,
131
- ):
132
- """
133
- Inicializa el coordinador de datos para entidades de predicción.
134
-
135
- Args:
136
- hass (HomeAssistant): Instancia de Home Assistant.
137
- entry_data (dict): Datos de configuración obtenidos de core.config_entries.
138
- update_interval (timedelta): Intervalo de actualización.
139
- """
140
- self.api_key = entry_data["api_key"]
141
- self.town_name = entry_data["town_name"]
142
- self.town_id = entry_data["town_id"]
143
- self.station_name = entry_data["station_name"]
144
- self.station_id = entry_data["station_id"]
145
- self.variable_name = entry_data["variable_name"]
146
- self.variable_id = entry_data["variable_id"]
147
- self.meteocat_forecast = MeteocatForecast(self.api_key)
148
-
149
- super().__init__(
150
- hass,
151
- _LOGGER,
152
- name=f"{DOMAIN} Entity Coordinator",
153
- update_interval=update_interval,
154
- )
155
-
156
- async def _async_update_data(self) -> Dict:
157
- """Actualiza los datos de las entidades de predicción desde la API de Meteocat."""
158
- try:
159
- hourly_forecast = await self.meteocat_forecast.get_prediccion_horaria(self.town_id)
160
- daily_forecast = await self.meteocat_forecast.get_prediccion_diaria(self.town_id)
161
- _LOGGER.debug(
162
- "Datos de predicción actualizados exitosamente (Town ID: %s)", self.town_id
163
- )
164
- return {
165
- "hourly_forecast": hourly_forecast,
166
- "daily_forecast": daily_forecast,
167
- }
168
- except ForbiddenError as err:
169
- _LOGGER.error(
170
- "Acceso denegado al obtener datos de predicción (Town ID: %s): %s",
171
- self.town_id,
172
- err,
173
- )
174
- raise ConfigEntryNotReady from err
175
- except TooManyRequestsError as err:
176
- _LOGGER.warning(
177
- "Límite de solicitudes alcanzado al obtener datos de predicción (Town ID: %s): %s",
178
- self.town_id,
179
- err,
180
- )
181
- raise ConfigEntryNotReady from err
182
- except (BadRequestError, InternalServerError, UnknownAPIError) as err:
183
- _LOGGER.error(
184
- "Error al obtener datos de predicción (Town ID: %s): %s",
185
- self.town_id,
186
- err,
187
- )
188
- raise
189
- except Exception as err:
190
- _LOGGER.exception(
191
- "Error inesperado al obtener datos de predicción (Town ID: %s): %s",
192
- self.town_id,
193
- err,
194
- )
195
- raise
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import json
5
+ import aiofiles
6
+ import logging
7
+ from datetime import timedelta
8
+ from typing import Dict
9
+
10
+ from homeassistant.core import HomeAssistant
11
+ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
12
+ from homeassistant.exceptions import ConfigEntryNotReady
13
+
14
+ from meteocatpy.data import MeteocatStationData
15
+ # from meteocatpy.forecast import MeteocatForecast
16
+ from meteocatpy.exceptions import (
17
+ BadRequestError,
18
+ ForbiddenError,
19
+ TooManyRequestsError,
20
+ InternalServerError,
21
+ UnknownAPIError,
22
+ )
23
+
24
+ from .const import DOMAIN
25
+
26
+ _LOGGER = logging.getLogger(__name__)
27
+
28
+ # Valores predeterminados para los intervalos de actualización
29
+ DEFAULT_SENSOR_UPDATE_INTERVAL = timedelta(minutes=90)
30
+ DEFAULT_ENTITY_UPDATE_INTERVAL = timedelta(hours=12)
31
+
32
+ async def save_json_to_file(data: dict, output_file: str) -> None:
33
+ """Save the JSON data to a file asynchronously."""
34
+ try:
35
+ # Crea el directorio si no existe
36
+ os.makedirs(os.path.dirname(output_file), exist_ok=True)
37
+
38
+ # Escribe los datos JSON de forma asíncrona
39
+ async with aiofiles.open(output_file, mode="w", encoding="utf-8") as f:
40
+ await f.write(json.dumps(data, indent=4, ensure_ascii=False))
41
+ except Exception as e:
42
+ raise RuntimeError(f"Error saving JSON to {output_file}: {e}")
43
+
44
+ class MeteocatSensorCoordinator(DataUpdateCoordinator):
45
+ """Coordinator para manejar la actualización de datos de los sensores."""
46
+
47
+ def __init__(
48
+ self,
49
+ hass: HomeAssistant,
50
+ entry_data: dict,
51
+ update_interval: timedelta = DEFAULT_SENSOR_UPDATE_INTERVAL,
52
+ ):
53
+ """
54
+ Inicializa el coordinador de sensores de Meteocat.
55
+
56
+ Args:
57
+ hass (HomeAssistant): Instancia de Home Assistant.
58
+ entry_data (dict): Datos de configuración obtenidos de core.config_entries.
59
+ update_interval (timedelta): Intervalo de actualización.
60
+ """
61
+ self.api_key = entry_data["api_key"] # Usamos la API key de la configuración
62
+ self.town_name = entry_data["town_name"] # Usamos el nombre del municipio
63
+ self.town_id = entry_data["town_id"] # Usamos el ID del municipio
64
+ self.station_name = entry_data["station_name"] # Usamos el nombre de la estación
65
+ self.station_id = entry_data["station_id"] # Usamos el ID de la estación
66
+ self.variable_name = entry_data["variable_name"] # Usamos el nombre de la variable
67
+ self.variable_id = entry_data["variable_id"] # Usamos el ID de la variable
68
+ self.meteocat_station_data = MeteocatStationData(self.api_key)
69
+
70
+ super().__init__(
71
+ hass,
72
+ _LOGGER,
73
+ name=f"{DOMAIN} Sensor Coordinator",
74
+ update_interval=update_interval,
75
+ )
76
+
77
+ async def _async_update_data(self) -> Dict:
78
+ """Actualiza los datos de los sensores desde la API de Meteocat."""
79
+ try:
80
+ # Obtener datos desde la API
81
+ data = await self.meteocat_station_data.get_station_data(self.station_id)
82
+ _LOGGER.debug("Datos de sensores actualizados exitosamente: %s", data)
83
+
84
+ # Determinar la ruta al archivo en la carpeta raíz del repositorio
85
+ output_file = os.path.join(
86
+ self.hass.config.path(), "custom_components", "meteocat", "files", "station_data.json"
87
+ )
88
+
89
+ # Guardar los datos en un archivo JSON
90
+ await save_json_to_file(data, output_file)
91
+
92
+ return data
93
+ except ForbiddenError as err:
94
+ _LOGGER.error(
95
+ "Acceso denegado al obtener datos de sensores (Station ID: %s): %s",
96
+ self.station_id,
97
+ err,
98
+ )
99
+ raise ConfigEntryNotReady from err
100
+ except TooManyRequestsError as err:
101
+ _LOGGER.warning(
102
+ "Límite de solicitudes alcanzado al obtener datos de sensores (Station ID: %s): %s",
103
+ self.station_id,
104
+ err,
105
+ )
106
+ raise ConfigEntryNotReady from err
107
+ except (BadRequestError, InternalServerError, UnknownAPIError) as err:
108
+ _LOGGER.error(
109
+ "Error al obtener datos de sensores (Station ID: %s): %s",
110
+ self.station_id,
111
+ err,
112
+ )
113
+ raise
114
+ except Exception as err:
115
+ _LOGGER.exception(
116
+ "Error inesperado al obtener datos de sensores (Station ID: %s): %s",
117
+ self.station_id,
118
+ err,
119
+ )
120
+ raise
121
+
122
+ # class MeteocatEntityCoordinator(DataUpdateCoordinator):
123
+ # """Coordinator para manejar la actualización de datos de las entidades de predicción."""
124
+
125
+ # def __init__(
126
+ # self,
127
+ # hass: HomeAssistant,
128
+ # entry_data: dict,
129
+ # update_interval: timedelta = DEFAULT_ENTITY_UPDATE_INTERVAL,
130
+ # ):
131
+ # """
132
+ # Inicializa el coordinador de datos para entidades de predicción.
133
+
134
+ # Args:
135
+ # hass (HomeAssistant): Instancia de Home Assistant.
136
+ # entry_data (dict): Datos de configuración obtenidos de core.config_entries.
137
+ # update_interval (timedelta): Intervalo de actualización.
138
+ # """
139
+ # self.api_key = entry_data["api_key"]
140
+ # self.town_name = entry_data["town_name"]
141
+ # self.town_id = entry_data["town_id"]
142
+ # self.station_name = entry_data["station_name"]
143
+ # self.station_id = entry_data["station_id"]
144
+ # self.variable_name = entry_data["variable_name"]
145
+ # self.variable_id = entry_data["variable_id"]
146
+ # self.meteocat_forecast = MeteocatForecast(self.api_key)
147
+
148
+ # super().__init__(
149
+ # hass,
150
+ # _LOGGER,
151
+ # name=f"{DOMAIN} Entity Coordinator",
152
+ # update_interval=update_interval,
153
+ # )
154
+
155
+ # async def _async_update_data(self) -> Dict:
156
+ # """Actualiza los datos de las entidades de predicción desde la API de Meteocat."""
157
+ # try:
158
+ # hourly_forecast = await self.meteocat_forecast.get_prediccion_horaria(self.town_id)
159
+ # daily_forecast = await self.meteocat_forecast.get_prediccion_diaria(self.town_id)
160
+ # _LOGGER.debug(
161
+ # "Datos de predicción actualizados exitosamente (Town ID: %s)", self.town_id
162
+ # )
163
+ # return {
164
+ # "hourly_forecast": hourly_forecast,
165
+ # "daily_forecast": daily_forecast,
166
+ # }
167
+ # except ForbiddenError as err:
168
+ # _LOGGER.error(
169
+ # "Acceso denegado al obtener datos de predicción (Town ID: %s): %s",
170
+ # self.town_id,
171
+ # err,
172
+ # )
173
+ # raise ConfigEntryNotReady from err
174
+ # except TooManyRequestsError as err:
175
+ # _LOGGER.warning(
176
+ # "Límite de solicitudes alcanzado al obtener datos de predicción (Town ID: %s): %s",
177
+ # self.town_id,
178
+ # err,
179
+ # )
180
+ # raise ConfigEntryNotReady from err
181
+ # except (BadRequestError, InternalServerError, UnknownAPIError) as err:
182
+ # _LOGGER.error(
183
+ # "Error al obtener datos de predicción (Town ID: %s): %s",
184
+ # self.town_id,
185
+ # err,
186
+ # )
187
+ # raise
188
+ # except Exception as err:
189
+ # _LOGGER.exception(
190
+ # "Error inesperado al obtener datos de predicción (Town ID: %s): %s",
191
+ # self.town_id,
192
+ # err,
193
+ # )
194
+ # raise
@@ -1,98 +1,98 @@
1
- from __future__ import annotations
2
-
3
- import asyncio
4
- import logging
5
- from homeassistant.components.weather import WeatherEntity
6
- from homeassistant.const import (
7
- DEGREE,
8
- PERCENTAGE,
9
- UnitOfPressure,
10
- UnitOfSpeed,
11
- UnitOfTemperature,
12
- UnitOfVolumetricFlux,
13
- )
14
-
15
- from .const import (
16
- DOMAIN,
17
- CONF_API_KEY,
18
- TOWN_ID,
19
- TEMPERATURE,
20
- HUMIDITY,
21
- WIND_SPEED,
22
- WIND_DIRECTION,
23
- )
24
- from .condition import get_condition_from_statcel
25
- from .coordinator import MeteocatEntityCoordinator
26
-
27
-
28
- _LOGGER = logging.getLogger(__name__)
29
-
30
- async def async_setup_entry(hass, config_entry, async_add_entities):
31
- """Configura el componente weather basado en una entrada de configuración."""
32
- api_key = config_entry.data[CONF_API_KEY]
33
- town_id = config_entry.data[TOWN_ID]
34
-
35
- # Crear el coordinador
36
- coordinator = MeteocatEntityCoordinator(hass, api_key, town_id)
37
- # Asegurarse de que el coordinador esté actualizado antes de agregar la entidad
38
- await coordinator.async_refresh()
39
-
40
- async_add_entities([MeteocatWeatherEntity(coordinator)], True)
41
-
42
- class MeteocatWeatherEntity(WeatherEntity):
43
- """Entidad de clima para la integración Meteocat."""
44
-
45
- def __init__(self, coordinator: MeteocatEntityCoordinator):
46
- """Inicializa la entidad MeteocatWeather."""
47
- self._coordinator = coordinator
48
- self._attr_temperature_unit = UnitOfTemperature.CELSIUS
49
- self._data = {}
50
-
51
- async def async_update(self):
52
- """Actualiza los datos meteorológicos."""
53
- try:
54
- # Usamos el coordinador para obtener los datos actualizados
55
- if self._coordinator.data:
56
- hourly_forecast = self._coordinator.data["hourly_forecast"]
57
- current_forecast = hourly_forecast["variables"]
58
- codi_estatcel = current_forecast.get("estatCel", {}).get("valor")
59
- is_night = current_forecast.get("is_night", False)
60
- self._data = {
61
- "temperature": current_forecast.get(TEMPERATURE, {}).get("valor"),
62
- "humidity": current_forecast.get(HUMIDITY, {}).get("valor"),
63
- "wind_speed": current_forecast.get(WIND_SPEED, {}).get("valor"),
64
- "wind_bearing": current_forecast.get(WIND_DIRECTION, {}).get("valor"),
65
- "condition": get_condition_from_statcel(codi_estatcel, is_night)["condition"],
66
- }
67
- except Exception as err:
68
- _LOGGER.error("Error al actualizar la predicción de Meteocat: %s", err)
69
-
70
- @property
71
- def name(self):
72
- """Retorna el nombre de la entidad."""
73
- return f"Clima {self._coordinator._town_id}"
74
-
75
- @property
76
- def temperature(self):
77
- """Retorna la temperatura actual."""
78
- return self._data.get("temperature")
79
-
80
- @property
81
- def humidity(self):
82
- """Retorna la humedad relativa actual."""
83
- return self._data.get("humidity")
84
-
85
- @property
86
- def wind_speed(self):
87
- """Retorna la velocidad del viento."""
88
- return self._data.get("wind_speed")
89
-
90
- @property
91
- def wind_bearing(self):
92
- """Retorna la dirección del viento."""
93
- return self._data.get("wind_bearing")
94
-
95
- @property
96
- def condition(self):
97
- """Retorna la condición climática."""
98
- return self._data.get("condition")
1
+ # from __future__ import annotations
2
+
3
+ # import asyncio
4
+ # import logging
5
+ # from homeassistant.components.weather import WeatherEntity
6
+ # from homeassistant.const import (
7
+ # DEGREE,
8
+ # PERCENTAGE,
9
+ # UnitOfPressure,
10
+ # UnitOfSpeed,
11
+ # UnitOfTemperature,
12
+ # UnitOfVolumetricFlux,
13
+ # )
14
+
15
+ # from .const import (
16
+ # DOMAIN,
17
+ # CONF_API_KEY,
18
+ # TOWN_ID,
19
+ # TEMPERATURE,
20
+ # HUMIDITY,
21
+ # WIND_SPEED,
22
+ # WIND_DIRECTION,
23
+ # )
24
+ # from .condition import get_condition_from_statcel
25
+ # from .coordinator import MeteocatEntityCoordinator
26
+
27
+
28
+ # _LOGGER = logging.getLogger(__name__)
29
+
30
+ # async def async_setup_entry(hass, config_entry, async_add_entities):
31
+ # """Configura el componente weather basado en una entrada de configuración."""
32
+ # api_key = config_entry.data[CONF_API_KEY]
33
+ # town_id = config_entry.data[TOWN_ID]
34
+
35
+ # # Crear el coordinador
36
+ # coordinator = MeteocatEntityCoordinator(hass, api_key, town_id)
37
+ # # Asegurarse de que el coordinador esté actualizado antes de agregar la entidad
38
+ # await coordinator.async_refresh()
39
+
40
+ # async_add_entities([MeteocatWeatherEntity(coordinator)], True)
41
+
42
+ # class MeteocatWeatherEntity(WeatherEntity):
43
+ # """Entidad de clima para la integración Meteocat."""
44
+
45
+ # def __init__(self, coordinator: MeteocatEntityCoordinator):
46
+ # """Inicializa la entidad MeteocatWeather."""
47
+ # self._coordinator = coordinator
48
+ # self._attr_temperature_unit = UnitOfTemperature.CELSIUS
49
+ # self._data = {}
50
+
51
+ # async def async_update(self):
52
+ # """Actualiza los datos meteorológicos."""
53
+ # try:
54
+ # # Usamos el coordinador para obtener los datos actualizados
55
+ # if self._coordinator.data:
56
+ # hourly_forecast = self._coordinator.data["hourly_forecast"]
57
+ # current_forecast = hourly_forecast["variables"]
58
+ # codi_estatcel = current_forecast.get("estatCel", {}).get("valor")
59
+ # is_night = current_forecast.get("is_night", False)
60
+ # self._data = {
61
+ # "temperature": current_forecast.get(TEMPERATURE, {}).get("valor"),
62
+ # "humidity": current_forecast.get(HUMIDITY, {}).get("valor"),
63
+ # "wind_speed": current_forecast.get(WIND_SPEED, {}).get("valor"),
64
+ # "wind_bearing": current_forecast.get(WIND_DIRECTION, {}).get("valor"),
65
+ # "condition": get_condition_from_statcel(codi_estatcel, is_night)["condition"],
66
+ # }
67
+ # except Exception as err:
68
+ # _LOGGER.error("Error al actualizar la predicción de Meteocat: %s", err)
69
+
70
+ # @property
71
+ # def name(self):
72
+ # """Retorna el nombre de la entidad."""
73
+ # return f"Clima {self._coordinator._town_id}"
74
+
75
+ # @property
76
+ # def temperature(self):
77
+ # """Retorna la temperatura actual."""
78
+ # return self._data.get("temperature")
79
+
80
+ # @property
81
+ # def humidity(self):
82
+ # """Retorna la humedad relativa actual."""
83
+ # return self._data.get("humidity")
84
+
85
+ # @property
86
+ # def wind_speed(self):
87
+ # """Retorna la velocidad del viento."""
88
+ # return self._data.get("wind_speed")
89
+
90
+ # @property
91
+ # def wind_bearing(self):
92
+ # """Retorna la dirección del viento."""
93
+ # return self._data.get("wind_bearing")
94
+
95
+ # @property
96
+ # def condition(self):
97
+ # """Retorna la condición climática."""
98
+ # return self._data.get("condition")