Il y a 7 heures
Bonjour, merci encore pour le travail et le partage réalisé.
André, je n'ai pas trouvé mon bonheur dans les réglages pour CACSI. Il est vraie que j'ai l’obsession permanenta d'aller chercher les quelques watts qui s’échappent chez Enedis !
. Je peaufine mes réglages via Mqtt et Node-RED.
J'ai mis en place une fonction dans Node-RED qui comprend une régulation "exponentielle" et filtres qui me donne plutôt de bons résultats. Je priorise aussi l'injection RouteurECS / RouteurRAD. Peut-être est-il possible d'ajouter ce type de chose nativement dans ton système. Je te joins ce script ci-dessous, à toute fin utile.
// ======================================================
// FILTRAGE PUISSANCE POUR ROUTEUR SOLAIRE F1ATB
// ======================================================
// Ce script :
// 1) vérifie la validité de la mesure
// 2) élimine les valeurs aberrantes
// 3) applique un filtre exponentiel (EMA)
// 4) ignore les petites perturbations (deadband)
// 5) applique un offset pour ajuster le seuil du routeur
// 6) envoie la puissance filtrée en MQTT
// ======================================================
// ------------------------------------------------------
// 1. Vérification de la structure du message
// ------------------------------------------------------
// On vérifie que le message contient bien svalue1
if (!msg.payload || msg.payload.svalue1 === undefined) {
return null; // message ignoré
}
// Conversion en nombre
let currentValue = Number(msg.payload.svalue1);
// Vérifie que la valeur est bien numérique
if (isNaN(currentValue)) {
return null;
}
// ------------------------------------------------------
// 2. Filtrage des valeurs aberrantes
// ------------------------------------------------------
// Ces limites dépendent de ton installation
// Elles évitent les bugs ou valeurs incohérentes
if (currentValue < -160 || currentValue > 4000) {
return null;
}
// ------------------------------------------------------
// 3. Paramètres du filtre
// ------------------------------------------------------
// coefficient du filtre exponentiel
// plus alpha est petit → filtrage fort
// valeurs typiques : 0.2 à 0.35
// 0.2-filtrage fort, [0.35](0.3)-bon compromis, 0.4-plus réactif
let alpha = 0.30;
// zone morte pour ignorer les petites variations
// évite les oscillations dues aux TV, box, etc.
// zone morte = ±xx W, variation prise en compte si hors de cette plage
// 10W-très sensible, [20W]-sensible, (30W)-bon compromis, 50W-très stable moins précis
//
// Remplacée par une version asymétrique :
// - import (consommation réseau) → plus sensible
// - export (surplus PV) → plus tolérant
let deadband_import = 15;
let deadband_export = 25;
// ------------------------------------------------------
// 4. Récupération de la valeur filtrée précédente
// ------------------------------------------------------
// On récupère la dernière valeur filtrée sauvegardée
let previousFiltered = context.get("filteredPower");
// si première exécution on initialise
if (previousFiltered === undefined) {
previousFiltered = currentValue;
}
// ------------------------------------------------------
// 5. Détection des petites perturbations
// ------------------------------------------------------
// Si la variation est trop faible on l'ignore
// Version asymétrique : seuil différent selon import/export
let delta = currentValue - previousFiltered;
// Cas IMPORT (puissance > 0 → on consomme du réseau)
if (currentValue > 0) {
if (Math.abs(delta) < deadband_import) {
// on garde simplement l'ancienne valeur
currentValue = previousFiltered;
}
// Cas EXPORT (puissance < 0 → surplus PV)
} else {
if (Math.abs(delta) < deadband_export) {
// on garde simplement l'ancienne valeur
currentValue = previousFiltered;
}
}
// ------------------------------------------------------
// 6. Filtre exponentiel
// ------------------------------------------------------
// Formule EMA
// filtered = alpha * mesure + (1-alpha) * ancienne valeur
let filtered = alpha * currentValue + (1 - alpha) * previousFiltered;
// ------------------------------------------------------
// 7. Sauvegarde pour la prochaine itération
// ------------------------------------------------------
context.set("filteredPower", filtered);
// ------------------------------------------------------
// 8. Ajustement du seuil du routeur
// ------------------------------------------------------
// offset utilisé pour ajuster la régulation
// (dans ton ancien script : -80)
// sert à éviter l’injection Linky réseau/pince modifiée Emphase
let offset = 70;
let finalPower = Math.round(filtered) - offset;
// sécurité supplémentaire
if (isNaN(finalPower)) {
return null;
}
// ------------------------------------------------------
// 9. Construction du message MQTT avec gestion RouteurECS/RouteurRAD
// ------------------------------------------------------
// ---------------- Récupération de l'état ECS_Injection % Idx247 ----------------
let injectionECS = Number(global.get("ECS_Injection") || 0);
// ---------------- DEBUG ----------------
// node.warn("Valeur ECS_Injection actuelle : " + injectionECS);
// ---------------- Définition des seuils et blocage ----------------
let seuilECS = 0; // Seuil mini pour ignorer blocage RouteurRAD
let seuilMaxECS = 100; // Seuil maxi pour ignorer blocage RouteurRAD
let blocageRAD = 40; // Valeur W ajoutée à "Pw" pour empêcher RAD de démarrer
// ---------------- Calcul de la puissance "Pw" pour RouteurRAD ----------------
let finalPowerRAD;
if (injectionECS > seuilECS && injectionECS < seuilMaxECS) {
// ECS en train de monter → priorité ECS → blocage RAD entre 0 et 100%
finalPowerRAD = finalPower + blocageRAD;
} else {
// ECS = 0% ou ECS saturé 100% → RAD autorisé
finalPowerRAD = finalPower;
}
// ---------------- DEBUG ----------------
// node.warn("ECS Pw = " + finalPower);
// node.warn("RAD Pw = " + finalPowerRAD);
// ---------------- Construction des messages MQTT ----------------
let msg1 = {
topic: "LinkyPwToRouteurECS",
payload: JSON.stringify({ Pw: finalPower })
};
let msg2 = {
topic: "LinkyPwToRouteurRAD",
payload: JSON.stringify({ Pw: finalPowerRAD })
};
// ---------------- Renvoi des deux messages ----------------
return [msg1, msg2];
André, je n'ai pas trouvé mon bonheur dans les réglages pour CACSI. Il est vraie que j'ai l’obsession permanenta d'aller chercher les quelques watts qui s’échappent chez Enedis !
. Je peaufine mes réglages via Mqtt et Node-RED.J'ai mis en place une fonction dans Node-RED qui comprend une régulation "exponentielle" et filtres qui me donne plutôt de bons résultats. Je priorise aussi l'injection RouteurECS / RouteurRAD. Peut-être est-il possible d'ajouter ce type de chose nativement dans ton système. Je te joins ce script ci-dessous, à toute fin utile.
// ======================================================
// FILTRAGE PUISSANCE POUR ROUTEUR SOLAIRE F1ATB
// ======================================================
// Ce script :
// 1) vérifie la validité de la mesure
// 2) élimine les valeurs aberrantes
// 3) applique un filtre exponentiel (EMA)
// 4) ignore les petites perturbations (deadband)
// 5) applique un offset pour ajuster le seuil du routeur
// 6) envoie la puissance filtrée en MQTT
// ======================================================
// ------------------------------------------------------
// 1. Vérification de la structure du message
// ------------------------------------------------------
// On vérifie que le message contient bien svalue1
if (!msg.payload || msg.payload.svalue1 === undefined) {
return null; // message ignoré
}
// Conversion en nombre
let currentValue = Number(msg.payload.svalue1);
// Vérifie que la valeur est bien numérique
if (isNaN(currentValue)) {
return null;
}
// ------------------------------------------------------
// 2. Filtrage des valeurs aberrantes
// ------------------------------------------------------
// Ces limites dépendent de ton installation
// Elles évitent les bugs ou valeurs incohérentes
if (currentValue < -160 || currentValue > 4000) {
return null;
}
// ------------------------------------------------------
// 3. Paramètres du filtre
// ------------------------------------------------------
// coefficient du filtre exponentiel
// plus alpha est petit → filtrage fort
// valeurs typiques : 0.2 à 0.35
// 0.2-filtrage fort, [0.35](0.3)-bon compromis, 0.4-plus réactif
let alpha = 0.30;
// zone morte pour ignorer les petites variations
// évite les oscillations dues aux TV, box, etc.
// zone morte = ±xx W, variation prise en compte si hors de cette plage
// 10W-très sensible, [20W]-sensible, (30W)-bon compromis, 50W-très stable moins précis
//
// Remplacée par une version asymétrique :
// - import (consommation réseau) → plus sensible
// - export (surplus PV) → plus tolérant
let deadband_import = 15;
let deadband_export = 25;
// ------------------------------------------------------
// 4. Récupération de la valeur filtrée précédente
// ------------------------------------------------------
// On récupère la dernière valeur filtrée sauvegardée
let previousFiltered = context.get("filteredPower");
// si première exécution on initialise
if (previousFiltered === undefined) {
previousFiltered = currentValue;
}
// ------------------------------------------------------
// 5. Détection des petites perturbations
// ------------------------------------------------------
// Si la variation est trop faible on l'ignore
// Version asymétrique : seuil différent selon import/export
let delta = currentValue - previousFiltered;
// Cas IMPORT (puissance > 0 → on consomme du réseau)
if (currentValue > 0) {
if (Math.abs(delta) < deadband_import) {
// on garde simplement l'ancienne valeur
currentValue = previousFiltered;
}
// Cas EXPORT (puissance < 0 → surplus PV)
} else {
if (Math.abs(delta) < deadband_export) {
// on garde simplement l'ancienne valeur
currentValue = previousFiltered;
}
}
// ------------------------------------------------------
// 6. Filtre exponentiel
// ------------------------------------------------------
// Formule EMA
// filtered = alpha * mesure + (1-alpha) * ancienne valeur
let filtered = alpha * currentValue + (1 - alpha) * previousFiltered;
// ------------------------------------------------------
// 7. Sauvegarde pour la prochaine itération
// ------------------------------------------------------
context.set("filteredPower", filtered);
// ------------------------------------------------------
// 8. Ajustement du seuil du routeur
// ------------------------------------------------------
// offset utilisé pour ajuster la régulation
// (dans ton ancien script : -80)
// sert à éviter l’injection Linky réseau/pince modifiée Emphase
let offset = 70;
let finalPower = Math.round(filtered) - offset;
// sécurité supplémentaire
if (isNaN(finalPower)) {
return null;
}
// ------------------------------------------------------
// 9. Construction du message MQTT avec gestion RouteurECS/RouteurRAD
// ------------------------------------------------------
// ---------------- Récupération de l'état ECS_Injection % Idx247 ----------------
let injectionECS = Number(global.get("ECS_Injection") || 0);
// ---------------- DEBUG ----------------
// node.warn("Valeur ECS_Injection actuelle : " + injectionECS);
// ---------------- Définition des seuils et blocage ----------------
let seuilECS = 0; // Seuil mini pour ignorer blocage RouteurRAD
let seuilMaxECS = 100; // Seuil maxi pour ignorer blocage RouteurRAD
let blocageRAD = 40; // Valeur W ajoutée à "Pw" pour empêcher RAD de démarrer
// ---------------- Calcul de la puissance "Pw" pour RouteurRAD ----------------
let finalPowerRAD;
if (injectionECS > seuilECS && injectionECS < seuilMaxECS) {
// ECS en train de monter → priorité ECS → blocage RAD entre 0 et 100%
finalPowerRAD = finalPower + blocageRAD;
} else {
// ECS = 0% ou ECS saturé 100% → RAD autorisé
finalPowerRAD = finalPower;
}
// ---------------- DEBUG ----------------
// node.warn("ECS Pw = " + finalPower);
// node.warn("RAD Pw = " + finalPowerRAD);
// ---------------- Construction des messages MQTT ----------------
let msg1 = {
topic: "LinkyPwToRouteurECS",
payload: JSON.stringify({ Pw: finalPower })
};
let msg2 = {
topic: "LinkyPwToRouteurRAD",
payload: JSON.stringify({ Pw: finalPowerRAD })
};
// ---------------- Renvoi des deux messages ----------------
return [msg1, msg2];
Enphase 13xIQ7A(366w) | CACSI Profil Zero injection | Batterie | RouteurECS(1500w)v17Mqtt | RouteurRAD(2000w)v17Mqtt | Full free Domoticz and Node-RED for the best
