Electricity Maps

Moderator: leecollings

Post Reply
User avatar
FireWizard
Posts: 1770
Joined: Tuesday 25 December 2018 12:11
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Voorthuizen (NL)
Contact:

Electricity Maps

Post by FireWizard »

This project should not be mixed with the Domoticz Energy Dashboard, however the data
can be send to a "Text" sensor in the Energy board.

This Node-RED flow retrieves environmental data from https://app.electricitymaps.com/map

This project aims to make users aware of their ecological footprint.
This is the easiest by monitoring your electrical energy consumption and know, where your energy comes from.

If you are the owner of a set of solar panels, you use a lot of fossil-free energy, but not all.
Sometimes you need the grid and in this case, while being aware, where the energy comes from, you can plan to use as much as
carbon free energy.

This flow retrieves the energy data from an API available at https://www.electricitymaps.com/free-tier-api
Documentation can be found at: hxxps://static.electricitymaps.com/api/docs/index.html
Get your free API key at: hxxps://www.electricitymaps.com/free-tier-api

Although more than 200 regions are available, I use the lat/lon coordinates, as configured in Domoticz.
This will avoid, that users has to lookup their "Region".

The health and the zones can be requested without an API key.

Beside actual data, historical data is available in the free tier.
However I use only 2(3) sensors.

1. For information I added a Carbon Intensity sensor.
This is a Custom sensor with an x-axis gCO2eq/kWh

2. I also added an Electrical (usage and counter) device.

3. I added an unused "Text¨ device in order to send some text to the Energy Dashboard

Screenshot_fossil-free_energy_widgets.png
Screenshot_fossil-free_energy_widgets.png (104.41 KiB) Viewed 1495 times

The Carbon Intensity sensor gets the data from:hxxps://api.electricitymap.org/v3/carbon-intensity/latest
The amount of used fossil-free energy is calculated from the data from the P1 Smartmeter and the value fossilFreePercentage from
hxxps://api.electricitymap.org/v3/power-breakdown/latest

As the P1 Smartmeter only the "Consumed Power" (and "Produced Power") has available as useful data Node-RED calculates
the daily used Energy themselves. Therefore the contrib node "Watt2kWh" has to be installed.
Domoticz can also calculate the Energy, based on the Power, but that widget cannot be used as input to the Energy Dashboard.
I need a Text device for that.

Perhaps a suggestion to @gizmocuz to make that possible.

After testing over a longer period and some fine-tuning, I think it is time to share it with the community.

A picture of the flow see below.

Screenshot_fossil-free_energy_flow.png
Screenshot_fossil-free_energy_flow.png (69.01 KiB) Viewed 1495 times

Code: Select all

[
    {
        "id": "38eba13e2b291140",
        "type": "tab",
        "label": "Electricity Map",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "47ea0daa093a0e0e",
        "type": "inject",
        "z": "38eba13e2b291140",
        "name": "Request Areas",
        "props": [],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 180,
        "y": 400,
        "wires": [
            [
                "3a9e851de597d511"
            ]
        ]
    },
    {
        "id": "3a9e851de597d511",
        "type": "http request",
        "z": "38eba13e2b291140",
        "name": "",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.electricitymap.org/v3/zones",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 390,
        "y": 400,
        "wires": [
            [
                "7ced18af8ff74714"
            ]
        ]
    },
    {
        "id": "7ced18af8ff74714",
        "type": "debug",
        "z": "38eba13e2b291140",
        "name": "debug 272",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 590,
        "y": 400,
        "wires": []
    },
    {
        "id": "eb852f83ee231945",
        "type": "inject",
        "z": "38eba13e2b291140",
        "name": "Get Domoticz Settings",
        "props": [],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "x": 200,
        "y": 120,
        "wires": [
            [
                "57780ec1ad27d090"
            ]
        ]
    },
    {
        "id": "57780ec1ad27d090",
        "type": "http request",
        "z": "38eba13e2b291140",
        "name": "Check Domoticz Settings",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "http://192.168.10.50:8080/json.htm?type=command&param=getsettings",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 470,
        "y": 120,
        "wires": [
            [
                "78ba556b0e4c6897"
            ]
        ]
    },
    {
        "id": "78ba556b0e4c6897",
        "type": "change",
        "z": "38eba13e2b291140",
        "name": "Import Home Lat/Lon",
        "rules": [
            {
                "t": "set",
                "p": "homeLat",
                "pt": "global",
                "to": "payload.Location.Latitude",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "homeLon",
                "pt": "global",
                "to": "payload.Location.Longitude",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 740,
        "y": 120,
        "wires": [
            [
                "2570cecd25c0c4cc"
            ]
        ]
    },
    {
        "id": "6750401a206385d6",
        "type": "inject",
        "z": "38eba13e2b291140",
        "name": "Start",
        "props": [],
        "repeat": "30",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "x": 150,
        "y": 600,
        "wires": [
            [
                "9adb98a595f08fbc"
            ]
        ]
    },
    {
        "id": "dc2492dfc9d7baa0",
        "type": "comment",
        "z": "38eba13e2b291140",
        "name": "Zones",
        "info": "",
        "x": 390,
        "y": 360,
        "wires": []
    },
    {
        "id": "797e8bf67221bd06",
        "type": "comment",
        "z": "38eba13e2b291140",
        "name": "Carbon Intensity",
        "info": "",
        "x": 540,
        "y": 560,
        "wires": []
    },
    {
        "id": "02809b553e120547",
        "type": "comment",
        "z": "38eba13e2b291140",
        "name": "Check Global Lat/Lon",
        "info": "",
        "x": 980,
        "y": 60,
        "wires": []
    },
    {
        "id": "29bbcc343972c09e",
        "type": "inject",
        "z": "38eba13e2b291140",
        "name": "Request Health",
        "props": [],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 180,
        "y": 300,
        "wires": [
            [
                "d21c9d04e9adac83"
            ]
        ]
    },
    {
        "id": "d21c9d04e9adac83",
        "type": "http request",
        "z": "38eba13e2b291140",
        "name": "",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.electricitymap.org/health",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 390,
        "y": 300,
        "wires": [
            [
                "47330cb648c5ef3b"
            ]
        ]
    },
    {
        "id": "47330cb648c5ef3b",
        "type": "debug",
        "z": "38eba13e2b291140",
        "name": "debug 277",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 590,
        "y": 300,
        "wires": []
    },
    {
        "id": "03fe1f30617003cb",
        "type": "comment",
        "z": "38eba13e2b291140",
        "name": "API Health",
        "info": "",
        "x": 400,
        "y": 260,
        "wires": []
    },
    {
        "id": "1b38ec45eb389464",
        "type": "comment",
        "z": "38eba13e2b291140",
        "name": "Live power breakdown",
        "info": "",
        "x": 760,
        "y": 660,
        "wires": []
    },
    {
        "id": "e2b96b2acef9687e",
        "type": "comment",
        "z": "38eba13e2b291140",
        "name": "Retrieve Domoticz Lat/Lon coordinates and store these in Global variables",
        "info": "",
        "x": 580,
        "y": 60,
        "wires": []
    },
    {
        "id": "2849bf72b217d1c6",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "Carbon Intensity to Domoticz",
        "func": "msg.payload = { \"command\": \"udevice\", \"idx\": 650, \"svalue\": msg.payload.carbonIntensity.toString() }\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 800,
        "y": 600,
        "wires": [
            [
                "0644f915d488aba7"
            ]
        ]
    },
    {
        "id": "0644f915d488aba7",
        "type": "mqtt out",
        "z": "38eba13e2b291140",
        "name": "To Domoticz",
        "topic": "domoticz/in",
        "qos": "0",
        "retain": "false",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "7aff5cd755ba2941",
        "x": 1050,
        "y": 600,
        "wires": []
    },
    {
        "id": "71f182d3980c16bf",
        "type": "mqtt in",
        "z": "38eba13e2b291140",
        "name": "Domoticz Out",
        "topic": "domoticz/out",
        "qos": "0",
        "datatype": "auto-detect",
        "broker": "7aff5cd755ba2941",
        "nl": false,
        "rap": false,
        "inputs": 0,
        "x": 130,
        "y": 700,
        "wires": [
            [
                "cb34da93c0df30ae"
            ]
        ]
    },
    {
        "id": "cb34da93c0df30ae",
        "type": "switch",
        "z": "38eba13e2b291140",
        "name": "Filter P1 meter",
        "property": "payload.idx",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "17",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 340,
        "y": 700,
        "wires": [
            [
                "06532e8d36b6425d"
            ]
        ]
    },
    {
        "id": "2570cecd25c0c4cc",
        "type": "change",
        "z": "38eba13e2b291140",
        "name": "Check lat/Lon",
        "rules": [
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            },
            {
                "t": "set",
                "p": "payload.Lat",
                "pt": "msg",
                "to": "homeLat",
                "tot": "global"
            },
            {
                "t": "set",
                "p": "payload.Lon",
                "pt": "msg",
                "to": "homeLon",
                "tot": "global"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 980,
        "y": 120,
        "wires": [
            [
                "f68d9f4a12c9489a"
            ]
        ]
    },
    {
        "id": "f68d9f4a12c9489a",
        "type": "debug",
        "z": "38eba13e2b291140",
        "name": "debug 284",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 1190,
        "y": 120,
        "wires": []
    },
    {
        "id": "06532e8d36b6425d",
        "type": "change",
        "z": "38eba13e2b291140",
        "name": "Store variables",
        "rules": [
            {
                "t": "set",
                "p": "totalPowerGrid",
                "pt": "flow",
                "to": "payload.svalue5",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "lat",
                "pt": "msg",
                "to": "homeLat",
                "tot": "global"
            },
            {
                "t": "set",
                "p": "lon",
                "pt": "msg",
                "to": "homeLon",
                "tot": "global"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 560,
        "y": 700,
        "wires": [
            [
                "0b5559dabc93d987"
            ]
        ]
    },
    {
        "id": "0b5559dabc93d987",
        "type": "http request",
        "z": "38eba13e2b291140",
        "name": "",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.electricitymap.org/v3/power-breakdown/latest?lat={{{lat}}}&lon={{{lon}}}",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [
            {
                "keyType": "other",
                "keyValue": "auth-token",
                "valueType": "other",
                "valueValue": "YbDsNLqFKuJaZ"
            }
        ],
        "x": 770,
        "y": 700,
        "wires": [
            [
                "131a3795372a54bc"
            ]
        ]
    },
    {
        "id": "131a3795372a54bc",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "Set Fossil-free Power",
        "func": "msg.topic = \"fossilFreePower\";\n\nflow.set(\"ffpower\", (Number(flow.get(\"totalPowerGrid\")) * (msg.payload.fossilFreePercentage / 100)));\n\nmsg.payload = flow.get(\"ffpower\");\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1000,
        "y": 700,
        "wires": [
            [
                "58d0e70c57c59a32"
            ]
        ]
    },
    {
        "id": "58d0e70c57c59a32",
        "type": "watt2kwh",
        "z": "38eba13e2b291140",
        "format": "kwh",
        "maximum": "60",
        "maximumunit": "mins",
        "name": "Energy Calc.",
        "x": 1230,
        "y": 700,
        "wires": [
            [
                "a188464d18e4940f"
            ]
        ]
    },
    {
        "id": "e3eb2523fb6562af",
        "type": "inject",
        "z": "38eba13e2b291140",
        "name": "Reset Midnight",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "00 00 * * *",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "reset",
        "payloadType": "str",
        "x": 1210,
        "y": 760,
        "wires": [
            [
                "a188464d18e4940f"
            ]
        ]
    },
    {
        "id": "a188464d18e4940f",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "Fossil-free to Domoticz",
        "func": "let msg1 = {};\nlet msg2 = {};\nmsg1.topic = \"fossilFreePowerEnergy\";\nmsg2.topic = \"fossilFreeEnergy\";\n\nif (msg.payload == \"reset\") {\n    flow.set(\"ffEnergy\", 0);\n} else {\n    let storedVal = flow.get(\"ffEnergy\") || 0;\n    storedVal += msg.payload;\n//    flow.set(\"ffEnergy\", (flow.get(\"ffEnergy\"),storedVal));\n    flow.set(\"ffEnergy\", storedVal);\n\nmsg1.payload = { \"command\": \"udevice\", \"idx\": 656, \"svalue\": flow.get(\"ffpower\").toFixed(0) + \";\" + (flow.get(\"ffEnergy\") * 1000).toFixed(0)};\nmsg2.payload = { \"command\": \"udevice\", \"idx\": 652, \"svalue\": \"Fossil free Energy: \" + flow.get(\"ffEnergy\").toFixed(3) + \" kWh\" };\n\nreturn [[msg1,msg2]];\n}",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1470,
        "y": 700,
        "wires": [
            [
                "47bf4a712b389eb9",
                "00eb0671e8713d71"
            ]
        ]
    },
    {
        "id": "00eb0671e8713d71",
        "type": "mqtt out",
        "z": "38eba13e2b291140",
        "name": "To Domoticz",
        "topic": "domoticz/in",
        "qos": "0",
        "retain": "false",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "7aff5cd755ba2941",
        "x": 1710,
        "y": 700,
        "wires": []
    },
    {
        "id": "47bf4a712b389eb9",
        "type": "debug",
        "z": "38eba13e2b291140",
        "name": "debug 290",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 1710,
        "y": 760,
        "wires": []
    },
    {
        "id": "46c0661344ebc0e4",
        "type": "http request",
        "z": "38eba13e2b291140",
        "name": "",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.electricitymap.org/v3/carbon-intensity/latest?lat={{{lat}}}&lon={{{lon}}}",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [
            {
                "keyType": "other",
                "keyValue": "auth-token",
                "valueType": "other",
                "valueValue": "YbDsNLqFKuJaZ"
            }
        ],
        "x": 550,
        "y": 600,
        "wires": [
            [
                "2849bf72b217d1c6"
            ]
        ]
    },
    {
        "id": "9adb98a595f08fbc",
        "type": "change",
        "z": "38eba13e2b291140",
        "name": "Store variables",
        "rules": [
            {
                "t": "set",
                "p": "lat",
                "pt": "msg",
                "to": "homeLat",
                "tot": "global"
            },
            {
                "t": "set",
                "p": "lon",
                "pt": "msg",
                "to": "homeLon",
                "tot": "global"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 340,
        "y": 600,
        "wires": [
            [
                "46c0661344ebc0e4"
            ]
        ]
    },
    {
        "id": "d493d15681a6f831",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "Set URL/API key/Lat/Lon",
        "func": "msg.headers = {};\nmsg.headers['auth-token'] = \"YbDsNLqFKuJaZ\";\n\nmsg.url = \"https://api.electricitymap.org/v3/power-breakdown/latest?lat=\" + global.get(\"homeLat\") + \"&lon=\" + global.get(\"homeLon\");\n\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1210,
        "y": 1460,
        "wires": [
            [
                "9a76d040e6a5832f"
            ]
        ]
    },
    {
        "id": "9a76d040e6a5832f",
        "type": "http request",
        "z": "38eba13e2b291140",
        "name": "",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 1450,
        "y": 1460,
        "wires": [
            [
                "e6192d31446baaa7"
            ]
        ]
    },
    {
        "id": "e6192d31446baaa7",
        "type": "change",
        "z": "38eba13e2b291140",
        "name": "Collect Fossil-free percentage",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.fossilFreePercentage",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "fossilFreePercentage",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1710,
        "y": 1460,
        "wires": [
            [
                "2b799b7f6a5a60f7"
            ]
        ]
    },
    {
        "id": "98a96603de0d6af8",
        "type": "change",
        "z": "38eba13e2b291140",
        "name": "Collect Total Power Grid",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.svalue5",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "totalPowerGrid",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1730,
        "y": 1540,
        "wires": [
            [
                "2b799b7f6a5a60f7"
            ]
        ]
    },
    {
        "id": "2b799b7f6a5a60f7",
        "type": "join",
        "z": "38eba13e2b291140",
        "name": "Join Power Grid Percentage",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "useparts": false,
        "accumulate": false,
        "timeout": "",
        "count": "2",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 2030,
        "y": 1500,
        "wires": [
            [
                "e22f4a964bdf5e54",
                "2b2b5866db754842"
            ]
        ]
    },
    {
        "id": "2b2b5866db754842",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "String2Number",
        "func": "msg.topic = \"fossilFreePower\";\n\nmsg.payload = Number(msg.payload.totalPowerGrid) * (msg.payload.fossilFreePercentage / 100);\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 2300,
        "y": 1540,
        "wires": [
            [
                "cf02c272945bd1e2"
            ]
        ]
    },
    {
        "id": "e22f4a964bdf5e54",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "Calculate Fossil-free percentage to Domoticz",
        "func": "let ffpower = Number(msg.payload.totalPowerGrid) * (msg.payload.fossilFreePercentage / 100);\n\nmsg.payload = { \"command\": \"udevice\", \"idx\": 651, \"svalue\": ffpower.toFixed(0) + \";0\" };\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 2400,
        "y": 1460,
        "wires": [
            []
        ]
    },
    {
        "id": "cf02c272945bd1e2",
        "type": "watt2kwh",
        "z": "38eba13e2b291140",
        "format": "kwh",
        "maximum": "60",
        "maximumunit": "mins",
        "name": "Energy Calc.",
        "x": 2510,
        "y": 1540,
        "wires": [
            [
                "3ee1b453b632de64"
            ]
        ]
    },
    {
        "id": "3953a16fefa09bdf",
        "type": "inject",
        "z": "38eba13e2b291140",
        "name": "Reset Midnight",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "00 00 * * *",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "reset",
        "payloadType": "str",
        "x": 2490,
        "y": 1580,
        "wires": [
            [
                "3ee1b453b632de64"
            ]
        ]
    },
    {
        "id": "3ee1b453b632de64",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "Fossil-free Text to Domoticz",
        "func": "msg.topic = \"fossilFreeEnergy\";\n\nlet inputVal = msg.payload;\nif (inputVal == \"reset\") {\n    flow.set(\"energyVal\", 0);\n} else {\n    let savedVal = flow.get(\"energyVal\") || 0;\n    savedVal += inputVal;\n    flow.set(\"energyVal\", savedVal);\n    msg.payload = { \"command\": \"udevice\", \"idx\": 652, \"svalue\": \"Fossil free Energy: \" + savedVal.toFixed(3) + \" kWh\" };\nreturn msg;\n}",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 2760,
        "y": 1540,
        "wires": [
            []
        ]
    },
    {
        "id": "7aff5cd755ba2941",
        "type": "mqtt-broker",
        "name": "Jonas_MQTT_Server",
        "broker": "192.168.10.24",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]

To use the flow do the following:

1. Go to the URL: https://www.electricitymaps.com/free-tier-api and get your free API key.

2. Create 3 Dummy devices:
1. Custom Sensor and for the Horizontal (x-axes) axis insert gCO2eq/Watt2kWh
2. Electric (Instant + Counter) Sensor. Set the configuration to Type: "Usage" and Energy read: "From device".
Actually it doesn't matter, whether Domoticz calculate the Energy or node-RED.
I preferred Node RED, just to be sure that the Electricity device and the Text device show exactly the same value
3. Text device. In Settings ==> Devices set this sensor to "Unused" after you configured the Energy dashboard.
(This sensor is only used as Text device in the Energy Dashboard).

3. Note down the IDX of your 3 newly created sensors

4. In the "http request" node insert your API key in the "Header" section. Note: Not necessary in the first 2 streams (API Health and Zones)

5. For the "Carbon Intensity" insert the correct IDX for Domoticz.

6. In the "Filter P1 meter" insert the correct IDX for your P1 device in Domoticz.

7. From the "Palette" install the "Custom" node, called "node-red-contrib-watt2kwh".

8. In the "Function" node, configure the correct IDX's in line 14 and 15.
You can select either the "Electricity" device or the "Text" device or both by modifying the "Function" node.

9. Configure your MQTT server.

Note: Replace in the links above hxxps into https.

I'm open for ideas, comment or suggestions.

Regards
User avatar
waltervl
Posts: 5396
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Electricity Maps

Post by waltervl »

From a personal point of view beside changing your grid electricity supplier you have no influence on the fossil foot print of the grid (in the Netherlands). So why would I like to see and track that in Domoticz?
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
User avatar
FireWizard
Posts: 1770
Joined: Tuesday 25 December 2018 12:11
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Voorthuizen (NL)
Contact:

Re: Electricity Maps

Post by FireWizard »

Hello @waltervl,

I had expected such a kind of question

You wrote:
From a personal point of view beside changing your grid electricity supplier you have no influence on the fossil foot print of the grid (in the Netherlands).
I agree with you, that you do not have any influence on the footprint of the production of the electricity in an area.
Changing the Energy supplier will not help you either, because the presented data is not specific for a supplier but for an area,
in this case The Netherlands.
So why would I like to see and track that in Domoticz?
First, there is a lot of data in Domoticz, which you have no influence on and that you cannot change, e.g. the weather.
Example, why do we track the air pressure. I cannot change the pressure, so why should I know that?

To illustrate the need for some people, I will give a few examples.

Assume the situation that you have an EV car and you do not have Solar panels.
When do I charge the battery?
If you are concerned about your Carbon footprint you would do that at the moment with the highest Fossil-free Energy.

Another example

We have dynamic Energy prices and it is implemented in Domoticz.
Why? Because users can plan their electricity consumption, so that they have the lowest bill
This is financial driven, I know, but what, if you can plan your consumption, so that we have a lower footprint.
We can not change it on the production side, I agree, but we can on the consumption side.

Remember, everything starts with awareness.

Regards
User avatar
FireWizard
Posts: 1770
Joined: Tuesday 25 December 2018 12:11
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Voorthuizen (NL)
Contact:

Re: Electricity Maps

Post by FireWizard »

Hi

I created a new flow, which sends the "Fossil-free Energy" to both a "Text" sensor, as well as an "Electricity (Instand + Counter)" sensor to Domoticz.

After the "Energy" calculation the flow splits to two "Function" nodes, marked "Fossil-free to Domoticz" and "Fossil-free (txt) to Domoticz".

You can use the first one, if you wish to create an "Electricity" sensor, which can be used as one of the extra sensors, connected to the "House" in the "Energy Dashboard". The second one (txt) can be used as you wish to create the extra "Text" sensor in the "Energy Dashboard".

Or if you wish you can use both :D

In order to survive a redeploy, restart of Node-RED or reboot of your device, i changed the previous flow and use persistent storage of the calculated "Fossil-free Energy".
To do so, you have to modify the "settings.js" file in your Node-RED directory. Normally ~/.node-red.

Add the following lines:

Code: Select all

contextStorage: {
      default: "memoryOnly",
      memoryOnly: { module: 'memory' },
      file: { module: 'localfilesystem' }
      },
The final complete flow you will find below:

Code: Select all

[
    {
        "id": "47ea0daa093a0e0e",
        "type": "inject",
        "z": "38eba13e2b291140",
        "name": "Request Areas",
        "props": [],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 180,
        "y": 400,
        "wires": [
            [
                "3a9e851de597d511"
            ]
        ]
    },
    {
        "id": "3a9e851de597d511",
        "type": "http request",
        "z": "38eba13e2b291140",
        "name": "",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.electricitymap.org/v3/zones",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 390,
        "y": 400,
        "wires": [
            [
                "7ced18af8ff74714"
            ]
        ]
    },
    {
        "id": "7ced18af8ff74714",
        "type": "debug",
        "z": "38eba13e2b291140",
        "name": "debug 272",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 590,
        "y": 400,
        "wires": []
    },
    {
        "id": "6750401a206385d6",
        "type": "inject",
        "z": "38eba13e2b291140",
        "name": "Start",
        "props": [],
        "repeat": "30",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "x": 150,
        "y": 600,
        "wires": [
            [
                "9adb98a595f08fbc"
            ]
        ]
    },
    {
        "id": "dc2492dfc9d7baa0",
        "type": "comment",
        "z": "38eba13e2b291140",
        "name": "Zones",
        "info": "",
        "x": 390,
        "y": 360,
        "wires": []
    },
    {
        "id": "797e8bf67221bd06",
        "type": "comment",
        "z": "38eba13e2b291140",
        "name": "Carbon Intensity",
        "info": "",
        "x": 540,
        "y": 560,
        "wires": []
    },
    {
        "id": "29bbcc343972c09e",
        "type": "inject",
        "z": "38eba13e2b291140",
        "name": "Request Health",
        "props": [],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 180,
        "y": 300,
        "wires": [
            [
                "d21c9d04e9adac83"
            ]
        ]
    },
    {
        "id": "d21c9d04e9adac83",
        "type": "http request",
        "z": "38eba13e2b291140",
        "name": "",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.electricitymap.org/health",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 390,
        "y": 300,
        "wires": [
            [
                "47330cb648c5ef3b"
            ]
        ]
    },
    {
        "id": "47330cb648c5ef3b",
        "type": "debug",
        "z": "38eba13e2b291140",
        "name": "debug 277",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 590,
        "y": 300,
        "wires": []
    },
    {
        "id": "03fe1f30617003cb",
        "type": "comment",
        "z": "38eba13e2b291140",
        "name": "API Health",
        "info": "",
        "x": 400,
        "y": 260,
        "wires": []
    },
    {
        "id": "1b38ec45eb389464",
        "type": "comment",
        "z": "38eba13e2b291140",
        "name": "Live power breakdown",
        "info": "",
        "x": 760,
        "y": 660,
        "wires": []
    },
    {
        "id": "2849bf72b217d1c6",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "Carbon Intensity to Domoticz",
        "func": "msg.payload = { \"command\": \"udevice\", \"idx\": 650, \"svalue\": msg.payload.carbonIntensity.toString() }\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 800,
        "y": 600,
        "wires": [
            [
                "0644f915d488aba7"
            ]
        ]
    },
    {
        "id": "0644f915d488aba7",
        "type": "mqtt out",
        "z": "38eba13e2b291140",
        "name": "To Domoticz",
        "topic": "domoticz/in",
        "qos": "0",
        "retain": "false",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "7aff5cd755ba2941",
        "x": 1050,
        "y": 600,
        "wires": []
    },
    {
        "id": "71f182d3980c16bf",
        "type": "mqtt in",
        "z": "38eba13e2b291140",
        "name": "Domoticz Out",
        "topic": "domoticz/out",
        "qos": "0",
        "datatype": "auto-detect",
        "broker": "7aff5cd755ba2941",
        "nl": false,
        "rap": false,
        "inputs": 0,
        "x": 130,
        "y": 700,
        "wires": [
            [
                "cb34da93c0df30ae"
            ]
        ]
    },
    {
        "id": "cb34da93c0df30ae",
        "type": "switch",
        "z": "38eba13e2b291140",
        "name": "Filter P1 meter",
        "property": "payload.idx",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "17",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 340,
        "y": 700,
        "wires": [
            [
                "06532e8d36b6425d"
            ]
        ]
    },
    {
        "id": "06532e8d36b6425d",
        "type": "change",
        "z": "38eba13e2b291140",
        "name": "Store variables",
        "rules": [
            {
                "t": "set",
                "p": "totalPowerGrid",
                "pt": "flow",
                "to": "payload.svalue5",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "lat",
                "pt": "msg",
                "to": "homeLat",
                "tot": "global"
            },
            {
                "t": "set",
                "p": "lon",
                "pt": "msg",
                "to": "homeLon",
                "tot": "global"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 560,
        "y": 700,
        "wires": [
            [
                "0b5559dabc93d987"
            ]
        ]
    },
    {
        "id": "0b5559dabc93d987",
        "type": "http request",
        "z": "38eba13e2b291140",
        "name": "",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.electricitymap.org/v3/power-breakdown/latest?lat={{{lat}}}&lon={{{lon}}}",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [
            {
                "keyType": "other",
                "keyValue": "auth-token",
                "valueType": "other",
                "valueValue": "YbDsNLqFKuJaZ"
            }
        ],
        "x": 770,
        "y": 700,
        "wires": [
            [
                "131a3795372a54bc"
            ]
        ]
    },
    {
        "id": "131a3795372a54bc",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "Set Fossil-free Power",
        "func": "msg.topic = \"fossilFreePower\";\n\nflow.set(\"ffpower\", (Number(flow.get(\"totalPowerGrid\")) * (msg.payload.fossilFreePercentage / 100)));\n\nmsg.payload = flow.get(\"ffpower\");\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1000,
        "y": 700,
        "wires": [
            [
                "58d0e70c57c59a32"
            ]
        ]
    },
    {
        "id": "58d0e70c57c59a32",
        "type": "watt2kwh",
        "z": "38eba13e2b291140",
        "format": "kwh",
        "maximum": "60",
        "maximumunit": "mins",
        "name": "Energy Calc.",
        "x": 1230,
        "y": 700,
        "wires": [
            [
                "84392802e7abb0ad",
                "a188464d18e4940f"
            ]
        ]
    },
    {
        "id": "e3eb2523fb6562af",
        "type": "inject",
        "z": "38eba13e2b291140",
        "name": "Reset Midnight",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "00 00 * * *",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "reset",
        "payloadType": "str",
        "x": 1210,
        "y": 780,
        "wires": [
            [
                "a188464d18e4940f"
            ]
        ]
    },
    {
        "id": "a188464d18e4940f",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "Fossil-free (txt) to Domoticz",
        "func": "if (msg.payload == \"reset\") {\n    flow.set(\"ffEnergy_txt\", 0, \"file\");\n} else {\n    let storedVal = flow.get(\"ffEnergy_txt\", \"file\") || 0;\n    storedVal += msg.payload;\n    flow.set(\"ffEnergy_txt\", storedVal, \"file\");\n\nmsg.payload = { \"command\": \"udevice\", \"idx\": 652, \"svalue\": \"Fossil free Energy: \" + flow.get(\"ffEnergy_txt\", \"file\").toFixed(3).toString() + \" kWh\" };\n\nreturn msg;\n}",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1480,
        "y": 740,
        "wires": [
            [
                "00eb0671e8713d71"
            ]
        ]
    },
    {
        "id": "00eb0671e8713d71",
        "type": "mqtt out",
        "z": "38eba13e2b291140",
        "name": "To Domoticz",
        "topic": "domoticz/in",
        "qos": "0",
        "retain": "false",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "7aff5cd755ba2941",
        "x": 1730,
        "y": 700,
        "wires": []
    },
    {
        "id": "46c0661344ebc0e4",
        "type": "http request",
        "z": "38eba13e2b291140",
        "name": "",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.electricitymap.org/v3/carbon-intensity/latest?lat={{{lat}}}&lon={{{lon}}}",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [
            {
                "keyType": "other",
                "keyValue": "auth-token",
                "valueType": "other",
                "valueValue": "YbDsNLqFKuJaZ"
            }
        ],
        "x": 550,
        "y": 600,
        "wires": [
            [
                "2849bf72b217d1c6"
            ]
        ]
    },
    {
        "id": "9adb98a595f08fbc",
        "type": "change",
        "z": "38eba13e2b291140",
        "name": "Store variables",
        "rules": [
            {
                "t": "set",
                "p": "lat",
                "pt": "msg",
                "to": "homeLat",
                "tot": "global"
            },
            {
                "t": "set",
                "p": "lon",
                "pt": "msg",
                "to": "homeLon",
                "tot": "global"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 340,
        "y": 600,
        "wires": [
            [
                "46c0661344ebc0e4"
            ]
        ]
    },
    {
        "id": "84392802e7abb0ad",
        "type": "function",
        "z": "38eba13e2b291140",
        "name": "Fossil-free to Domoticz",
        "func": "let storedVal = flow.get(\"ffEnergy\", \"file\") || 0;\nstoredVal += msg.payload;\nflow.set(\"ffEnergy\", storedVal, \"file\");\n\nmsg.payload = { \"command\": \"udevice\", \"idx\": 656, \"svalue\": flow.get(\"ffpower\").toFixed(0).toString() + \";\" + (flow.get(\"ffEnergy\", \"file\") * 1000).toFixed(3).toString()};\n\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1470,
        "y": 660,
        "wires": [
            [
                "00eb0671e8713d71"
            ]
        ]
    },
    {
        "id": "7aff5cd755ba2941",
        "type": "mqtt-broker",
        "name": "Jonas_MQTT_Server",
        "broker": "192.168.10.24",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]
Best regards
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests