Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 30 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

27 changes: 23 additions & 4 deletions custom_components/tarif_edf/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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()

Expand Down Expand Up @@ -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
Expand All @@ -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):
Expand All @@ -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)
Expand Down
44 changes: 32 additions & 12 deletions custom_components/tarif_edf/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,40 +35,58 @@ 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:
sensors.append(
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"
Expand All @@ -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,
Expand Down