Skip to content

Instantly share code, notes, and snippets.

@dirkjanfaber
Last active January 4, 2023 12:16
Show Gist options
  • Save dirkjanfaber/9960a5c608fba8bc01c091ad04d805c9 to your computer and use it in GitHub Desktop.
Save dirkjanfaber/9960a5c608fba8bc01c091ad04d805c9 to your computer and use it in GitHub Desktop.
Energy zero

This subflow uses the energy zero API for retrieving the hourly energy prices from the API of https://www.energyzero.nl/ for either today or the next day. These are the prices as they are used by the Dutch energy providers ANWB energie, Energie van Ons and others.

Energy zero

In order not to load the API too heavy a rate limiter of 1 query per 15 minutes has been added to the subflow.

Do note that tomorrows prices can be queried after 15:00, so there is a delay built in the node that handles that.

Configuration

Price information can be retrieved for either today or tomorrow (default). It is also possible set if the prices should be retrieved including (default) or excluding tax.

Input

It triggers when injecting a message into the node.

Output

The output is an object with the result and a status message stored into the msg.payload.

Most important is the msg.payload.result, which contains the estimated production of the panels. E.g.:

payload: object
  Prices: array[24]
    [0 … 9]
    [10 … 19]
    [20 … 23]
      20: object
        price: 0.15
        readingDate: "2023-01-04T19:00:00Z"
      21: object
      22: object
      23: object
  intervalType: 4
  average: 0.12
  fromDate: "2023-01-03T23:00:00Z"
  tillDate: "2023-01-04T22:59:59.999Z"

The msg.payload.average gives the average price.

Status

In order not to load the api too much a rate limit has been added to maximize queries once per 15 minutes. The status message turns green when a query is allowed and red if it is not allowed.

If the delay is active (tomorrows prices can be queried after 15:00), the node will show that and wait until 15:00 before passing the message.

[
{
"id": "85b704305b8de34d",
"type": "subflow",
"name": "Energy zero",
"info": "This subflow uses the energy zero API for retrieving the hourly energy prices from the API of https://www.energyzero.nl/ for either today or the next day. \nThese are the prices as they are used by the Dutch energy providers ANWB energie, Energie van Ons and others.\n\nIn order not to load the API too heavy a rate limiter of 1 query per 15 minutes has been added to the subflow.\n\nDo note that tomorrows prices can be queried after 15:00, so there is a delay built in the\nnode that handles that.\n\n# Configuration\n\nPrice information can be retrieved for either today or tomorrow (default). It\nis also possible set if the prices should be retrieved including (default) or excluding tax.\n\n# Input\n\nIt triggers when injecting a message into the node.\n\n# Output\n\nThe output is an object with the result and a status message stored into the `msg.payload`.\n\nMost important is the `msg.payload.result`, which contains the estimated production of the panels. E.g.:\n\n```\npayload: object\n Prices: array[24]\n [0 … 9]\n [10 … 19]\n [20 … 23]\n 20: object\n price: 0.15\n readingDate: \"2023-01-04T19:00:00Z\"\n 21: object\n 22: object\n 23: object\n intervalType: 4\n average: 0.12\n fromDate: \"2023-01-03T23:00:00Z\"\n tillDate: \"2023-01-04T22:59:59.999Z\"\n```\n\nThe `msg.payload.average` gives the average price.\n\n# Status\n\nIn order not to load the api too much a rate limit has been added to maximize\nqueries once per 15 minutes. The status message turns green when a query is\nallowed and red if it is not allowed.\n\nIf the delay is active (tomorrows prices can be queried after 15:00), the\nnode will show that and wait until 15:00 before passing the message.\n",
"category": "",
"in": [
{
"x": 40,
"y": 80,
"wires": [
{
"id": "b4ce655d9d9618a6"
},
{
"id": "7d094a4741b9e75e"
}
]
}
],
"out": [
{
"x": 1120,
"y": 80,
"wires": [
{
"id": "0f4b7b69a5599dbf",
"port": 0
}
]
}
],
"env": [
{
"name": "type",
"type": "str",
"value": "tomorrow",
"ui": {
"icon": "font-awesome/fa-calendar",
"label": {
"en-US": "Type"
},
"type": "select",
"opts": {
"opts": [
{
"l": {
"en-US": "Today"
},
"v": "today"
},
{
"l": {
"en-US": "Tomorrow"
},
"v": "tomorrow"
}
]
}
}
},
{
"name": "inctax",
"type": "bool",
"value": "true",
"ui": {
"icon": "font-awesome/fa-money",
"label": {
"en-US": "Inc. tax"
},
"type": "checkbox"
}
}
],
"meta": {
"module": "Energy zero",
"version": "0.0.2",
"author": "Dirk-Jan Faber <dfaber@victronenergy.com>",
"desc": "Query the Energy Zero API",
"keywords": "energy zero, anwb, victron",
"license": "GPL-3.0"
},
"color": "#00bb00",
"icon": "font-awesome/fa-sun-o",
"status": {
"x": 940,
"y": 240,
"wires": [
{
"id": "7d094a4741b9e75e",
"port": 0
},
{
"id": "91f83c638f586ba6",
"port": 0
},
{
"id": "23b786399f036a4e",
"port": 0
},
{
"id": "eb17633dff6a3911",
"port": 0
}
]
}
},
{
"id": "b3574c7b467531ca",
"type": "http request",
"z": "85b704305b8de34d",
"name": "",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 810,
"y": 80,
"wires": [
[
"0f4b7b69a5599dbf"
]
]
},
{
"id": "802d7ded45575579",
"type": "function",
"z": "85b704305b8de34d",
"name": "create energyzero url",
"func": "msg.url = 'https://api.energyzero.nl/v1/energyprices';\nvar offset = 0;\nmsg.delay = 0;\nvar start = new Date();\n\nif (env.get('type') == 'tomorrow') {\n offset = 24;\n const targetTime = new Date(start.getFullYear(), start.getMonth(), start.getDate(), 15, 0, 0);\n msg.delay = targetTime.getTime() - start.getTime();\n}\n\nstart.setUTCHours(0 + offset, start.getTimezoneOffset(), 0, 0);\nmsg.url += '?fromDate=' + start.toISOString();\n\nvar end = new Date();\nend.setUTCHours(23 + offset, start.getTimezoneOffset()+59, 59, 999);\nmsg.url += '&tillDate=' + end.toISOString();\n\nmsg.url += '&interval=4&usageType=1'\n\nif (env.get('inctax')) {\n msg.url += '&inclBtw=true'\n} else {\n msg.url += '&inclBtw=false'\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 420,
"y": 80,
"wires": [
[
"c8efeaf1bda4f722",
"0b6dfae4dc6f1d38"
]
]
},
{
"id": "0f4b7b69a5599dbf",
"type": "json",
"z": "85b704305b8de34d",
"name": "Convert to json",
"property": "payload",
"action": "",
"pretty": false,
"x": 980,
"y": 80,
"wires": [
[]
]
},
{
"id": "b4ce655d9d9618a6",
"type": "delay",
"z": "85b704305b8de34d",
"name": "1 msg/15 minutes",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "15",
"rateUnits": "minute",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 190,
"y": 80,
"wires": [
[
"802d7ded45575579",
"f7513796331e20c0"
]
]
},
{
"id": "f7513796331e20c0",
"type": "delay",
"z": "85b704305b8de34d",
"name": "",
"pauseType": "delay",
"timeout": "15",
"timeoutUnits": "minutes",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 410,
"y": 220,
"wires": [
[
"91f83c638f586ba6"
]
]
},
{
"id": "7d094a4741b9e75e",
"type": "change",
"z": "85b704305b8de34d",
"name": "rate limit active",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{ \"fill\": \"yellow\", \"text\": \"Rate limiter active\" }",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 400,
"y": 320,
"wires": [
[]
]
},
{
"id": "91f83c638f586ba6",
"type": "change",
"z": "85b704305b8de34d",
"name": "rate limit inactive",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{ \"fill\": \"green\", \"text\": \"Ok\" }",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 630,
"y": 240,
"wires": [
[]
]
},
{
"id": "c63cd121af3ccc53",
"type": "inject",
"z": "85b704305b8de34d",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 410,
"y": 260,
"wires": [
[
"91f83c638f586ba6"
]
]
},
{
"id": "c8efeaf1bda4f722",
"type": "delay",
"z": "85b704305b8de34d",
"name": "Optional delay",
"pauseType": "delayv",
"timeout": "1",
"timeoutUnits": "milliseconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 640,
"y": 80,
"wires": [
[
"b3574c7b467531ca",
"eb17633dff6a3911"
]
]
},
{
"id": "0b6dfae4dc6f1d38",
"type": "switch",
"z": "85b704305b8de34d",
"name": "",
"property": "delay",
"propertyType": "msg",
"rules": [
{
"t": "gt",
"v": "0",
"vt": "num"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 630,
"y": 160,
"wires": [
[
"23b786399f036a4e"
]
]
},
{
"id": "23b786399f036a4e",
"type": "change",
"z": "85b704305b8de34d",
"name": "delay",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{ \"fill\": \"yellow\", \"text\": \"Delaying until 15.00\" }",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 750,
"y": 160,
"wires": [
[]
]
},
{
"id": "eb17633dff6a3911",
"type": "change",
"z": "85b704305b8de34d",
"name": "Ok",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{ \"fill\": \"green\", \"text\": \"Ok\" }",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 750,
"y": 120,
"wires": [
[]
]
},
{
"id": "74a9593f42aa1853",
"type": "subflow:85b704305b8de34d",
"z": "d9430a3cc87ff736",
"name": "ANWB morgen",
"x": 740,
"y": 320,
"wires": [
[
"5fb92f949343c2c0"
]
]
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment