Hello everyone,
As promised in the tutorial by @mutmut: (Thanks to him for this tutorial)
And following my tutorial that allows retrieving off-peak rates:
I wanted to see how to automate the retrieval of the different costs.
I then came across this Jeedom tutorial (Thanks to its author), which I heavily drew inspiration from, including copying the Node-RED code:
The goal here is to retrieve the PDF file of the Tempo tariff grid directly from the EDF website to update the values directly in Gladys and have the real cost per kWh ready to use in other scenes ![]()
The file can be found here:
https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf
We just have to hope that the structure/composition of the file is not changed by EDF ![]()
The final result:

Here is the Node-Red flow:
(An error catch is present to retrieve errors and send them by email)
[
{
"id": "670838a9edef0758",
"type": "catch",
"z": "d6333988d9cfb817",
"name": "Errors",
"scope": null,
"uncaught": false,
"x": 110,
"y": 60,
"wires": [
[
"c097dad994334b5e"
]
]
},
{
"id": "c097dad994334b5e",
"type": "e-mail",
"z": "d6333988d9cfb817",
"server": "myemailserver",
"port": "465",
"authtype": "BASIC",
"saslformat": false,
"token": "oauth2Response.access_token",
"secure": true,
"tls": true,
"name": "myaddress@email.fr",
"dname": "Mail",
"x": 250,
"y": 60,
"wires": []
},
{
"id": "bf708d78a507d9c3",
"type": "http request",
"z": "d6333988d9cfb817",
"name": "",
"method": "GET",
"ret": "bin",
"paytoqs": "ignore",
"url": "https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 430,
"y": 140,
"wires": [
[
"c6602cec6bea28ca"
]
]
},
{
"id": "c6602cec6bea28ca",
"type": "file",
"z": "d6333988d9cfb817",
"name": "",
"filename": "/tmp/Grille_prix_Tarif_Bleu.pdf",
"filenameType": "str",
"appendNewline": true,
"createDir": false,
"overwriteFile": "true",
"encoding": "none",
"x": 290,
"y": 200,
"wires": [
[
"866bd16b214c1d1d"
]
]
},
{
"id": "a0349e7017779b4a",
"type": "change",
"z": "d6333988d9cfb817",
"name": "Text",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "payload.text",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 670,
"y": 200,
"wires": [
[
"d23eb75a79c8996d"
]
]
},
{
"id": "d23eb75a79c8996d",
"type": "function",
"z": "d6333988d9cfb817",
"name": "After \"Option Tempo\"",
"func": "const regex = /Option Tempo((.|\\n)*)/gm;\nconst found = msg.payload.match(regex);\nmsg.payload = found[0];\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 480,
"y": 280,
"wires": [
[
"09faecd167fed230"
]
]
},
{
"id": "09faecd167fed230",
"type": "function",
"z": "d6333988d9cfb817",
"name": "6 kVA",
"func": "const regex = /^12\b.*$/gm; // subscribed power\nconst found = msg.payload.match(regex);\nconst searchRegExp = /,/g; // replace commas with dots\nconst replaceWith = '.';\nmsg.payload = found[0];\nmsg.payload = msg.payload.replace(searchRegExp, replaceWith);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 670,
"y": 280,
"wires": [
[
"e7ca8ee4d891c581"
]
]
},
{
"id": "e7ca8ee4d891c581",
"type": "split",
"z": "d6333988d9cfb817",
"name": "",
"splt": " ",
"spltType": "str",
"arraySplt": 1,
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 510,
"y": 360,
"wires": [
[
"9f3df8ae0bd5d4bf"
]
]
},
{
"id": "9f3df8ae0bd5d4bf",
"type": "join",
"z": "d6333988d9cfb817",
"name": "",
"mode": "custom",
"build": "array",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": false,
"timeout": "",
"count": "",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "num",
"reduceFixup": "",
"x": 650,
"y": 360,
"wires": [
[
"88eaf52f02be48c8"
]
]
},
{
"id": "88eaf52f02be48c8",
"type": "function",
"z": "d6333988d9cfb817",
"name": "JSON",
"func": "msg.payload = {\n \"power\": msg.payload[0],\n \"subscription_price\": Number((Number(msg.payload[1]) * 12).toFixed(2)),\n \"HCJB_price\": Number(Number(msg.payload[2] / 100).toFixed(4)),\n \"HPJB_price\": Number(Number(msg.payload[3] / 100).toFixed(4)),\n \"HCJW_price\": Number(Number(msg.payload[4] / 100).toFixed(4)),\n \"HPJW_price\": Number(Number(msg.payload[5] / 100).toFixed(4)),\n \"HCJR_price\": Number(Number(msg.payload[6] / 100).toFixed(4)),\n \"HPJR_price\": Number(Number(msg.payload[7] / 100).toFixed(4)),\n}\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 790,
"y": 360,
"wires": [
[
"6e2b78e27c34c026",
"4d19e36f157bd2c0",
"50608e9e9bdecdc6",
"d9fe4a5ac7c52d90",
"b4a2b0d2177a9058",
"c5f9959555f3e7b9"
]
]
},
{
"id": "1316dbce795332d5",
"type": "inject",
"z": "d6333988d9cfb817",
"name": "Every day at 9:30 AM",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "30 09 * * *",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 220,
"y": 140,
"wires": [
[
"bf708d78a507d9c3"
]
]
},
{
"id": "866bd16b214c1d1d",
"type": "pdfparse",
"z": "d6333988d9cfb817",
"name": "",
"path": "/tmp/Grille_prix_Tarif_Bleu.pdf",
"x": 520,
"y": 200,
"wires": [
[
"a0349e7017779b4a"
]
]
},
{
"id": "6e2b78e27c34c026",
"type": "function",
"z": "d6333988d9cfb817",
"name": "Blue day HC",
"func": "msg.payload = msg.payload.HCJB_price;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 960,
"y": 300,
"wires": [
[
"0a6e473635b8b423"
]
]
},
{
"id": "4d19e36f157bd2c0",
"type": "function",
"z": "d6333988d9cfb817",
"name": "Blue day HP",
"func": "msg.payload = msg.payload.HPJB_price;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 960,
"y": 340,
"wires": [
[
"69c1fb09c3ede0e0"
]
]
},
{
"id": "50608e9e9bdecdc6",
"type": "function",
"z": "d6333988d9cfb817",
"name": "White day HC",
"func": "msg.payload = msg.payload.HCJW_price;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 970,
"y": 380wires": [
[
"467f6ce03f7ed6c0"
]
]
},
{
"id": "d9fe4a5ac7c52d90",
"type": "function",
"z": "d6333988d9cfb817",
"name": "White day HP",
"func": "msg.payload = msg.payload.prix_HPJW;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 970,
"y": 420,
"wires": [
[
"ed628e4d71dbbc38"
]
]
},
{
"id": "b4a2b0d2177a9058",
"type": "function",
"z": "d6333988d9cfb817",
"name": "Red day HC",
"func": "msg.payload = msg.payload.prix_HCJR;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 970,
"y": 460,
"wires": [
[
"f2b3869570196614"
]
]
},
{
"id": "c5f9959555f3e7b9",
"type": "function",
"z": "d6333988d9cfb817",
"name": "Red day HP",
"func": "msg.payload = msg.payload.prix_HPJR;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 970,
"y": 500,
"wires": [
[
"ae1d548f6cb679aa"
]
]
},
{
"id": "0a6e473635b8b423",
"type": "mqtt out",
"z": "d6333988d9cfb817",
"name": "",
"topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-bleu-hc/state",
"qos": "2",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "0ee77e0f90aa9681",
"x": 1370,
"y": 300,
"wires": []
},
{
"id": "69c1fb09c3ede0e0",
"type": "mqtt out",
"z": "d6333988d9cfb817",
"name": "",
"topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-bleu-hp/state",
"qos": "2",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "0ee77e0f90aa9681",
"x": 1370,
"y": 340,
"wires": []
},
{
"id": "467f6ce03f7ed6c0",
"type": "mqtt out",
"z": "d6333988d9cfb817",
"name": "",
"topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-blanc-hc/state",
"qos": "2",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "0ee77e0f90aa9681",
"x": 1370,
"y": 380,
"wires": []
},
{
"id": "ed628e4d71dbbc38",
"type": "mqtt out",
"z": "d6333988d9cfb817",
"name": "",
"topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-blanc-hp/state",
"qos": "2",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "0ee77e0f90aa9681",
"x": 1370,
"y": 420,
"wires": []
},
{
"id": "f2b3869570196614",
"type": "mqtt out",
"z": "d6333988d9cfb817",
"name": "",
"topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-rouge-hc/state",
"qos": "2",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "0ee77e0f90aa9681",
"x": 1370,
"y": 460,
"wires": []
},
{
"id": "ae1d548f6cb679aa",
"type": "mqtt out",
"z": "d6333988d9cfb817",
"name": "",
"topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-rouge-hp/state",
"qos": "2",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "0ee77e0f90aa9681",
"x": 1370,
"y": 500,
"wires": []
},
{
"id": "0ee77e0f90aa9681",
"type": "mqtt-broker",
"name": "GLADYS-MQTT",
"broker": "mqtt://192.168.0.248",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"autoUnsubscribe": true,
"birthTopic": "",
"birthQos": "0",
"birthRetain": "false",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closeRetain": "false",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willRetain": "false",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
}
]
Don’t forget to modify the subscribed power ![]()
Prerequisites:
Install the node-red-contrib-pdfparse module:
Here is the MQTT device with the features:
Here are the scenes:
White day - HC:
White day - HP:
Blue day - HC:
Blue day - HP:
Red day - HC:
Red day - HP:
If you have any questions/comments, feel free to let me know ![]()
Changelog to come:
- None (Your comments
)



































