diff --git a/README.md b/README.md index b26dd86..a5576f2 100644 --- a/README.md +++ b/README.md @@ -19,31 +19,49 @@ Copy the `tarif_edf` folder from latest release to the `custom_components` folde ### Common Sensors (All Contracts) | Sensor | Description | Unit | Example | |--------|-------------|------|---------| -| `sensor.tarif_actuel_[type]_[power]kva_ttc` | Current applicable rate | EUR/kWh | `sensor.tarif_actuel_base_6kva_ttc` | +| `sensor.puissance_souscrite_[type]_[power]kva` | Subscribed power | kVA | `sensor.puissance_souscrite_base_6kva` | +| `sensor.tarif_actuel_[type]_[power]kva_ttc` | Current applicable rate (incl. taxes) | EUR/kWh | `sensor.tarif_actuel_base_6kva_ttc` | +| `sensor.tarif_actuel_[type]_[power]kva_ht` | Current applicable rate (excl. taxes) | EUR/kWh | `sensor.tarif_actuel_base_6kva_ht` | ### Base Contract | Sensor | Description | Unit | |--------|-------------|------| -| `sensor.tarif_base_ttc` | Base rate | EUR/kWh | +| `sensor.tarif_base_fixe_ttc` | Fixed rate (incl. taxes) | EUR/an | +| `sensor.tarif_base_fixe_ht` | Fixed rate (excl. taxes) | EUR/an | +| `sensor.tarif_base_variable_ttc` | Variable rate (incl. taxes) | EUR/kWh | +| `sensor.tarif_base_variable_ht` | Variable rate (excl. taxes) | EUR/kWh | ### HP/HC Contract (Peak/Off-Peak) | Sensor | Description | Unit | |--------|-------------|------| -| `sensor.tarif_heures_creuses_ttc` | Off-peak hours rate | EUR/kWh | -| `sensor.tarif_heures_pleines_ttc` | Peak hours rate | EUR/kWh | +| `sensor.tarif_hphc_fixe_ttc` | Fixed rate (incl. taxes) | EUR/an | +| `sensor.tarif_hphc_fixe_ht` | Fixed rate (excl. taxes) | EUR/an | +| `sensor.tarif_hphc_heures_creuses_ttc` | Off-peak hours rate (incl. taxes) | EUR/kWh | +| `sensor.tarif_hphc_heures_creuses_ht` | Off-peak hours rate (excl. taxes) | EUR/kWh | +| `sensor.tarif_hphc_heures_pleines_ttc` | Peak hours rate (incl. taxes) | EUR/kWh | +| `sensor.tarif_hphc_heures_pleines_ht` | Peak hours rate (excl. taxes) | EUR/kWh | ### Tempo Contract | Sensor | Description | Unit | |--------|-------------|------| +| `sensor.tarif_tempo_fixe_ttc` | Fixed rate (incl. taxes) | EUR/an | +| `sensor.tarif_tempo_fixe_ht` | Fixed rate (excl. taxes) | EUR/an | | `sensor.tarif_tempo_couleur` | Current Tempo color | - | | `sensor.tarif_tempo_couleur_hier` | Yesterday's Tempo color | - | | `sensor.tarif_tempo_couleur_aujourd_hui` | Today's Tempo color | - | | `sensor.tarif_tempo_couleur_demain` | Tomorrow's Tempo color | - | -| `sensor.tarif_tempo_heures_creuses_ttc` | Current off-peak hours rate | EUR/kWh | -| `sensor.tarif_tempo_heures_pleines_ttc` | Current peak hours rate | EUR/kWh | -| `sensor.tarif_bleu_tempo_heures_creuses_ttc` | Blue days off-peak rate | EUR/kWh | -| `sensor.tarif_bleu_tempo_heures_pleines_ttc` | Blue days peak rate | EUR/kWh | -| `sensor.tarif_blanc_tempo_heures_creuses_ttc` | White days off-peak rate | EUR/kWh | -| `sensor.tarif_blanc_tempo_heures_pleines_ttc` | White days peak rate | EUR/kWh | -| `sensor.tarif_rouge_tempo_heures_creuses_ttc` | Red days off-peak rate | EUR/kWh | -| `sensor.tarif_rouge_tempo_heures_pleines_ttc` | Red days peak rate | EUR/kWh | +| `sensor.tarif_bleu_tempo_heures_creuses_ttc` | Blue days off-peak rate (incl. taxes) | EUR/kWh | +| `sensor.tarif_bleu_tempo_heures_creuses_ht` | Blue days off-peak rate (excl. taxes) | EUR/kWh | +| `sensor.tarif_bleu_tempo_heures_pleines_ttc` | Blue days peak rate (incl. taxes) | EUR/kWh | +| `sensor.tarif_bleu_tempo_heures_pleines_ht` | Blue days peak rate (excl. taxes) | EUR/kWh | +| `sensor.tarif_blanc_tempo_heures_creuses_ttc` | White days off-peak rate (incl. taxes) | EUR/kWh | +| `sensor.tarif_blanc_tempo_heures_creuses_ht` | White days off-peak rate (excl. taxes) | EUR/kWh | +| `sensor.tarif_blanc_tempo_heures_pleines_ttc` | White days peak rate (incl. taxes) | EUR/kWh | +| `sensor.tarif_blanc_tempo_heures_pleines_ht` | White days peak rate (excl. taxes) | EUR/kWh | +| `sensor.tarif_rouge_tempo_heures_creuses_ttc` | Red days off-peak rate (incl. taxes) | EUR/kWh | +| `sensor.tarif_rouge_tempo_heures_creuses_ht` | Red days off-peak rate (excl. taxes) | EUR/kWh | +| `sensor.tarif_rouge_tempo_heures_pleines_ttc` | Red days peak rate (incl. taxes) | EUR/kWh | +| `sensor.tarif_rouge_tempo_heures_pleines_ht` | Red days peak rate (excl. taxes) | EUR/kWh | + +Note: Sensors with suffix "_ht" (excluding taxes) are disabled by default and can be enabled in the Home Assistant interface if needed. + diff --git a/custom_components/tarif_edf/coordinator.py b/custom_components/tarif_edf/coordinator.py index cfe28e1..21d0142 100644 --- a/custom_components/tarif_edf/coordinator.py +++ b/custom_components/tarif_edf/coordinator.py @@ -96,7 +96,8 @@ async def _async_update_data(self) -> dict[Platform, dict[str, Any]]: "contract_power": data['contract_power'], "contract_type": data['contract_type'], "last_refresh_at": None, - "tarif_actuel_ttc": None + "tarif_actuel_ttc": None, + "tarif_actuel_ht": None } fresh_data_limit = datetime.now() - timedelta(days=self.config_entry.options.get("refresh_interval", DEFAULT_REFRESH_INTERVAL)) @@ -121,19 +122,31 @@ async def _async_update_data(self) -> dict[Platform, dict[str, Any]]: if row[1] == '' and row[2] == data['contract_power']: if data['contract_type'] == CONTRACT_TYPE_BASE: self.data['base_fixe_ttc'] = float(row[4].replace(",", "." )) + self.data['base_fixe_ht'] = float(row[3].replace(",", "." )) self.data['base_variable_ttc'] = float(row[6].replace(",", "." )) + self.data['base_variable_ht'] = float(row[5].replace(",", "." )) elif data['contract_type'] == CONTRACT_TYPE_HPHC: self.data['hphc_fixe_ttc'] = float(row[4].replace(",", "." )) + self.data['hphc_fixe_ht'] = float(row[3].replace(",", "." )) self.data['hphc_variable_hc_ttc'] = float(row[6].replace(",", "." )) + self.data['hphc_variable_hc_ht'] = float(row[5].replace(",", "." )) self.data['hphc_variable_hp_ttc'] = float(row[8].replace(",", "." )) + self.data['hphc_variable_hp_ht'] = float(row[7].replace(",", "." )) elif data['contract_type'] == CONTRACT_TYPE_TEMPO: self.data['tempo_fixe_ttc'] = float(row[4].replace(",", "." )) + self.data['tempo_fixe_ht'] = float(row[3].replace(",", "." )) self.data['tempo_variable_hc_bleu_ttc'] = float(row[6].replace(",", "." )) + self.data['tempo_variable_hc_bleu_ht'] = float(row[5].replace(",", "." )) self.data['tempo_variable_hp_bleu_ttc'] = float(row[8].replace(",", "." )) + self.data['tempo_variable_hp_bleu_ht'] = float(row[7].replace(",", "." )) self.data['tempo_variable_hc_blanc_ttc'] = float(row[10].replace(",", "." )) + self.data['tempo_variable_hc_blanc_ht'] = float(row[9].replace(",", "." )) self.data['tempo_variable_hp_blanc_ttc'] = float(row[12].replace(",", "." )) + self.data['tempo_variable_hp_blanc_ht'] = float(row[11].replace(",", "." )) self.data['tempo_variable_hc_rouge_ttc'] = float(row[14].replace(",", "." )) + self.data['tempo_variable_hc_rouge_ht'] = float(row[13].replace(",", "." )) self.data['tempo_variable_hp_rouge_ttc'] = float(row[16].replace(",", "." )) + self.data['tempo_variable_hp_rouge_ht'] = float(row[15].replace(",", "." )) self.data['last_refresh_at'] = datetime.now() @@ -169,7 +182,9 @@ async def _async_update_data(self) -> dict[Platform, dict[str, Any]]: color = get_tempo_color_from_code(currentColorCode) self.data['tempo_couleur'] = color self.data['tempo_variable_hp_ttc'] = self.data[f"tempo_variable_hp_{color}_ttc"] + self.data['tempo_variable_hp_ht'] = self.data[f"tempo_variable_hp_{color}_ht"] self.data['tempo_variable_hc_ttc'] = self.data[f"tempo_variable_hc_{color}_ttc"] + self.data['tempo_variable_hc_ht'] = self.data[f"tempo_variable_hc_{color}_ht"] self.data['last_refresh_at'] = datetime.now() default_offpeak_hours = None @@ -179,9 +194,11 @@ async def _async_update_data(self) -> dict[Platform, dict[str, Any]]: if data['contract_type'] == CONTRACT_TYPE_BASE: self.data['tarif_actuel_ttc'] = self.data['base_variable_ttc'] + self.data['tarif_actuel_ht'] = self.data['base_variable_ht'] elif data['contract_type'] in [CONTRACT_TYPE_HPHC, CONTRACT_TYPE_TEMPO] and off_peak_hours_ranges is not None: contract_type_key = 'hphc' if data['contract_type'] == CONTRACT_TYPE_HPHC else 'tempo' - tarif_actuel = self.data[contract_type_key+'_variable_hp_ttc'] + tarif_actuel_ttc = self.data[contract_type_key+'_variable_hp_ttc'] + tarif_actuel_ht = self.data[contract_type_key+'_variable_hp_ht'] now = datetime.now().time() for range in off_peak_hours_ranges.split(','): if not re.match(r'([0-1]?[0-9]|2[0-3]):[0-5][0-9]-([0-1]?[0-9]|2[0-3]):[0-5][0-9]', range): @@ -192,10 +209,12 @@ async def _async_update_data(self) -> dict[Platform, dict[str, Any]]: end_at = str_to_time(hours[1]) if time_in_between(now, start_at, end_at): - tarif_actuel = self.data[contract_type_key+'_variable_hc_ttc'] + tarif_actuel_ttc = self.data[contract_type_key+'_variable_hc_ttc'] + tarif_actuel_ht = self.data[contract_type_key+'_variable_hc_ht'] break - self.data['tarif_actuel_ttc'] = tarif_actuel + self.data['tarif_actuel_ttc'] = tarif_actuel_ttc + self.data['tarif_actuel_ht'] = tarif_actuel_ht self.logger.info('EDF Tarif') self.logger.info(self.data) diff --git a/custom_components/tarif_edf/sensor.py b/custom_components/tarif_edf/sensor.py index 2f5b968..7388bd4 100644 --- a/custom_components/tarif_edf/sensor.py +++ b/custom_components/tarif_edf/sensor.py @@ -35,27 +35,40 @@ async def async_setup_entry( if coordinator.data['contract_type'] == CONTRACT_TYPE_BASE: sensors.extend([ - TarifEdfSensor(coordinator, 'base_variable_ttc', 'Tarif Base TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'base_fixe_ttc', 'Tarif Base Fixe TTC', 'EUR/an'), + TarifEdfSensor(coordinator, 'base_fixe_ht', 'Tarif Base Fixe HT', 'EUR/an'), + TarifEdfSensor(coordinator, 'base_variable_ttc', 'Tarif Base Variable TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'base_variable_ht', 'Tarif Base Variable HT', 'EUR/kWh'), ]) elif coordinator.data['contract_type'] == CONTRACT_TYPE_HPHC: sensors.extend([ - TarifEdfSensor(coordinator, 'hphc_variable_hc_ttc', 'Tarif Heures creuses TTC', 'EUR/kWh'), - TarifEdfSensor(coordinator, 'hphc_variable_hp_ttc', 'Tarif Heures pleines TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'hphc_fixe_ttc', 'Tarif HPHC Fixe TTC', 'EUR/an'), + TarifEdfSensor(coordinator, 'hphc_fixe_ht', 'Tarif HPHC Fixe HT', 'EUR/an'), + TarifEdfSensor(coordinator, 'hphc_variable_hc_ttc', 'Tarif HPHC Heures Creuses TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'hphc_variable_hc_ht', 'Tarif HPHC Heures Creuses HT', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'hphc_variable_hp_ttc', 'Tarif HPHC Heures Pleines TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'hphc_variable_hp_ht', 'Tarif HPHC Heures Pleines HT', 'EUR/kWh'), ]) elif coordinator.data['contract_type'] == CONTRACT_TYPE_TEMPO: sensors.extend([ + TarifEdfSensor(coordinator, 'tempo_fixe_ttc', 'Tarif Tempo Fixe TTC', 'EUR/an'), + TarifEdfSensor(coordinator, 'tempo_fixe_ht', 'Tarif Tempo Fixe HT', 'EUR/an'), + TarifEdfSensor(coordinator, 'tempo_variable_hc_bleu_ttc', 'Tarif Bleu Tempo Heures Creuses TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hc_bleu_ht', 'Tarif Bleu Tempo Heures Creuses HT', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hp_bleu_ttc', 'Tarif Bleu Tempo Heures Pleines TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hp_bleu_ht', 'Tarif Bleu Tempo Heures Pleines HT', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hc_blanc_ttc', 'Tarif Blanc Tempo Heures Creuses TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hc_blanc_ht', 'Tarif Blanc Tempo Heures Creuses HT', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hp_blanc_ttc', 'Tarif Blanc Tempo Heures Pleines TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hp_blanc_ht', 'Tarif Blanc Tempo Heures Pleines HT', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hc_rouge_ttc', 'Tarif Rouge Tempo Heures Creuses TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hc_rouge_ht', 'Tarif Rouge Tempo Heures Creuses HT', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hp_rouge_ttc', 'Tarif Rouge Tempo Heures Pleines TTC', 'EUR/kWh'), + TarifEdfSensor(coordinator, 'tempo_variable_hp_rouge_ht', 'Tarif Rouge Tempo Heures Pleines HT', 'EUR/kWh'), TarifEdfSensor(coordinator, 'tempo_couleur', 'Tarif Tempo Couleur'), TarifEdfSensor(coordinator, 'tempo_couleur_hier', 'Tarif Tempo Couleur Hier'), TarifEdfSensor(coordinator, 'tempo_couleur_aujourdhui', "Tarif Tempo Couleur Aujourd'hui"), TarifEdfSensor(coordinator, 'tempo_couleur_demain', 'Tarif Tempo Couleur Demain'), - TarifEdfSensor(coordinator, 'tempo_variable_hc_ttc', 'Tarif Tempo Heures creuses TTC', 'EUR/kWh'), - TarifEdfSensor(coordinator, 'tempo_variable_hp_ttc', 'Tarif Tempo Heures pleines TTC', 'EUR/kWh'), - TarifEdfSensor(coordinator, 'tempo_variable_hc_bleu_ttc', 'Tarif Bleu Tempo Heures creuses TTC', 'EUR/kWh'), - TarifEdfSensor(coordinator, 'tempo_variable_hp_bleu_ttc', 'Tarif Bleu Tempo Heures pleines TTC', 'EUR/kWh'), - TarifEdfSensor(coordinator, 'tempo_variable_hc_rouge_ttc', 'Tarif Rouge Tempo Heures creuses TTC', 'EUR/kWh'), - TarifEdfSensor(coordinator, 'tempo_variable_hp_rouge_ttc', 'Tarif Rouge Tempo Heures pleines TTC', 'EUR/kWh'), - TarifEdfSensor(coordinator, 'tempo_variable_hc_blanc_ttc', 'Tarif Blanc Tempo Heures creuses TTC', 'EUR/kWh'), - TarifEdfSensor(coordinator, 'tempo_variable_hp_blanc_ttc', 'Tarif Blanc Tempo Heures pleines TTC', 'EUR/kWh'), ]) if coordinator.data['tarif_actuel_ttc'] is not None: @@ -63,12 +76,17 @@ async def async_setup_entry( TarifEdfSensor(coordinator, 'tarif_actuel_ttc', f"Tarif actuel {coordinator.data['contract_type']} {coordinator.data['contract_power']}kVA TTC", 'EUR/kWh') ) + if coordinator.data['tarif_actuel_ht'] is not None: + sensors.append( + TarifEdfSensor(coordinator, 'tarif_actuel_ht', f"Tarif actuel {coordinator.data['contract_type']} {coordinator.data['contract_power']}kVA HT", 'EUR/kWh') + ) + async_add_entities(sensors, False) class TarifEdfSensor(CoordinatorEntity, SensorEntity): """Representation of a Tarif EDF sensor.""" - def __init__(self, coordinator, coordinator_key: str, name: str, unit_of_measurement: str = None) -> None: + def __init__(self, coordinator, coordinator_key: str, name: str, unit_of_measurement: str = None, icon: str = None) -> None: """Initialize the Tarif EDF sensor.""" super().__init__(coordinator) contract_name = str.upper(self.coordinator.data['contract_type']) + " " + self.coordinator.data['contract_power'] + "kVA" @@ -77,6 +95,8 @@ def __init__(self, coordinator, coordinator_key: str, name: str, unit_of_measure self._name = name self._attr_unique_id = f"tarif_edf_{self._name}" self._attr_name = name + self._attr_icon = "mdi:currency-eur" if unit_of_measurement and "EUR" in unit_of_measurement else icon + self._attr_entity_registry_enabled_default = not coordinator_key.endswith('_ht') self._attr_device_info = DeviceInfo( name=f"Tarif EDF - {contract_name}", entry_type=DeviceEntryType.SERVICE,