Photovoltaique-Gestion de mon Système Solaire Victron avec Node-RED : Partie 3 – Prévision de la Production Solaire

Intro

Sur mon blog domo.rem81.com, je partage mes projets domotiques pour rendre ma maison plus intelligente et économe. Après avoir présenté le flow « Communs » pour la collecte des données générales et le flow « Batteries » pour la gestion de ma batterie, je vous présente aujourd’hui un troisième flow Node-RED, nommé « Prévision production solaire ». Ce flow récupère les prévisions de production photovoltaïque (PV) via l’API VRM de Victron, les traite, et les publie via MQTT pour une intégration avec Home Assistant. Ces prévisions me permettent d’anticiper ma production d’énergie et d’optimiser mes automatisations.

Objectif du flow

Ce flow « Prévision production solaire » a pour but de récupérer les prévisions de production PV pour mon onduleur PV et mon contrôleur MPPT1 via le portail VRM (Victron Remote Management), de calculer une prévision totale, et de publier ces données via MQTT. Les prévisions sont mises à jour toutes les heures, me permettant de planifier ma consommation d’énergie en fonction de la production attendue.

Le flow Node-RED

Code json

Vous pouvez copier/coller le fichier .json en Annexe.

Visualisation du flow :

Voici une capture d’écran de mon flow « Prévision production solaire » dans Node-RED, où vous pouvez voir la disposition des nœuds et le flux des données entre eux :

Cette capture montre les sous-flux principaux : la récupération des prévisions pour l’onduleur PV et le MPPT1 (nœuds vrm-api), la conversion des données (nœuds function nommés « Convert et Arrondi »), le calcul de la prévision totale (nœud function nommé « Somme des deux »), et les publications MQTT (nœuds mqtt out).

Analyse du flow :

  1. Déclenchement périodique :
  • Un nœud inject déclenche une action toutes les heures (3600 secondes), avec un démarrage initial après 30 secondes. Cela permet de mettre à jour les prévisions régulièrement.
  1. Prévision de l’onduleur PV :
  • Un nœud vrm-api récupère la prévision de production de l’onduleur PV (vrm_pv_inverter_yield_fc) via l’API VRM pour mon site (ID 223181).
  • La valeur est extraite, convertie de Wh à kWh, arrondie, et publiée sur le topic mp2/prediction/prod_onduleur.
  1. Prévision du MPPT1 :
  • Un autre nœud vrm-api récupère la prévision de production du MPPT1 (vrm_pv_charger_yield_fc).
  • La valeur est extraite, convertie de Wh à kWh, arrondie, et publiée sur le topic mp2/prediction/prod_mppt1.
  1. Prévision totale :
  • Un nœud function additionne les deux prévisions (onduleur PV et MPPT1), convertit le total en kWh, et arrondit.
  • Le résultat est publié sur le topic mp2/prediction/prod_total avec un QoS de 2 et un message conservé (retain: true), et envoyé à un autre flow via un nœud link out.

Détails techniques :

  • Conversion de Wh à kWh : Les scripts suivants convertissent les prévisions de Wh à kWh et arrondissent :
  let p = flow.get('previmo'); // ou 'previmppt1' pour le MPPT1
  var sum = 0;
  sum = (p / 1000).toFixed(0); // Conversion en kWh et arrondi
  msg.payload = (sum);
  return [msg];
  • Calcul de la prévision totale : Le script suivant additionne les deux prévisions :
  let p = flow.get('previmo');
  let c = flow.get('previmppt1');
  var sum = 0;
  sum = ((p + c) / 1000).toFixed(0); // Somme et conversion en kWh
  msg.payload = (sum);
  return [msg];
  • Brokers MQTT : Les données sont publiées via le broker « MQTTHA » (192.168.0.37:1883) pour une intégration avec Home Assistant.

Interactions avec les flows « Communs » et « Batteries » :

Ce flow est complémentaire aux flows précédents :

  • Le flow « Communs » fournit les données en temps réel de la production PV (mp2/multiplus2/prod_totale), que je peux comparer avec les prévisions de ce flow.
  • Le flow « Batteries » fournit l’état de charge (SOC) de ma batterie (mp2/batteries/soc), que je peux utiliser avec les prévisions pour planifier des automatisations, comme charger la batterie en cas de faible production prévue.
  • Un nœud link out (out_prod_total) envoie la prévision totale à un autre flow (non détaillé ici), probablement pour des automatisations ou des alertes.

Intégration avec Home Assistant

Ce flow envoie les prévisions via MQTT à Home Assistant (broker à 192.168.0.37:1883). Par exemple, le topic mp2/prediction/prod_total me permet d’afficher la production PV prévue pour la journée dans un tableau de bord, ce qui m’aide à anticiper ma consommation ou à planifier des charges.

Pourquoi Node-RED ?

  • Simplicité : Je peux interroger l’API VRM et traiter les données sans écrire de code complexe.
  • Flexibilité : Les nœuds VRM s’intègrent parfaitement avec MQTT et Home Assistant.
  • Visuel : L’interface de Node-RED me permet de voir clairement le flux des données.

Palettes Utilisées

Pour reproduire ce flow, vous aurez besoin d’installer les palettes suivantes dans Node-RED :

  • node-red-contrib-victron : Fournit les nœuds pour interagir avec les systèmes Victron Energy, y compris le nœud vrm-api pour les prévisions. Installez-la via le gestionnaire de palettes de Node-RED ou avec la commande :
  npm install node-red-contrib-victron
  • node-red-node-mqtt : Fournit les nœuds MQTT (mqtt out, mqtt-broker). Cette palette est généralement incluse par défaut dans Node-RED, mais si elle est absente, vous pouvez l’installer avec :
  npm install node-red-node-mqtt
  • Nœuds de base (Core) : Les nœuds comme inject, debug, function, change, comment, et link out sont inclus par défaut dans Node-RED.

Note : Pour utiliser le nœud vrm-api, vous devez configurer une connexion au portail VRM avec un jeton API valide (obtenu depuis votre compte VRM).

Conclusion

Ce flow « Prévision production solaire » complète mon système de gestion d’énergie solaire avec Victron Energy en me fournissant des prévisions de production PV. Combiné aux flows « Communs » et « Batteries », il me permet d’avoir une vue d’ensemble de ma production actuelle et future, essentielle pour optimiser ma consommation et mes automatisations. Dans un prochain article, je partagerai d’autres flows, comme « Gestion des charges programmées », pour montrer comment j’utilise ces données pour automatiser ma maison. Si vous avez un système Victron ou utilisez Node-RED, ce projet pourrait vous inspirer. Des questions ou des idées ? Laissez un commentaire sur domo.rem81.


Annexe: Code Json

[
    {
        "id": "2955345bfd5612a1",
        "type": "tab",
        "label": "Prevision production solaire",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "36c89ae65ba3a77f",
        "type": "vrm-api",
        "z": "2955345bfd5612a1",
        "vrm": "88310ce625b06ec6",
        "name": "production PV inverter",
        "idSite": "223181",
        "installations": "stats",
        "attribute": "vrm_pv_inverter_yield_fc",
        "stats_interval": "days",
        "stats_start": "0",
        "stats_end": "86400",
        "verbose": false,
        "x": 140,
        "y": 140,
        "wires": [
            [
                "ce1f0fbcebdff6f0"
            ]
        ]
    },
    {
        "id": "6979d1aeb87544f0",
        "type": "debug",
        "z": "2955345bfd5612a1",
        "name": "debug 1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 540,
        "y": 80,
        "wires": []
    },
    {
        "id": "1dca4ea24c4642db",
        "type": "inject",
        "z": "2955345bfd5612a1",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "3600",
        "crontab": "",
        "once": true,
        "onceDelay": "30",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 110,
        "y": 320,
        "wires": [
            [
                "e65bd001b5bac48d",
                "36c89ae65ba3a77f"
            ]
        ]
    },
    {
        "id": "ce1f0fbcebdff6f0",
        "type": "change",
        "z": "2955345bfd5612a1",
        "name": "Extrac Previ MO",
        "rules": [
            {
                "t": "set",
                "p": "previmo",
                "pt": "flow",
                "to": "payload[\"totals\"][\"vrm_pv_inverter_yield_fc\"]",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 340,
        "y": 140,
        "wires": [
            [
                "d17c8b59cf0651c2",
                "a234285b07af8d7e",
                "6979d1aeb87544f0"
            ]
        ]
    },
    {
        "id": "57d48a7eda9ece0c",
        "type": "debug",
        "z": "2955345bfd5612a1",
        "name": "Previ MO",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 940,
        "y": 140,
        "wires": []
    },
    {
        "id": "a95d3adb1422d8aa",
        "type": "mqtt out",
        "z": "2955345bfd5612a1",
        "name": "Previ. prod. MO",
        "topic": "mp2/prediction/prod_onduleur",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "a89b02435258ed38",
        "x": 780,
        "y": 160,
        "wires": []
    },
    {
        "id": "e65bd001b5bac48d",
        "type": "vrm-api",
        "z": "2955345bfd5612a1",
        "vrm": "88310ce625b06ec6",
        "name": "Production MPPT1",
        "idSite": "223181",
        "installations": "stats",
        "attribute": "vrm_pv_charger_yield_fc",
        "stats_interval": "days",
        "stats_start": "0",
        "stats_end": "86400",
        "verbose": false,
        "x": 130,
        "y": 240,
        "wires": [
            [
                "2c61edb84c53d946"
            ]
        ]
    },
    {
        "id": "29b7e4c45b1b6946",
        "type": "debug",
        "z": "2955345bfd5612a1",
        "name": "Previ MPPT1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 970,
        "y": 240,
        "wires": []
    },
    {
        "id": "2c61edb84c53d946",
        "type": "change",
        "z": "2955345bfd5612a1",
        "name": "Extrac Previ MPPT1",
        "rules": [
            {
                "t": "set",
                "p": "previmppt1",
                "pt": "flow",
                "to": "payload[\"records\"][\"vrm_pv_charger_yield_fc\"][0][1]",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 360,
        "y": 240,
        "wires": [
            [
                "908239da70cb99f4",
                "a234285b07af8d7e",
                "5a3fa930636a955a"
            ]
        ]
    },
    {
        "id": "5a3fa930636a955a",
        "type": "debug",
        "z": "2955345bfd5612a1",
        "name": "debug 5",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 320,
        "y": 320,
        "wires": []
    },
    {
        "id": "c02172de44eb3d7e",
        "type": "mqtt out",
        "z": "2955345bfd5612a1",
        "name": "Predi. prod. MPPT1",
        "topic": "mp2/prediction/prod_mppt1",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "a89b02435258ed38",
        "x": 790,
        "y": 240,
        "wires": []
    },
    {
        "id": "d7196b1374d9bb8c",
        "type": "debug",
        "z": "2955345bfd5612a1",
        "name": "Previ Total",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "mo",
        "statusType": "auto",
        "x": 890,
        "y": 420,
        "wires": []
    },
    {
        "id": "7fb429cb111076e4",
        "type": "mqtt out",
        "z": "2955345bfd5612a1",
        "name": "Prediction prod total",
        "topic": "mp2/prediction/prod_total",
        "qos": "2",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "a89b02435258ed38",
        "x": 900,
        "y": 360,
        "wires": []
    },
    {
        "id": "581108ee019398cd",
        "type": "link out",
        "z": "2955345bfd5612a1",
        "name": "out_prod_total",
        "mode": "link",
        "links": [
            "6713fa86a6f1eacd"
        ],
        "x": 855,
        "y": 480,
        "wires": []
    },
    {
        "id": "3a3c787b4152e6e1",
        "type": "comment",
        "z": "2955345bfd5612a1",
        "name": "Estimation de la production PV",
        "info": "",
        "x": 490,
        "y": 40,
        "wires": []
    },
    {
        "id": "a234285b07af8d7e",
        "type": "function",
        "z": "2955345bfd5612a1",
        "name": "Somme des deux",
        "func": "let p = flow.get('previmo');\nlet c = flow.get('previmppt1');\nvar sum=0;\n\nsum = ((p+c)/1000).toFixed(0);\n\nmsg.payload = (sum);\nreturn [msg]\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 530,
        "y": 400,
        "wires": [
            [
                "7fb429cb111076e4",
                "d7196b1374d9bb8c",
                "581108ee019398cd"
            ]
        ]
    },
    {
        "id": "d17c8b59cf0651c2",
        "type": "function",
        "z": "2955345bfd5612a1",
        "name": "Convert et Arrondi",
        "func": "let p = flow.get('previmo')\nvar sum=0;\nsum = (p/1000).toFixed(0);\n\nmsg.payload = (sum);\nreturn [msg]\n\n\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 570,
        "y": 140,
        "wires": [
            [
                "a95d3adb1422d8aa",
                "57d48a7eda9ece0c"
            ]
        ]
    },
    {
        "id": "908239da70cb99f4",
        "type": "function",
        "z": "2955345bfd5612a1",
        "name": "Convert et Arrondi",
        "func": "let p = flow.get('previmo')\nvar sum=0;\nsum = (p/1000).toFixed(0);\n\nmsg.payload = (sum);\nreturn [msg]\n\n\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 570,
        "y": 240,
        "wires": [
            [
                "c02172de44eb3d7e",
                "29b7e4c45b1b6946"
            ]
        ]
    },
    {
        "id": "88310ce625b06ec6",
        "type": "config-vrm-api",
        "name": "vrm_remy",
        "token": "882b24ed02ff97334557ecc6b4f5a7ba61042ac40a8a361a09c9b725fb146fd9"
    },
    {
        "id": "a89b02435258ed38",
        "type": "mqtt-broker",
        "name": "MQTTHA",
        "broker": "192.168.0.37",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *