ECO Compteur sur Home assistant

Introduction

Le boîtier LEGRAND permet de mesurer et suivre les consommations de cinq postes différents, tels que le chauffage, le refroidissement, l’eau chaude sanitaire, le réseau de prises de courant, et d’autres, conformément à la réglementation thermique 2012. Il offre un affichage des consommations en euros ou en kWh sur une page web dédiée.

En plus de mesurer la consommation électrique en temps réel, le boîtier LEGRAND permet également d’afficher les consommations d’eau et de gaz. Il s’installe directement dans le tableau électrique, mais doit être protégé par un disjoncteur.

Pour mettre à jour votre écocompteur, vous pouvez vous rendre sur le site de LEGRAND : https://www.legrandoc.com/412000. Cependant, soyez prudent lors de la mise à jour, car il peut y avoir des risques d’incompatibilité.

Liste matériel

Pour à peu près 300€, nous pouvons mesurer toute notre maison (plus précis qu’un LINKY) et l’interconnecter avec Home Assistant.

Installation matériel

Une fois raccordement en 220v effectué après un disjoncteur. Nous trouvons sur la face bas du boitier les borniers pour y connecter les pinces tores:

C1 : Chauffage C2 : Refroidissement C3 : Eau Chaude Sanitaire C4 : Prises de courant C5 : Prises de courant

PS: Chaque bornier peut recevoir jusqu’à deux pinces ce qui nous permet de cumuler le suivi de deux pinces tores sur un même poste. Sur la face en bas nous avons :

Sur la face haut nous trouvons :

SCS : sortie Bus/SCS pour affichage des consommations sur écran TIC : Compteur Général, pour relever la téléinfo directement CI2 : compteur impulsion pour l’eau CI1 : compteur impulsion pour le gaz

Un port Ethernet pour le connecter à notre baie.

Ce qui nous permet d’accéder à l’interface WEB.

Un schéma pour résumer tout ça :

issu de la notice

L’intégration dans le compteur électrique est vraiment simple :

issu de la notice

Intégration avec HS

La communauté Home Assistant a déjà développé une solution pour intégrer le boîtier LEGRAND avec Home Assistant. Vous pouvez consulter les étapes détaillées et les discussions à ce sujet sur le forum de la communauté en suivant ce lien:

https://community.home-assistant.io/t/how-to-decode-special-json-ex-conso-hc-006699756/253018/21

Secret

On met à jour notre fichier de secret

Attention remplacer 172.16.X.X par l’IP de votre éco compteur :)

Legrand_Source_Data: http://172.16.X.X/data.json
Legrand_Source_Instantanes: http://172.16.X.X/inst.json
Legrand_Cmd_Tarif_Courant: curl -s 'http://172.16.X.X/data.json' | jq '.tarif_courant'
Legrand_Cmd_Intensite_Souscrite: curl -s 'http://172.16.X.X/data.json' | jq '.isousc'
Legrand_Cmd_Conso_HC: curl -s 'http://172.16.X.X/data.json' | jq '.conso_hc /1000 | floor'
Legrand_Cmd_Conso_HP: curl -s 'http://172.16.X.X/data.json' | jq '.conso_hp /1000 | floor'

Package YAML

On crée notre package ici

vi .../config/packages/package_legrand.yaml

Attention ici ma version modifiée, orignal est ici : https://community.home-assistant.io/t/how-to-decode-special-json-ex-conso-hc-006699756/253018/21

#---
   ############################################################
   ##                                                        ##
   ##                PACKAGE LEGRAND ECO-COMPTEUR            ##
   ##                                                        ##
   ############################################################
homeassistant:
   ############################################################
   ##                                                        ##
   ##                     CUSTOMIZE                          ##
   ##                                                        ##
   ############################################################

  customize:

    #################
    ## Node Anchors #
    #################
    package.node_anchors:
      customize: &customize
        package: 'package_legrand_ecocompteur'

    ##########################################
    ##   Personnalisation Sensors Circuits   #
    ##########################################

# Circuit 1 = label_entree1
    sensor.phase_1:
      <<: *customize
      friendly_name: "Phase 1"
      icon: mdi:alpha-w-circle-outline

# Circuit 2 = label_entree2
    sensor.phase_2:
      <<: *customize
      friendly_name: "Phase 2"
      icon: mdi:alpha-w-circle-outline

# Circuit 3 = label_entree3
    sensor.phase_3:
      <<: *customize
      friendly_name: "Phase 3"
      icon: mdi:alpha-w-circle-outline

# Circuit 4 = label_entree4
    sensor.chaudiere:
      <<: *customize
      friendly_name: "Chaudière"
      icon: mdi:alpha-w-circle-outline

# Circuit 5 = label_entree5
    sensor.legrand_puissance_circuit_5:
      <<: *customize
      friendly_name: "Data Center"
      icon: mdi:alpha-w-circle-outline



    #################################################################
    ##   Personnalisation Sensors Tableau Consommation Electrique   #
    #################################################################


    sensor.legrand_hchp:
      <<: *customize
      friendly_name: "Legrand Tarif en Cours"
      icon: mdi:av-timer


    sensor.legrand_intensite_souscrite:
      <<: *customize
      friendly_name: "Legrand Intensité Souscrite"
      icon: mdi:alpha-w-circle-outline


    sensor.legrand_puissance_souscrite:
      <<: *customize
      friendly_name: "Legrand Puissance Abonnement"
      icon: mdi:alpha-w-circle-outline


    ##########################################
    ##   Personnalisation Sensors Circuits   #
    ##########################################


    sensor.legrand_consommation_hp:
      <<: *customize
      friendly_name: "Legrand Conso. Heures Pleines"
      icon: mdi:counter


    sensor.legrand_consommation_hc:
      <<: *customize
      friendly_name: "Legrand Conso. Heures Creuses"
      icon: mdi:counter


    sensor.legrand_tarif_en_cours:
      <<: *customize
      friendly_name: "Legrand Indicateur Tarif en Cours"
      icon: mdi:counter

    ###########################################
    ##   Personnalisation Conso Electricité   #
    ###########################################

    sensor.legrand_conso_totale:
      <<: *customize
      friendly_name: "Legrand Conso. Totale"
      icon: mdi:counter

# Personnalisation Electricité Utility Meter

    sensor.energy_daily_cost:
      <<: *customize
      friendly_name: "Legrand Conso. Electr. Quotid."
      icon: mdi:counter

    sensor.energy_weekly_cost:
      <<: *customize
      friendly_name: "Legrand Conso. Electr. Hebdo."
      icon: mdi:counter

    sensor.energy_monthly_cost:
      <<: *customize
      friendly_name: "Legrand Conso. Electr. Mensuelle"
      icon: mdi:counter

    sensor.energy_yearly_cost:
      <<: *customize
      friendly_name: "Legrand Conso. Electr. Annuelle"
      icon: mdi:counter




#     ###################################
#     ##   Personnalisation Conso Eau   #
#     ###################################

# # Compteur Eau
#     sensor.legrand_consommation_totale_eau_m3:
#       <<: *customize
#       friendly_name: "Legrand Conso. Totale Eau"
#       icon: mdi:water


# # Personnalisation Eau Utility Meter

#     sensor.water_daily_total:
#       <<: *customize
#       friendly_name: "Legrand Conso. Eau Quotid."
#       icon: mdi:water

#     sensor.water_weekly_total:
#       <<: *customize
#       friendly_name: "Legrand Conso. Eau Hebdo."
#       icon: mdi:water

#     sensor.water_monthly_total:
#       <<: *customize
#       friendly_name: "Legrand Conso. Eau Mensuelle"
#       icon: mdi:water

#     sensor.water_yearly_total:
#       <<: *customize
#       friendly_name: "Legrand Conso. Eau Annuelle"
#       icon: mdi:water

   #####################################
   ##                                 ##
   ##        SENSORS PUISSANCES       ##
   ##           INSTANTANEES          ##
   ##                                 ##
   #####################################

sensor:

#     ELECTRICITE

# Commande Récupération Valeur Puissances Instantanées Circuit 1
  - platform: rest
    resource: !secret Legrand_Source_Instantanes
    name: Phase 1
    value_template: '{{ value_json.data1| round(0) }}'
    device_class: power
    unit_of_measurement: W

# Commande Récupération Valeur Puissances Instantanées Circuit 2

  - platform: rest
    resource: !secret Legrand_Source_Instantanes
    name: Phase 2
    value_template: '{{ value_json.data2| round(0) }}'
    device_class: power
    unit_of_measurement: W

# Commande Récupération Valeur Puissances Instantanées Circuit 3
  - platform: rest
    resource: !secret Legrand_Source_Instantanes
    name: Phase 3
    value_template: '{{ value_json.data3| round(0) }}'
    device_class: power
    unit_of_measurement: W

# Commande Récupération Valeur Puissances Instantanées Circuit 4
  - platform: rest
    resource: !secret Legrand_Source_Instantanes
    name: Chaudière
    value_template: '{{ value_json.data4| round(0) }}'
    device_class: power
    unit_of_measurement: W

# Commande Récupération Valeur Puissances Instantanées Circuit 5
  - platform: rest
    resource: !secret Legrand_Source_Instantanes
    name: Data Center
    value_template: '{{ value_json.data5| round(0) }}'
    device_class: power
    unit_of_measurement: W


# #     EAU


# # Commande Récupération Valeur Volume Conso Total Eau (m3)
#   - platform: rest
#     resource: !secret Legrand_Source_Instantanes
#     name: Legrand Consommation Totale Eau m3
#     value_template: '{{ value_json.data6m3 }}'
#     unit_of_measurement: m3


#    #####################################
#    ##                                 ##
#    ##       SENSORS & TEMPLATES       ##
#    ##    CONSOMMATIONS ELECTRIQUE     ##
#    ##                                 ##
#    #####################################

# # Tarif en Cours Donnée Brute
# # Valeurs : 2 = Pleine / 1 = Creuse
#   - platform: command_line
#     name: Legrand Tarif en Cours
#     command: !secret Legrand_Cmd_Tarif_Courant
#     scan_interval: 10

# # Transformation Tarif en Cours > Tranche Tarifaire
#   - platform: template
#     sensors:
#       legrand_hchp:
#         entity_id: sensor.legrand_tarif_en_cours
#         value_template: >
#           {% if is_state('sensor.legrand_tarif_en_cours', '2') %}
#             Pleine
#           {% else %}
#             Creuse
#           {% endif %}


   #####################################
   ##                                 ##
   ##             RELEVES             ##
   ##           ABONNEMENT            ##
   ##                                 ##
   #####################################

# Intensité Souscrite
  - platform: command_line
    name: Legrand Intensité Souscrite
    command: !secret Legrand_Cmd_Intensite_Souscrite
    scan_interval: 60
    unit_of_measurement: A

# Puissance Souscrite
  - platform: template
    sensors:
      legrand_puissance_souscrite:
        friendly_name: "Legrand Puissance Souscrite"
        value_template: >-
          {% set i = states('sensor.legrand_intensite_souscrite') | float %}
          {{ ( i / 5 ) | round(2) }}          
        unit_of_measurement: 'kVA'
        icon_template: mdi:gauge

# Conso. HC
  - platform: command_line
    name: Legrand Consommation HC
    command: !secret Legrand_Cmd_Conso_HC
    scan_interval: 10
    unit_of_measurement: kWh

# Conso. HP
  - platform: command_line
    name: Legrand Consommation HP
    command: !secret Legrand_Cmd_Conso_HP
    scan_interval: 10
    unit_of_measurement: kWh


   #####################################
   ##                                 ##
   ##         SENSORS CALCULS         ##
   ##           CONSOMMATION          ##
   ##                                 ##
   #####################################


# Calcul Consommation Totale (HP + HC)
  - platform: template
    sensors:
      legrand_conso_totale:
        friendly_name: "Legrand Consommation Totale"
        unit_of_measurement: "kWh"
        value_template: >-
                    {{ float(states.sensor.legrand_consommation_hp.state) + float(states.sensor.legrand_consommation_hc.state) | round(2) }}


   #####################################
   ##                                 ##
   ##          SENSORS COUTS          ##
   ##      FACTURATION ELECTRICITE    ##
   ##                                 ##
   #####################################

# Sensor Input Text Abonnement
  - platform: template
    sensors:
      electricite_prix_abo:
        friendly_name: "Legrand Prix Abo"
        unit_of_measurement: "€"
        value_template: >
                    {{ states('input_text.legrand_prix_abo') | round(2) }}
        icon_template: mdi:currency-eur

# Sensor Input Text Prix kwh HP
  - platform: template
    sensors:
      electricite_prix_kwh_hp:
        friendly_name: "Legrand Prix kWh HP"
        unit_of_measurement: "€"
        value_template: >
                    {{ states('input_text.legrand_prix_kwh_hp') | round(2) }}
        icon_template: mdi:currency-eur

# Sensor Input Text Prix Kwh HC
  - platform: template
    sensors:
      electricite_prix_kwh_hc:
        friendly_name: "Legrand Prix kWh HC"
        unit_of_measurement: "€"
        value_template: >
                    {{ states('input_text.legrand_prix_kwh_hc') | round(2) }}
        icon_template: mdi:currency-eur


     ###########################################
     ##     CALCULS CONSOMMATIONS TOTALES     ##
     ###########################################

       #########################
       ##     ELECTRICITE     ##
       #########################

## CALCULS FACTURATION ELECTRICITE

# TEST Ravin calcul cout maison en WATT ( Phase 1 + Phase 2 + Phase 3)
  - platform: template
    sensors:
      consommation_maison:
        friendly_name: Consommation maison
        value_template: >-
          {% set p1 = states('sensor.phase_1') | float %}
          {% set p2 = states('sensor.phase_2') | float %}
          {% set p3 = states('sensor.phase_3') | float %}
          {{ p1 + p2 + p3 | round(2) }}          
        unit_of_measurement: 'W'
        icon_template: mdi:counter

# Calcul Coût Quotidien
  - platform: template
    sensors:
      energy_daily_cost:
        friendly_name: Electricité Coût Quotdien
        value_template: >-
          {% set p = states('sensor.legrand_daily_energy_peak') | float %}
          {% set o = states('sensor.legrand_daily_energy_offpeak') | float %}
          {% set a = states('sensor.electricite_prix_abo') | float %}
          {% set h = states('sensor.electricite_prix_kwh_hp') | float %}
          {% set c = states('sensor.electricite_prix_kwh_hc') | float %}
          {{ ((a * 12 / 365 ) + (p * h) + (c * o)) | round(2) }}          
        unit_of_measurement: '€'
        icon_template: mdi:currency-eur

# Calcul Coût Hebdomadaire
      energy_weekly_cost:
        friendly_name: Electricité Coût Hebdo
        value_template: >-
          {% set p = states('sensor.legrand_weekly_energy_peak') | float %}
          {% set o = states('sensor.legrand_weekly_energy_offpeak') | float %}
          {% set a = states('sensor.energy_daily_cost') | float %}
          {% set h = states('sensor.electricite_prix_kwh_hp') | float %}
          {% set c = states('sensor.electricite_prix_kwh_hc') | float %}
          {{ ((a * 7 ) + (p * h) + (c * o)) | round(2) }}          
        unit_of_measurement: '€'
        icon_template: mdi:currency-eur

# Calcul Coût Mensuel
      energy_monthly_cost:
        friendly_name: Electricité Coût Mensuel
        value_template: >-
          {% set p = states('sensor.legrand_monthly_energy_peak') | float %}
          {% set o = states('sensor.legrand_monthly_energy_offpeak') | float %}
          {% set a = states('sensor.electricite_prix_abo') | float %}
          {% set h = states('sensor.electricite_prix_kwh_hp') | float %}
          {% set c = states('sensor.electricite_prix_kwh_hc') | float %}
          {{ (a + (p * h) + (c * o)) | round(2) }}          
        unit_of_measurement: '€'
        icon_template: mdi:currency-eur

# Calcul Coût Annuel
      energy_yearly_cost:
        friendly_name: Electricité Coût Annuel
        value_template: >-
          {% set p = states('sensor.legrand_yearly_energy_peak') | float %}
          {% set o = states('sensor.legrand_yearly_energy_offpeak') | float %}
          {% set a = states('sensor.electricite_prix_abo') | float %}
          {% set h = states('sensor.electricite_prix_kwh_hp') | float %}
          {% set c = states('sensor.electricite_prix_kwh_hc') | float %}
          {{ ((a * 12) + (p * h) + (c * o)) | round(2) }}          
        unit_of_measurement: '€'
        icon_template: mdi:currency-eur


# Calcul Consommation TOTALE Quotidienne ELECTRICITE
  - platform: template
    sensors:
      energy_daily_total:
        friendly_name: Electricité Consommation Quotidienne Totale
        value_template: >-
          {% set p = states('sensor.legrand_daily_energy_peak') | float %}
          {% set o = states('sensor.legrand_daily_energy_offpeak') | float %}
          {{ (o + p) | round(2) }}          
        unit_of_measurement: 'kWh'
        icon_template: mdi:counter

# Calcul Consommation TOTALE Hebdo ELECTRICITE
  - platform: template
    sensors:
      energy_weekly_total:
        friendly_name: Electricité Consommation Hebdo Totale
        value_template: >-
          {% set p = states('sensor.legrand_weekly_energy_peak') | float %}
          {% set o = states('sensor.legrand_weekly_energy_offpeak') | float %}
          {{ (o + p) | round(2) }}          
        unit_of_measurement: 'kWh'
        icon_template: mdi:counter

# Calcul Consommation TOTALE Mensuelle ELECTRICITE
  - platform: template
    sensors:
      energy_monthly_total:
        friendly_name: Electricité Consommation Mensuelle Totale
        value_template: >-
          {% set p = states('sensor.legrand_monthly_energy_peak') | float %}
          {% set o = states('sensor.legrand_monthly_energy_offpeak') | float %}
          {{ (o + p) | round(2) }}          
        unit_of_measurement: 'kWh'
        icon_template: mdi:counter

# Calcul Consommation TOTALE Annuelle ELECTRICITE
  - platform: template
    sensors:
      energy_yearly_total:
        friendly_name: Electricité Consommation Annuelle Totale
        value_template: >-
          {% set p = states('sensor.legrand_yearly_energy_peak') | float %}
          {% set o = states('sensor.legrand_yearly_energy_offpeak') | float %}
          {{ (o + p) | round(2) }}          
        unit_of_measurement: 'kWh'
        icon_template: mdi:counter


#        #########################
#        ##         EAU         ##
#        #########################

# # Calcul Consommation Totale Quotidienne EAU (LITRES)
#   - platform: template
#     sensors:
#       water_daily_total:
#         friendly_name: Eau Consommation Quotidienne Totale
#         value_template: >-
#           {% set p = states('sensor.legrand_daily_water_peak') | float %}
#           {% set o = states('sensor.legrand_daily_water_offpeak') | float %}
#           {{ (o + p) * 1000 | round(2) }}
#         unit_of_measurement: 'l'


# # Calcul Consommation Totale Hebdomadaire EAU (LITRES)
#   - platform: template
#     sensors:
#       water_weekly_total:
#         friendly_name: Eau Consommation Hebdo Totale
#         value_template: >-
#           {% set p = states('sensor.legrand_weekly_water_peak') | float | round(2) %}
#           {% set o = states('sensor.legrand_weekly_water_offpeak') | float | round(1) %}
#           {{ (o + p) * 1000 }}
#         unit_of_measurement: 'l'


# # Calcul Consommation Totale Mensuelle EAU (LITRES)
#   - platform: template
#     sensors:
#       water_monthly_total:
#         friendly_name: Eau Consommation Mensuelle Totale
#         value_template: >-
#           {% set p = states('sensor.legrand_monthly_water_peak') | float %}
#           {% set o = states('sensor.legrand_monthly_water_offpeak') | float %}
#           {{ (o + p) * 1000 | round(2) }}
#         unit_of_measurement: 'l'


# # Calcul Consommation Totale Annuelle EAU (LITRES)
#   - platform: template
#     sensors:
#       water_yearly_total:
#         friendly_name: Eau Consommation Annuelle Totale
#         value_template: >-
#           {% set p = states('sensor.legrand_yearly_water_peak') | float %}
#           {% set o = states('sensor.legrand_yearly_water_offpeak') | float %}
#           {{ (o + p) * 1000 | round(2) }}
#         unit_of_measurement: 'l'


   #####################################
   ##                                 ##
   ##         UTILITY METER           ##
   ##                                 ##
   #####################################

utility_meter:

       #########################
       ##     ELECTRICITE     ##
       #########################

  legrand_daily_energy:
    source: sensor.legrand_conso_totale
    cycle: daily
    tariffs:
      - peak
      - offpeak
  legrand_weekly_energy:
    source: sensor.legrand_conso_totale
    cycle: weekly
    tariffs:
      - peak
      - offpeak
  legrand_monthly_energy:
    source: sensor.legrand_conso_totale
    cycle: monthly
    tariffs:
      - peak
      - offpeak
  legrand_yearly_energy:
    source: sensor.legrand_conso_totale
    cycle: yearly
    tariffs:
      - peak
      - offpeak


  #      #########################
  #      ##         EAU         ##
  #      #########################


  # legrand_daily_water:
  #   source: sensor.legrand_consommation_totale_eau_m3
  #   cycle: daily
  #   tariffs:
  #     - peak
  #     - offpeak
  # legrand_weekly_water:
  #   source: sensor.legrand_consommation_totale_eau_m3
  #   cycle: weekly
  #   tariffs:
  #     - peak
  #     - offpeak
  # legrand_monthly_water:
  #   source: sensor.legrand_consommation_totale_eau_m3
  #   cycle: monthly
  #   tariffs:
  #     - peak
  #     - offpeak
  # legrand_yearly_water:
  #   source: sensor.legrand_consommation_totale_eau_m3
  #   cycle: yearly
  #   tariffs:
  #     - peak
  #     - offpeak

   ############################################################
   ##                                                        ##
   ##               INPUT TEXT ENERGY PRICES                 ##
   ##                                                        ##
   ############################################################

input_text:

       ###############################
       ##       ELECTRICITE         ##
       ###############################

  legrand_prix_abo:
    name: Electricité Prix Abo Mensuel

  legrand_prix_kwh_hc:
    name: Electricité Prix kWh HC

  legrand_prix_kwh_hp:
    name: Electricité Prix kWh HP


   ############################################################
   ##                                                        ##
   ##                       AUTOMATION                       ##
   ##                                                        ##
   ############################################################

automation:

       #########################
       ##     ELECTRICITE     ##
       #########################

  - alias: '[ELECTRICITE] Passage Heures Pleines'
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: sensor.legrand_tarif_en_cours
# Valeur 2 = Heures Pleines
        to: '2'
    action:
      - service: utility_meter.select_tariff
        data:
          entity_id:
            - utility_meter.legrand_daily_energy
            - utility_meter.legrand_weekly_energy
            - utility_meter.legrand_monthly_energy
            - utility_meter.legrand_yearly_energy
          tariff: peak

  - alias: '[ELECTRICITE] Passage Heures Creuses'
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: sensor.legrand_tarif_en_cours
# Valeur 1 = Heures Creuses
        to: '1'
    action:
      - service: utility_meter.select_tariff
        data:
          entity_id:
            - utility_meter.legrand_daily_energy
            - utility_meter.legrand_weekly_energy
            - utility_meter.legrand_monthly_energy
            - utility_meter.legrand_yearly_energy
          tariff: offpeak

#        #########################
#        ##         EAU         ##
#        #########################

#   - alias: '[EAU] Passage Heures Pleines'
#     initial_state: 'on'
#     trigger:
#       - platform: state
#         entity_id: sensor.legrand_tarif_en_cours
# # Valeur 2 = Heures Pleines
#         to: '2'
#     action:
#       - service: utility_meter.select_tariff
#         data:
#           entity_id:
#             - utility_meter.legrand_daily_water
#             - utility_meter.legrand_weekly_water
#             - utility_meter.legrand_monthly_water
#             - utility_meter.legrand_yearly_water
#           tariff: peak

#   - alias: '[EAU] Passage Heures Creuses'
#     initial_state: 'on'
#     trigger:
#       - platform: state
#         entity_id: sensor.legrand_tarif_en_cours
# # Valeur 1 = Heures Creuses
#         to: '1'
#     action:
#       - service: utility_meter.select_tariff
#         data:
#           entity_id:
#             - utility_meter.legrand_daily_water
#             - utility_meter.legrand_weekly_water
#             - utility_meter.legrand_monthly_water
#             - utility_meter.legrand_yearly_water
#           tariff: offpeak

Home assisant

La consommation de mon mini datacenter sous forme de graphe :

Installation matériel panneau solaire

Intégration Panneaux solaire dans HS

Prévue pour Q2 2024

Si vous voulez plus de scripts Home automations ou sur Domoticz vous pouvez voir mes repos à ce sujet : https://github.com/ravindrajob/