TEMPO - Commande du mode Onduleur PV via Shelly Modbus AddOn

Pour ceux que ça pourrait intéresser, voici une présentation de ma “création” conjointe avec Gemini pour contrôler le mode de votre onduleur SOFAR SOLAR. L’avantage est d’utiliser le très récent AddOn Modbus de chez Shelly en binôme avec un Shelly Pro 2 (NON PM car pas compatible apparemment).

Le tout pour moins de 100€, sans (trop de) prise de tête.

Objectif: Contrôler la charge batterie d’un onduleur Sofar HYD-6000 EP via Shelly Pro 2 + AddOn RS485 Modbus et Jeedom

L’objectif principal est d’optimiser son contrat EDF Tempo lors des jours rouges. Ce montage permet d’automatiser (via Jeedom ou manuellement) la charge complète de la batterie pendant les heures creuses de la nuit (22h - 6h). La journée, la maison tourne sur la batterie ainsi chargée au tarif réduit, évitant de soutirer sur le réseau au prix fort.

1. Prérequis firmware & configuration Shelly

  • Firmware Shelly : Utilisez simplement le firmware d’origine (stock) du Shelly Pro 2. Aucun firmware alternatif (Tasmota, ESPHome…) ni mise à jour spécifique pour l’Add-on RS485 n’est nécessaire.

  • Configuration Modbus dans le Shelly : Dans l’interface web du Shelly, activez l’Add-on RS485 et configurez le port série avec les paramètres suivants :

    • Vitesse (Baud rate) : 9600

    • Configuration : 8N1 (8 bits de données, pas de parité, 1 bit de stop)

    • Adresse Modbus Client (ID) : 100 (utilisée par défaut par le Shelly)

    • Adresse Esclave Sofar (SID) : 1 (adresse Modbus par défaut de l’onduleur)

2. Principe de fonctionnement et configuration du Sofar

Par défaut, l’onduleur fonctionne en mode Self-Use (autoconsommation classique) : il gère la batterie en toute autonomie selon la production solaire et la consommation de la maison.

Pour forcer la charge de la batterie sur le réseau pendant les heures creuses, le Shelly va basculer l’onduleur en mode Time-of-Use.

Configuration préalable sur l’écran du Sofar

Il faut programmer la plage horaire souhaitée directement dans le menu de l’onduleur :

  • Mode : Time-of-Use

  • Plage horaire : 22:00 - 06:00

  • Puissance de charge : 2000 W (ou selon votre abonnement)

  • Objectif SOC : 100 %

Le script basculera le registre de l’onduleur entre Self-Use (0) et Time-of-Use (1). En mode Time-of-Use, le Sofar applique la règle horaire pré-enregistrée ci-dessus. Le reste du temps, il repasse en Self-Use normal.

3. Câblage matériel

Connexions Modbus

  • Onduleur Sofar HYD 6000-EP : Port RS485-1, bornes 5 (A1) et 6 (B1). (Remarque : vérifiez le pinout dans le manuel de votre modèle s’il s’agit d’une autre déclinaison).

  • Shelly Pro 2 : Raccordez les câbles sur les bornes A et B de l’Add-on RS485.

4. Le Script mJS (à intégrer dans le Shelly Pro 2)

Dans l’interface web du Shelly, allez dans Scripts, créez un nouveau script, collez ce code, sauvegardez et activez l’Auto-start.

JavaScript

// ==========================================================
// PILOTAGE MODE SOFAR HYD VIA SHELLY PRO 2 & ADD-ON RS485
// Canal 1 (switch:0) -> Activation du mode Time-of-Use
// Canal 2 (switch:1) -> Retour de confirmation (Activation réelle)
// ==========================================================

let RS485_ID = 100;           // ID Add-on RS485 (configuré dans le Shelly)
let SOFAR_SLAVE_ADDR = 1;     // Adresse Modbus Sofar
let REG_WORK_MODE = 4368;     // Registre 0x1110 (Work Mode)

let MODE_SELF_USE = 0;        // Mode Autoconsommation (Normal)
let MODE_TIME_OF_USE = 1;     // Mode Plages horaires / Charge forcée (Tempo)

// Pilotage du deuxième canal (Retour d'état / Confirmation)
function setStatusLED(state) {
  Shelly.call("Switch.Set", { id: 1, on: state }, function (result, error_code) {
    // Relais 2 collé si le mode Time-of-Use est confirmé par l'onduleur
  });
}

// Envoie la trame Modbus pour changer le mode de travail
function setInverterMode(targetMode) {
  print("[MODBUS] Demande de changement de mode vers :", targetMode);

  Shelly.call(
    "MbRtuClient.WriteHoldingRegisters",
    {
      id: RS485_ID,
      sid: SOFAR_SLAVE_ADDR,
      addr: REG_WORK_MODE,
      values: [targetMode]
    },
    function (result, error_code, error_message) {
      if (error_code !== 0) {
        print("❌ ERREUR ÉCRITURE MODBUS :", error_code, "|", error_message);
      } else {
        print("✅ Commande acceptée par l'onduleur Sofar.");
        let isTempo = (targetMode === MODE_TIME_OF_USE);
        setStatusLED(isTempo);
      }
    }
  );
}

// Lecture du registre pour synchroniser l'état réel
function updateStateFromInverter() {
  Shelly.call(
    "MbRtuClient.ReadHoldingRegisters",
    {
      id: RS485_ID,
      sid: SOFAR_SLAVE_ADDR,
      addr: REG_WORK_MODE,
      qty: 1
    },
    function (result, error_code) {
      if (error_code === 0 && result && result.registers) {
        let actualMode = result.registers[0];
        let isTempoConfirmed = (actualMode === MODE_TIME_OF_USE);
        print("[LECTURE SOFAR] Mode actuel réel :", actualMode);
        setStatusLED(isTempoConfirmed);
      } else {
        print("❌ Erreur lecture état Sofar :", error_code);
      }
    }
  );
}

// 1. Écoute des commandes reçues sur le Canal 1 (switch:0)
Shelly.addEventHandler(function (event) {
  if (event.component === "switch:0" && event.info.event === "toggle") {
    let isCmdOn = event.info.state;
    let targetMode = isCmdOn ? MODE_TIME_OF_USE : MODE_SELF_USE;
    
    print("[EVENT] Commande reçue -> Passage au mode :", targetMode);
    setInverterMode(targetMode);
  }
});

// 2. Synchronisation initiale au démarrage
updateStateFromInverter();

// 3. Vérification de sécurité toutes les 60 secondes
Timer.set(60000, true, function () {
  updateStateFromInverter();
});

5. Intégration sous Jeedom

Le principe repose sur la séparation des deux canaux du Shelly Pro 2 :

  • Canal 1 (switch:0) — L’activation : C’est la commande d’ordre.

    • ON = Demande à l’onduleur de passer en Time-of-Use (charge nocturne).

    • OFF = Demande à l’onduleur de repasser en Self-Use (autoconsommation).

      (Un scénario Jeedom la veille d’un Jour Rouge à 22h peut ainsi activer ce canal automatiquement).

  • Canal 2 (switch:1) — Le retour d’état : C’est la confirmation réelle. Il est piloté directement par le script après vérification auprès de l’onduleur. Quand il est à ON, vous avez la certitude que l’onduleur est bien en mode Time-of-Use.

Le petit plus

  • En raccordant un interrupteur mécanique sur l’entrée SW1 (entrée 1), vous pouvez forcer le basculement manuellement sans ouvrir Jeedom.

  • En raccordant un voyant lumineux sur la sortie Relais 2 (sortie 2), vous récupérez une confirmation visuelle en direct : le voyant s’allume dès que l’onduleur est réellement passé en Time-of-Use (que la commande vienne de l’interrupteur, de Jeedom ou de l’application mobile).

Voilà ma contribution! En espérant que ça puisse servir.

Salut, merci pour le partage. Je fais la même chose avec le plugin solarman associé à un scénario

Cela peut bien entendu être rendu beaucoup plus simple si tu ne vas pas chercher les paramètres dans un virtuel et que tu les envoies en dur

Salut,

Je n’ai pas précisé mais l’onduleur est un HYD 6000 EP qui à ma connaissance ne permet pas d’écriture en Modbus TCP. Donc passage obligé par du câblé.

D’ailleurs ça peut marcher pour n’importe quel onduleur. Il suffit de changer le numéro du registre et les valeurs à lui appliquer en début de script.

Et là tu peux même être en Standalone sans Jeedom, tu peux changer le mode via l’app Shelly en 1 clic (il est possible de le faire à partir de l’appli Sofar Cloud mais du coup c’est plus pilotable par Jeedom).

De plus coté Jeedom ça reste très basique: un switch pour la demande, un switch pour la confirmation. Bref, pour 100€ c’est sans grosse prise de tête et ça marche top!

A+

Pourtant ils parlent bien d’écrire avec en 0x10 dans cette doc mais je ne l’ai pas complétement lus car non concerné :wink:

https://community.jeedom.com/uploads/short-url/iYlPDAz5JyuRMlRd6TS8qHnc987.pdf

Sinon sur le principe tu as raison concernant le côté indépendant du système mais il te faut quand même un declenchement cas de jour rouge annoncé

Pourquoi avec un shelly ? on peut faire du modbus RTU avec un ESP et un module MAX485 à même pas 10 balles…

Entre autres:
_

-Out of the box

-Intégration dans le tableau électrique sur rail DIN

-Alim intégrée / rien qui traine. C’est propre.

-Config Shelly simple via interface http

-Aucune config côté Jeedom

-Les contacts de puissance pour activation éventuelle d’un chauffage alternatif

-Activation à distance simple via App. Applicable même pour les gens sans domotique.
_

Il est certain que le bidouillage est toujours moins couteux. Mais chacun voit midi à sa porte!