meteocat 1.1.1 → 2.0.1
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 +17 -0
- package/README.md +16 -2
- package/custom_components/meteocat/__init__.py +23 -1
- package/custom_components/meteocat/config_flow.py +56 -35
- package/custom_components/meteocat/const.py +21 -2
- package/custom_components/meteocat/coordinator.py +455 -0
- package/custom_components/meteocat/manifest.json +1 -1
- package/custom_components/meteocat/options_flow.py +104 -25
- package/custom_components/meteocat/sensor.py +340 -3
- package/custom_components/meteocat/strings.json +447 -2
- package/custom_components/meteocat/translations/ca.json +448 -3
- package/custom_components/meteocat/translations/en.json +447 -3
- package/custom_components/meteocat/translations/es.json +447 -2
- package/custom_components/meteocat/version.py +1 -1
- package/filetree.txt +1 -0
- package/images/api_limits.png +0 -0
- package/images/dynamic_sensors.png +0 -0
- package/images/pick_station.png +0 -0
- package/package.json +1 -1
- package/pyproject.toml +1 -1
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from datetime import datetime, timezone, time
|
|
5
|
-
from zoneinfo import ZoneInfo
|
|
4
|
+
from datetime import datetime, timezone, time, timedelta
|
|
5
|
+
from zoneinfo import ZoneInfo
|
|
6
|
+
import os
|
|
7
|
+
import json
|
|
8
|
+
import aiofiles
|
|
9
|
+
import asyncio
|
|
6
10
|
import logging
|
|
7
11
|
from homeassistant.helpers.entity import (
|
|
8
12
|
DeviceInfo,
|
|
@@ -15,6 +19,7 @@ from homeassistant.components.sensor import (
|
|
|
15
19
|
SensorStateClass,
|
|
16
20
|
)
|
|
17
21
|
from homeassistant.core import callback
|
|
22
|
+
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
18
23
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
19
24
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|
20
25
|
from homeassistant.const import (
|
|
@@ -55,6 +60,16 @@ from .const import (
|
|
|
55
60
|
HOURLY_FORECAST_FILE_STATUS,
|
|
56
61
|
DAILY_FORECAST_FILE_STATUS,
|
|
57
62
|
UVI_FILE_STATUS,
|
|
63
|
+
ALERTS,
|
|
64
|
+
ALERT_FILE_STATUS,
|
|
65
|
+
ALERT_WIND,
|
|
66
|
+
ALERT_RAIN_INTENSITY,
|
|
67
|
+
ALERT_RAIN,
|
|
68
|
+
ALERT_SEA,
|
|
69
|
+
ALERT_COLD,
|
|
70
|
+
ALERT_WARM,
|
|
71
|
+
ALERT_WARM_NIGHT,
|
|
72
|
+
ALERT_SNOW,
|
|
58
73
|
WIND_SPEED_CODE,
|
|
59
74
|
WIND_DIRECTION_CODE,
|
|
60
75
|
TEMPERATURE_CODE,
|
|
@@ -70,6 +85,7 @@ from .const import (
|
|
|
70
85
|
DEFAULT_VALIDITY_DAYS,
|
|
71
86
|
DEFAULT_VALIDITY_HOURS,
|
|
72
87
|
DEFAULT_VALIDITY_MINUTES,
|
|
88
|
+
DEFAULT_ALERT_VALIDITY_TIME,
|
|
73
89
|
)
|
|
74
90
|
|
|
75
91
|
from .coordinator import (
|
|
@@ -81,6 +97,8 @@ from .coordinator import (
|
|
|
81
97
|
MeteocatEntityCoordinator,
|
|
82
98
|
DailyForecastCoordinator,
|
|
83
99
|
MeteocatUviCoordinator,
|
|
100
|
+
MeteocatAlertsCoordinator,
|
|
101
|
+
MeteocatAlertsRegionCoordinator,
|
|
84
102
|
)
|
|
85
103
|
|
|
86
104
|
# Definir la zona horaria local
|
|
@@ -275,6 +293,57 @@ SENSOR_TYPES: tuple[MeteocatSensorEntityDescription, ...] = (
|
|
|
275
293
|
translation_key="uvi_file_status",
|
|
276
294
|
icon="mdi:update",
|
|
277
295
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
296
|
+
),
|
|
297
|
+
MeteocatSensorEntityDescription(
|
|
298
|
+
key=ALERTS,
|
|
299
|
+
translation_key="alerts",
|
|
300
|
+
icon="mdi:alert-outline",
|
|
301
|
+
),
|
|
302
|
+
MeteocatSensorEntityDescription(
|
|
303
|
+
key=ALERT_FILE_STATUS,
|
|
304
|
+
translation_key="alert_file_status",
|
|
305
|
+
icon="mdi:update",
|
|
306
|
+
entity_category=EntityCategory.DIAGNOSTIC,
|
|
307
|
+
),
|
|
308
|
+
MeteocatSensorEntityDescription(
|
|
309
|
+
key=ALERT_WIND,
|
|
310
|
+
translation_key="alert_wind",
|
|
311
|
+
icon="mdi:alert-outline",
|
|
312
|
+
),
|
|
313
|
+
MeteocatSensorEntityDescription(
|
|
314
|
+
key=ALERT_RAIN_INTENSITY,
|
|
315
|
+
translation_key="alert_rain_intensity",
|
|
316
|
+
icon="mdi:alert-outline",
|
|
317
|
+
),
|
|
318
|
+
MeteocatSensorEntityDescription(
|
|
319
|
+
key=ALERT_RAIN,
|
|
320
|
+
translation_key="alert_rain",
|
|
321
|
+
icon="mdi:alert-outline",
|
|
322
|
+
),
|
|
323
|
+
MeteocatSensorEntityDescription(
|
|
324
|
+
key=ALERT_SEA,
|
|
325
|
+
translation_key="alert_sea",
|
|
326
|
+
icon="mdi:alert-outline",
|
|
327
|
+
),
|
|
328
|
+
MeteocatSensorEntityDescription(
|
|
329
|
+
key=ALERT_COLD,
|
|
330
|
+
translation_key="alert_cold",
|
|
331
|
+
icon="mdi:alert-outline",
|
|
332
|
+
),
|
|
333
|
+
MeteocatSensorEntityDescription(
|
|
334
|
+
key=ALERT_WARM,
|
|
335
|
+
translation_key="alert_warm",
|
|
336
|
+
icon="mdi:alert-outline",
|
|
337
|
+
),
|
|
338
|
+
MeteocatSensorEntityDescription(
|
|
339
|
+
key=ALERT_WARM_NIGHT,
|
|
340
|
+
translation_key="alert_warm_night",
|
|
341
|
+
icon="mdi:alert-outline",
|
|
342
|
+
),
|
|
343
|
+
MeteocatSensorEntityDescription(
|
|
344
|
+
key=ALERT_SNOW,
|
|
345
|
+
translation_key="alert_snow",
|
|
346
|
+
icon="mdi:alert-outline",
|
|
278
347
|
)
|
|
279
348
|
)
|
|
280
349
|
|
|
@@ -292,6 +361,8 @@ async def async_setup_entry(hass, entry, async_add_entities: AddEntitiesCallback
|
|
|
292
361
|
temp_forecast_coordinator = entry_data.get("temp_forecast_coordinator")
|
|
293
362
|
entity_coordinator = entry_data.get("entity_coordinator")
|
|
294
363
|
uvi_coordinator = entry_data.get("uvi_coordinator")
|
|
364
|
+
alerts_coordinator = entry_data.get("alerts_coordinator")
|
|
365
|
+
alerts_region_coordinator = entry_data.get("alerts_region_coordinator")
|
|
295
366
|
|
|
296
367
|
# Sensores generales
|
|
297
368
|
async_add_entities(
|
|
@@ -356,6 +427,27 @@ async def async_setup_entry(hass, entry, async_add_entities: AddEntitiesCallback
|
|
|
356
427
|
if description.key == UVI_FILE_STATUS
|
|
357
428
|
)
|
|
358
429
|
|
|
430
|
+
# Sensores de alertas
|
|
431
|
+
async_add_entities(
|
|
432
|
+
MeteocatAlertStatusSensor(alerts_coordinator, description, entry_data)
|
|
433
|
+
for description in SENSOR_TYPES
|
|
434
|
+
if description.key == ALERT_FILE_STATUS
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
# Sensores de alertas para la comarca
|
|
438
|
+
async_add_entities(
|
|
439
|
+
MeteocatAlertRegionSensor(alerts_region_coordinator, description, entry_data)
|
|
440
|
+
for description in SENSOR_TYPES
|
|
441
|
+
if description.key == ALERTS
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
# Sensores de alertas para cada meteor
|
|
445
|
+
async_add_entities(
|
|
446
|
+
MeteocatAlertMeteorSensor(alerts_region_coordinator, description, entry_data)
|
|
447
|
+
for description in SENSOR_TYPES
|
|
448
|
+
if description.key in {ALERT_WIND, ALERT_RAIN_INTENSITY, ALERT_RAIN, ALERT_SEA, ALERT_COLD, ALERT_WARM, ALERT_WARM_NIGHT, ALERT_SNOW}
|
|
449
|
+
)
|
|
450
|
+
|
|
359
451
|
# Cambiar UTC a la zona horaria local
|
|
360
452
|
def convert_to_local_time(utc_time: str, local_tz: str = "Europe/Madrid") -> datetime | None:
|
|
361
453
|
"""
|
|
@@ -1032,4 +1124,249 @@ class MeteocatUviStatusSensor(CoordinatorEntity[MeteocatUviCoordinator], SensorE
|
|
|
1032
1124
|
name="Meteocat " + self._station_id + " " + self._town_name,
|
|
1033
1125
|
manufacturer="Meteocat",
|
|
1034
1126
|
model="Meteocat API",
|
|
1035
|
-
)
|
|
1127
|
+
)
|
|
1128
|
+
|
|
1129
|
+
class MeteocatAlertStatusSensor(CoordinatorEntity[MeteocatAlertsCoordinator], SensorEntity):
|
|
1130
|
+
_attr_has_entity_name = True # Activa el uso de nombres basados en el dispositivo
|
|
1131
|
+
|
|
1132
|
+
def __init__(self, alerts_coordinator, description, entry_data):
|
|
1133
|
+
super().__init__(alerts_coordinator)
|
|
1134
|
+
self.entity_description = description
|
|
1135
|
+
self._town_name = entry_data["town_name"]
|
|
1136
|
+
self._town_id = entry_data["town_id"]
|
|
1137
|
+
self._station_id = entry_data["station_id"]
|
|
1138
|
+
self._region_id = entry_data["region_id"]
|
|
1139
|
+
|
|
1140
|
+
# Unique ID for the entity
|
|
1141
|
+
self._attr_unique_id = f"sensor.{DOMAIN}_{self._region_id}_alert_status"
|
|
1142
|
+
|
|
1143
|
+
# Assign entity_category if defined in the description
|
|
1144
|
+
self._attr_entity_category = getattr(description, "entity_category", None)
|
|
1145
|
+
|
|
1146
|
+
def _get_data_update(self):
|
|
1147
|
+
"""Obtiene la fecha de actualización directamente desde el coordinador."""
|
|
1148
|
+
data_update = self.coordinator.data.get("actualizado")
|
|
1149
|
+
if data_update:
|
|
1150
|
+
try:
|
|
1151
|
+
return datetime.fromisoformat(data_update.rstrip("Z"))
|
|
1152
|
+
except ValueError:
|
|
1153
|
+
_LOGGER.error("Formato de fecha de actualización inválido: %s", data_update)
|
|
1154
|
+
return None
|
|
1155
|
+
|
|
1156
|
+
@property
|
|
1157
|
+
def native_value(self):
|
|
1158
|
+
"""Devuelve el estado actual de las alertas basado en la fecha de actualización."""
|
|
1159
|
+
data_update = self._get_data_update()
|
|
1160
|
+
if not data_update:
|
|
1161
|
+
return "unknown"
|
|
1162
|
+
|
|
1163
|
+
current_time = datetime.now(ZoneInfo("UTC"))
|
|
1164
|
+
|
|
1165
|
+
# Comprobar si el archivo de alertas está obsoleto
|
|
1166
|
+
if current_time - data_update >= timedelta(hours=DEFAULT_ALERT_VALIDITY_TIME):
|
|
1167
|
+
return "obsolete"
|
|
1168
|
+
|
|
1169
|
+
return "updated"
|
|
1170
|
+
|
|
1171
|
+
@property
|
|
1172
|
+
def extra_state_attributes(self):
|
|
1173
|
+
"""Devuelve los atributos adicionales del estado."""
|
|
1174
|
+
attributes = super().extra_state_attributes or {}
|
|
1175
|
+
data_update = self._get_data_update()
|
|
1176
|
+
if data_update:
|
|
1177
|
+
attributes["update_date"] = data_update.isoformat()
|
|
1178
|
+
return attributes
|
|
1179
|
+
|
|
1180
|
+
@property
|
|
1181
|
+
def device_info(self) -> DeviceInfo:
|
|
1182
|
+
"""Devuelve la información del dispositivo."""
|
|
1183
|
+
return DeviceInfo(
|
|
1184
|
+
identifiers={(DOMAIN, self._town_id)},
|
|
1185
|
+
name=f"Meteocat {self._station_id} {self._town_name}",
|
|
1186
|
+
manufacturer="Meteocat",
|
|
1187
|
+
model="Meteocat API",
|
|
1188
|
+
)
|
|
1189
|
+
|
|
1190
|
+
class MeteocatAlertRegionSensor(CoordinatorEntity[MeteocatAlertsRegionCoordinator], SensorEntity):
|
|
1191
|
+
"""Sensor dinámico que muestra el estado de las alertas por región."""
|
|
1192
|
+
|
|
1193
|
+
METEOR_MAPPING = {
|
|
1194
|
+
"Temps violent": "violent_weather",
|
|
1195
|
+
"Intensitat de pluja": "rain_intensity",
|
|
1196
|
+
"Acumulació de pluja": "rain_amount",
|
|
1197
|
+
"Neu acumulada en 24 hores": "snow_amount_24",
|
|
1198
|
+
"Vent": "wind",
|
|
1199
|
+
"Estat de la mar": "sea_state",
|
|
1200
|
+
"Fred": "cold",
|
|
1201
|
+
"Calor": "heat",
|
|
1202
|
+
"Calor nocturna": "night_heat",
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
_attr_has_entity_name = True # Activa el uso de nombres basados en el dispositivo
|
|
1206
|
+
|
|
1207
|
+
def __init__(self, alerts_region_coordinator, description, entry_data):
|
|
1208
|
+
super().__init__(alerts_region_coordinator)
|
|
1209
|
+
self.entity_description = description
|
|
1210
|
+
self._town_name = entry_data["town_name"]
|
|
1211
|
+
self._town_id = entry_data["town_id"]
|
|
1212
|
+
self._station_id = entry_data["station_id"]
|
|
1213
|
+
self._region_id = entry_data["region_id"]
|
|
1214
|
+
|
|
1215
|
+
# Unique ID for the entity
|
|
1216
|
+
self._attr_unique_id = f"sensor.{DOMAIN}_{self._region_id}_alerts"
|
|
1217
|
+
|
|
1218
|
+
# Assign entity_category if defined in the description
|
|
1219
|
+
self._attr_entity_category = getattr(description, "entity_category", None)
|
|
1220
|
+
|
|
1221
|
+
@property
|
|
1222
|
+
def native_value(self):
|
|
1223
|
+
"""Devuelve el número de alertas activas."""
|
|
1224
|
+
return self.coordinator.data.get("activas", 0)
|
|
1225
|
+
|
|
1226
|
+
@property
|
|
1227
|
+
def extra_state_attributes(self):
|
|
1228
|
+
"""Devuelve los atributos extra del sensor con los nombres traducidos."""
|
|
1229
|
+
meteor_details = self.coordinator.data.get("detalles", {}).get("meteor", {})
|
|
1230
|
+
|
|
1231
|
+
# Convertimos las claves al formato deseado usando el mapping
|
|
1232
|
+
attributes = {
|
|
1233
|
+
f"alert_{i+1}": self.METEOR_MAPPING.get(meteor, "unknown")
|
|
1234
|
+
for i, meteor in enumerate(meteor_details.keys())
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
_LOGGER.info("Atributos traducidos del sensor: %s", attributes)
|
|
1238
|
+
return attributes
|
|
1239
|
+
|
|
1240
|
+
@property
|
|
1241
|
+
def device_info(self) -> DeviceInfo:
|
|
1242
|
+
"""Devuelve la información del dispositivo."""
|
|
1243
|
+
return DeviceInfo(
|
|
1244
|
+
identifiers={(DOMAIN, self._town_id)},
|
|
1245
|
+
name="Meteocat " + self._station_id + " " + self._town_name,
|
|
1246
|
+
manufacturer="Meteocat",
|
|
1247
|
+
model="Meteocat API",
|
|
1248
|
+
)
|
|
1249
|
+
|
|
1250
|
+
class MeteocatAlertMeteorSensor(CoordinatorEntity[MeteocatAlertsRegionCoordinator], SensorEntity):
|
|
1251
|
+
"""Sensor dinámico que muestra el estado de las alertas por cada meteor para una región."""
|
|
1252
|
+
METEOR_MAPPING = {
|
|
1253
|
+
ALERT_WIND: "Vent",
|
|
1254
|
+
ALERT_RAIN_INTENSITY: "Intensitat de pluja",
|
|
1255
|
+
ALERT_RAIN: "Acumulació de pluja",
|
|
1256
|
+
ALERT_SEA: "Estat de la mar",
|
|
1257
|
+
ALERT_COLD: "Fred",
|
|
1258
|
+
ALERT_WARM: "Calor",
|
|
1259
|
+
ALERT_WARM_NIGHT: "Calor nocturna",
|
|
1260
|
+
ALERT_SNOW: "Neu acumulada en 24 hores",
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
STATE_MAPPING = {
|
|
1264
|
+
"Obert": "opened",
|
|
1265
|
+
"Tancat": "closed",
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
UMBRAL_MAPPING = {
|
|
1269
|
+
"Ratxes de vent > 25 m/s": "wind_gusts_25",
|
|
1270
|
+
"Esclafits": "microburst",
|
|
1271
|
+
"Tornados o mànegues": "tornadoes",
|
|
1272
|
+
"Ratxa màxima > 40m/s": "wind_40",
|
|
1273
|
+
"Ratxa màxima > 35m/s": "wind_35",
|
|
1274
|
+
"Ratxa màxima > 30m/s": "wind_30",
|
|
1275
|
+
"Ratxa màxima > 25m/s": "wind_25",
|
|
1276
|
+
"Ratxa màxima > 20m/s": "wind_20",
|
|
1277
|
+
"Pedra de diàmetre > 2 cm": "hail_2_cm",
|
|
1278
|
+
"Intensitat > 40 mm / 30 minuts": "intensity_40_30",
|
|
1279
|
+
"Intensitat > 20 mm / 30 minuts": "intensity_20_30",
|
|
1280
|
+
"Acumulada > 200 mm /24 hores": "rain_200_24",
|
|
1281
|
+
"Acumulada > 100 mm /24 hores": "rain_100_24",
|
|
1282
|
+
"Onades > 4.00 metres (mar brava)": "waves_4",
|
|
1283
|
+
"Onades > 2.50 metres (maregassa)": "waves_2_50",
|
|
1284
|
+
"Fred molt intens": "cold_very_intense",
|
|
1285
|
+
"Fred intens": "cold_intense",
|
|
1286
|
+
"Calor molt intensa": "heat_very_intense",
|
|
1287
|
+
"Calor intensa": "heat_intense",
|
|
1288
|
+
"Calor nocturna molt intensa": "heat_night_very_intense",
|
|
1289
|
+
"Calor nocturna intensa": "heat_night_intense",
|
|
1290
|
+
"gruix > 50 cm a cotes superiors a 1000 metres fins a 1500 metres": "thickness_50_at_1000",
|
|
1291
|
+
"gruix > 30 cm a cotes superiors a 800 metres fins a 1000 metres": "thickness_30_at_800",
|
|
1292
|
+
"gruix > 20 cm a cotes superiors a 600 metres fins a 800 metres": "thickness_20_at_600",
|
|
1293
|
+
"gruix > 20 cm a cotes superiors a 1000 metres fins a 1500 metres": "thickness_20_at_1000",
|
|
1294
|
+
"gruix > 15 cm a cotes superiors a 300 metres fins a 600 metres": "thickness_15_at_300",
|
|
1295
|
+
"gruix > 10 cm a cotes superiors a 800 metres fins a 1000 metres": "thickness_10_at_800",
|
|
1296
|
+
"gruix > 5 cm a cotes inferiors a 300 metres": "thickness_5_at_300",
|
|
1297
|
+
"gruix > 5 cm a cotes superiors a 600 metres fins a 800 metres": "thickness_5_at_600",
|
|
1298
|
+
"gruix > 2 cm a cotes superiors a 300 metres fins a 600 metres": "thickness_2_at_300",
|
|
1299
|
+
"gruix ≥ 0 cm a cotes inferiors a 300 metres": "thickness_0_at_300",
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
_attr_has_entity_name = True # Activa el uso de nombres basados en el dispositivo
|
|
1303
|
+
|
|
1304
|
+
def __init__(self, alerts_region_coordinator, description, entry_data):
|
|
1305
|
+
super().__init__(alerts_region_coordinator)
|
|
1306
|
+
self.entity_description = description
|
|
1307
|
+
self._town_name = entry_data["town_name"]
|
|
1308
|
+
self._town_id = entry_data["town_id"]
|
|
1309
|
+
self._station_id = entry_data["station_id"]
|
|
1310
|
+
self._region_id = entry_data["region_id"]
|
|
1311
|
+
|
|
1312
|
+
# Unique ID for the entity
|
|
1313
|
+
self._attr_unique_id = f"sensor.{DOMAIN}_{self._region_id}_{self.entity_description.key}"
|
|
1314
|
+
|
|
1315
|
+
# Assign entity_category if defined in the description
|
|
1316
|
+
self._attr_entity_category = getattr(description, "entity_category", None)
|
|
1317
|
+
|
|
1318
|
+
# Log para depuración
|
|
1319
|
+
_LOGGER.debug(
|
|
1320
|
+
"Inicializando sensor: %s, Unique ID: %s",
|
|
1321
|
+
self.entity_description.name,
|
|
1322
|
+
self._attr_unique_id,
|
|
1323
|
+
)
|
|
1324
|
+
|
|
1325
|
+
@property
|
|
1326
|
+
def native_value(self):
|
|
1327
|
+
"""Devuelve el estado de la alerta específica."""
|
|
1328
|
+
meteor_type = self.METEOR_MAPPING.get(self.entity_description.key)
|
|
1329
|
+
if not meteor_type:
|
|
1330
|
+
return "Desconocido"
|
|
1331
|
+
|
|
1332
|
+
meteor_data = self.coordinator.data.get("detalles", {}).get("meteor", {}).get(meteor_type, {})
|
|
1333
|
+
|
|
1334
|
+
# Convertir estado para translation_key
|
|
1335
|
+
estado_original = meteor_data.get("estado", "Tancat")
|
|
1336
|
+
return self.STATE_MAPPING.get(estado_original, "unknown")
|
|
1337
|
+
|
|
1338
|
+
@property
|
|
1339
|
+
def extra_state_attributes(self):
|
|
1340
|
+
"""Devuelve los atributos específicos de la alerta."""
|
|
1341
|
+
meteor_type = self.METEOR_MAPPING.get(self.entity_description.key)
|
|
1342
|
+
if not meteor_type:
|
|
1343
|
+
return {}
|
|
1344
|
+
|
|
1345
|
+
meteor_data = self.coordinator.data.get("detalles", {}).get("meteor", {}).get(meteor_type, {})
|
|
1346
|
+
if not meteor_data:
|
|
1347
|
+
return {}
|
|
1348
|
+
|
|
1349
|
+
# Convertir umbral para translation_key
|
|
1350
|
+
umbral_original = meteor_data.get("umbral")
|
|
1351
|
+
umbral_convertido = self.UMBRAL_MAPPING.get(umbral_original, "unknown")
|
|
1352
|
+
|
|
1353
|
+
return {
|
|
1354
|
+
"inicio": meteor_data.get("inicio"),
|
|
1355
|
+
"fin": meteor_data.get("fin"),
|
|
1356
|
+
"fecha": meteor_data.get("fecha"),
|
|
1357
|
+
"periodo": meteor_data.get("periodo"),
|
|
1358
|
+
"umbral": umbral_convertido,
|
|
1359
|
+
"nivel": meteor_data.get("nivel"),
|
|
1360
|
+
"peligro": meteor_data.get("peligro"),
|
|
1361
|
+
"comentario": meteor_data.get("comentario"),
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
@property
|
|
1365
|
+
def device_info(self) -> DeviceInfo:
|
|
1366
|
+
"""Devuelve la información del dispositivo."""
|
|
1367
|
+
return DeviceInfo(
|
|
1368
|
+
identifiers={(DOMAIN, self._town_id)},
|
|
1369
|
+
name="Meteocat " + self._station_id + " " + self._town_name,
|
|
1370
|
+
manufacturer="Meteocat",
|
|
1371
|
+
model="Meteocat API",
|
|
1372
|
+
)
|