meteocat 0.1.45 → 0.1.47

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.
@@ -24,8 +24,14 @@ jobs:
24
24
  # Paso 3: Instalar dependencias necesarias
25
25
  - name: Install dependencies
26
26
  run: npm ci
27
+
28
+ # Paso 4: Configurar el autor de Git
29
+ - name: Configure Git author
30
+ run: |
31
+ git config user.name "semantic-release-bot"
32
+ git config user.email "jdcuartero@yahoo.es"
27
33
 
28
- # Paso 4: Ejecutar semantic-release
34
+ # Paso 5: Ejecutar semantic-release
29
35
  - name: Run semantic-release
30
36
  env:
31
37
  GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
package/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## [0.1.47](https://github.com/figorr/meteocat/compare/v0.1.46...v0.1.47) (2025-01-02)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * 0.1.47 ([03d1d08](https://github.com/figorr/meteocat/commit/03d1d08dd837dc47d8f2062ba561be706e1d8b05))
7
+ * convert to local time from UTC ([0dfe9f9](https://github.com/figorr/meteocat/commit/0dfe9f9ef7409bcd23d839963076aff14921f114))
8
+ * fix semantic-release-bot ([754f18b](https://github.com/figorr/meteocat/commit/754f18b2c0378c704eb255259192655b76100c43))
9
+ * fix timestamp sensor from UTC to local time Europe/Madrid ([e64539a](https://github.com/figorr/meteocat/commit/e64539a091adecfd4e23419c63bc54eda2293da3))
10
+
11
+ ## [0.1.46](https://github.com/figorr/meteocat/compare/v0.1.45...v0.1.46) (2025-01-01)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * 0.1.46 ([e2e736e](https://github.com/figorr/meteocat/commit/e2e736e102f25da704060bc6329696eec8c8fac6))
17
+ * add validity days, hours and minutes ([61a6761](https://github.com/figorr/meteocat/commit/61a6761cde31c321dbed4dce126416f65062a90f))
18
+
1
19
  ## [0.1.45](https://github.com/figorr/meteocat/compare/v0.1.44...v0.1.45) (2024-12-31)
2
20
 
3
21
 
@@ -25,7 +25,7 @@ from .const import DOMAIN, PLATFORMS
25
25
  _LOGGER = logging.getLogger(__name__)
26
26
 
27
27
  # Versión
28
- __version__ = "0.1.45"
28
+ __version__ = "0.1.47"
29
29
 
30
30
  def safe_remove(path: Path, is_folder: bool = False):
31
31
  """Elimina de forma segura un archivo o carpeta si existe."""
@@ -27,6 +27,10 @@ ATTRIBUTION = "Powered by Meteocatpy"
27
27
  PLATFORMS = [Platform.SENSOR, Platform.WEATHER]
28
28
  DEFAULT_NAME = "METEOCAT"
29
29
 
30
+ # Tiempos para validación de API
31
+ DEFAULT_VALIDITY_DAYS = 1 # Número de días a partir de los cuales se considera que el archivo de información está obsoleto
32
+ DEFAULT_VALIDITY_HOURS = 5 # Hora a partir de la cuall la API tiene la información actualizada de predicciones disponible para descarga
33
+ DEFAULT_VALIDITY_MINUTES = 0 # Minutos a partir de los cuales la API tiene la información actualizada de predicciones disponible para descarga
30
34
 
31
35
  # Códigos de sensores de la API
32
36
  WIND_SPEED = "wind_speed" # Velocidad del viento
@@ -5,7 +5,8 @@ import json
5
5
  import aiofiles
6
6
  import logging
7
7
  import asyncio
8
- from datetime import datetime, timedelta, timezone
8
+ from datetime import datetime, timedelta, timezone, time
9
+ from zoneinfo import ZoneInfo
9
10
  from typing import Dict, Any
10
11
 
11
12
  from homeassistant.core import HomeAssistant
@@ -29,6 +30,9 @@ from .condition import get_condition_from_statcel
29
30
  from .const import (
30
31
  DOMAIN,
31
32
  CONDITION_MAPPING,
33
+ DEFAULT_VALIDITY_DAYS,
34
+ DEFAULT_VALIDITY_HOURS,
35
+ DEFAULT_VALIDITY_MINUTES,
32
36
  )
33
37
 
34
38
  _LOGGER = logging.getLogger(__name__)
@@ -77,6 +81,30 @@ async def load_json_from_file(input_file: str) -> dict:
77
81
  _LOGGER.error("Error al decodificar JSON del archivo %s: %s", input_file, err)
78
82
  return {}
79
83
 
84
+ # Cambiar UTC a la zona horaria local
85
+ def convert_to_local_time(utc_time: str, local_tz: str = "Europe/Madrid") -> datetime | None:
86
+ """
87
+ Convierte una fecha/hora UTC en formato ISO 8601 a la zona horaria local especificada.
88
+
89
+ Args:
90
+ utc_time (str): Fecha/hora en formato ISO 8601 (ejemplo: '2025-01-02T12:00:00Z').
91
+ local_tz (str): Zona horaria local en formato IANA (por defecto, 'Europe/Madrid').
92
+
93
+ Returns:
94
+ datetime | None: Objeto datetime convertido a la zona horaria local, o None si hay un error.
95
+ """
96
+ try:
97
+ utc_dt = datetime.fromisoformat(utc_time.replace("Z", "+00:00"))
98
+ local_dt = utc_dt.replace(tzinfo=ZoneInfo("UTC")).astimezone(ZoneInfo(local_tz))
99
+ return local_dt
100
+ except ValueError:
101
+ return None
102
+
103
+ # Obtener la hora local en lugar de la hora UTC
104
+ def get_local_datetime(tz: str = "Europe/Madrid"):
105
+ """Obtiene la fecha y hora local según la zona horaria proporcionada."""
106
+ return datetime.now(ZoneInfo(tz))
107
+
80
108
  class MeteocatSensorCoordinator(DataUpdateCoordinator):
81
109
  """Coordinator para manejar la actualización de datos de los sensores."""
82
110
 
@@ -283,8 +311,9 @@ class MeteocatUviCoordinator(DataUpdateCoordinator):
283
311
  data = json.loads(content)
284
312
 
285
313
  # Validar la fecha del primer elemento superior a 1 día
286
- first_date = datetime.strptime(data["uvi"][0].get("date"), "%Y-%m-%d").date()
287
- today = datetime.now(timezone.utc).date()
314
+ first_date = convert_to_local_time(data["uvi"][0].get("date"), "%Y-%m-%d").date()
315
+ today = get_local_datetime().date() # Usar la hora local
316
+ current_time = get_local_datetime().time()
288
317
 
289
318
  # Log detallado
290
319
  _LOGGER.info(
@@ -292,10 +321,11 @@ class MeteocatUviCoordinator(DataUpdateCoordinator):
292
321
  self.uvi_file,
293
322
  today,
294
323
  first_date,
324
+ current_time,
295
325
  )
296
326
 
297
327
  # Verificar si la antigüedad es mayor a un día
298
- if (today - first_date).days > 1:
328
+ if (today - first_date).days > DEFAULT_VALIDITY_DAYS and current_time >= time(DEFAULT_VALIDITY_HOURS, DEFAULT_VALIDITY_MINUTES):
299
329
  _LOGGER.info(
300
330
  "Los datos en %s son antiguos. Se procederá a llamar a la API.",
301
331
  self.uvi_file,
@@ -423,8 +453,8 @@ class MeteocatUviFileCoordinator(DataUpdateCoordinator):
423
453
 
424
454
  def _get_uv_for_current_hour(self, raw_data):
425
455
  """Get UV data for the current hour."""
426
- # Fecha y hora actual
427
- current_datetime = datetime.now()
456
+ # # Obtiene la fecha y hora locales
457
+ current_datetime = get_local_datetime()
428
458
  current_date = current_datetime.strftime("%Y-%m-%d")
429
459
  current_hour = current_datetime.hour
430
460
 
@@ -505,9 +535,10 @@ class MeteocatEntityCoordinator(DataUpdateCoordinator):
505
535
  content = await f.read()
506
536
  data = json.loads(content)
507
537
 
508
- # Obtener la fecha del primer día
509
- first_date = datetime.fromisoformat(data["dies"][0]["data"].rstrip("Z")).date()
510
- today = datetime.now(timezone.utc).date()
538
+ # Convertir la fecha del primer día a la zona horaria local
539
+ first_date = convert_to_local_time(data["dies"][0]["data"]).date()
540
+ today = get_local_datetime().date() # Usar la hora local
541
+ current_time = get_local_datetime().time()
511
542
 
512
543
  # Log detallado
513
544
  _LOGGER.info(
@@ -515,10 +546,11 @@ class MeteocatEntityCoordinator(DataUpdateCoordinator):
515
546
  file_path,
516
547
  today,
517
548
  first_date,
549
+ current_time,
518
550
  )
519
551
 
520
552
  # Verificar si la antigüedad es mayor a un día
521
- if (today - first_date).days > 1:
553
+ if (today - first_date).days > DEFAULT_VALIDITY_DAYS and current_time >= time(DEFAULT_VALIDITY_HOURS, DEFAULT_VALIDITY_MINUTES):
522
554
  _LOGGER.info(
523
555
  "Los datos en %s son antiguos. Se procederá a llamar a la API.",
524
556
  file_path,
@@ -545,6 +577,11 @@ class MeteocatEntityCoordinator(DataUpdateCoordinator):
545
577
  hourly_data = await self._fetch_and_save_data(
546
578
  self.meteocat_forecast.get_prediccion_horaria, self.hourly_file
547
579
  )
580
+
581
+ # Convertir las fechas horarias a hora local
582
+ for day in hourly_data.get("dies", []):
583
+ for hour_data in day["variables"].get("temp", {}).get("valors", []):
584
+ hour_data["data"] = convert_to_local_time(hour_data["data"]).isoformat()
548
585
 
549
586
  # Validar o actualizar datos diarios
550
587
  daily_data = await self.validate_forecast_data(self.daily_file)
@@ -553,6 +590,10 @@ class MeteocatEntityCoordinator(DataUpdateCoordinator):
553
590
  self.meteocat_forecast.get_prediccion_diaria, self.daily_file
554
591
  )
555
592
 
593
+ # Convertir las fechas diarias a hora local
594
+ for day in daily_data.get("dies", []):
595
+ day["data"] = convert_to_local_time(day["data"]).isoformat()
596
+
556
597
  return {"hourly": hourly_data, "daily": daily_data}
557
598
 
558
599
  except asyncio.TimeoutError as err:
@@ -639,10 +680,10 @@ class HourlyForecastCoordinator(DataUpdateCoordinator):
639
680
  if not data or "dies" not in data:
640
681
  return False
641
682
 
642
- now = datetime.now(timezone.utc)
683
+ now = get_local_datetime()
643
684
  for dia in data["dies"]:
644
685
  for forecast in dia.get("variables", {}).get("estatCel", {}).get("valors", []):
645
- forecast_time = datetime.fromisoformat(forecast["data"].rstrip("Z")).replace(tzinfo=timezone.utc)
686
+ forecast_time = convert_to_local_time(forecast["data"])
646
687
  if forecast_time >= now:
647
688
  return True
648
689
 
@@ -668,7 +709,7 @@ class HourlyForecastCoordinator(DataUpdateCoordinator):
668
709
  variables = dia.get("variables", {})
669
710
  condition_code = next(
670
711
  (item["valor"] for item in variables.get("estatCel", {}).get("valors", []) if
671
- datetime.fromisoformat(item["data"].rstrip("Z")).replace(tzinfo=timezone.utc) == forecast_time),
712
+ convert_to_local_time(item["data"]) == forecast_time),
672
713
  -1,
673
714
  )
674
715
 
@@ -697,10 +738,10 @@ class HourlyForecastCoordinator(DataUpdateCoordinator):
697
738
  return []
698
739
 
699
740
  forecasts = []
700
- now = datetime.now(timezone.utc)
741
+ now = get_local_datetime()
701
742
  for dia in self.data["dies"]:
702
743
  for forecast in dia.get("variables", {}).get("estatCel", {}).get("valors", []):
703
- forecast_time = datetime.fromisoformat(forecast["data"].rstrip("Z")).replace(tzinfo=timezone.utc)
744
+ forecast_time = convert_to_local_time(forecast["data"])
704
745
  if forecast_time >= now:
705
746
  forecasts.append(self.parse_hourly_forecast(dia, forecast_time))
706
747
  return forecasts
@@ -720,7 +761,7 @@ class HourlyForecastCoordinator(DataUpdateCoordinator):
720
761
 
721
762
  for valor in valores:
722
763
  try:
723
- data_hora = datetime.fromisoformat(valor["data"].rstrip("Z")).replace(tzinfo=timezone.utc)
764
+ data_hora = convert_to_local_time(valor["data"])
724
765
  if data_hora == target_time:
725
766
  return float(valor["valor"])
726
767
  except (KeyError, ValueError) as e:
@@ -770,9 +811,9 @@ class DailyForecastCoordinator(DataUpdateCoordinator):
770
811
  if not data or "dies" not in data or not data["dies"]:
771
812
  return False
772
813
 
773
- today = datetime.now(timezone.utc).date()
814
+ today = get_local_datetime().date() # Usar la hora local
774
815
  for dia in data["dies"]:
775
- forecast_date = datetime.fromisoformat(dia["data"].rstrip("Z")).date()
816
+ forecast_date = convert_to_local_time(dia["data"], "Europe/Madrid").date()
776
817
  if forecast_date >= today:
777
818
  return True
778
819
 
@@ -790,10 +831,10 @@ class DailyForecastCoordinator(DataUpdateCoordinator):
790
831
  data = json.loads(content)
791
832
 
792
833
  # Filtrar días pasados
793
- today = datetime.now(timezone.utc).date()
834
+ today = get_local_datetime().date() # Usar la hora local
794
835
  data["dies"] = [
795
836
  dia for dia in data["dies"]
796
- if datetime.fromisoformat(dia["data"].rstrip("Z")).date() >= today
837
+ if convert_to_local_time(dia["data"], "Europe/Madrid").date() >= today
797
838
  ]
798
839
  return data
799
840
  except Exception as e:
@@ -806,9 +847,9 @@ class DailyForecastCoordinator(DataUpdateCoordinator):
806
847
  if not self.data or "dies" not in self.data or not self.data["dies"]:
807
848
  return None
808
849
 
809
- today = datetime.now(timezone.utc).date()
850
+ today = get_local_datetime().date() # Usar la hora local
810
851
  for dia in self.data["dies"]:
811
- forecast_date = datetime.fromisoformat(dia["data"].rstrip("Z")).date()
852
+ forecast_date = convert_to_local_time(dia["data"], "Europe/Madrid").date()
812
853
  if forecast_date == today:
813
854
  return dia
814
855
  return None
@@ -820,7 +861,7 @@ class DailyForecastCoordinator(DataUpdateCoordinator):
820
861
  condition = get_condition_from_code(int(condition_code))
821
862
 
822
863
  forecast_data = {
823
- "date": datetime.fromisoformat(dia["data"].rstrip("Z")).date(),
864
+ "date": convert_to_local_time(dia["data"], "Europe/Madrid").date(),
824
865
  "temperature_max": float(variables.get("tmax", {}).get("valor", 0.0)),
825
866
  "temperature_min": float(variables.get("tmin", {}).get("valor", 0.0)),
826
867
  "precipitation": float(variables.get("precipitacio", {}).get("valor", 0.0)),
@@ -900,7 +941,7 @@ class MeteocatConditionCoordinator(DataUpdateCoordinator):
900
941
  def _get_condition_for_current_hour(self, raw_data):
901
942
  """Get condition data for the current hour."""
902
943
  # Fecha y hora actual
903
- current_datetime = datetime.now()
944
+ current_datetime = get_local_datetime() # Usar la zona horaria local
904
945
  current_date = current_datetime.strftime("%Y-%m-%d")
905
946
  current_hour = current_datetime.hour
906
947
 
@@ -908,7 +949,7 @@ class MeteocatConditionCoordinator(DataUpdateCoordinator):
908
949
  for day in raw_data.get("dies", []):
909
950
  if day["data"].startswith(current_date):
910
951
  for value in day["variables"]["estatCel"]["valors"]:
911
- data_hour = datetime.fromisoformat(value["data"])
952
+ data_hour = convert_to_local_time(value["data"])
912
953
  if data_hour.hour == current_hour:
913
954
  codi_estatcel = value["valor"]
914
955
  condition = get_condition_from_statcel(
@@ -979,9 +1020,9 @@ class MeteocatTempForecastCoordinator(DataUpdateCoordinator):
979
1020
  if not data or "dies" not in data or not data["dies"]:
980
1021
  return False
981
1022
 
982
- today = datetime.now(timezone.utc).date()
1023
+ today = get_local_datetime().date()
983
1024
  for dia in data["dies"]:
984
- forecast_date = datetime.fromisoformat(dia["data"].rstrip("Z")).date()
1025
+ forecast_date = convert_to_local_time(dia["data"]).date() # Convertir a hora local
985
1026
  if forecast_date >= today:
986
1027
  return True
987
1028
 
@@ -999,10 +1040,10 @@ class MeteocatTempForecastCoordinator(DataUpdateCoordinator):
999
1040
  data = json.loads(content)
1000
1041
 
1001
1042
  # Filtrar días pasados
1002
- today = datetime.now(timezone.utc).date()
1043
+ today = get_local_datetime().date() # Usar la hora local
1003
1044
  data["dies"] = [
1004
1045
  dia for dia in data["dies"]
1005
- if datetime.fromisoformat(dia["data"].rstrip("Z")).date() >= today
1046
+ if convert_to_local_time(dia["data"]).date() >= today # Convertir a hora local
1006
1047
  ]
1007
1048
 
1008
1049
  # Usar datos de temperatura del día actual si están disponibles
@@ -1020,9 +1061,9 @@ class MeteocatTempForecastCoordinator(DataUpdateCoordinator):
1020
1061
  if not data or "dies" not in data or not data["dies"]:
1021
1062
  return None
1022
1063
 
1023
- today = datetime.now(timezone.utc).date()
1064
+ today = get_local_datetime().date() # Usar la hora local
1024
1065
  for dia in data["dies"]:
1025
- forecast_date = datetime.fromisoformat(dia["data"].rstrip("Z")).date()
1066
+ forecast_date = convert_to_local_time(dia["data"]).date() # Convertir a hora local
1026
1067
  if forecast_date == today:
1027
1068
  return dia
1028
1069
  return None
@@ -1032,7 +1073,7 @@ class MeteocatTempForecastCoordinator(DataUpdateCoordinator):
1032
1073
  variables = dia.get("variables", {})
1033
1074
 
1034
1075
  temp_forecast_data = {
1035
- "date": datetime.fromisoformat(dia["data"].rstrip("Z")).date(),
1076
+ "date": convert_to_local_time(dia["data"]), # Fecha convertida a hora local
1036
1077
  "max_temp_forecast": float(variables.get("tmax", {}).get("valor", 0.0)),
1037
1078
  "min_temp_forecast": float(variables.get("tmin", {}).get("valor", 0.0)),
1038
1079
  }
@@ -8,5 +8,5 @@
8
8
  "documentation": "https://gitlab.com/figorr/meteocat",
9
9
  "loggers": ["meteocatpy"],
10
10
  "requirements": ["meteocatpy==0.0.17", "packaging>=20.3", "wrapt>=1.14.0"],
11
- "version": "0.1.45"
11
+ "version": "0.1.47"
12
12
  }
@@ -1,7 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
- from datetime import datetime, timezone
4
+ from datetime import datetime, timezone, time
5
+ from zoneinfo import ZoneInfo
5
6
  import logging
6
7
  from homeassistant.helpers.entity import (
7
8
  DeviceInfo,
@@ -63,6 +64,9 @@ from .const import (
63
64
  MIN_TEMPERATURE_CODE,
64
65
  FEELS_LIKE,
65
66
  WIND_GUST_CODE,
67
+ DEFAULT_VALIDITY_DAYS,
68
+ DEFAULT_VALIDITY_HOURS,
69
+ DEFAULT_VALIDITY_MINUTES,
66
70
  )
67
71
 
68
72
  from .coordinator import (
@@ -324,6 +328,29 @@ async def async_setup_entry(hass, entry, async_add_entities: AddEntitiesCallback
324
328
  if description.key == UVI_FILE_STATUS
325
329
  )
326
330
 
331
+ # Cambiar UTC a la zona horaria local
332
+ def convert_to_local_time(utc_time: str, local_tz: str = "Europe/Madrid") -> datetime | None:
333
+ """
334
+ Convierte una fecha/hora UTC en formato ISO 8601 a la zona horaria local especificada.
335
+
336
+ Args:
337
+ utc_time (str): Fecha/hora en formato ISO 8601 (ejemplo: '2025-01-02T12:00:00Z').
338
+ local_tz (str): Zona horaria local en formato IANA (por defecto, 'Europe/Madrid').
339
+
340
+ Returns:
341
+ datetime | None: Objeto datetime convertido a la zona horaria local, o None si hay un error.
342
+ """
343
+ try:
344
+ # Convertir la cadena UTC a un objeto datetime
345
+ utc_dt = datetime.fromisoformat(utc_time.replace("Z", "+00:00"))
346
+
347
+ # Convertir a la zona horaria local usando ZoneInfo
348
+ local_dt = utc_dt.replace(tzinfo=ZoneInfo("UTC")).astimezone(ZoneInfo(local_tz))
349
+
350
+ return local_dt
351
+ except ValueError:
352
+ return None
353
+
327
354
  class MeteocatStaticSensor(CoordinatorEntity[MeteocatStaticSensorCoordinator], SensorEntity):
328
355
  """Representation of a static Meteocat sensor."""
329
356
  STATIC_KEYS = {TOWN_NAME, TOWN_ID, STATION_NAME, STATION_ID}
@@ -630,9 +657,13 @@ class MeteocatSensor(CoordinatorEntity[MeteocatSensorCoordinator], SensorEntity)
630
657
  if raw_timestamp:
631
658
  # Convertir el timestamp a un objeto datetime
632
659
  try:
633
- return datetime.fromisoformat(raw_timestamp.replace("Z", "+00:00"))
660
+ # Convertimos raw_timestamp a hora local
661
+ local_time = convert_to_local_time(raw_timestamp)
662
+ _LOGGER.debug("Hora UTC: %s convertida a hora local: %s", raw_timestamp, local_time)
663
+ return local_time
634
664
  except ValueError:
635
665
  # Manejo de errores si el formato no es válido
666
+ _LOGGER.error(f"Error al convertir el timestamp '{raw_timestamp}' a hora local.")
636
667
  return None
637
668
 
638
669
  # Nuevo sensor para la precipitación acumulada
@@ -793,9 +824,21 @@ class MeteocatHourlyForecastStatusSensor(CoordinatorEntity[MeteocatEntityCoordin
793
824
  first_date = self._get_first_date()
794
825
  if first_date:
795
826
  today = datetime.now(timezone.utc).date()
827
+ current_time = datetime.now(timezone.utc).time()
796
828
  days_difference = (today - first_date).days
797
- _LOGGER.debug(f"Diferencia de días para predicciones horarias: {days_difference}")
798
- return "updated" if days_difference <= 1 else "obsolete"
829
+ _LOGGER.debug(
830
+ f"Diferencia de días para predicciones horarias: {days_difference}."
831
+ f"Hora actual de validación: {current_time}."
832
+ f"Para la validación: "
833
+ f"número de días= {DEFAULT_VALIDITY_DAYS}, "
834
+ f"hora de contacto a la API >= {DEFAULT_VALIDITY_HOURS}, "
835
+ f"minutos de contacto a la API >= {DEFAULT_VALIDITY_MINUTES}."
836
+ )
837
+
838
+ # Validar fecha y hora según la lógica del coordinador
839
+ if days_difference > DEFAULT_VALIDITY_DAYS and current_time >= time(DEFAULT_VALIDITY_HOURS, DEFAULT_VALIDITY_MINUTES):
840
+ return "obsolete"
841
+ return "updated"
799
842
  return "unknown"
800
843
 
801
844
  @property
@@ -844,9 +887,21 @@ class MeteocatDailyForecastStatusSensor(CoordinatorEntity[MeteocatEntityCoordina
844
887
  first_date = self._get_first_date()
845
888
  if first_date:
846
889
  today = datetime.now(timezone.utc).date()
890
+ current_time = datetime.now(timezone.utc).time()
847
891
  days_difference = (today - first_date).days
848
- _LOGGER.debug(f"Diferencia de días para predicciones diarias: {days_difference}")
849
- return "updated" if days_difference <= 1 else "obsolete"
892
+ _LOGGER.debug(
893
+ f"Diferencia de días para predicciones diarias: {days_difference}."
894
+ f"Hora actual de validación: {current_time}."
895
+ f"Para la validación: "
896
+ f"número de días= {DEFAULT_VALIDITY_DAYS}, "
897
+ f"hora de contacto a la API >= {DEFAULT_VALIDITY_HOURS}, "
898
+ f"minutos de contacto a la API >= {DEFAULT_VALIDITY_MINUTES}."
899
+ )
900
+
901
+ # Validar fecha y hora según la lógica del coordinador
902
+ if days_difference > DEFAULT_VALIDITY_DAYS and current_time >= time(DEFAULT_VALIDITY_HOURS, DEFAULT_VALIDITY_MINUTES):
903
+ return "obsolete"
904
+ return "updated"
850
905
  return "unknown"
851
906
 
852
907
  @property
@@ -894,9 +949,21 @@ class MeteocatUviStatusSensor(CoordinatorEntity[MeteocatUviCoordinator], SensorE
894
949
  first_date = self._get_first_date()
895
950
  if first_date:
896
951
  today = datetime.now(timezone.utc).date()
952
+ current_time = datetime.now(timezone.utc).time()
897
953
  days_difference = (today - first_date).days
898
- _LOGGER.debug(f"Diferencia de días para UVI: {days_difference}")
899
- return "updated" if days_difference <= 1 else "obsolete"
954
+ _LOGGER.debug(
955
+ f"Diferencia de días para datos UVI: {days_difference}."
956
+ f"Hora actual de validación: {current_time}."
957
+ f"Para la validación: "
958
+ f"número de días= {DEFAULT_VALIDITY_DAYS}, "
959
+ f"hora de contacto a la API >= {DEFAULT_VALIDITY_HOURS}, "
960
+ f"minutos de contacto a la API >= {DEFAULT_VALIDITY_MINUTES}."
961
+ )
962
+
963
+ # Validar fecha y hora según la lógica del coordinador
964
+ if days_difference > DEFAULT_VALIDITY_DAYS and current_time >= time(DEFAULT_VALIDITY_HOURS, DEFAULT_VALIDITY_MINUTES):
965
+ return "obsolete"
966
+ return "updated"
900
967
  return "unknown"
901
968
 
902
969
  @property
@@ -1,2 +1,2 @@
1
1
  # version.py
2
- __version__ = "0.1.45"
2
+ __version__ = "0.1.47"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meteocat",
3
- "version": "0.1.45",
3
+ "version": "0.1.47",
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.45"
3
+ version = "0.1.47"
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"