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 :
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.