As the previous URL for "Stookalert" has been taken offline at the end of January 2025,
I hereby publish a new Node-RED flow for the "Stookwijzer".
See topic ; viewtopic.php?p=323436#p323436
For background of "Stookwijzer", see: https://iplo.nl/thema/lucht/houtstook-stookwijzer/
The new Node-RED flow uses the Lat/Lon coördinates as inserted in the "Settings" page of Domoticz.
The top row of nodes collect the geographical coördinates for your location.
The first "Inject" node injects the IP address of your device with the Domoticz application.
So you have to insert the correct IP address in the Inject node.
The first HTTP node requests the Lat/Lon coördinates from Domoticz.
These coördinates give the Lat/Lon values in WGS 84 format. This is equal to EPSG 4326.
However the new RIVM API uses a different system, EPSG 28992. This is based on the x, y coördinates of
Onze Lieve Vrouwetoren (Amersfoort). See: https://nl.wikipedia.org/wiki/Onze_Liev ... mersfoort)
For EPSG, see: https://epsg.io/
The conversion from EPSG 4326 to EPSG 28992 is rather complex, but fortunately epsg.io has an API, which does the hard work.
So the Lat/Lon coördinates of Domoticz are inserted in a HTTP request to the epsg.io API and the x, y coördinates are,
in case of a valid response, stored in a Node-RED flow variable.
If Node-RED is restarted or the flow is redeployed, the Lat/Lon data is collected and
a request to the (complex) new API of RIVM will be made.
It will require a bounding box, based on the x, y co-ordinates, which is set in the change node,
followed by a HTTP request node to RIVM API for "Stookwijzer".
The data is parsed from the response and only the data for the next 6 hours is used, together with the latest available time,
wind speed and LKI.
To use it, do the following:
1. Create a "Dummy" device (does nothing) and a virtual sensor of the type "Alert".
Note the idx number of this sensor.
2. Insert the IP address of your Domoticz device, including the used port number.
3. Insert the noted idx number in the first line of the "Function" node (before the MQTT-Out node.
4. Configure your MQTT node.
The data is collected from the RIVM API every 6 hours and so we need a timer, that triggers the lower part of the flow every 6 hours.
The "node-red-contrib-cron-plus" node is used for this. So install that one with the "Palette Manager".
Finally:
Burn your wood in a responsible way.
Regards
The flow:
Code: Select all
[
{
"id": "a446df5948eb661c",
"type": "tab",
"label": "Stookwijzer",
"disabled": false,
"info": "",
"env": []
},
{
"id": "df3ceeac39b0a9a0",
"type": "http request",
"z": "a446df5948eb661c",
"name": "HTTP Domoticz",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://{{{ip}}}/json.htm?type=command¶m=getsettings",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 500,
"y": 100,
"wires": [
[
"634a641fea351fa6"
]
]
},
{
"id": "ef4cc1c86321fc0f",
"type": "inject",
"z": "a446df5948eb661c",
"name": "Request Home Coordinates",
"props": [
{
"p": "ip",
"v": "192.168.1.1:8080",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"x": 240,
"y": 100,
"wires": [
[
"df3ceeac39b0a9a0"
]
]
},
{
"id": "634a641fea351fa6",
"type": "http request",
"z": "a446df5948eb661c",
"name": "HTTP EPSG",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://epsg.io/srs/transform/{{{payload.Location.Longitude}}},{{{payload.Location.Latitude}}}.json?key=default&s_srs=4326&t_srs=28992",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 770,
"y": 100,
"wires": [
[
"7a5b56b0404ba3de"
]
]
},
{
"id": "f12c06af180d0a52",
"type": "http request",
"z": "a446df5948eb661c",
"name": "Request RIVM Stookwijzer",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://data.rivm.nl/geo/alo/wms?service=WMS&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetFeatureInfo&FORMAT=image/png&TRANSPARENT=true&QUERY_LAYERS=stookwijzer_v2&LAYERS=stookwijzer_v2&servicekey=82b124ad-834d-4c10-8bd0-ee730d5c1cc8&STYLES=&BUFFER=1&EXCEPTIONS=INIMAGE&info_format=application/json&feature_count=1&I=139&J=222&WIDTH=256&HEIGHT=256&CRS=EPSG:28992&BBOX={{{x_min}}}%2C{{{y_min}}}%2C{{{x_max}}}%2C{{{y_max}}}",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 720,
"y": 180,
"wires": [
[
"38741d8f4c1483f3"
]
]
},
{
"id": "38741d8f4c1483f3",
"type": "function",
"z": "a446df5948eb661c",
"name": "Prepare Domoticz",
"func": "let idx = 123;\nlet runtime = msg.payload.features[0].properties.model_runtime;\nlet lki = msg.payload.features[0].properties.lki.toString();\nlet wind = msg.payload.features[0].properties.wind_bft.toString();\nlet level = msg.payload.features[0].properties.advies_0 + 2;\n\nmsg.payload = { \"command\": \"udevice\", \"idx\": idx, \"nvalue\": level, \"svalue\": \"Laatst bijgewerkt: \" + runtime + \"\\nWindsnelheid: \" + wind + \" Bft.\\nLKI: \" + lki };\n\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 990,
"y": 180,
"wires": [
[
"b871d94dc598d43e"
]
]
},
{
"id": "b871d94dc598d43e",
"type": "mqtt out",
"z": "a446df5948eb661c",
"name": "To Domoticz",
"topic": "domoticz/in",
"qos": "0",
"retain": "false",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "f8a872af.a6898",
"x": 1230,
"y": 180,
"wires": []
},
{
"id": "f0682fef54f8b981",
"type": "change",
"z": "a446df5948eb661c",
"name": "Set bbox",
"rules": [
{
"t": "set",
"p": "x_min",
"pt": "msg",
"to": "x_min",
"tot": "flow"
},
{
"t": "set",
"p": "y_min",
"pt": "msg",
"to": "y_min",
"tot": "flow"
},
{
"t": "set",
"p": "x_max",
"pt": "msg",
"to": "x_min + 10",
"tot": "jsonata"
},
{
"t": "set",
"p": "y_max",
"pt": "msg",
"to": "y_min + 10",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 480,
"y": 180,
"wires": [
[
"f12c06af180d0a52"
]
]
},
{
"id": "f6587744b1ba764e",
"type": "cronplus",
"z": "a446df5948eb661c",
"name": "Request Stookwijzer every 6 h",
"outputField": "payload",
"timeZone": "",
"storeName": "",
"commandResponseMsgOutput": "output1",
"defaultLocation": "52.17928818043169 5.606535673141479",
"defaultLocationType": "fixed",
"outputs": 1,
"options": [
{
"name": "schedule1",
"topic": "morning",
"payloadType": "default",
"payload": "",
"expressionType": "cron",
"expression": "0 0 10 * * *",
"location": "",
"offset": "0",
"solarType": "all",
"solarEvents": "sunrise,sunset"
},
{
"name": "schedule2",
"topic": "afternoon",
"payloadType": "default",
"payload": "",
"expressionType": "cron",
"expression": "0 0 16 * * *",
"location": "",
"offset": "0",
"solarType": "all",
"solarEvents": "sunrise,sunset"
},
{
"name": "schedule3",
"topic": "evening",
"payloadType": "default",
"payload": "",
"expressionType": "cron",
"expression": "0 0 22 * * *",
"location": "",
"offset": "0",
"solarType": "all",
"solarEvents": "sunrise,sunset"
},
{
"name": "schedule4",
"topic": "night",
"payloadType": "default",
"payload": "",
"expressionType": "cron",
"expression": "0 0 4 * * *",
"location": "",
"offset": "0",
"solarType": "all",
"solarEvents": "sunrise,sunset"
}
],
"x": 230,
"y": 180,
"wires": [
[
"f0682fef54f8b981"
]
]
},
{
"id": "7a5b56b0404ba3de",
"type": "switch",
"z": "a446df5948eb661c",
"name": "Check Response",
"property": "statusCode",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "200",
"vt": "num"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 990,
"y": 100,
"wires": [
[
"41cb4bfd4ef8fc89"
]
]
},
{
"id": "41cb4bfd4ef8fc89",
"type": "change",
"z": "a446df5948eb661c",
"name": "Store x and y",
"rules": [
{
"t": "set",
"p": "x_min",
"pt": "flow",
"to": "payload.results[0].x",
"tot": "msg"
},
{
"t": "set",
"p": "y_min",
"pt": "flow",
"to": "payload.results[0].y",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1220,
"y": 100,
"wires": [
[
"f0682fef54f8b981"
]
]
},
{
"id": "f8a872af.a6898",
"type": "mqtt-broker",
"name": "Jonas_MQTT_Server",
"broker": "mqtt.jonasnet.nl",
"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": ""
}
]