Contrat Tempo EDF

La petite occupation pendant une journée pluvieuse des vacances de Noel: Tempo

Le contrat EDF Tempo est un plan d’électricité avec des tarifs variables basés sur le jour, catégorisés en trois couleurs (bleu, blanc, rouge) indiquant différents tarifs, les jours rouges étant les plus chers. Ce plan vise à encourager la consommation en dehors des périodes de pointe. L’offre peut sembler étrange et peut-être inquiétante à première vue (le tarif des jours rouges est très élevé, à presque 73 centimes par kWh !, alors qu’au Tarif Bleu, il est de 22 centimes). Mais elle mérite d’être examinée. Évidemment, nous pouvons calculer les avantages simplement en prenant les pires jours de consommation de l’année et en appliquant un tarif Rouge puis Blanc à ceux-ci… Mais l’objectif ici n’est pas seulement de mieux évaluer les économies, mais aussi de pouvoir suivre les périodes ou les jours où les jours rouges sont souvent présents et aussi de savoir si nos habitudes de consommation ont un impact significatif. Petit plus, je vous partage un systeme de notification interessant pour rester alerté en cas de jour rouge ou blanc…

see GitHub source

Recuperer et nettoyer les donnees

Le site web d’EDF vous offre la possibilité de télécharger toutes vos données de consommation au format CSV : le problème est que ces formats seront très difficiles à utiliser, donc nous allons d’abord nettoyer ces données :

EDFDatas

Voici le script:

import pandas as pd

def update_file(input_file_path, output_file_path):
    with open(input_file_path, 'r', encoding='ISO-8859-1') as file:
        lines = file.readlines()

    current_date = None
    updated_lines = []

    for line in lines:
        
        line = line.strip()
        if line.endswith(';;'):
            
            current_date = line.split(';;')[0]
        else:
            
            if current_date:
                updated_line = f"{current_date};{line}"
                if not updated_line.endswith(';'):
                    updated_lines.append(updated_line)

    
    with open(output_file_path, 'w', encoding='ISO-8859-1') as file:
        for line in updated_lines:
            file.write(line + '\n')


input_file_path = 'datas/mes-puissances-atteintes-30min-1640-64.csv'
output_file_path = 'datas/mes-puissances-atteintes-30min-cleaned.csv'
update_file(input_file_path, output_file_path)

Grille tarifaire

Nous avons nos données de consommation avec tout l’historique et les détails des heures avec la consommation associée. Il est maintenant nécessaire d’appliquer les tarifs.

TarifsTempo.png

Je vais generer des tables ( j’ai utilisé un LLM pour convertir en quelques secondes cette image :)

# Données des tarifs électriques EDF

# Option Base
prixbase = [{'Puissance': 3, 'Abonnement': 9.47, 'PrixKW': 22.76}, {'Puissance': 6, 'Abonnement': 12.44, 'PrixKW': 22.76}, {'Puissance': 9, 'Abonnement': 15.63, 'PrixKW': 22.76}, {'Puissance': 12, 'Abonnement': 18.89, 'PrixKW': 22.76}, {'Puissance': 15, 'Abonnement': 21.92, 'PrixKW': 22.76}, {'Puissance': 18, 'Abonnement': 24.92, 'PrixKW': 22.76}, {'Puissance': 24, 'Abonnement': 31.6, 'PrixKW': 22.76}, {'Puissance': 30, 'Abonnement': 37.29, 'PrixKW': 22.76}, {'Puissance': 36, 'Abonnement': 44.66, 'PrixKW': 22.76}]

# Option Tempo
prixtempo = [{'Puissance': 6, 'Abonnement': 12.8, 'BLUE_HC': 10.56, 'BLUE_HP': 13.69, 'WHITE_HC': 12.46, 'BLUE_HP': 16.54, 'RED_HC': 13.28, 'RED_HP': 73.24}, {'Puissance': 9, 'Abonnement': 16.0, 'BLUE_HC': 10.56, 'BLUE_HP': 13.69, 'WHITE_HC': 12.46, 'WHITE_HP': 16.54, 'RED_HC': 13.28, 'RED_HP': 73.24}, {'Puissance': 12, 'Abonnement': 19.29, 'BLUE_HC': 10.56, 'BLUE_HP': 13.69, 'WHITE_HC': 12.46, 'WHITE_HP': 16.54, 'RED_HC': 13.28, 'RED_HP': 73.24}, {'Puissance': 15, 'Abonnement': 22.3, 'BLUE_HC': 10.56, 'BLUE_HP': 13.69, 'WHITE_HC': 12.46, 'WHITE_HP': 16.54, 'RED_HC': 13.28, 'RED_HP': 73.24}, {'Puissance': 18, 'Abonnement': 25.29, 'BLUE_HC': 10.56, 'BLUE_HP': 13.69, 'WHITE_HC': 12.46, 'WHITE_HP': 16.54, 'RED_HC': 13.28, 'RED_HP': 73.24}, {'Puissance': 30, 'Abonnement': 38.13, 'BLUE_HC': 10.56, 'BLUE_HP': 13.69, 'WHITE_HC': 12.46, 'WHITE_HP': 16.54, 'RED_HC': 13.28, 'RED_HP': 73.24}, {'Puissance': 36, 'Abonnement': 44.28, 'BLUE_HC': 10.56, 'BLUE_HP': 13.69, 'WHITE_HC': 12.46, 'WHITE_HP': 16.54, 'RED_HC': 13.28, 'RED_HP': 73.24}]

Tempo Vision Project - Utiliser l’API RTE

RTE France offre un accès à ses données via une API très pratique. Il est possible, grâce à cette API, de récupérer toutes les données historiques des jours rouges, bleus ou blancs par date. Parfait, c’est exactement ce dont j’ai besoin. Donc, je commence le travail.

TempoVision

Le projet consiste en des constantes d’API (le secret partagé et la clé d’autorisation), des fonctions qui demanderont le jeton d’accès, et récupéreront les données Tempo pour une plage de dates donnée. Sur ces mêmes dates, nous extrairons la consommation, calculerons le coût en Tarif Bleu, et calculerons le coût en Tarif Tempo selon les tableaux tarifaires, mais en utilisant les données historiques de Tempo. C’est un paramètre important car en janvier il y a plus de pics de consommation et cela peut avoir un impact sur votre taux annuel.

Enfin, j’utilise les bibliothèques Matplotlib et représente toutes ces données :

AnnualConso

aller plus loin 😎

Recuperer la date et couleur des jours

import requests
from datetime import datetime, timedelta

def get_access_token(base64_auth_str):
    """
    Récupère un access token pour l'API.
    """
    token_url = "https://digital.iservices.rte-france.com/token/oauth"
    headers = {
        "Authorization": f"Basic {base64_auth_str}",
        "Content-Type": "application/x-www-form-urlencoded"
    }
    data = {"grant_type": "client_credentials"}
    response = requests.post(token_url, data=data, headers=headers)

    if response.status_code == 200:
        return response.json().get("access_token")
    else:
        print("Erreur lors de l'obtention du token:", response.status_code)
        print(response.text)
        return None

def get_color_emoji(color):
    emojis = {
        'RED': '🔴',
        'WHITE': '⚪',
        'BLUE': '🔵'
    }
    return emojis.get(color, '')  # Retourne l'emoji correspondant ou une chaîne vide si la couleur n'est pas trouvée

def get_tempo_like_calendar(access_token, start_date, end_date):
    """
    Récupère les informations de l'API pour les dates spécifiées.
    """
    api_url = (f"https://digital.iservices.rte-france.com/open_api/tempo_like_supply_contract/v1/tempo_like_calendars"
               f"?start_date={start_date}&end_date={end_date}&fallback_status=true")
    headers = {'Authorization': f'Bearer {access_token}', 'Accept': 'application/json'}
    response = requests.get(api_url, headers=headers)

    if response.status_code == 200:
        return response.json()
    else:
        print("Erreur lors de la récupération des données:", response.status_code)
        print(response.text)
        return None

def format_response(api_response):
    try:
        values = api_response['tempo_like_calendars']['values']
        formatted_responses = []

        for value in values:
            color = value['value']
            color_emoji = get_color_emoji(color)

            start_date = datetime.fromisoformat(value['start_date'])
            formatted_date = start_date.strftime("%Y-%m-%d")
            formatted_responses.append(f"{formatted_date}: {color} {color_emoji}")

        return '\n'.join(formatted_responses)
    except KeyError as e:
        return "Erreur lors du formatage de la réponse: " + str(e)

# Main execution
if __name__ == "__main__":
    base64_auth_str = "----YOUR API TOKEN -- See RTE TEmpo API like calendar"
    access_token = get_access_token(base64_auth_str)

    if access_token:
        start_date = (datetime.now() - timedelta(days=3)).strftime("%Y-%m-%dT00:00:00+01:00")
        end_date = (datetime.now() + timedelta(days=2)).strftime("%Y-%m-%dT00:00:00+01:00")

        response = get_tempo_like_calendar(access_token, start_date, end_date)

        if response:
            formatted_response = format_response(response)
            print(formatted_response)
        else:
            print("Aucune donnée retournée.")


Notification via un Raspberry Pi

Lorsque nous avons une offre Tempo en place, l’objectif est d’être régulièrement informé des changements de jours, en particulier s’il passe en blanc ou en rouge, car nous devrons adapter notre consommation d’électricité. En plus de pouvoir automatiser les équipements (via Home Assistant ou la programmation Synology), il est intéressant de pouvoir être notifié. J’ai connecté 6 LED à un Raspberry Pi pour pouvoir facilement obtenir l’information et j’ai construit un programme pour allumer les LED en fonction des predictions Tempo. Je vous partage ici le montage qui est tres simple:

Gpio montage1 montage2

Notification via un Bot telegram

L’objectif etait de pouvoir notifier tous les membre de ma famille et amis qui pourraient avoir besoin de Tempo.

pre-requis:

pip install python-telegram-bot

Voici le code du bot pour envoyer des messages à l’ID de chat - (consultez Bot Father pour créer le bot et obtenir un jeton.)

import requests
import subprocess

def send_telegram_message(text, bot_token, chat_id):
    url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
    payload = {
        "chat_id": chat_id,
        "text": text
    }
    requests.post(url, data=payload)

def get_script_output():
    process = subprocess.Popen(["python3", "/opt/TempoBot/getdate.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output, error = process.communicate()
    if error:
        return f"Erreur lors de l'exécution du script : {error.decode()}"
    return output.decode()

bot_token = "----YOUR TOKEN HERE-----"
chat_id = "YOUR CHAT ID HERE"

result = get_script_output()
send_telegram_message(result, bot_token, chat_id)

Maintenant, ma famille et moi pouvons recevoir les mises à jour de notification Telegram qui reflètent le jour suivant pour les jours de contrat Tempo EDF donnés par RTE.

Bot