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.
@@ -1,42 +1,41 @@
1
1
  from __future__ import annotations
2
2
 
3
- from datetime import datetime, time
4
- from homeassistant.helpers import entity_registry
5
-
6
- def get_sun_times(hass) -> tuple:
7
- """
8
- Obtiene las horas de amanecer y atardecer desde la integración sun.
9
-
10
- :param hass: Instancia de Home Assistant.
11
- :return: Tupla con las horas de amanecer y atardecer (datetime).
12
- """
13
- sun_entity = hass.states.get("sun.sun")
14
- if sun_entity:
15
- sunrise = sun_entity.attributes.get("next_rising")
16
- sunset = sun_entity.attributes.get("next_setting")
17
- if sunrise and sunset:
18
- return (
19
- hass.util.dt.as_local(hass.util.dt.parse_datetime(sunrise)),
20
- hass.util.dt.as_local(hass.util.dt.parse_datetime(sunset)),
21
- )
22
- raise ValueError("No se pudo obtener las horas de amanecer y atardecer de sun.sun")
23
-
24
-
25
- def is_night(current_time: datetime, hass) -> bool:
26
- """
27
- Determina si la hora actual está fuera del rango entre el amanecer y el atardecer.
28
-
29
- :param current_time: Hora actual como objeto datetime.
30
- :param hass: Instancia de Home Assistant.
31
- :return: True si es de noche, False si es de día.
32
- """
33
- # Obtener las horas de amanecer y atardecer de la integración sun
34
- sunrise, sunset = get_sun_times(hass)
35
-
36
- # Convertimos a objetos time para comparar solo las horas
37
- current_time_only = current_time.time()
38
- sunrise_time_only = sunrise.time()
39
- sunset_time_only = sunset.time()
40
-
41
- # Devuelve True si la hora está fuera del rango del día
42
- return current_time_only < sunrise_time_only or current_time_only > sunset_time_only
3
+ import logging
4
+ from datetime import datetime, timedelta
5
+ from homeassistant.core import HomeAssistant
6
+ from homeassistant.util.dt import as_local, as_utc
7
+ from homeassistant.helpers.sun import get_astral_event_next
8
+
9
+ _LOGGER = logging.getLogger(__name__)
10
+
11
+ def get_sun_times(hass: HomeAssistant, current_time: datetime | None = None):
12
+ """Get the sunrise and sunset times."""
13
+ # Usa la hora actual si no se proporciona una hora específica
14
+ if current_time is None:
15
+ current_time = datetime.now()
16
+
17
+ # Asegúrate de que current_time es aware (UTC con offset)
18
+ current_time = as_utc(current_time)
19
+
20
+ # Obtén los tiempos de amanecer y atardecer desde el helper
21
+ sunrise = get_astral_event_next(hass, "sunrise", utc_point_in_time=current_time)
22
+ sunset = get_astral_event_next(hass, "sunset", utc_point_in_time=current_time)
23
+
24
+ # Asegúrate de que no sean None y conviértelos a la zona horaria local
25
+ if sunrise and sunset:
26
+ return as_local(sunrise), as_local(sunset)
27
+
28
+ # Lanza un error si no se pudieron determinar los eventos
29
+ raise ValueError("Sunrise or sunset data is unavailable.")
30
+
31
+ def is_night(current_time: datetime, hass: HomeAssistant) -> bool:
32
+ """Determine if it is currently night based on sunrise and sunset times."""
33
+ # Convierte current_time a UTC si no tiene información de zona horaria
34
+ if current_time.tzinfo is None:
35
+ current_time = as_utc(current_time)
36
+
37
+ # Obtén los tiempos de amanecer y atardecer
38
+ sunrise, sunset = get_sun_times(hass, current_time)
39
+
40
+ # Compara las horas
41
+ return current_time < sunrise or current_time > sunset
@@ -8,5 +8,5 @@
8
8
  "documentation": "https://gitlab.com/figorr/meteocat",
9
9
  "loggers": ["meteocatpy"],
10
10
  "requirements": ["meteocatpy==0.0.15", "packaging>=20.3", "wrapt>=1.14.0"],
11
- "version": "0.1.38"
11
+ "version": "0.1.39"
12
12
  }
@@ -45,6 +45,7 @@ from .const import (
45
45
  MIN_TEMPERATURE,
46
46
  WIND_GUST,
47
47
  STATION_TIMESTAMP,
48
+ CONDITION,
48
49
  WIND_SPEED_CODE,
49
50
  WIND_DIRECTION_CODE,
50
51
  TEMPERATURE_CODE,
@@ -61,7 +62,9 @@ from .const import (
61
62
 
62
63
  from .coordinator import (
63
64
  MeteocatSensorCoordinator,
65
+ MeteocatStaticSensorCoordinator,
64
66
  MeteocatUviFileCoordinator,
67
+ MeteocatConditionCoordinator,
65
68
  )
66
69
 
67
70
  _LOGGER = logging.getLogger(__name__)
@@ -137,7 +140,7 @@ SENSOR_TYPES: tuple[MeteocatSensorEntityDescription, ...] = (
137
140
  MeteocatSensorEntityDescription(
138
141
  key=UV_INDEX,
139
142
  translation_key="uv_index",
140
- icon="mdi:weather-sunny",
143
+ icon="mdi:weather-sunny-alert",
141
144
  ),
142
145
  MeteocatSensorEntityDescription(
143
146
  key=MAX_TEMPERATURE,
@@ -197,10 +200,15 @@ SENSOR_TYPES: tuple[MeteocatSensorEntityDescription, ...] = (
197
200
  entity_category=EntityCategory.DIAGNOSTIC,
198
201
  ),
199
202
  MeteocatSensorEntityDescription(
200
- key=STATION_TIMESTAMP,
201
- translation_key="station_timestamp",
202
- icon="mdi:calendar-clock",
203
- device_class=SensorDeviceClass.TIMESTAMP,
203
+ key=STATION_TIMESTAMP,
204
+ translation_key="station_timestamp",
205
+ icon="mdi:calendar-clock",
206
+ device_class=SensorDeviceClass.TIMESTAMP,
207
+ ),
208
+ MeteocatSensorEntityDescription(
209
+ key=CONDITION,
210
+ translation_key="condition",
211
+ icon="mdi:weather-partly-cloudy",
204
212
  )
205
213
  )
206
214
 
@@ -212,12 +220,21 @@ async def async_setup_entry(hass, entry, async_add_entities: AddEntitiesCallback
212
220
  # Coordinadores para sensores
213
221
  coordinator = entry_data.get("sensor_coordinator")
214
222
  uvi_file_coordinator = entry_data.get("uvi_file_coordinator")
223
+ static_sensor_coordinator = entry_data.get("static_sensor_coordinator")
224
+ condition_coordinator = entry_data.get("condition_coordinator")
215
225
 
216
226
  # Sensores generales
217
227
  async_add_entities(
218
228
  MeteocatSensor(coordinator, description, entry_data)
219
229
  for description in SENSOR_TYPES
220
- if description.key != UV_INDEX # Excluir UVI del coordinador general
230
+ if description.key not in {TOWN_NAME, TOWN_ID, STATION_NAME, STATION_ID, UV_INDEX, CONDITION} # Excluir estáticos y UVI
231
+ )
232
+
233
+ # Sensores estáticos
234
+ async_add_entities(
235
+ MeteocatStaticSensor(static_sensor_coordinator, description, entry_data)
236
+ for description in SENSOR_TYPES
237
+ if description.key in {TOWN_NAME, TOWN_ID, STATION_NAME, STATION_ID}
221
238
  )
222
239
 
223
240
  # Sensor UVI
@@ -227,6 +244,66 @@ async def async_setup_entry(hass, entry, async_add_entities: AddEntitiesCallback
227
244
  if description.key == UV_INDEX # Incluir UVI en el coordinador UVI FILE COORDINATOR
228
245
  )
229
246
 
247
+ # Sensor CONDITION para estado del cielo
248
+ async_add_entities(
249
+ MeteocatConditionSensor(condition_coordinator, description, entry_data)
250
+ for description in SENSOR_TYPES
251
+ if description.key == CONDITION # Incluir CONDITION en el coordinador CONDITION COORDINATOR
252
+ )
253
+
254
+ class MeteocatStaticSensor(CoordinatorEntity[MeteocatStaticSensorCoordinator], SensorEntity):
255
+ """Representation of a static Meteocat sensor."""
256
+ STATIC_KEYS = {TOWN_NAME, TOWN_ID, STATION_NAME, STATION_ID}
257
+
258
+ _attr_has_entity_name = True # Activa el uso de nombres basados en el dispositivo
259
+
260
+ def __init__(self, static_sensor_coordinator, description, entry_data):
261
+ """Initialize the static sensor."""
262
+ super().__init__(static_sensor_coordinator)
263
+ self.entity_description = description
264
+ self._town_name = entry_data["town_name"]
265
+ self._town_id = entry_data["town_id"]
266
+ self._station_name = entry_data["station_name"]
267
+ self._station_id = entry_data["station_id"]
268
+
269
+ # Unique ID for the entity
270
+ self._attr_unique_id = f"sensor.{DOMAIN}_{self._station_id}_{self.entity_description.key}"
271
+
272
+ # Assign entity_category if defined in the description
273
+ self._attr_entity_category = getattr(description, "entity_category", None)
274
+
275
+ # Log para depuración
276
+ _LOGGER.debug(
277
+ "Inicializando sensor: %s, Unique ID: %s",
278
+ self.entity_description.name,
279
+ self._attr_unique_id,
280
+ )
281
+
282
+ @property
283
+ def native_value(self):
284
+ """Return the state of the sensor."""
285
+ # Información estática
286
+ if self.entity_description.key in self.STATIC_KEYS:
287
+ # Información estática del `entry_data`
288
+ if self.entity_description.key == TOWN_NAME:
289
+ return self._town_name
290
+ if self.entity_description.key == TOWN_ID:
291
+ return self._town_id
292
+ if self.entity_description.key == STATION_NAME:
293
+ return self._station_name
294
+ if self.entity_description.key == STATION_ID:
295
+ return self._station_id
296
+
297
+ @property
298
+ def device_info(self) -> DeviceInfo:
299
+ """Return the device info."""
300
+ return DeviceInfo(
301
+ identifiers={(DOMAIN, self._town_id)},
302
+ name="Meteocat " + self._station_id + " " + self._town_name,
303
+ manufacturer="Meteocat",
304
+ model="Meteocat API",
305
+ )
306
+
230
307
  class MeteocatUviSensor(CoordinatorEntity[MeteocatUviFileCoordinator], SensorEntity):
231
308
  """Representation of a Meteocat UV Index sensor."""
232
309
 
@@ -280,9 +357,61 @@ class MeteocatUviSensor(CoordinatorEntity[MeteocatUviFileCoordinator], SensorEnt
280
357
  model="Meteocat API",
281
358
  )
282
359
 
360
+ class MeteocatConditionSensor(CoordinatorEntity[MeteocatConditionCoordinator], SensorEntity):
361
+ """Representation of a Meteocat UV Index sensor."""
362
+
363
+ _attr_has_entity_name = True # Activa el uso de nombres basados en el dispositivo
364
+
365
+ def __init__(self, condition_coordinator, description, entry_data):
366
+ """Initialize the UV Index sensor."""
367
+ super().__init__(condition_coordinator)
368
+ self.entity_description = description
369
+ self._town_name = entry_data["town_name"]
370
+ self._town_id = entry_data["town_id"]
371
+ self._station_id = entry_data["station_id"]
372
+
373
+ # Unique ID for the entity
374
+ self._attr_unique_id = f"sensor.{DOMAIN}_{self._town_id}_{self.entity_description.key}"
375
+
376
+ # Asigna entity_category desde description (si está definido)
377
+ self._attr_entity_category = getattr(description, "entity_category", None)
378
+
379
+ # Log para depuración
380
+ _LOGGER.debug(
381
+ "Inicializando sensor: %s, Unique ID: %s",
382
+ self.entity_description.name,
383
+ self._attr_unique_id,
384
+ )
385
+
386
+ @property
387
+ def native_value(self):
388
+ """Return the current UV index value."""
389
+ if self.entity_description.key == CONDITION:
390
+ condition_data = self.coordinator.data or {}
391
+ return condition_data.get("condition", None)
392
+
393
+ @property
394
+ def extra_state_attributes(self):
395
+ """Return additional attributes for the sensor."""
396
+ attributes = super().extra_state_attributes or {}
397
+ if self.entity_description.key == CONDITION:
398
+ condition_data = self.coordinator.data or {}
399
+ # Add the "hour" attribute if it exists
400
+ attributes["hour"] = condition_data.get("hour", None)
401
+ return attributes
402
+
403
+ @property
404
+ def device_info(self) -> DeviceInfo:
405
+ """Return the device info."""
406
+ return DeviceInfo(
407
+ identifiers={(DOMAIN, self._town_id)},
408
+ name="Meteocat " + self._station_id + " " + self._town_name,
409
+ manufacturer="Meteocat",
410
+ model="Meteocat API",
411
+ )
412
+
283
413
  class MeteocatSensor(CoordinatorEntity[MeteocatSensorCoordinator], SensorEntity):
284
414
  """Representation of a Meteocat sensor."""
285
- STATIC_KEYS = {TOWN_NAME, TOWN_ID, STATION_NAME, STATION_ID}
286
415
 
287
416
  CODE_MAPPING = {
288
417
  WIND_SPEED: WIND_SPEED_CODE,
@@ -326,19 +455,7 @@ class MeteocatSensor(CoordinatorEntity[MeteocatSensorCoordinator], SensorEntity)
326
455
  @property
327
456
  def native_value(self):
328
457
  """Return the state of the sensor."""
329
- # Información estática
330
- if self.entity_description.key in self.STATIC_KEYS:
331
- # Información estática del `entry_data`
332
- if self.entity_description.key == TOWN_NAME:
333
- return self._town_name
334
- if self.entity_description.key == TOWN_ID:
335
- return self._town_id
336
- if self.entity_description.key == STATION_NAME:
337
- return self._station_name
338
- if self.entity_description.key == STATION_ID:
339
- return self._station_id
340
458
  # Información dinámica
341
-
342
459
  if self.entity_description.key == FEELS_LIKE:
343
460
  stations = self.coordinator.data or []
344
461
 
@@ -107,6 +107,26 @@
107
107
  },
108
108
  "station_timestamp": {
109
109
  "name": "Station Timestamp"
110
+ },
111
+ "condition": {
112
+ "name": "Condition",
113
+ "state": {
114
+ "sunny": "Sunny",
115
+ "clear-night": "Clear Night",
116
+ "partlycloudy": "Partly Cloudy",
117
+ "cloudy": "Cloudy",
118
+ "rainy": "Rainy",
119
+ "pouring": "Pouring",
120
+ "lightning-rainy": "Lightning Rainy",
121
+ "hail": "Hail",
122
+ "snowy": "Snowy",
123
+ "snow-rainy": "Snow Rainy"
124
+ },
125
+ "state_attributes": {
126
+ "hour": {
127
+ "name": "Hour"
128
+ }
129
+ }
110
130
  }
111
131
  }
112
132
  }
@@ -107,6 +107,26 @@
107
107
  },
108
108
  "station_timestamp": {
109
109
  "name": "Estació Timestamp"
110
+ },
111
+ "condition": {
112
+ "name": "Estat del Cel",
113
+ "state": {
114
+ "sunny": "Assolellat",
115
+ "clear-night": "Nit Clara",
116
+ "partlycloudy": "Parcialment ennuvolat",
117
+ "cloudy": "Ennuvolat",
118
+ "rainy": "Plovent",
119
+ "pouring": "Tormenta",
120
+ "lightning-rainy": "Tormenta amb Llamps",
121
+ "hail": "Calamarsa",
122
+ "snowy": "Nevant",
123
+ "snow-rainy": "Neu amb Pluja"
124
+ },
125
+ "state_attributes": {
126
+ "hour": {
127
+ "name": "Hora"
128
+ }
129
+ }
110
130
  }
111
131
  }
112
132
  }
@@ -107,6 +107,26 @@
107
107
  },
108
108
  "station_timestamp": {
109
109
  "name": "Station Timestamp"
110
+ },
111
+ "condition": {
112
+ "name": "Condition",
113
+ "state": {
114
+ "sunny": "Sunny",
115
+ "clear-night": "Clear Night",
116
+ "partlycloudy": "Partly Cloudy",
117
+ "cloudy": "Cloudy",
118
+ "rainy": "Rainy",
119
+ "pouring": "Pouring",
120
+ "lightning-rainy": "Lightning Rainy",
121
+ "hail": "Hail",
122
+ "snowy": "Snowy",
123
+ "snow-rainy": "Snow Rainy"
124
+ },
125
+ "state_attributes": {
126
+ "hour": {
127
+ "name": "Hour"
128
+ }
129
+ }
110
130
  }
111
131
  }
112
132
  }
@@ -107,6 +107,26 @@
107
107
  },
108
108
  "station_timestamp": {
109
109
  "name": "Estación Timestamp"
110
+ },
111
+ "condition": {
112
+ "name": "Estado del cielo",
113
+ "state": {
114
+ "sunny": "Soleado",
115
+ "clear-night": "Noche Despejada",
116
+ "partlycloudy": "Parcialmente Nublado",
117
+ "cloudy": "Nublado",
118
+ "rainy": "Lluvioso",
119
+ "pouring": "Tormenta",
120
+ "lightning-rainy": "Tormenta con Rayos",
121
+ "hail": "Granizo",
122
+ "snowy": "Nevando",
123
+ "snow-rainy": "Nieve con Lluvia"
124
+ },
125
+ "state_attributes": {
126
+ "hour": {
127
+ "name": "Hora"
128
+ }
129
+ }
110
130
  }
111
131
  }
112
132
  }
@@ -1,2 +1,2 @@
1
1
  # version.py
2
- __version__ = "0.1.38"
2
+ __version__ = "0.1.39"
@@ -0,0 +1,171 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from datetime import datetime
5
+ from typing import Optional
6
+ from homeassistant.helpers.update_coordinator import CoordinatorEntity
7
+ from homeassistant.components.weather import (
8
+ WeatherEntity,
9
+ WeatherEntityFeature,
10
+ Forecast,
11
+ )
12
+ from homeassistant.core import callback
13
+ from homeassistant.helpers.entity_platform import AddEntitiesCallback
14
+ from homeassistant.components.weather import Forecast
15
+ from homeassistant.helpers.device_registry import DeviceInfo
16
+ from homeassistant.const import (
17
+ DEGREE,
18
+ PERCENTAGE,
19
+ UnitOfPrecipitationDepth,
20
+ UnitOfVolumetricFlux,
21
+ UnitOfPressure,
22
+ UnitOfSpeed,
23
+ UnitOfTemperature,
24
+ )
25
+
26
+ from .const import (
27
+ DOMAIN,
28
+ ATTRIBUTION,
29
+ )
30
+ from .coordinator import (
31
+ HourlyForecastCoordinator,
32
+ DailyForecastCoordinator,
33
+ )
34
+
35
+ _LOGGER = logging.getLogger(__name__)
36
+
37
+ @callback
38
+ async def async_setup_entry(hass, entry, async_add_entities: AddEntitiesCallback) -> None:
39
+ """Set up Meteocat weather entity from a config entry."""
40
+ entry_data = hass.data[DOMAIN][entry.entry_id]
41
+
42
+ hourly_forecast_coordinator = entry_data.get("hourly_forecast_coordinator")
43
+ daily_forecast_coordinator = entry_data.get("daily_forecast_coordinator")
44
+
45
+ async_add_entities([
46
+ MeteocatWeatherEntity(hourly_forecast_coordinator, daily_forecast_coordinator, entry_data)
47
+ ])
48
+
49
+ class MeteocatWeatherEntity(CoordinatorEntity, WeatherEntity):
50
+ """Representation of a Meteocat Weather Entity."""
51
+ _attr_attribution = ATTRIBUTION
52
+ _attr_has_entity_name = True
53
+ _attr_native_precipitation_unit = UnitOfPrecipitationDepth.MILLIMETERS
54
+ _attr_native_pressure_unit = UnitOfPressure.HPA
55
+ _attr_native_temperature_unit = UnitOfTemperature.CELSIUS
56
+ _attr_native_wind_speed_unit = UnitOfSpeed.KILOMETERS_PER_HOUR
57
+ _attr_native_wind_bearing_unit = DEGREE
58
+ _attr_supported_features = (
59
+ WeatherEntityFeature.FORECAST_HOURLY | WeatherEntityFeature.FORECAST_DAILY
60
+ )
61
+
62
+ def __init__(
63
+ self,
64
+ hourly_forecast_coordinator: HourlyForecastCoordinator,
65
+ daily_forecast_coordinator: DailyForecastCoordinator,
66
+ entry_data: dict,
67
+ ) -> None:
68
+ """Initialize the weather entity."""
69
+ super().__init__(hourly_forecast_coordinator)
70
+ self._hourly_forecast_coordinator = hourly_forecast_coordinator
71
+ self._daily_forecast_coordinator = daily_forecast_coordinator
72
+ self._town_name = entry_data["town_name"]
73
+ self._town_id = entry_data["town_id"]
74
+ self._station_id = entry_data["station_id"]
75
+
76
+ @property
77
+ def name(self) -> str:
78
+ """Return the name of the entity."""
79
+ return f"Weather {self._town_name}"
80
+
81
+ @property
82
+ def unique_id(self) -> str:
83
+ """Return the unique ID of the entity."""
84
+ return f"weather.{DOMAIN}_{self._station_id}"
85
+
86
+ @property
87
+ def condition(self) -> Optional[str]:
88
+ """Return the current weather condition."""
89
+ forecast_today = self._daily_forecast_coordinator.get_forecast_for_today()
90
+ if forecast_today:
91
+ return forecast_today.get("condition")
92
+ return None
93
+
94
+ @property
95
+ def temperature(self) -> Optional[float]:
96
+ """Return the current temperature."""
97
+ forecast_today = self._daily_forecast_coordinator.get_forecast_for_today()
98
+ if forecast_today:
99
+ return (forecast_today.get("temperature_max") + forecast_today.get("temperature_min")) / 2
100
+ return None
101
+
102
+ @property
103
+ def forecast(self) -> list[Forecast]:
104
+ """Return the daily forecast."""
105
+ daily_forecasts = self._daily_forecast_coordinator.get_all_daily_forecasts()
106
+ return [
107
+ Forecast(
108
+ datetime=forecast["date"],
109
+ temperature=forecast["temperature_max"],
110
+ templow=forecast["temperature_min"],
111
+ precipitation=forecast["precipitation"],
112
+ condition=forecast["condition"],
113
+ )
114
+ for forecast in daily_forecasts
115
+ ]
116
+
117
+ async def async_forecast_hourly(self) -> list[Forecast] | None:
118
+ """Return the hourly forecast."""
119
+ hourly_forecasts = await self._hourly_forecast_coordinator.async_forecast_hourly()
120
+ if not hourly_forecasts:
121
+ return None
122
+
123
+ return [
124
+ Forecast(
125
+ datetime=forecast.datetime,
126
+ temperature=forecast.temperature,
127
+ precipitation=forecast.precipitation,
128
+ condition=forecast.condition,
129
+ wind_speed=forecast.wind_speed,
130
+ wind_bearing=forecast.wind_bearing,
131
+ humidity=forecast.humidity,
132
+ )
133
+ for forecast in hourly_forecasts
134
+ ]
135
+
136
+ async def async_forecast_daily(self) -> list[Forecast] | None:
137
+ """Return the daily forecast."""
138
+ # Asegúrate de que los datos estén actualizados antes de procesarlos
139
+ await self._daily_forecast_coordinator.async_request_refresh()
140
+
141
+ # Obtén las predicciones diarias procesadas desde el coordinador
142
+ daily_forecasts = self._daily_forecast_coordinator.get_all_daily_forecasts()
143
+ if not daily_forecasts:
144
+ return None
145
+
146
+ # Convierte las predicciones a la estructura Forecast de Home Assistant
147
+ return [
148
+ Forecast(
149
+ datetime=forecast["date"],
150
+ temperature=forecast["temperature_max"],
151
+ templow=forecast["temperature_min"],
152
+ precipitation=forecast["precipitation"],
153
+ condition=forecast["condition"],
154
+ )
155
+ for forecast in daily_forecasts
156
+ ]
157
+
158
+ async def async_update(self) -> None:
159
+ """Update the weather entity."""
160
+ await self._hourly_forecast_coordinator.async_request_refresh()
161
+ await self._daily_forecast_coordinator.async_request_refresh()
162
+
163
+ @property
164
+ def device_info(self) -> DeviceInfo:
165
+ """Return the device info."""
166
+ return DeviceInfo(
167
+ identifiers={(DOMAIN, self._town_id)},
168
+ name=f"Meteocat {self._station_id}",
169
+ manufacturer="Meteocat",
170
+ model="Meteocat API",
171
+ )
package/filetree.txt CHANGED
@@ -10,6 +10,7 @@
10
10
  ├── CHANGELOG.md
11
11
  ├── LICENSE
12
12
  ├── README.md
13
+ ├── conftest.py
13
14
  └── custom_components/
14
15
  └── meteocat/
15
16
  ├── __init__.py
@@ -17,7 +18,6 @@
17
18
  ├── config_flow.py
18
19
  ├── const.py
19
20
  ├── coordinator.py
20
- ├── entity.py
21
21
  ├── helpers.py
22
22
  ├── manifest.json
23
23
  ├── options_flow.py
@@ -28,6 +28,7 @@
28
28
  ├── en.json
29
29
  ├── es.json
30
30
  ├── version.py
31
+ ├── weather.py
31
32
  ├── filetree.py
32
33
  ├── filetree.txt
33
34
  ├── hacs.json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meteocat",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\r [![Python version compatibility](https://img.shields.io/pypi/pyversions/meteocat)](https://pypi.org/project/meteocat)\r [![pipeline status](https://gitlab.com/figorr/meteocat/badges/master/pipeline.svg)](https://gitlab.com/figorr/meteocat/commits/master)",
5
5
  "main": "index.js",
6
6
  "directories": {
package/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "meteocat"
3
- version = "0.1.38"
3
+ version = "0.1.39"
4
4
  description = "Script para obtener datos meteorológicos de la API de Meteocat"
5
5
  authors = ["figorr <jdcuartero@yahoo.es>"]
6
6
  license = "Apache-2.0"