# Reboot a distance

**URL:** <https://forum.gce-electronics.com/t/reboot-a-distance/20390>\
**Category:** Ecodevices 3\
**Created:** [Octobre 22, 2026, 3:46 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390 "2026-10-22T15:46:54Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cocof](https://forum.gce-electronics.com/letter_avatar_proxy/v4/letter/c/f17d59/32.png) [@Cocof](https://forum.gce-electronics.com/u/Cocof)\
**Post date:** [Octobre 22, 2026, 3:46 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390/1 "2026-10-22T15:46:54Z")

</div>

Bonjour,

Je possède un [EcoDevices 3](https://gce-electronics.com/2120-.html) avec le dernier firmware (Version IHM :1.2.0 et Version du firmware:1.3.0). Il communique avec Home Assistant.

Est-il possible de redémarrer l’ED3 à distance par une commande HTTP/REST, une API ou une autre méthode réseau, sans couper physiquement son alimentation ?

Si oui, pourriez-vous me communiquer la commande ou la documentation correspondante ?

Mon objectif est de redémarrer automatiquement l’ED3 ne renvoie plus de valeur vers home assistant (ex : si la valeur du tarif Linky ne correspond plus à `HEURE PLEINE` ou `HEURE CREUSE`)

Merci pour votre aide.

---

<div class="post-metadata">

**Author:** ![Pascalsc](https://forum.gce-electronics.com/user_avatar/forum.gce-electronics.com/pascalsc/32/13181_2.png) [@Pascalsc](https://forum.gce-electronics.com/u/Pascalsc)\
**Post date:** [Octobre 23, 2026, 12:30 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390/2 "2026-10-23T00:30:39Z")

</div>

Bonsoir @Cocof ,

Oui, bien sûr, vous pouvez redémarrer à distance votre ED3.. Il suffit de vous connecter à l’IP de votre ED3, d’entrer votre mdp puis sur la roue dentée (paramètres), système, vous avez 4 boutons et le quatrième est « Redémarrer »

Bonne soirée

---

<div class="post-metadata">

**Author:** ![cce66](https://forum.gce-electronics.com/letter_avatar_proxy/v4/letter/c/8797f3/32.png) [@cce66](https://forum.gce-electronics.com/u/cce66)\
**Post date:** [Octobre 23, 2026, 8:18 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390/3 "2026-10-23T08:18:40Z")

</div>

Bonjour @Cocof

Oui c’est possible, il faut utiliser cet utilitaire (pour un accès distant depuis le net il faut un vpn)

> [@Utilitaires pour la gamme IPX800 , EcoDevices, XPool, X-Display v2 etc](https://forum.gce-electronics.com/t/utilitaires-pour-la-gamme-ipx800-ecodevices-xpool-x-display-v2-etc/20158/9):
>
> Bonjour maj 26/06/2026 ajout Testeur API + reboot [ECODEVICES 3](https://gce-electronics.com/2120-.html) - API Deck v2 [GCE\_ED3\_Api-Deck v2.zip](https://forum.gce-electronics.com/uploads/short-url/pygpgjNHlTZCy1iMofqLpZgn2U8.zip) (21,3 Ko)

---

<div class="post-metadata">

**Author:** ![fgtoul](https://forum.gce-electronics.com/user_avatar/forum.gce-electronics.com/fgtoul/32/28801_2.png) [@fgtoul](https://forum.gce-electronics.com/u/fgtoul)\
**Post date:** [Octobre 23, 2026, 8:56 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390/4 "2026-10-23T08:56:10Z")

</div>

> [@Cocof](#):
>
> Mon objectif est de redémarrer automatiquement l’ED3

Bonjour,  
je pense que ça ne répond pas aux besoins 😉

@cocof : l’api ne permet pas de rebooter l’ECO3, c’est une fonctionnalité qui avait été demandée pendant les bétatests, mais non implémentée à ma connaissance.  
A part couper l’alim par un relais, je ne vois pas comment faire autrement.  
Bonne journée

---

<div class="post-metadata">

**Author:** ![Cocof](https://forum.gce-electronics.com/letter_avatar_proxy/v4/letter/c/f17d59/32.png) [@Cocof](https://forum.gce-electronics.com/u/Cocof)\
**Post date:** [Octobre 23, 2026, 6:03 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390/5 "2026-10-23T18:03:20Z")

</div>

bjr

en effet je veux automatiser via mon home assistant ce reboot. c’est pour cela qu’il me faut une commande via le reseau

---

<div class="post-metadata">

**Author:** ![Cocof](https://forum.gce-electronics.com/letter_avatar_proxy/v4/letter/c/f17d59/32.png) [@Cocof](https://forum.gce-electronics.com/u/Cocof)\
**Post date:** [Octobre 23, 2026, 6:09 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390/6 "2026-10-23T18:09:20Z")

</div>

bonjour la commande semble etre POST [http://192.168.0.91:5080/api/system/reboot](http://192.168.0.91:5080/api/system/reboot)?

mais avec le logon et le mot de passe. Il faudrait les mettre ou dans la commande ? (ou l’apikey ?)

---

<div class="post-metadata">

**Author:** ![cce66](https://forum.gce-electronics.com/letter_avatar_proxy/v4/letter/c/8797f3/32.png) [@cce66](https://forum.gce-electronics.com/u/cce66)\
**Post date:** [Octobre 23, 2026, 7:50 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390/7 "2026-10-23T19:50:37Z")

</div>

il faut passer par le soft pour l’instant

 ![image](https://forum.gce-electronics.com/uploads/default/original/3X/4/9/49fb0bab5447d65f45ecf1818aca4ff76170142e.png)

---

<div class="post-metadata">

**Author:** ![Cocof](https://forum.gce-electronics.com/letter_avatar_proxy/v4/letter/c/f17d59/32.png) [@Cocof](https://forum.gce-electronics.com/u/Cocof)\
**Post date:** [Octobre 24, 2026, 6:25 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390/8 "2026-10-24T18:25:58Z")

</div>

Merci. Ce que ton soft fait, ha doit bien savoir le faire. Je vais voir avec Claude ou autre je teste demain matin ( besoin d’une double ou triple authentification d’après ce que j’ai compris, mais ça semble faisable.

---

<div class="post-metadata">

**Author:** ![cce66](https://forum.gce-electronics.com/letter_avatar_proxy/v4/letter/c/8797f3/32.png) [@cce66](https://forum.gce-electronics.com/u/cce66)\
**Post date:** [Octobre 24, 2026, 10:53 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390/9 "2026-10-24T22:53:12Z")

</div>

c’est du html, tu télécharge et tu peux examiner le code et sit u veux juste la partie reboot il suffit d’isoler le bloc de code qui le fait et de voir avec Claude Code pour le mettre en script dans HA

Pour les infos concernant le reboot, les voici (il faut que les champs IP et APIKEY soient remplis) :

Le reboot de l’[EcoDevices 3](https://gce-electronics.com/2120-.html) utilise un mécanisme d’authentification en 3 étapes :

**Étape 1 — Challenge** : `POST /api/auth/secure/root` avec body `{}` → le serveur génère et retourne une `secureKey` aléatoire à usage unique (ex: `WqMFIrEWuqtK0MKi`).

**Étape 2 — Login chiffré** : le deck chiffre `{"login":"root","passwd":"root"}` en **AES-ECB** avec la `secureKey` comme clé (parsée en UTF-8), puis envoie le résultat en `secureContent` via `POST /api/auth/login/root?secure=true` → le serveur retourne un `AuthToken` de session.

**Étape 3 — Reboot** : `POST /api/system/reboot?AuthToken=xxx` avec body `{}` → le serveur redémarre en ~1 seconde.

Points clés découverts par rétro-ingénierie :

- L’auth utilise `AuthToken` (session) et **non** `ApiKey` (statique)
- Le chiffrement est **AES-ECB** — identifié en capturant les échanges F12 et en testant les modes de déchiffrement
- Le mot de passe ne transite jamais en clair
- La `secureKey` est à usage unique — elle expire immédiatement après l’étape 2

---

<div class="post-metadata">

**Author:** ![Cocof](https://forum.gce-electronics.com/letter_avatar_proxy/v4/letter/c/f17d59/32.png) [@Cocof](https://forum.gce-electronics.com/u/Cocof)\
**Post date:** [Octobre 25, 2026, 2:12 UTC](https://forum.gce-electronics.com/t/reboot-a-distance/20390/10 "2026-10-25T14:12:58Z")

</div>

Hello ca fonctionne 🙂 tuto :

creation du fichier ecodevices\_reboot.py dans le repertoire config de home assistant :

```auto

import json
import re
import sys
import base64
import urllib.parse
import urllib.request
from pathlib import Path

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.padding import PKCS7

SECRETS_FILE = Path("/config/secrets.yaml")

def read_secret(name):
    text = SECRETS_FILE.read_text(encoding="utf-8")

    match = re.search(
        r"(?m)^" + re.escape(name) + r"\s*:\s*(.*?)\s*$",
        text,
    )

    if not match:
        raise RuntimeError(f"Clé absente de secrets.yaml : {name}")

    value = match.group(1).strip()

    if (
        len(value) >= 2
        and value[0] == value[-1]
        and value[0] in "'\""
    ):
        value = value[1:-1]

    return value

def post(base_url, path, data):
    request = urllib.request.Request(
        base_url.rstrip("/") + path,
        data=json.dumps(
            data,
            ensure_ascii=False,
        ).encode("utf-8"),
        headers={"Content-Type": "application/json"},
        method="POST",
    )

    with urllib.request.urlopen(request, timeout=10) as response:
        body = response.read().decode("utf-8")

        if not body.strip():
            return {}

        return json.loads(body)

def authenticate(base_url, login, password):
    encoded_login = urllib.parse.quote(login, safe="")

    # Étape 1 : récupération de la clé de chiffrement
    challenge = post(
        base_url,
        f"/api/auth/secure/{encoded_login}",
        {},
    )

    secure_key = challenge["secureKey"].encode("utf-8")

    if len(secure_key) not in (16, 24, 32):
        raise RuntimeError(
            f"Longueur inattendue de secureKey : "
            f"{len(secure_key)} octets"
        )

    # Étape 2 : chiffrement des identifiants selon l'API GCE
    payload = json.dumps(
        {
            "login": login,
            "passwd": password,
        },
        separators=(",", ":"),
        ensure_ascii=False,
    ).encode("utf-8")

    padder = PKCS7(128).padder()
    padded_payload = (
        padder.update(payload) + padder.finalize()
    )

    encryptor = Cipher(
        algorithms.AES(secure_key),
        modes.ECB(),
    ).encryptor()

    encrypted_payload = (
        encryptor.update(padded_payload)
        + encryptor.finalize()
    )

    secure_content = base64.b64encode(
        encrypted_payload
    ).decode("ascii")

    # Étape 3 : authentification
    result = post(
        base_url,
        f"/api/auth/login/{encoded_login}?secure=true",
        {"secureContent": secure_content},
    )

    token = result.get("AuthToken")

    if not token:
        raise RuntimeError(
            "Authentification refusée : AuthToken absent"
        )

    return token

def reboot():
    base_url = read_secret("ecodevices_url").rstrip("/")
    login = read_secret("ecodevices_login")
    password = read_secret("ecodevices_password")

    token = authenticate(base_url, login, password)

    # Étape 4 : envoi de la commande de redémarrage
    path = "/api/system/reboot?" + urllib.parse.urlencode(
        {"AuthToken": token}
    )

    post(base_url, path, {})

    print("Commande de redémarrage envoyée à l'ECODEVICES 3.")

if __name__ == " __main__":
    try:
        reboot()
    except Exception as err:
        print(f"Erreur : {type(err). __name__ }: {err}")
        sys.exit(1)

```

dans le fichier configuration.yaml :

```auto
shell_command:
  reboot_ecodevices3: "/usr/local/bin/python3 /config/ecodevices_reboot.py"

```

dans le fichier secret.yaml :

```auto
ecodevices_login: "root"
ecodevices_password: "mot_de_passe_root"
ecodevices_url: "http://192.168.x.xx:xxxx"

```

il suffit après de creer une automatisation du type :

```auto
alias: Linky - Alerte si tarif invalide
description: >-
  Alerte dès la perte du tarif, puis jusqu'à deux tentatives
  de redémarrage de l'EcoDevices 3 si le problème persiste.

triggers:
  - trigger: template
    id: tarif_invalide
    value_template: >-
      {{ states('sensor.linky_tarif_en_cours') not in
         ['HEURE PLEINE', 'HEURE CREUSE'] }}
    for:
      minutes: 1

  - trigger: homeassistant
    event: start
    id: demarrage_ha

conditions: []

actions:
  # Après démarrage de HA, laisser les intégrations se stabiliser
  - if:
      - condition: trigger
        id: demarrage_ha
    then:
      - delay:
          minutes: 2

  # Vérifier que le tarif est toujours invalide
  - condition: template
    value_template: >-
      {{ states('sensor.linky_tarif_en_cours') not in
         ['HEURE PLEINE', 'HEURE CREUSE'] }}

  # Notification immédiate
  - action: notify.mobile_app_christophe
    data:
      title: "⚠️ ALERTE Linky"
      message: >-
        Perte ou valeur invalide du tarif Linky détectée.
        Valeur actuelle : {{ states('sensor.linky_tarif_en_cours') }}.
        Tentative de redémarrage de l'EcoDevices 3 en cours.

  # Première tentative de redémarrage
  - action: shell_command.reboot_ecodevices3
    continue_on_error: true

  - delay:
      minutes: 1

  # Deuxième tentative seulement si le tarif reste invalide
  - if:
      - condition: template
        value_template: >-
          {{ states('sensor.linky_tarif_en_cours') not in
             ['HEURE PLEINE', 'HEURE CREUSE'] }}
    then:
      - action: shell_command.reboot_ecodevices3
        continue_on_error: true

      - delay:
          minutes: 1

  # Notification finale si le problème persiste
  - if:
      - condition: template
        value_template: >-
          {{ states('sensor.linky_tarif_en_cours') not in
             ['HEURE PLEINE', 'HEURE CREUSE'] }}
    then:
      - action: notify.mobile_app_christophe
        data:
          title: "🚨 Linky - Tarif toujours invalide"
          message: >-
            Le tarif reste invalide après les tentatives de redémarrage
            de l'EcoDevices 3.
            Valeur actuelle : {{ states('sensor.linky_tarif_en_cours') }}.
            Vérifier l'appareil et sa communication.

mode: single
max_exceeded: silent

```
