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
}
]