F1ATB forum
Filtrage pour CACSI - Version imprimable

+- F1ATB forum (https://f1atb.fr/forum_f1atb)
+-- Forum : Forum de F1ATB (https://f1atb.fr/forum_f1atb/forum-3.html)
+--- Forum : Routeur Photovoltaïque (https://f1atb.fr/forum_f1atb/forum-4.html)
+--- Sujet : Filtrage pour CACSI (/thread-2504.html)



Filtrage pour CACSI - Alain59 - 05-04-2026

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 ! Wink . 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];


RE: Filtrage pour CACSI - alexandeur - 05-04-2026

si ton mode de routage c est linky , et que tu chasses les watt , c est pas le systeme de routage le meilleur..


RE: Filtrage pour CACSI - Laurent53 - 07-04-2026

Avec une lecture tous les deux secondes du linky impossible d'avoir une régulation ultra précise, passe en Mode UI ou UI2 (rafraîchissement toutes les 400 millisecondes)


RE: Filtrage pour CACSI - Sgb31 - 07-04-2026

Mode de mesure linky ou Enphase ? Dans les deux cas, pas des plus réactifs ...


RE: Filtrage pour CACSI - Alain59 - 08-04-2026

(07-04-2026, 05:56 PM)Sgb31 a écrit : Mode de mesure linky ou Enphase ? Dans les deux cas, pas des plus réactifs ...
Bonjour à tous,

Je me permets de faire une réponse globale afin d’éviter de multiplier les messages, et je vous remercie pour la richesse des échanges.

Je suis dans une configuration CACSI avec profil Enphase en zéro injection. Dans ce contexte, la logique de régulation d’un routeur classique se retrouve quelque peu détournée de son fonctionnement habituel.
En effet, dans un système standard, le routeur travaille principalement à partir de la détection d’une puissance négative (surplus injecté) pour ajuster sa charge. Or, dans mon cas, dès qu’une tentative d’injection apparaît, les micro-onduleurs Enphase limitent immédiatement leur production. De ce fait, le routeur ne “voit” pratiquement jamais de puissance négative.
Cela impose de positionner un seuil de déclenchement volontairement positif, typiquement autour de +60 à +80 W (voire légèrement plus), afin de permettre au routeur de fonctionner correctement. Ce réglage n’est pas un compromis arbitraire mais bien une adaptation nécessaire à la physique du système : le routeur tente ici de capter un surplus qui est, par conception, instantanément réduit par les micro-onduleurs.
Concernant la réactivité, je lis souvent que le système devrait réagir en quelques centaines de millisecondes. Dans la pratique, et notamment dans mon environnement, cela me semble peu réaliste, voire contre-productif.
Nos installations domestiques sont parcourues par de nombreux éléments de type RLC (résistances, inductances, condensateurs), sans compter les alimentations à découpage et les capacités importantes présentes dans les onduleurs. L’ensemble génère des effets de filtrage, de déphasage et des réponses transitoires complexes. À cela s’ajoutent des charges dynamiques du quotidien : à titre d’exemple, mon téléviseur (Ambilight) génère à lui seul des variations rapides et permanentes de puissance active.
Dans ce contexte, une régulation trop rapide a tendance à suivre le bruit plutôt que la tendance réelle, ce qui peut engendrer des oscillations et un comportement instable du routeur.
À l’usage, j’ai constaté qu’il est préférable de laisser une certaine inertie au système, avec une régulation qui s’inscrit sur un cycle de quelques secondes. Cela permet de lisser les perturbations et d’éviter d’ajouter du désordre à un signal déjà bruité. Les courbes observées sur de longues durées confirment que ce compromis est, dans mon cas, plus efficace.
Il me semble important de noter que, dans une configuration zéro injection Enphase, il existe en réalité une hiérarchie de régulation :
* les micro-onduleurs Enphase, très réactifs, ajustent en permanence la production,
* le routeur doit alors adopter un comportement plus lent, jouant un rôle d’amortisseur plutôt que de correcteur instantané.
Concernant mon ressenti actuel, il porte davantage sur la “profondeur” de la régulation que sur sa vitesse. Le routeur réagit correctement et rapidement aux variations, mais il peine à “creuser” suffisamment lors de l’apparition d’un surplus durable. Le comportement reste assez “plat”.
Avec mon réglage PID actuel de 30 / 12 / 0, cela pourrait s’expliquer par un terme intégral encore un peu faible dans ce contexte spécifique, où l’erreur mesurée reste limitée du fait du fonctionnement même d’Enphase. Une légère augmentation de l’intégrale pourrait permettre d’améliorer la captation du surplus sans dégrader la stabilité. Mais je ne l’ai pas constaté.
En ce qui concerne les sources de mesure, j’ai testé plusieurs approches :
* information Linky/ESP : très réactive mais très/trop sensible à la puissance réactive,
* Shelly EM : résultats corrects,
* API serveur Enphase : fonctionnement acceptable mais dépendance externe.
La solution qui me donne aujourd’hui les meilleurs résultats repose sur un compteur PZEM-004T piloté via ESP, positionné en tête de ligne. Les données sont traitées via Domoticz/Node-RED puis diffusées en MQTT vers les routeurs.
Bien que cette architecture introduise une latence supplémentaire, celle-ci agit en pratique comme un filtre bénéfique, améliorant la stabilité globale du système. Les résultats sont cohérents avec les courbes de production Enphase et les relevés (1/2 heure) de consommation Enedis, qui restent pour moi les références finales et les juges de paix.
En résumé, dans une configuration comme la mienne :
* une régulation ultra rapide n’est pas nécessairement souhaitable,
* une approche plus lente et amortie est souvent plus efficace,
* le seuil positif est indispensable pour compenser le fonctionnement zéro injection,
* et une mesure stable, même légèrement retardée, peut donner de meilleurs résultats qu’une mesure instantanée mais bruitée.
* Mon filtrage et adaptation dans NodeRED me donnent plus de production et moins de perte.

Au plaisir d’échanger avec vous.