Electricity Day Ahead Prices for Home Assistant using Node-Red and Entso-E API

I was interested to get the day ahead electricity prices in Finland into Home Assistant, but I found it quite difficult to find any ready made complete instructions how to get the future prices into a graph like this.
image

My solution uses following componenents:
• Home Assistant
• Node-Red integration for Home Assistant
• MQTT broker (Mosquitto)
• ENTSO-E API https://transparency.entsoe.eu/ ,(you’ll need a personal API key to use it.: Static Content)
• Apexcharts for the visualization: https://github.com/RomRider/apexcharts-card

I’m defining the MQTT sensor in configuration.yaml as follows:

sensor:
    - platform: mqtt
    name: 'Day-ahead-price'
    unit_of_measurement: "€"
    state_topic: enstoe/day-ahead
    value_template: '{{ value_json.day_ahead_price }}'
    json_attributes_topic: enstoe/day-ahead

In node-red, I have a following flow, where I use the API to get the daily data just after midnight, and then I update the data to HA every hour.

image

Here are the codes for the function nodes:
Generate URL:

const today = new Date()
let todayDate = ("0" + today.getDate()).slice(-2)
let todayMonth = ("0" + (today.getMonth() + 1)).slice(-2);
let todayYear = today.getFullYear();
let todayString= todayYear+todayMonth +todayDate;

var urlAddr="https://transparency.entsoe.eu/api?securityToken=<YOUR SECURITY TOKEN>&documentType=A44&in_Domain=10YFI-1--------U&out_Domain=10YFI-1--------U&periodStart="+todayString+"0000&periodEnd="+todayString+"2300"
msg.url=urlAddr;
return msg;

Generate Array:

var priceArray=[];
for (let i=0; i<24 ; i++){
    priceArray[i]=msg.payload.Publication_MarketDocument.TimeSeries[0].Period[0].Point[i]["price.amount"][0];
}
flow.set("pArray", priceArray);
msg.payload= { "day_ahead_price": priceArray};
return msg ;

Get next hour price:

var priceArray=[];
priceArray=flow.get("pArray");
const today = new Date();
let todayHour = today.getHours();
let todayDate = ("0" + today.getDate()).slice(-2)
let todayMonth = ("0" + (today.getMonth() + 1)).slice(-2);
let todayYear = today.getFullYear();

msg.payload= { "day_ahead_price": priceArray[todayHour],
     "records": [
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T00:00:00",
              "Price": priceArray[0]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T01:00:00",
              "Price": priceArray[1]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T02:00:00",
              "Price": priceArray[2]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T03:00:00",
              "Price": priceArray[3]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T04:00:00",
              "Price": priceArray[4]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T05:00:00",
              "Price": priceArray[5]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T06:00:00",
              "Price": priceArray[6]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T07:00:00",
              "Price": priceArray[7]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T08:00:00",
              "Price": priceArray[8]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T09:00:00",
              "Price": priceArray[9]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T10:00:00",
              "Price": priceArray[10]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T11:00:00",
              "Price": priceArray[11]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T12:00:00",
              "Price": priceArray[12]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T13:00:00",
              "Price": priceArray[13]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T14:00:00",
              "Price": priceArray[14]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T15:00:00",
              "Price": priceArray[15]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T16:00:00",
              "Price": priceArray[16]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T17:00:00",
              "Price": priceArray[17]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T18:00:00",
              "Price": priceArray[18]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T19:00:00",
              "Price": priceArray[19]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T20:00:00",
              "Price": priceArray[20]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T21:00:00",
              "Price": priceArray[21]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T22:00:00",
              "Price": priceArray[22]
            },
            {
              "Time": todayYear+"-"+todayMonth+"-"+todayDate+"T23:00:00",
              "Price": priceArray[23]
            }
            ]
};
return msg ;

Mqtt node is configured like this:
image

As a result, you’ll get this data to Home Assistant every hour:

Then you may use the Apexcharts to visalize the daily data:

type: custom:apexcharts-card
graph_span: 24h
span:
  start: day
now:
  show: true
  label: Now
header:
  show: true
  title: FI Electricity spot price (€/MWh) (CET)
series:
  - entity: sensor.day_ahead_price
    stroke_width: 2
    type: area
    opacity: 0.3
    color: '#1007f0'
    data_generator: |
      return entity.attributes.records.map((record, index) => {
              return [record.Time, record.Price];
            });

My solution may not be the most elegant implmentation, but most importantly it seems to work :slight_smile:

10 Likes

Wanted to write to say that I appreciate you publishing this here! I used your approach to get my prices for sweden. I later switched the API for “tibber” which is my local provider to more accuratly get the prices in SEK. I also added the next days prices (attaching a screenshot).
We’ll see how well this works tomorrow as the prices for the next day are not published until 12:00. Yet to see :smiley: If its an empty right hand side of the graph its all good I guess.

Nice to hear that you got it working for your needs! :slight_smile:

1 Like

Nice work @Tontsa !

I have not used Node-Red before, so this is new to me… However, I think I have managed to configure it, up to a point, that is. Few problems seem to still exist:

  • How can I have the day-ahead prices as entities in Home Assistant? I’m using Mosquitto and I can see the values when listening the topic enstoe/day-ahead. Also MQTT Explorer sees it (MQTT Explorer is a handy client for monitoring MQTT, see http://mqtt-explorer.com/ ) However, I cannot see any entities created, even though I have enabled MQTT discovery (Mosquitto → Configure → Re-configure MQTT)
  • How do I configure timezone? I can monitor the values as explained above, but they seem to be off by 1 hour.

EDIT: Managed to get the readings to HA by configuring day-ahead sensor in configuration.yaml. However, MQTT integration (Mosquitto) does not see its as a device nor entities in it. This is probably because the node-red code does not send any configuration topic to HA, after which the process should be automatic. Is there a particular reason not arranging this configuration topic in the node-red sample?

The second issue is a pain in the a***. No matter how I try to configure the GET URL periodStart and periodEnd parameters in “generate url” block, there is always this 1 hour shift. Why is this? How to configure this?

What makes me even more puzzled is, that according to Transparency Platform RESTful API - user guide the time parameters are UTC. There is a difference of 3 hours to UTC from where I live, still it’s of by 1 hour??? Why is this?

Hello Tonsa,

Thank you very much for posting your code!
I’ve been fiddling with this api for a while and i couldn’t get it to work.

Do you know if there is a way to easily import the data from let’s say the last three months into an influxdb1.8 database?

I’ve set up the logging of the last hourly prices to influxdb with your flow, but i still have a few months of measurements i would like to compare.

End goal will be to see if i would be better off taking an hourly rate instead of a fixed tarrif.

Now, when i modify the url string e.g. as follows (only the relevant parts of url shown)

documentType=A44&in_Domain=10YFI-1--------U&out_Domain=10YFI-1--------U&periodStart=202208172300&periodEnd=202208182200

…and feed that into the browser URL for testing, I get as response an xml like this (just the beginning of the response shown):

<Publication_MarketDocument>
<script/>
<mRID>removed from this</mRID>
<revisionNumber>1</revisionNumber>
<type>A44</type>
<sender_MarketParticipant.mRID codingScheme="A01">10X1001A1001A450</sender_MarketParticipant.mRID>
<sender_MarketParticipant.marketRole.type>A32</sender_MarketParticipant.marketRole.type>
<receiver_MarketParticipant.mRID codingScheme="A01">10X1001A1001A450</receiver_MarketParticipant.mRID>
<receiver_MarketParticipant.marketRole.type>A33</receiver_MarketParticipant.marketRole.type>
<createdDateTime>2022-08-18T12:00:15Z</createdDateTime>
<period.timeInterval>
<start>2022-08-17T22:00Z</start>
<end>2022-08-18T22:00Z</end>
</period.timeInterval>
<TimeSeries>
<mRID>1</mRID>
<businessType>A62</businessType>
<in_Domain.mRID codingScheme="A01">10YFI-1--------U</in_Domain.mRID>
<out_Domain.mRID codingScheme="A01">10YFI-1--------U</out_Domain.mRID>
<currency_Unit.name>EUR</currency_Unit.name>
<price_Measure_Unit.name>MWH</price_Measure_Unit.name>
<curveType>A01</curveType>
<Period>
<timeInterval>
<start>2022-08-17T22:00Z</start>
<end>2022-08-18T22:00Z</end>
</timeInterval>
<resolution>PT60M</resolution>
<Point>
<position>1</position>
<price.amount>50.04</price.amount>
</Point>

Pls. pay attention to the lines:

<start>2022-08-17T22:00Z</start>
<end>2022-08-18T22:00Z</end>

In the url it was

periodStart=202208172300&periodEnd=202208182200

If I try to make the query with:

periodStart=202208172200&periodEnd=202208182100

I still get xml response with

<start>2022-08-17T22:00Z</start>
<end>2022-08-18T22:00Z</end>

Exactly the same as in first case. In other words, it does not care whjat i put here as start and end times. It just pushes back what it wants

WTF?

Hi, I picked up this post and tried to do the things you described.
But the node-red stuff is new and unknown to me. I installed node-red and was able to create some of the flows and functions but i’m missing the right pieces. I dont understand how to connect the node-red stuff to HA.
What kind of instructions do I have to fill in at “http request” and “xml”? can you provide me some screenshots how you build your code in node-red? That could be helpfull.
txs, Harold

“Node-Red code” is really more or less those flows Tontsa described. Just try to replicate them. The parameters and defs inside the most important blocks he has described there. What comes to http request, it is just a simple GET like this:

image

For xml I just let the block be what it is, like this

image

Seems to be working, as much those problems I described above are not considered, and which I think have nothing to do with http request and xml blocks.

However, what You did not ask, Tontsa did not fully explain and what I think is important, is to configure correctly that mqqt out block (purple block with text day_ahead_price on it. See that small green square with text “connected” underneath it? That tells it is configured correctly. Take a look of the picture he shared about it. Copy the texts to your block, but for the “mqtt broker”, press that little pen -icon on the right side of it and you get a window where to configure your mqtt. It is really only mqqt server ip and in the security tab your credentiasls to it.

You need to have a mqtt broker also installed into your HA, I (and probably everyone else) have Mosquitto.

You also need to do modify your configuration.yaml as Tontsa described to get your mqqt sensors visible in HA. I think it should be done otyherwise, but that probably needs some additional blocks of node-red stuf, and I take a look on those later. Or just leave it as it is…

BTW, in “generate url” block the address is not anymore

"https://transparency.entsoe.eu/api...

it is like nowadays

"https://web-api.tp.entsoe.eu/api...

The old address, however, still works, but there might be some other changes in the protocol, I’m in the process of trying to get a hold of them. It really does not help. that entso-e api documentation seems to be old and probably outdated at some parts.

Answer to my own question of why I’m getting data sets only 22:00UTC-22:00UTC the next day is, that this has been limited to that by BNZ|FI data provider. This information comes from ENTSO-E service desk.

This means, whatever I try to query for, it responses with set 22:00 UTC-22:00 UTC the next day.

From Restful API guide:

Also in the response, time is always expressed in UTC. System returns both partially and exactly matching data. Amount of returned data depends on regulation article. For example, a query for one day of a weekly forecast will always return a whole week. Likewise, if the requested time interval in a query for a day-ahead forecast covers the last hours of one day and the first hours of the following day, the response will contain complete data for both days.

For the following regulation articles the query response will contain data for a whole day (or a multiple of days, depending on the length of the requested time interval): 6.1.b, 12.1.b, 12.1.d, 12.1.f, 14.1.c and 14.1.d. For the following regulation articles, the query response will contain data for the requested MTU or BTU period(s): 6.1.a, 12.1.g, 16.1.a, 16.1.b&c, 17.1.d-h and 17.1.j.

Combined with 22:00 UTC- 22:00 UTC limitation, we get one or more records of 24 positions depending on the length of the dateframe set by periodStart and periodEnd parameters.

E.g. with te following:

...&periodStart=202208180000&periodEnd=202208192300

we will get data for 18.8. and 19.8. However, due to dataset limitation to 22:00UTC-22:00UTC the next day, we will actually get data starting from 17.8 at 22:00 UTC and ending 19:8 at 22:00 UTC. This data is represented in xml listing all 24 datapoints and each date having its own xml chart in the same record.

Now if you change the

periodStart=202208172300,

You will get exactly the same data set. Also for

periodStart=2202208172200

You will get the same set.
BUT, with the

periodStart=202208172100

it goes “under” the dataset limit, resulting in record starting with 16.8 at 22:00UTC and further resulting in 3 xml charts in a record instead of 2.

Well, this should be just fine in the wintertime, when the timezone difference is UTC+2, BUT in the DST (summertime) time is actually UTC+3, causing datasets to start with a value of 1:00 EEST, instead of 0:00 EET

This is the case with Finland. For other areas, You need to test the query and see what it returns.

What we need, is actually a routine that during DST parses the 24 hours price data from 2 different dates. These can be queried at the same query or divided to 2 different queries, whichever is easier to implement.

Now, I’m not much of a coder (anymore that is, some 30 years ago used to do lots of robot & PLC programming), so are there anyone who could try to make the missing routines for node-red?

Txs! that helped.
I now see some data comming out of the node-red routine by debugging.
However, still no data in HA. But I guess that has something to do with the configuration.yaml file.
I noticed that the integration package doesn’t accept changes in configuration.yaml like Tontsa reported. The integration package does its own config. So I have to find out how to change that config.

I’ve it working now. txs for the help.
Now figuring out how to do some calculations since I need min/max and avg prices to act on.
If someone has some tips, be so kind to share them with me.

I now see some data comming out of the node-red routine by debugging.
However, still no data in HA. But I guess that has something to do with the configuration.yaml file.

Did you add those lines Tontsa described in your configuratiojn.yaml?

sensor:
    - platform: mqtt
    name: 'Day-ahead-price'
    unit_of_measurement: "€"
    state_topic: enstoe/day-ahead
    value_template: '{{ value_json.day_ahead_price }}'
    json_attributes_topic: enstoe/day-ahead

However, it’s according to the legacy format, nowadays it should be more liket this (copy from my own):

mqtt:
  sensor:
    - name:  'Day-ahead-price'
      unit_of_measurement: "c/kWh"
      state_topic: entsoe/day-ahead
      value_template: '{{ value_json.day_ahead_price }}'
      json_attributes_topic: entsoe/day-ahead

Pls also note that Tontsa has used name “enstoe” in many places, even though it is just a name of the parameter, it should be written exactly the same way in all the configs. E.g. I have translated that to “entsoe”, which probabaly was the purpose and “enstoe” is just a misspelling in his config

Ansewering again my own question, I did the changes myself to handel the EEST/DST. Requires some fiddling in generating arrays and then also parseing the required data in Get next hour price -block. Nothing fancy, just raw work. Maybe some coder would make cleaner work, but I made it work for my purpose. This is really something everyone should tailor to one’s own needs

Now figuring out how to do some calculations since I need min/max and avg prices to act on.
If someone has some tips, be so kind to share them with me.

For min and max You can add into the “Get next hour” block the following before the line msg.payload = {...

max_today = (Math.max(...priceArray));
min_today = (Math.min(...priceArray));

Then after that payload line and before "records": [... add

    "max_today": max_today,
    "min_today": min_today,

You can probably combine those mins and maxs to one line for each, but you can tidy up that yourself, if you wish. Wirh those max_today and min_today (and all the variables, if that matters) You need to think how/where to use them, so check keywoards, let, var and const

Care to share the changes needed? Struggling with same problem and I’m not a much of a coder to be honest so pretty much stuck at the moment.

Well, I am not a coder either. This is actually my first attempt with node-red to do something… I did automation programming almost some 30 years ago for my living, though.

Pls. note that the following is just done to meet my requirements, and I have not bothered much tidying it up. Some real programmer might do much more elegant work. I really don’t have much time, so let’s get to it.

Mine looks like this now. Includes more or less various tinkering especially with delays trying to get web http requests timed right.

The middle section is to generate the url, make the http requests and generate arrays.

Because I need data for today and tomorrow (tomorrow values are usually published in the afternoon) and taking into notice (described earlier) that ENTSO-E returns my area values 22:00 the previous day to 22:00 to current day, I actually need to parse the correct arrays from data over 3 days to get what I want. This is something that depends on your area, timezone and DST, and you need to test it and refer to the ENTSO-E API documentation ( Static Content )

In the middle there is also a catch block for the situation where tomorrow data is not yet published and it fills the tomorrow values with zeros until the real data is got. Basically , if the “generate tomorrow array” returns an error, which it does if no data published yet, it is caught by “catch” block, which generates the “tomorrow empty array”, which again is not actually empty, but filled with zeros.

The lowest group is for DST. Block “Check DST true” checks whether your time is DST and if so, it the takes the upper (DST = true) route. Otherwise the lower one. For this I have us the red block, which actually is not installed by default, but you can get it as a part of this package: node-red-contrib-boolean-logic-ultimate (node) - Node-RED Maybe some native block can do it as well, but I used this.

In the end there those day-ahead price and msg payload blocks from original poster.

Now, the impulses and delays in the beginning

On the top left corner I have those 3 blocks (switch not needed) is to run updating the data after HA restarts with 10 sec delay

Impulse in the middle triggers the http requests and others in the chain past midnight

Lowest chain of blocks is triggered hourly.

What comes to delays, they attempt to give http requests time before updating. Those leads coming and going to delay blocks are to prepare to various situations requiring updating and you can tinker with them to meet your needs.

Some information on the used blocks I put to another post later today.

1 Like

image

image

const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1);
let yesterdayDate = ("0" + yesterday.getDate()).slice(-2)
let yesterdayMonth = ("0" + (yesterday.getMonth() + 1)).slice(-2);
let yesterdayYear = yesterday.getFullYear();
let yesterdayString = yesterdayYear + yesterdayMonth + yesterdayDate;
var urlAddry = "https://web-api.tp.entsoe.eu/api?securityToken=PUT_YOUR_OWN_TOKEN_HERE&documentType=A44&in_Domain=10YFI-1--------U&out_Domain=10YFI-1--------U&periodStart="+yesterdayString+"0000&periodEnd="+yesterdayString+"2200"
msg.url = urlAddry;
return msg;

image

const today = new Date()
let todayDate = ("0" + today.getDate()).slice(-2)
let todayMonth = ("0" + (today.getMonth() + 1)).slice(-2);
let todayYear = today.getFullYear();
let todayString = todayYear + todayMonth + todayDate;
var urlAddr = "https://web-api.tp.entsoe.eu/api?securityToken=PUT_YOUR_OWN_TOKEN_HERE&documentType=A44&in_Domain=10YFI-1--------U&out_Domain=10YFI-1--------U&periodStart="+todayString+"0000&periodEnd="+todayString+"2300"
msg.url = urlAddr;
return msg;

image

const tomorrow = new Date()
tomorrow.setDate(tomorrow.getDate() + 1);
let tomorrowDate = ("0" + tomorrow.getDate()).slice(-2)
let tomorrowMonth = ("0" + (tomorrow.getMonth() + 1)).slice(-2);
let tomorrowYear = tomorrow.getFullYear();
let tomorrowString = tomorrowYear + tomorrowMonth + tomorrowDate;
var urlAddrt = "https://web-api.tp.entsoe.eu/api?securityToken=PUT_YOUR_OWN_TOKEN_HERE&documentType=A44&in_Domain=10YFI-1--------U&out_Domain=10YFI-1--------U&periodStart="+tomorrowString+"0000&periodEnd="+tomorrowString+"2200"
msg.url = urlAddrt;
return msg;

Pls. note that all blocks use start and end time values starting from 0:00. Like explained earlier, it does not rally matter, because the server will return you 22:00-22:00 anyway… :slight_smile:

1 Like

image

In the same order:

var ypriceArray = [];
for (let i = 0; i < 24; i++) {
    ypriceArray[i] = Math.round(100 * (0.21 + 2.79372 +4.56+0.1*1.24*(msg.payload.Publication_MarketDocument.TimeSeries[0].Period[0].Point[i]["price.amount"][0])))/100;
}
flow.set("ypArray", ypriceArray);
msg.payload = { "yday_ahead_price": ypriceArray };
return msg;
var priceArray = [];
for (let i = 0; i < 24; i++) {
    priceArray[i] = Math.round(100 * (0.21 + 2.79372 + 4.56 + 0.1 * 1.24 *(msg.payload.Publication_MarketDocument.TimeSeries[0].Period[0].Point[i]["price.amount"][0]))) / 100;
}
flow.set("pArray", priceArray);
msg.payload = { "day_ahead_price": priceArray };
return msg;
var tpriceArray = [];
    for (let i = 0; i < 24; i++) {
        tpriceArray[i] = Math.round(100 * (0.21 + 2.79372 + 4.56 + 0.1 * 1.24 *(msg.payload.Publication_MarketDocument.TimeSeries[0].Period[0].Point[i]["price.amount"][0]))) / 100;
    }
flow.set("tpArray", tpriceArray);
msg.payload = { "tday_ahead_price": tpriceArray };
return msg;
var tpriceArray = [];
    for (let i = 0; i < 24; i++) {
        tpriceArray[i] = 0
    }
flow.set("tpArray", tpriceArray);
msg.payload = { "tday_ahead_price": tpriceArray };
return msg;

Pls. note that here: Math.round(100 * (0.21 + 2.79372 + 4.56 + 0.1 * 1.24 *(msg.payload.Publication_MarketDocument.TimeSeries[0].Period[0].Point[i]["price.amount"][0]))) / 100;

I have various other kWh-based costs like electricity company marginal (0.21), tax (2.79372), transfer company fee (4.56) + then some scaling and the VAT (1.24).

This means my arrays have all the kWh-based costs, you need to do your own stuff here.

image
image

if (new Date().getTimezoneOffset() < 0) {
  msg.payload = true;
}
else {
  msg.paylaod = false;
}
return msg;

image

image

In the same order:

var priceArray = [];
var ypriceArray = [];
var tpriceArray = [];
var c_day_ahead_price;
var max_today;
var min_today;
priceArray = flow.get("pArray");
ypriceArray = flow.get("ypArray");
tpriceArray = flow.get("tpArray");
const today = new Date();
let todayHour = today.getHours();
let todayDate = ("0" + today.getDate()).slice(-2)
let todayMonth = ("0" + (today.getMonth() + 1)).slice(-2);
let todayYear = today.getFullYear();
const tomorrow = new Date()
tomorrow.setDate(tomorrow.getDate() + 1);
let tomorrowDate = ("0" + tomorrow.getDate()).slice(-2)
let tomorrowMonth = ("0" + (tomorrow.getMonth() + 1)).slice(-2);
let tomorrowYear = tomorrow.getFullYear();
let tomorrowString = tomorrowYear + tomorrowMonth + tomorrowDate;

max_today = (Math.max(...priceArray, ypriceArray[23]));
min_today = (Math.min(...priceArray, ypriceArray[23]));

if (todayHour < 1) {
    c_day_ahead_price = ypriceArray[23];
} else {
    c_day_ahead_price = priceArray[todayHour - 1];
}

msg.payload = {

    "day_ahead_price": c_day_ahead_price,
    "max_today": max_today,
    "min_today": min_today,

    "records": [
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T00:00:00",
            "Price": ypriceArray[23]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T01:00:00",
            "Price": priceArray[0]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T02:00:00",
            "Price": priceArray[1]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T03:00:00",
            "Price": priceArray[2]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T04:00:00",
            "Price": priceArray[3]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T05:00:00",
            "Price": priceArray[4]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T06:00:00",
            "Price": priceArray[5]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T07:00:00",
            "Price": priceArray[6]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T08:00:00",
            "Price": priceArray[7]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T09:00:00",
            "Price": priceArray[8]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T10:00:00",
            "Price": priceArray[9]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T11:00:00",
            "Price": priceArray[10]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T12:00:00",
            "Price": priceArray[11]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T13:00:00",
            "Price": priceArray[12]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T14:00:00",
            "Price": priceArray[13]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T15:00:00",
            "Price": priceArray[14]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T16:00:00",
            "Price": priceArray[15]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T17:00:00",
            "Price": priceArray[16]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T18:00:00",
            "Price": priceArray[17]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T19:00:00",
            "Price": priceArray[18]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T20:00:00",
            "Price": priceArray[19]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T21:00:00",
            "Price": priceArray[20]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T22:00:00",
            "Price": priceArray[21]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T23:00:00",
            "Price": priceArray[22]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T00:00:00",
            "Price": priceArray[23]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T01:00:00",
            "Price": tpriceArray[0]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T02:00:00",
            "Price": tpriceArray[1]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T03:00:00",
            "Price": tpriceArray[2]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T04:00:00",
            "Price": tpriceArray[3]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T05:00:00",
            "Price": tpriceArray[4]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T06:00:00",
            "Price": tpriceArray[5]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T07:00:00",
            "Price": tpriceArray[6]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T08:00:00",
            "Price": tpriceArray[7]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T09:00:00",
            "Price": tpriceArray[8]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T10:00:00",
            "Price": tpriceArray[9]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T11:00:00",
            "Price": tpriceArray[10]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T12:00:00",
            "Price": tpriceArray[11]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T13:00:00",
            "Price": tpriceArray[12]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T14:00:00",
            "Price": tpriceArray[13]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T15:00:00",
            "Price": tpriceArray[14]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T16:00:00",
            "Price": tpriceArray[15]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T17:00:00",
            "Price": tpriceArray[16]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T18:00:00",
            "Price": tpriceArray[17]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T19:00:00",
            "Price": tpriceArray[18]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T20:00:00",
            "Price": tpriceArray[19]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T21:00:00",
            "Price": tpriceArray[20]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T22:00:00",
            "Price": tpriceArray[21]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T23:00:00",
            "Price": tpriceArray[22]
        }
    ]
};
return msg;
var priceArray = [];
var tpriceArray = [];
var max_today;
var min_today;
priceArray = flow.get("pArray");
const today = new Date();
let todayHour = today.getHours();
let todayDate = ("0" + today.getDate()).slice(-2)
let todayMonth = ("0" + (today.getMonth() + 1)).slice(-2);
let todayYear = today.getFullYear();
const tomorrow = new Date()
tomorrow.setDate(tomorrow.getDate() + 1);
let tomorrowDate = ("0" + tomorrow.getDate()).slice(-2)
let tomorrowMonth = ("0" + (tomorrow.getMonth() + 1)).slice(-2);
let tomorrowYear = tomorrow.getFullYear();
let tomorrowString = tomorrowYear + tomorrowMonth + tomorrowDate;

max_today = (Math.max(...priceArray));
min_today = (Math.min(...priceArray));

msg.payload = {
    "day_ahead_price": priceArray[todayHour],
    "max_today": max_today,
    "min_today": min_today,
    "records": [
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T00:00:00",
            "Price": priceArray[0]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T01:00:00",
            "Price": priceArray[1]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T02:00:00",
            "Price": priceArray[2]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T03:00:00",
            "Price": priceArray[3]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T04:00:00",
            "Price": priceArray[4]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T05:00:00",
            "Price": priceArray[5]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T06:00:00",
            "Price": priceArray[6]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T07:00:00",
            "Price": priceArray[7]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T08:00:00",
            "Price": priceArray[8]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T09:00:00",
            "Price": priceArray[9]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T10:00:00",
            "Price": priceArray[10]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T11:00:00",
            "Price": priceArray[11]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T12:00:00",
            "Price": priceArray[12]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T13:00:00",
            "Price": priceArray[13]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T14:00:00",
            "Price": priceArray[14]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T15:00:00",
            "Price": priceArray[15]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T16:00:00",
            "Price": priceArray[16]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T17:00:00",
            "Price": priceArray[17]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T18:00:00",
            "Price": priceArray[18]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T19:00:00",
            "Price": priceArray[19]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T20:00:00",
            "Price": priceArray[20]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T21:00:00",
            "Price": priceArray[21]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T22:00:00",
            "Price": priceArray[22]
        },
        {
            "Time": todayYear + "-" + todayMonth + "-" + todayDate + "T23:00:00",
            "Price": priceArray[23]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T00:00:00",
            "Price": tpriceArray[0]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T01:00:00",
            "Price": tpriceArray[1]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T02:00:00",
            "Price": tpriceArray[2]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T03:00:00",
            "Price": tpriceArray[3]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T04:00:00",
            "Price": tpriceArray[4]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T05:00:00",
            "Price": tpriceArray[5]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T06:00:00",
            "Price": tpriceArray[6]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T07:00:00",
            "Price": tpriceArray[7]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T08:00:00",
            "Price": tpriceArray[8]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T09:00:00",
            "Price": tpriceArray[9]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T10:00:00",
            "Price": tpriceArray[10]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T11:00:00",
            "Price": tpriceArray[11]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T12:00:00",
            "Price": tpriceArray[12]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T13:00:00",
            "Price": tpriceArray[13]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T14:00:00",
            "Price": tpriceArray[14]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T15:00:00",
            "Price": tpriceArray[15]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T16:00:00",
            "Price": tpriceArray[16]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T17:00:00",
            "Price": tpriceArray[17]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T18:00:00",
            "Price": tpriceArray[18]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T19:00:00",
            "Price": tpriceArray[19]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T20:00:00",
            "Price": tpriceArray[20]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T21:00:00",
            "Price": tpriceArray[21]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T22:00:00",
            "Price": tpriceArray[22]
        },
        {
            "Time": tomorrowYear + "-" + tomorrowMonth + "-" + tomorrowDate + "T23:00:00",
            "Price": tpriceArray[23]
        }
    ]
};
return msg;

Try with these.

2 Likes

Thanks mekanics! I was online waiting for this post :wink:

Do you have guidance for pushing data from array to node-red dashboard chart?
I have not managed to produce correct format for dashboard chart.
There is some additional information in the data that is likely mixing my array.
I would like to get only next day hourly prices, I do not need anything else.

I’m afraid that I cannot help you with that. My solution, based on the original poster’s one, is pushing data to MQTT, which is then used in HA and visualized with Apex charts

And the current value is of course used in various automations to control things.