meteocat 0.1.38 → 0.1.39

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## [0.1.39](https://github.com/figorr/meteocat/compare/v0.1.38...v0.1.39) (2024-12-25)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * 0.1.39 ([be7e9f3](https://github.com/figorr/meteocat/commit/be7e9f394a02be59521fce9a20100d3091092358))
7
+ * add conditions constants ([95fa3bb](https://github.com/figorr/meteocat/commit/95fa3bba33722d2d976e1545bb58a7f97636ab7b))
8
+ * add MeteocatEntityCoordinator and def json to save files ([f5816cc](https://github.com/figorr/meteocat/commit/f5816cc71dd2d7f4900c796d482969742a67ca05))
9
+ * add MeteocatyEntityCoordinator and update async_remove_entry ([99a9883](https://github.com/figorr/meteocat/commit/99a98837de9923ba4a8604b5ff5ea6e628a51097))
10
+ * add translations to new condition sensor ([92d757c](https://github.com/figorr/meteocat/commit/92d757c82bf9c33bd392d16f74d666f806fc27cb))
11
+ * add weather entity ([914c407](https://github.com/figorr/meteocat/commit/914c4076457c8dd2ff1527ef83e5f62b911112a1))
12
+ * fix condition code ([04c6ea3](https://github.com/figorr/meteocat/commit/04c6ea3e668b19bad95141154ffa6910d4aa8f3a))
13
+ * fix is night code ([d50d587](https://github.com/figorr/meteocat/commit/d50d5871d89eb3ae20217e2070db61dcfc6c2503))
14
+ * fix uvi icon ([d16d452](https://github.com/figorr/meteocat/commit/d16d45282f5eae83f5a337a58d34d5c5e62bee6f))
15
+ * new condition sensor ([8f352fc](https://github.com/figorr/meteocat/commit/8f352fcff6f97e1bfe9ea49d22f03837b177f680))
16
+ * new repo file structure ([ac61261](https://github.com/figorr/meteocat/commit/ac612613e386f926eed526e2796cadd325a3fabc))
17
+ * new weather and condition coordinators ([f8307d8](https://github.com/figorr/meteocat/commit/f8307d8d8de915592c3a285e91dc8c79164953b5))
18
+ * new weather and condition coordinators ([4c457e8](https://github.com/figorr/meteocat/commit/4c457e87f17564fa50743064dfbdd922e4babc17))
19
+ * use await to save json files ([0945320](https://github.com/figorr/meteocat/commit/09453205bf891dcfef811c2628e72bf921aac8bb))
20
+
1
21
  ## [0.1.38](https://github.com/figorr/meteocat/compare/v0.1.37...v0.1.38) (2024-12-18)
2
22
 
3
23
 
package/conftest.py ADDED
@@ -0,0 +1,11 @@
1
+ import pytest
2
+ from homeassistant.core import HomeAssistant
3
+ from pytest_homeassistant_custom_component.common import mock_component
4
+ from homeassistant.setup import async_setup_component
5
+
6
+ @pytest.fixture(autouse=True)
7
+ async def auto_enable_custom_integrations(hass: HomeAssistant):
8
+ """Enable custom integrations."""
9
+ mock_component(hass, "meteocat")
10
+ await async_setup_component(hass, 'meteocat', {})
11
+ yield
@@ -10,9 +10,13 @@ from homeassistant.helpers.entity_platform import async_get_platforms
10
10
 
11
11
  from .coordinator import (
12
12
  MeteocatSensorCoordinator,
13
- # MeteocatEntityCoordinator,
13
+ MeteocatStaticSensorCoordinator,
14
+ MeteocatEntityCoordinator,
14
15
  MeteocatUviCoordinator,
15
16
  MeteocatUviFileCoordinator,
17
+ HourlyForecastCoordinator,
18
+ DailyForecastCoordinator,
19
+ MeteocatConditionCoordinator,
16
20
  )
17
21
 
18
22
  from .const import DOMAIN, PLATFORMS
@@ -20,7 +24,7 @@ from .const import DOMAIN, PLATFORMS
20
24
  _LOGGER = logging.getLogger(__name__)
21
25
 
22
26
  # Versión
23
- __version__ = "0.1.38"
27
+ __version__ = "0.1.39"
24
28
 
25
29
  def safe_remove(path: Path, is_folder: bool = False):
26
30
  """Elimina de forma segura un archivo o carpeta si existe."""
@@ -65,9 +69,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
65
69
  try:
66
70
  sensor_coordinator = MeteocatSensorCoordinator(hass=hass, entry_data=entry_data)
67
71
  await sensor_coordinator.async_config_entry_first_refresh()
72
+
73
+ static_sensor_coordinator = MeteocatStaticSensorCoordinator(hass=hass, entry_data=entry_data)
74
+ await sensor_coordinator.async_config_entry_first_refresh()
68
75
 
69
- # entity_coordinator = MeteocatEntityCoordinator(hass=hass, entry_data=entry_data)
70
- # await entity_coordinator.async_config_entry_first_refresh()
76
+ entity_coordinator = MeteocatEntityCoordinator(hass=hass, entry_data=entry_data)
77
+ await entity_coordinator.async_config_entry_first_refresh()
71
78
 
72
79
  uvi_coordinator = MeteocatUviCoordinator(hass=hass, entry_data=entry_data)
73
80
  await uvi_coordinator.async_config_entry_first_refresh()
@@ -75,6 +82,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
75
82
  uvi_file_coordinator = MeteocatUviFileCoordinator(hass=hass, entry_data=entry_data)
76
83
  await uvi_file_coordinator.async_config_entry_first_refresh()
77
84
 
85
+ hourly_forecast_coordinator = HourlyForecastCoordinator(hass=hass, entry_data=entry_data)
86
+ await hourly_forecast_coordinator.async_config_entry_first_refresh()
87
+
88
+ daily_forecast_coordinator = DailyForecastCoordinator(hass=hass, entry_data=entry_data)
89
+ await daily_forecast_coordinator.async_config_entry_first_refresh()
90
+
91
+ condition_coordinator = MeteocatConditionCoordinator(hass=hass, entry_data=entry_data)
92
+ await condition_coordinator.async_config_entry_first_refresh()
93
+
78
94
  except Exception as err: # Capturar todos los errores
79
95
  _LOGGER.exception(f"Error al inicializar los coordinadores: {err}")
80
96
  return False
@@ -83,9 +99,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
83
99
  hass.data.setdefault(DOMAIN, {})
84
100
  hass.data[DOMAIN][entry.entry_id] = {
85
101
  "sensor_coordinator": sensor_coordinator,
86
- # "entity_coordinator": entity_coordinator,
102
+ "static_sensor_coordinator": static_sensor_coordinator,
103
+ "entity_coordinator": entity_coordinator,
87
104
  "uvi_coordinator": uvi_coordinator,
88
105
  "uvi_file_coordinator": uvi_file_coordinator,
106
+ "hourly_forecast_coordinator": hourly_forecast_coordinator,
107
+ "daily_forecast_coordinator": daily_forecast_coordinator,
108
+ "condition_coordinator": condition_coordinator,
89
109
  **entry_data,
90
110
  }
91
111
 
@@ -138,6 +158,10 @@ async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
138
158
  # Archivo JSON UVI del municipio
139
159
  town_data_file = files_folder / f"uvi_{town_id.lower()}_data.json"
140
160
 
161
+ # Arhivos JSON de las predicciones del municipio a eliminar
162
+ forecast_hourly_data_file = files_folder / f"forecast_{town_id.lower()}_hourly_data.json"
163
+ forecast_daily_data_file = files_folder / f"forecast_{town_id.lower()}_daily_data.json"
164
+
141
165
  # Validar la ruta base
142
166
  if not custom_components_path.exists():
143
167
  _LOGGER.warning(f"La ruta {custom_components_path} no existe. No se realizará la limpieza.")
@@ -148,5 +172,7 @@ async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
148
172
  safe_remove(variables_file)
149
173
  safe_remove(station_data_file)
150
174
  safe_remove(town_data_file)
175
+ safe_remove(forecast_hourly_data_file)
176
+ safe_remove(forecast_daily_data_file)
151
177
  safe_remove(assets_folder, is_folder=True)
152
178
  safe_remove(files_folder, is_folder=True)
@@ -2,23 +2,33 @@ from __future__ import annotations
2
2
 
3
3
  from datetime import datetime
4
4
  from .const import CONDITION_MAPPING
5
- from .helpers import is_night # Importar la función is_night de helpers.py
5
+ from .helpers import is_night
6
6
 
7
- def get_condition_from_statcel(codi_estatcel, current_time: datetime, hass) -> dict:
7
+
8
+ def get_condition_from_statcel(
9
+ codi_estatcel, current_time: datetime, hass, is_hourly: bool = True
10
+ ) -> dict:
8
11
  """
9
12
  Convierte el código 'estatCel' en condición de Home Assistant.
10
13
 
11
- :param codi_estatcel: Código del estado del cielo (celestial state code).
14
+ :param codi_estatcel: Código o lista de códigos del estado del cielo.
12
15
  :param current_time: Fecha y hora actual (datetime).
13
16
  :param hass: Instancia de Home Assistant.
17
+ :param is_hourly: Indica si los datos son de predicción horaria (True) o diaria (False).
14
18
  :return: Diccionario con la condición y el icono.
15
19
  """
16
- # Determinar si es de noche usando la lógica centralizada en helpers.py
20
+ # Asegurarse de que codi_estatcel sea una lista válida
21
+ if codi_estatcel is None:
22
+ codi_estatcel = []
23
+ elif isinstance(codi_estatcel, int): # Convertir enteros en lista
24
+ codi_estatcel = [codi_estatcel]
25
+
26
+ # Determinar si es de noche
17
27
  is_night_flag = is_night(current_time, hass)
18
28
 
19
29
  # Identificar la condición basada en el código
20
30
  for condition, codes in CONDITION_MAPPING.items():
21
- if codi_estatcel in codes:
31
+ if any(code in codes for code in codi_estatcel):
22
32
  # Ajustar para condiciones nocturnas si aplica
23
33
  if condition == "sunny" and is_night_flag:
24
34
  return {"condition": "clear-night", "icon": None}
@@ -9,6 +9,13 @@ VARIABLE_ID = "variable_id"
9
9
  STATION_NAME = "station_name"
10
10
  STATION_ID = "station_id"
11
11
 
12
+ from homeassistant.const import Platform
13
+
14
+ ATTRIBUTION = "Powered by Meteocatpy"
15
+ PLATFORMS = [Platform.SENSOR, Platform.WEATHER]
16
+ DEFAULT_NAME = "METEOCAT"
17
+
18
+
12
19
  # Códigos de sensores de la API
13
20
  WIND_SPEED = "wind_speed" # Velocidad del viento
14
21
  WIND_DIRECTION = "wind_direction" # Dirección del viento
@@ -24,6 +31,7 @@ MIN_TEMPERATURE = "min_temperature" # Temperatura mínima
24
31
  FEELS_LIKE = "feels_like" # Sensación térmica
25
32
  WIND_GUST = "wind_gust" # Racha de viento
26
33
  STATION_TIMESTAMP = "station_timestamp" # Código de tiempo de la estación
34
+ CONDITION = "condition" # Estado del cielo
27
35
 
28
36
  # Definición de códigos para variables
29
37
  WIND_SPEED_CODE = 30
@@ -41,7 +49,7 @@ WIND_GUST_CODE = 50
41
49
  # Mapeo de códigos 'estatCel' a condiciones de Home Assistant
42
50
  CONDITION_MAPPING = {
43
51
  "sunny": [1],
44
- "clear-night": [1],
52
+ # "clear-night": [1],
45
53
  "partlycloudy": [2, 3],
46
54
  "cloudy": [4, 20, 21, 22],
47
55
  "rainy": [5, 6, 23],
@@ -52,6 +60,3 @@ CONDITION_MAPPING = {
52
60
  "fog": [11, 12],
53
61
  "snow-rainy": [27, 29, 30],
54
62
  }
55
-
56
- # Platforms
57
- PLATFORMS = ["sensor"]