diff --git a/custom_components/pzo_sensor/__init__.py b/custom_components/pzo_sensor/__init__.py index 6206346..ef25e66 100644 --- a/custom_components/pzo_sensor/__init__.py +++ b/custom_components/pzo_sensor/__init__.py @@ -12,7 +12,7 @@ from homeassistant.helpers.event import async_call_later, async_track_point_in_time import homeassistant.util.dt as dt_util -from .const import CONF_ACTUAL_DATA_ONLY, CONF_SCAN_HOUR, CONF_ZONE, CONF_MONTH_AVG, DOMAIN, WEB_RETRIES_MINUTES +from .const import CONF_ACTUAL_DATA_ONLY, CONF_SCAN_HOUR, ZONE_CODES, CONF_ZONE, CONTRACTS, CONF_CONTRACT, CONF_MONTH_AVG, DOMAIN, WEB_RETRIES_MINUTES from .coordinator import PricesDataUpdateCoordinator if AwesomeVersion(HA_VERSION) >= AwesomeVersion("2024.5.0"): @@ -79,7 +79,14 @@ async def update_listener(hass: HomeAssistant, config: ConfigEntry) -> None: config.options[CONF_ZONE] != coordinator.zone ): # Modificata la zona geografica nelle opzioni - coordinator.scan_hour = config.options[CONF_SCAN_HOUR] + coordinator.zone = ZONE_CODES[config.options[CONF_ZONE]] + reload = True + + if (CONF_CONTRACT in config.options) and ( + config.options[CONF_CONTRACT] != coordinator.contract + ): + # Modificata il tipo di contratto nelle opzioni + coordinator.contract = CONTRACTS[config.options[CONF_CONTRACT]] reload = True if (CONF_SCAN_HOUR in config.options) and ( diff --git a/custom_components/pzo_sensor/config_flow.py b/custom_components/pzo_sensor/config_flow.py index 29689d7..588b39e 100644 --- a/custom_components/pzo_sensor/config_flow.py +++ b/custom_components/pzo_sensor/config_flow.py @@ -7,7 +7,7 @@ from homeassistant.data_entry_flow import FlowResult import homeassistant.helpers.config_validation as cv -from .const import CONF_ACTUAL_DATA_ONLY, CONF_SCAN_HOUR, CONF_ZONE, CONF_MONTH_AVG, ZONE_CODES, DEFAULT_ZONE, DOMAIN +from .const import CONF_ACTUAL_DATA_ONLY, CONF_SCAN_HOUR, CONF_ZONE, DEFAULT_ZONE, CONF_CONTRACT, DEFAULT_CONTRACT, CONF_MONTH_AVG, ZONE_CODES, CONTRACTS, DOMAIN class OptionsFlow(config_entries.OptionsFlow): @@ -32,6 +32,12 @@ async def async_step_init(self, user_input=None) -> FlowResult: CONF_ZONE, self.config_entry.data[CONF_ZONE] ) ): vol.In(ZONE_CODES.keys()), + vol.Required( + CONF_CONTRACT, + default=self.config_entry.options.get( + CONF_CONTRACT, self.config_entry.data[CONF_CONTRACT] + ) + ): vol.In(CONTRACTS.keys()), vol.Required( CONF_SCAN_HOUR, default=self.config_entry.options.get( @@ -86,6 +92,7 @@ async def async_step_user(self, user_input=None): # Schema dati di configurazione (con default fissi) data_schema = { vol.Required(CONF_ZONE, default=DEFAULT_ZONE): vol.In(ZONE_CODES.keys()), + vol.Required(CONF_CONTRACT, default=DEFAULT_CONTRACT): vol.In(CONTRACTS.keys()), vol.Required(CONF_SCAN_HOUR, default=1): vol.All( cv.positive_int, vol.Range(min=0, max=23) ), diff --git a/custom_components/pzo_sensor/const.py b/custom_components/pzo_sensor/const.py index 5ec1add..60636a5 100644 --- a/custom_components/pzo_sensor/const.py +++ b/custom_components/pzo_sensor/const.py @@ -14,6 +14,7 @@ # Parametri configurabili da configuration.yaml CONF_ZONE = "zone" +CONF_CONTRACT = "contract" CONF_SCAN_HOUR = "scan_hour" CONF_ACTUAL_DATA_ONLY = "actual_data_only" CONF_MONTH_AVG = "month_average" @@ -21,6 +22,9 @@ # Parametri interni CONF_SCAN_MINUTE = "scan_minute" +CONTRACTS = {"Tri-orario": 3, "Bi-orario": 2, "Mono-orario": 1} +DEFAULT_CONTRACT = "Tri-orario" + # Traduce i nomi delle zone nei rispettivi codici presenti nell'xml ZONE_CODES = { #"Austria": "AUST", @@ -35,7 +39,7 @@ #"Grecia": "GREC", #"Malta": "MALT", #"Montenegro": "MONT", - "Italia (senza vincoli)": "NAT", + "Italia": "NAT", "Nord": "NORD", "Sardegna": "SARD", "Sicilia": "SICI", @@ -47,6 +51,5 @@ #"Grecia Coupling": "XGRE", } -DEFAULT_ZONE = "NAT" - +DEFAULT_ZONE = "Italia" PHYSICAL_ZONES = ["CALA", "CNOR", "CSUD", "NORD", "SARD", "SICI", "SUD"] \ No newline at end of file diff --git a/custom_components/pzo_sensor/coordinator.py b/custom_components/pzo_sensor/coordinator.py index 99b1d54..717e607 100644 --- a/custom_components/pzo_sensor/coordinator.py +++ b/custom_components/pzo_sensor/coordinator.py @@ -21,6 +21,9 @@ CONF_ZONE, ZONE_CODES, DEFAULT_ZONE, + CONTRACTS, + CONF_CONTRACT, + DEFAULT_CONTRACT, CONF_ACTUAL_DATA_ONLY, CONF_MONTH_AVG, CONF_SCAN_HOUR, @@ -62,7 +65,10 @@ def __init__(self, hass: HomeAssistant, config: ConfigEntry) -> None: # Inizializza i valori di configurazione (dalle opzioni o dalla configurazione iniziale) self.zone = ZONE_CODES[config.options.get( - CONF_ZONE, config.data.get(CONF_ZONE, DEFAULT_ZONE) + CONF_ZONE, config.data.get(CONF_ZONE, ZONE_CODES[DEFAULT_ZONE]) + )] + self.contract = CONTRACTS[config.options.get( + CONF_CONTRACT, config.data.get(CONF_CONTRACT, CONTRACTS[DEFAULT_CONTRACT]) )] self.actual_data_only = config.options.get( CONF_ACTUAL_DATA_ONLY, config.data.get(CONF_ACTUAL_DATA_ONLY, False) @@ -205,13 +211,12 @@ async def _async_update_data(self): # Calcola le fasce facendo la media dei prezzi orari che le compongono if fascia == Fascia.ORARIA: self.pz_values.value[fascia] = pz_list[datetime.now().hour] + self.pz_values.value[Fascia.MONO] = mean(self.pz_data.data[fascia]) else: self.pz_values.value[fascia] = mean(self.pz_data.data[fascia]) - # Calcola la fascia F23 e il mono-fascia facendo la media delle fasce che le compongono ponderata sul numero di ore che coprono - ore_fasce = {Fascia.F1: len(self.pz_data.data[Fascia.F1]), Fascia.F2: len(self.pz_data.data[Fascia.F2]), Fascia.F3: len(self.pz_data.data[Fascia.F3])} - self.pz_values.value[Fascia.MONO] = (self.pz_values.value[Fascia.F1] * ore_fasce[Fascia.F1] + self.pz_values.value[Fascia.F2] * ore_fasce[Fascia.F2] + self.pz_values.value[Fascia.F3] * ore_fasce[Fascia.F3]) / 24 - self.pz_values.value[Fascia.F23] = (self.pz_values.value[Fascia.F2] * ore_fasce[Fascia.F2] + self.pz_values.value[Fascia.F3] * ore_fasce[Fascia.F3]) / (ore_fasce[Fascia.F2] + ore_fasce[Fascia.F3]) + # Calcola la fascia F23 + self.pz_values.value[Fascia.F23] = self.pz_values.value[Fascia.F2] * 0.46 + self.pz_values.value[Fascia.F3] * 0.54 # Logga i dati _LOGGER.debug( @@ -265,12 +270,12 @@ async def update_fascia(self, now=None): # Ottiene la fascia oraria corrente e il prossimo aggiornamento self.fascia_corrente, self.prossimo_cambio_fascia = get_fascia( - dt_util.now(time_zone=time_zone) + dt_util.now(time_zone=time_zone), self.contract ) # Calcola la fascia futura ri-applicando lo stesso algoritmo self.fascia_successiva, self.termine_prossima_fascia = get_fascia( - self.prossimo_cambio_fascia + self.prossimo_cambio_fascia, self.contract ) _LOGGER.info( "Nuova fascia corrente: %s (prossima: %s alle %s)", diff --git a/custom_components/pzo_sensor/manifest.json b/custom_components/pzo_sensor/manifest.json index 1027088..76e0cc3 100644 --- a/custom_components/pzo_sensor/manifest.json +++ b/custom_components/pzo_sensor/manifest.json @@ -12,5 +12,5 @@ "loggers": ["pzo_sensor"], "requirements": [], "single_config_entry": true, - "version": "0.1.1" + "version": "0.1.2" } diff --git a/custom_components/pzo_sensor/sensor.py b/custom_components/pzo_sensor/sensor.py index 05e7be3..5b0f5ae 100644 --- a/custom_components/pzo_sensor/sensor.py +++ b/custom_components/pzo_sensor/sensor.py @@ -56,13 +56,23 @@ async def async_setup_entry( # Crea i sensori dei valori dei prezzi zonali (legati al coordinator) entities: list[SensorEntity] = [] - entities.extend( - PriceSensorEntity(coordinator, fascia) for fascia in PricesValues().value - ) + match coordinator.contract: + case 3: + entities.append(PrezzoSensorEntity(coordinator, Fascia.F1)) + entities.append(PrezzoSensorEntity(coordinator, Fascia.F2)) + entities.append(PrezzoSensorEntity(coordinator, Fascia.F3)) + case 2: + entities.append(PrezzoSensorEntity(coordinator, Fascia.F1)) + entities.append(PrezzoSensorEntity(coordinator, Fascia.F23)) + case 1: + entities.append(PrezzoSensorEntity(coordinator, Fascia.MONO)) # Crea sensori aggiuntivi - entities.append(FasciaSensorEntity(coordinator)) - entities.append(PrezzoFasciaSensorEntity(coordinator)) + if coordinator.contract != 1: + entities.append(FasciaSensorEntity(coordinator)) + entities.append(PrezzoFasciaSensorEntity(coordinator)) + + entities.append(PrezzoOrarioSensorEntity(coordinator)) # Aggiunge i sensori ma non aggiorna automaticamente via web # per lasciare il tempo ad Home Assistant di avviarsi @@ -80,7 +90,7 @@ def fmt_float(num: float) -> float: return round(num, 6) -class PriceSensorEntity(CoordinatorEntity, SensorEntity, RestoreEntity): +class PrezzoSensorEntity(CoordinatorEntity, SensorEntity, RestoreEntity): """Sensore relativo al prezzo per fasce.""" def __init__(self, coordinator: PricesDataUpdateCoordinator, fascia: Fascia) -> None: @@ -94,17 +104,15 @@ def __init__(self, coordinator: PricesDataUpdateCoordinator, fascia: Fascia) -> # ID univoco sensore basato su un nome fisso match self.fascia: case Fascia.MONO: - self.entity_id = ENTITY_ID_FORMAT.format(f"prezzo_zonale_mono_orario") + self.entity_id = ENTITY_ID_FORMAT.format("prezzo_zonale_mono_orario") case Fascia.F1: - self.entity_id = ENTITY_ID_FORMAT.format(f"prezzo_zonale_fascia_f1") + self.entity_id = ENTITY_ID_FORMAT.format("prezzo_zonale_fascia_f1") case Fascia.F2: - self.entity_id = ENTITY_ID_FORMAT.format(f"prezzo_zonale_fascia_f2") + self.entity_id = ENTITY_ID_FORMAT.format("prezzo_zonale_fascia_f2") case Fascia.F3: - self.entity_id = ENTITY_ID_FORMAT.format(f"prezzo_zonale_fascia_f3") + self.entity_id = ENTITY_ID_FORMAT.format("prezzo_zonale_fascia_f3") case Fascia.F23: - self.entity_id = ENTITY_ID_FORMAT.format(f"prezzo_zonale_fascia_f23") - case Fascia.ORARIA: - self.entity_id = ENTITY_ID_FORMAT.format(f"prezzo_zonale_orario") + self.entity_id = ENTITY_ID_FORMAT.format("prezzo_zonale_fascia_f23") case _: self.entity_id = None self._attr_unique_id = self.entity_id @@ -247,13 +255,16 @@ def device_class(self) -> SensorDeviceClass | None: @property def options(self) -> list[str] | None: """Possibili stati del sensore.""" - return [Fascia.F1.value, Fascia.F2.value, Fascia.F3.value] + match self.coordinator.contract: + case 3: return [Fascia.F1.value, Fascia.F2.value, Fascia.F3.value] + case 2: return [Fascia.F1.value, Fascia.F23.value] @property def native_value(self) -> str | None: """Restituisce la fascia corrente come stato.""" if not self.coordinator.fascia_corrente: return None + return self.coordinator.fascia_corrente.value @property @@ -289,7 +300,7 @@ def __init__(self, coordinator: PricesDataUpdateCoordinator) -> None: self.coordinator = coordinator # ID univoco sensore basato su un nome fisso - self.entity_id = ENTITY_ID_FORMAT.format(f"prezzo_zonale_fascia_corrente") + self.entity_id = ENTITY_ID_FORMAT.format("prezzo_zonale_fascia_corrente") self._attr_unique_id = self.entity_id self._attr_has_entity_name = True @@ -298,20 +309,21 @@ def __init__(self, coordinator: PricesDataUpdateCoordinator) -> None: self._attr_suggested_display_precision = 6 self._available = False self._native_value = 0 - self._friendly_name = f"Prezzo zonale fascia corrente" + self._friendly_name = "Prezzo zonale fascia corrente" def _handle_coordinator_update(self) -> None: """Gestisce l'aggiornamento dei dati dal coordinator.""" if self.coordinator.fascia_corrente is not None and self.coordinator.pz_values.value[self.coordinator.fascia_corrente] > 0: - self._available = len(self.coordinator.pz_data.data[self.coordinator.fascia_corrente]) > 0 + self._available = self.coordinator.pz_values.value[self.coordinator.fascia_corrente] > 0 self._native_value = self.coordinator.pz_values.value[self.coordinator.fascia_corrente] self._friendly_name = f"Prezzo zonale fascia corrente ({self.coordinator.fascia_corrente.value})" + else: self._available = False self._native_value = 0 - self._friendly_name = f"Prezzo zonale fascia corrente" + self._friendly_name = "Prezzo zonale fascia corrente" self.async_write_ha_state() @@ -378,3 +390,103 @@ def extra_state_attributes(self) -> dict[str, Any]: # Nelle versioni precedenti di Home Assistant # restituisce un valore arrotondato come attributo return {ATTR_ROUNDED_DECIMALS: str(format(round(self.native_value, 3), ".3f"))} + +class PrezzoOrarioSensorEntity(CoordinatorEntity, SensorEntity, RestoreEntity): + """Sensore che rappresenta il prezzo zonale della fascia corrente.""" + + def __init__(self, coordinator: PricesDataUpdateCoordinator) -> None: + """Inizializza il sensore.""" + super().__init__(coordinator) + + # Inizializza coordinator + self.coordinator = coordinator + + # ID univoco sensore basato su un nome fisso + self.entity_id = ENTITY_ID_FORMAT.format("prezzo_zonale_orario") + self._attr_unique_id = self.entity_id + self._attr_has_entity_name = True + + # Inizializza le proprietà comuni + self._attr_state_class = SensorStateClass.MEASUREMENT + self._attr_suggested_display_precision = 6 + self._available = False + self._native_value = 0 + self._friendly_name = "Prezzo zonale orario" + + def _handle_coordinator_update(self) -> None: + """Gestisce l'aggiornamento dei dati dal coordinator.""" + + if self.coordinator.pz_values.value[Fascia.ORARIA] > 0: + self._available = len(self.coordinator.pz_data.data[Fascia.ORARIA]) > 0 + self._native_value = self.coordinator.pz_values.value[Fascia.ORARIA] + self._friendly_name = f"Prezzo zonale orario ({datetime.now().hour})" + else: + self._available = False + self._native_value = 0 + self._friendly_name = "Prezzo zonale orario" + + self.async_write_ha_state() + + @property + def extra_restore_state_data(self) -> ExtraStoredData: + """Determina i dati da salvare per il ripristino successivo.""" + return RestoredExtraData( + { + "native_value": self._native_value if self._available else None, + "friendly_name": self._friendly_name if self._available else None, + } + ) + + async def async_added_to_hass(self) -> None: + """Entità aggiunta ad Home Assistant.""" + await super().async_added_to_hass() + + # Recupera lo stato precedente, se esiste + if (old_data := await self.async_get_last_extra_data()) is not None: + if (old_native_value := old_data.as_dict().get("native_value")) is not None: + self._available = True + self._native_value = old_native_value + if ( + old_friendly_name := old_data.as_dict().get("friendly_name") + ) is not None: + self._friendly_name = old_friendly_name + + @property + def should_poll(self) -> bool: + """Determina l'aggiornamento automatico.""" + return False + + @property + def available(self) -> bool: + """Determina se il valore è disponibile.""" + return self._available + + @property + def native_value(self) -> float: + """Restituisce il prezzo della fascia corrente.""" + return fmt_float(self._native_value) + + @property + def native_unit_of_measurement(self) -> str: + """Unita' di misura.""" + return f"{CURRENCY_EURO}/{UnitOfEnergy.KILO_WATT_HOUR}" + + @property + def icon(self) -> str: + """Icona da usare nel frontend.""" + return "mdi:currency-eur" + + @property + def name(self) -> str: + """Restituisce il nome del sensore.""" + return self._friendly_name + + @property + def extra_state_attributes(self) -> dict[str, Any]: + """Restituisce gli attributi di stato.""" + if CommonSettings.has_suggested_display_precision: + return {} + + # Nelle versioni precedenti di Home Assistant + # restituisce un valore arrotondato come attributo + return {ATTR_ROUNDED_DECIMALS: str(format(round(self.native_value, 3), ".3f"))} \ No newline at end of file diff --git a/custom_components/pzo_sensor/strings.json b/custom_components/pzo_sensor/strings.json index 519e6a9..43988c0 100644 --- a/custom_components/pzo_sensor/strings.json +++ b/custom_components/pzo_sensor/strings.json @@ -5,6 +5,7 @@ "title": "Impostazioni scraping prezzi zonali GME", "data": { "zone": "Zona geografica", + "contract": "Tipo di contratto", "scan_hour": "Ora inizio download dati (0-23)", "month_average": "Calcola la media del mese corrente (altrimenti fornisce solo il dato odierno)", "actual_data_only": "Usa solo dati reali ad inizio mese" @@ -24,6 +25,7 @@ "title": "Modifica impostazioni scraping prezzi zonali GME", "data": { "zone": "Zona geografica", + "contract": "Tipo di contratto", "scan_hour": "Ora inizio download dati (0-23)", "month_average": "Calcola la media del mese corrente (altrimenti fornisce solo il dato odierno)", "actual_data_only": "Usa solo dati reali ad inizio mese" diff --git a/custom_components/pzo_sensor/utils.py b/custom_components/pzo_sensor/utils.py index 569532e..94c4cbb 100644 --- a/custom_components/pzo_sensor/utils.py +++ b/custom_components/pzo_sensor/utils.py @@ -7,8 +7,7 @@ import defusedxml.ElementTree as et # type: ignore[import-untyped] import holidays -from .const import PHYSICAL_ZONES -from .interfaces import Fascia, PricesData +from .interfaces import Fascia # Ottiene il logger _LOGGER = logging.getLogger(__name__) @@ -38,7 +37,7 @@ def get_fascia_for_xml(data: date, festivo: bool, ora: int) -> Fascia: return Fascia.F3 -def get_fascia(dataora: datetime) -> tuple[Fascia, datetime]: +def get_fascia(dataora: datetime, contract: int) -> tuple[Fascia, datetime]: """Restituisce la fascia della data/ora indicata e la data del prossimo cambiamento.""" # Verifica se la data corrente è un giorno con festività @@ -49,41 +48,49 @@ def get_fascia(dataora: datetime) -> tuple[Fascia, datetime]: # F2 = lu-ve 7-8, lu-ve 19-23, sa 7-23 # F3 = lu-sa 0-7, lu-sa 23-24, do, festivi # Festivi - if festivo: - fascia = Fascia.F3 - - # Prossima fascia: alle 7 di un giorno non domenica o festività - prossima = get_next_date(dataora, 7, 1, True) - - return fascia, prossima - match dataora.weekday(): - # Domenica - case 6: + if festivo or dataora.weekday() in [5, 6]: + if contract == 2: + fascia = Fascia.F23 + # Prossima fascia: alle 8 di un giorno non domenica, sabato o festività + prossima = get_next_date(dataora, 8, 1, True, True) + + elif dataora.weekday() != 5: fascia = Fascia.F3 + # Prossima fascia: alle 7 di un giorno non domenica o festività prossima = get_next_date(dataora, 7, 1, True) + return fascia, prossima + + match dataora.weekday(): # Sabato case 5: - if 7 <= dataora.hour < 23: - # Sabato dalle 7 alle 23 - fascia = Fascia.F2 - # Prossima fascia: alle 23 dello stesso giorno - prossima = get_next_date(dataora, 23) - # abbiamo solo due fasce quindi facciamo solo il check per la prossima fascia - else: - # Sabato dopo le 23 e prima delle 7 - fascia = Fascia.F3 - - if dataora.hour < 7: - # Prossima fascia: alle 7 dello stesso giorno - prossima = get_next_date(dataora, 7) + if contract != 2: + if 7 <= dataora.hour < 23: + # Sabato dalle 7 alle 23 + fascia = Fascia.F2 + # Prossima fascia: alle 23 dello stesso giorno + prossima = get_next_date(dataora, 23) + # abbiamo solo due fasce quindi facciamo solo il check per la prossima fascia else: - # Prossima fascia: alle 7 di un giorno non domenica o festività - prossima = get_next_date(dataora, 7, 1, True) + # Sabato dopo le 23 e prima delle 7 + fascia = Fascia.F3 + + if dataora.hour < 7: + # Prossima fascia: alle 7 dello stesso giorno + prossima = get_next_date(dataora, 7) + else: + # Prossima fascia: alle 7 di un giorno non domenica o festività + prossima = get_next_date(dataora, 7, 1, True) # Altri giorni della settimana case _: - if dataora.hour == 7 or 19 <= dataora.hour < 23: + if 8 <= dataora.hour < 19: + # Lunedì-venerdì dalle 8 alle 19 + fascia = Fascia.F1 + # Prossima fascia: alle 19 dello stesso giorno + prossima = get_next_date(dataora, 19) + + elif (dataora.hour == 7 or 19 <= dataora.hour < 23) and contract != 2: # Lunedì-venerdì dalle 7 alle 8 e dalle 19 alle 23 fascia = Fascia.F2 @@ -94,13 +101,7 @@ def get_fascia(dataora: datetime) -> tuple[Fascia, datetime]: # Prossima fascia: alle 23 dello stesso giorno prossima = get_next_date(dataora, 23) - elif 8 <= dataora.hour < 19: - # Lunedì-venerdì dalle 8 alle 19 - fascia = Fascia.F1 - # Prossima fascia: alle 19 dello stesso giorno - prossima = get_next_date(dataora, 19) - - else: + elif contract != 2: # Lunedì-venerdì dalle 23 alle 7 del giorno dopo fascia = Fascia.F3 @@ -112,12 +113,15 @@ def get_fascia(dataora: datetime) -> tuple[Fascia, datetime]: # Prossima fascia: alle 7 di un giorno non domenica o festività prossima = get_next_date(dataora, 7, 1, True) + else: + fascia = Fascia.F23 + # Prossima fascia: alle 8 di un giorno non domenica, sabato o festività + prossima = get_next_date(dataora, 8, 1, True, True) + return fascia, prossima -def get_next_date( - dataora: datetime, ora: int, offset: int = 0, feriale: bool = False, minuto: int = 0 -) -> datetime: +def get_next_date(dataora: datetime, ora: int, offset: int = 0, feriale: bool = False, sabato: bool = False, minuto: int = 0) -> datetime: """Ritorna una datetime in base ai parametri. Args: @@ -125,6 +129,7 @@ def get_next_date( ora (int): l'ora a cui impostare la data. offset (int = 0): scostamento in giorni rispetto a dataora. feriale (bool = False): se True ritorna sempre una giornata lavorativa (no festivi, domeniche) + sabato (bool = False): se True non considera il sabato un giorno lavorativo minuto (int = 0): minuto a cui impostare la data. Returns: @@ -137,7 +142,7 @@ def get_next_date( ) if feriale: - while (prossima in holidays.IT()) or (prossima.weekday() == 6): # type: ignore[attr-defined] + while prossima in holidays.IT() or prossima.weekday() == 6 or (sabato and prossima.weekday() == 5): # type: ignore[attr-defined] prossima += timedelta(days=1) return prossima @@ -154,8 +159,8 @@ def extract_xml(priceArchive: ZipFile, pz_data: dict, zone: str) -> list[dict[Fa it_holidays = holidays.IT() # type: ignore[attr-defined] # Azzera i dati precedenti - for fascia in pz_data.keys(): - pz_data[fascia].clear() + for f in pz_data.keys(): + pz_data[f].clear() # Esamina ogni file XML negli ZIP (ordinandoli prima) priceFiles = priceArchive.namelist() @@ -217,17 +222,15 @@ def extract_xml(priceArchive: ZipFile, pz_data: dict, zone: str) -> list[dict[Fa # Somma i valori dei diversi file per fascia per poter fare la media in seguito if file_index > 0: pz_data[Fascia.ORARIA][ora] += prezzo_pz - pz_data[fascia][ora] += prezzo_pz else: pz_data[Fascia.ORARIA].append(prezzo_pz) - pz_data[fascia].append(prezzo_pz) + pz_data[fascia].append(prezzo_pz) # Divide per il numero di file in cui erano presenti prezzi per completare la media - for fascia, dati in pz_data.items(): - for ora in range(len(dati)): - dati[ora] /= fileNumber + for ora in range(len(pz_data[Fascia.ORARIA])): + pz_data[Fascia.ORARIA][ora] /= fileNumber - if fascia == Fascia.ORARIA: - _LOGGER.debug(f'Prezzo {zone} ora {ora}: {pz_data[Fascia.ORARIA][ora]}.') + if fascia == Fascia.ORARIA: + _LOGGER.debug(f'Prezzo {zone} ora {ora}: {pz_data[Fascia.ORARIA][ora]}.') return pz_data \ No newline at end of file