decramy.net

Webstek van Tjerk Jan


Enphase Envoy S-Metered to InfluxDB using Node-Red

A few weeks ago I installed 20 pieces of 375Wp solar panels on our roof. I've connected them using Enpase IQ7+ micro inverters and bought also a Envoy-S Metered with them to read out the production statistics.

Right after connecting the power lines to the grid I already have some statistics of the grid meter (in the Netherlands called the Slimme meter, which you can read through the P1-port using i.e. dsmr-reader. Also the Envoy-S is connected to the cloud and using the app on your phone you are able to see the performance per panel. But thats using the cloud :(

Using the internet there are a lot of examples on how the individual inverters are exposed at the http://envoy.local/api/v1/production/inverters URL. But the Envoy-S Metered also exposes the readings from the CT-clamps on http://envoy.local/stream/meter; the production readings, the grid readings and the calculated consumption readings. So I wanted to have those readings as wel :-)

There is one blog-post which is exactly what I want: https://dtbaker.net/blog/monitoring-solar-panels-with-nodered-influxdb-grafana/ ... ending with "todo.."

Well, I figured it out and I want to share with you.

Node-Red

You will need the node-red-contrib-sse-client palette for this. This was the hardest part in figuring out the setup of dtbaker.

Installer password

The installer password could be calculated using the device serial number. The main thread about this is at https://thecomputerperson.wordpress.com/2016/08/28/reverse-engineering-the-enphase-installer-toolkit/

The code

And this will look like:

[
    {
        "id": "830c8b80.f89718",
        "type": "inject",
        "z": "45ce5843.4f3ce",
        "name": "Start / Restart / Unpause stream",
        "props": [
            {
                "p": "payload",
                "v": "",
                "vt": "date"
            },
            {
                "p": "topic",
                "v": "",
                "vt": "string"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 170,
        "y": 560,
        "wires": [
            [
                "5944b091.17285"
            ]
        ]
    },
    {
        "id": "de79afb2.f459b",
        "type": "inject",
        "z": "45ce5843.4f3ce",
        "name": "Pause stream",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 230,
        "y": 680,
        "wires": [
            [
                "31c2c1a4.b6aabe"
            ]
        ]
    },
    {
        "id": "31c2c1a4.b6aabe",
        "type": "change",
        "z": "45ce5843.4f3ce",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "pause",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 460,
        "y": 680,
        "wires": [
            [
                "50364aa0.f4b3d4"
            ]
        ]
    },
    {
        "id": "fc7709e7.f95788",
        "type": "inject",
        "z": "45ce5843.4f3ce",
        "name": "Stop stream",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 230,
        "y": 640,
        "wires": [
            [
                "fc633663.b0ce48"
            ]
        ]
    },
    {
        "id": "fc633663.b0ce48",
        "type": "change",
        "z": "45ce5843.4f3ce",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "stop",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 470,
        "y": 640,
        "wires": [
            [
                "50364aa0.f4b3d4"
            ]
        ]
    },
    {
        "id": "50364aa0.f4b3d4",
        "type": "sse-client",
        "z": "45ce5843.4f3ce",
        "name": "",
        "url": "http://172.24.42.199/stream/meter",
        "events": [],
        "headers": {},
        "proxy": "",
        "restart": true,
        "rejectUnauthorized": false,
        "withCredentials": true,
        "timeout": "10",
        "x": 690,
        "y": 660,
        "wires": [
            [
                "6fa504f8fca90df3"
            ]
        ]
    },
    {
        "id": "5944b091.17285",
        "type": "http request",
        "z": "45ce5843.4f3ce",
        "name": "",
        "method": "GET",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "http://172.24.42.199/installer/setup/home",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "digest",
        "x": 410,
        "y": 560,
        "wires": [
            [
                "5e0c1620.061b18"
            ]
        ]
    },
    {
        "id": "5e0c1620.061b18",
        "type": "function",
        "z": "45ce5843.4f3ce",
        "name": "Set Cookie",
        "func": "msg.headers = {'Cookie': 'sessionId=' + msg.responseCookies.sessionId.value};\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 610,
        "y": 560,
        "wires": [
            [
                "50364aa0.f4b3d4"
            ]
        ]
    },
    {
        "id": "6fa504f8fca90df3",
        "type": "json",
        "z": "45ce5843.4f3ce",
        "name": "",
        "property": "payload",
        "action": "",
        "pretty": false,
        "x": 690,
        "y": 720,
        "wires": [
            [
                "29dd2e5fd14716ea"
            ]
        ]
    },
    {
        "id": "8e1dfedd9994b9aa",
        "type": "influxdb out",
        "z": "45ce5843.4f3ce",
        "influxdb": "5e1bce89.bfd22",
        "name": "Influxdb envoy_meter",
        "measurement": "envoy_meter",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "s",
        "retentionPolicyV18Flux": "",
        "org": "default",
        "bucket": "default",
        "x": 1020,
        "y": 660,
        "wires": []
    },
    {
        "id": "29e442028acaef29",
        "type": "function",
        "z": "45ce5843.4f3ce",
        "name": "reconstruct data",
        "func": "// Influx:\n// If msg.payload is an array containing two objects, \n// the first object will be written as the set of \n// named fields, the second is the set of named tags.\n\n// {\"event\":\"message\",\"payload\":{\"p\":-109.715,\"q\":-164.932,\"s\":267.003,\"v\":234.435,\"i\":1.134,\"pf\":-0.42,\"f\":50},\"parts\":{\"parts\":{\"id\":\"7f5ab7eaf0763c52\",\"type\":\"object\",\"key\":\"net-consumption\",\"index\":1,\"count\":3},\"id\":\"75bdb43ad68df8ae\",\"type\":\"object\",\"key\":\"ph-b\",\"index\":1,\"count\":3},\"topic\":\"net-consumption\",\"phase\":\"ph-b\",\"_msgid\":\"f81b1819c033b07d\"}\n\nfields = {};\ntags = {};\n\ntags   = {\"topic\": (msg.topic),\n          \"phase\": (msg.phase)\n         };\nfields = {\"wNow\": (msg.payload.p),\n          \"reactPower\": (msg.payload.q),\n          \"apprntPwr\": (msg.payload.s),\n          \"rmsVoltage\": (msg.payload.v),\n          \"rmsCurrent\": (msg.payload.i),\n          \"pwrFactor\": (msg.payload.pf),\n          \"frequency\": (msg.payload.f)\n         };\n\nmsg.payload = [fields,tags]\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1100,
        "y": 720,
        "wires": [
            [
                "8e1dfedd9994b9aa"
            ]
        ]
    },
    {
        "id": "e498a42fbb59c40c",
        "type": "split",
        "z": "45ce5843.4f3ce",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "phase",
        "x": 930,
        "y": 720,
        "wires": [
            [
                "29e442028acaef29"
            ]
        ]
    },
    {
        "id": "29dd2e5fd14716ea",
        "type": "split",
        "z": "45ce5843.4f3ce",
        "name": "",
        "splt": "",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "topic",
        "x": 810,
        "y": 720,
        "wires": [
            [
                "e498a42fbb59c40c"
            ]
        ]
    },
    {
        "id": "5e1bce89.bfd22",
        "type": "influxdb",
        "hostname": "127.0.0.1",
        "port": "8086",
        "protocol": "http",
        "database": "database",
        "name": "Regelkast Influx",
        "usetls": false,
        "tls": "a0af54c0.3a7438",
        "influxdbVersion": "2.0",
        "url": "http://172.24.42.1:8086",
        "rejectUnauthorized": false
    },
    {
        "id": "a0af54c0.3a7438",
        "type": "tls-config",
        "name": "",
        "cert": "",
        "key": "",
        "ca": "",
        "certname": "",
        "keyname": "",
        "caname": "",
        "servername": "",
        "verifyservercert": false
    }
]
Huh?
Persoonlijke webstek op het internet van Tjerk Jan. De site is begonnen om mijn documentatie-behoefte een plekje te geven en in plaats van een afgeschermde wiki ben ik de boel maar op het publieke internet gaan zetten. Ik houd me naast mijn werk bezig met mijn (klus-)huis, welke ik zo veel als mogelijk computergestuurd maak. Hobbymatig ook een server in een datacenter hangen waar mail en ander klein prul draait.