Same problem with no price for tomorrow. ENERGY USEAGE SENSOR is a Tibber entity that displays monthly usage.
Mind exporting your flow and share?
I don’t see that I have that sensor. Maybe it comes with their HAN port reader? I am using my own ESPHome based.
The reason the graph does not show tomorrow I think must be because the script returns today’s price immediately and that the second return is just dead code. I’m guessing the arrays new to be combined before returning.
oh, sorry I didn’t notice, it’s not a tibber sensor, I get this from discovergy integration.
I see that tibber is reporting consumption for me in this sensor:
- platform: rest
name: Tibber consumption
resource: https://api.tibber.com/v1-beta/gql
method: POST
scan_interval: 60
payload: '{ "query": "{viewer{homes{consumption(resolution: HOURLY, last: 24) { nodes {from cost consumption}}}}}" }'
json_attributes_path: "$.data.viewer.homes[0].consumption"
json_attributes:
- nodes
value_template: Ok
headers:
Authorization: "**[APIKEY]**"
Content-Type: application/json
User-Agent: REST
and apex config:
type: custom:apexcharts-card
apex_config:
chart:
height: 500px
header:
show: true
title: Energy stats
show_states: true
colorize_states: true
now:
show: true
color: white
label: NOW
hours_12: false
graph_span: 24h
span:
start: day
yaxis:
- id: kWh
decimals: 2
opposite: true
apex_config:
tickAmount: 4
- id: EUR
decimals: 2
series:
- entity: sensor.tibber_consumption
type: column
show:
extremas: true
name: Usage
float_precision: 2
stroke_width: 2
color: '#64511c'
opacity: 0.3
yaxis_id: kWh
group_by:
func: avg
duration: 15min
data_generator: |
var a = entity.attributes.nodes.map((entry) => {
return [new Date(entry.from), entry.consumption];
});
return a;
if that works for you too, you could put the 2 things together
No probs It can easily be made by e.g. an utility meter. What kind of data does it provide? Is it hourly, daily or monthly accumulated consumption in kwh? I wonder as when I added one of the sensors I do have (total kwh on the meter from like forever) it did not seem to divide this data into hourly sections but rather just present the value at each hour.
You can choose the period reporting kWh, here I used last 24 hours for each hour.
(resolution: HOURLY, last: 24)
If you go to Tibber Developer you can query your stuff directly. by putting this query for example:
{viewer{homes{consumption(resolution: HOURLY, last: 24) { nodes {from cost consumption}}}}}
or use samples they provide.
And for those not getting pricing data for tomorrow, I see it’s only giving the Today node, not sure why the tomorrow is empty. Today node returns next 24 hours for me starting at midnight today.
Sweet tool there! So did you create a sensor like this for the graph? Or could info already in HA be used instead to avoid polling the API too much?`I’ve heard the tibber API does not allow for that many queries a day. Also local data will update faster than the tibber database as it is read more often. I believe data to tibber is sent in my case through 4G connection (mobile).
EDIT: I created this sensor that works great. Now I just have to figure out how to add it to the chart
Although using available data in HA from my p1 (HAN) port reader would update the most current data quicker.
- platform: rest
name: Tibber 24h Hourly Consumption
resource: https://api.tibber.com/v1-beta/gql
method: POST
scan_interval: 60
payload: '{ "query": "{ viewer { homes { consumption(resolution: HOURLY, last: 24) { nodes {from cost consumption }}}}}" }'
json_attributes_path: "$.data.viewer.homes[0].consumption"
json_attributes:
- nodes
value_template: Ok
headers:
Authorization: !secret tibber_api_token
Content-Type: application/json
User-Agent: REST
Yes, below code plots the graph on apexcharts:
You can set scan_interval of the sensor to increase/decrease frequency of polling. They have limit 100 requests in 5 minutes per IP address, so the limit is quite low.
type: custom:apexcharts-card
apex_config:
chart:
height: 500px
header:
show: true
title: Energy stats
show_states: true
colorize_states: true
now:
show: true
color: white
label: NOW
hours_12: false
graph_span: 24h
span:
start: day
yaxis:
- id: kWh
decimals: 2
opposite: true
apex_config:
tickAmount: 4
- id: EUR
decimals: 2
series:
- entity: sensor.Tibber_24h_Hourly_Consumption
type: column
show:
extremas: true
name: Usage
float_precision: 2
stroke_width: 2
color: '#64511c'
opacity: 0.3
yaxis_id: kWh
group_by:
func: avg
duration: 60min
data_generator: |
var a = entity.attributes.nodes.map((entry) => {
return [new Date(entry.from), entry.consumption];
});
return a;
Thanks a lot for the code. It seems unfortunately tibber does not update so fast. Missing all data from today (and its now 20:44)
{
"data": {
"viewer": {
"homes": [
{
"consumption": {
"nodes": [
{
"from": "2022-09-17T20:00:00.000+02:00",
"cost": 0.8351015625,
"consumption": 0.555
},
{
"from": "2022-09-17T21:00:00.000+02:00",
"cost": 0.9424128,
"consumption": 0.896
},
{
"from": "2022-09-17T22:00:00.000+02:00",
"cost": 1.7347201875,
"consumption": 1.737
},
{
"from": "2022-09-17T23:00:00.000+02:00",
"cost": 0.442479375,
"consumption": 0.675
},
{
"from": "2022-09-18T00:00:00.000+02:00",
"cost": 0.1590415,
"consumption": 0.358
},
{
"from": "2022-09-18T01:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T02:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T03:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T04:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T05:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T06:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T07:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T08:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T09:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T10:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T11:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T12:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T13:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T14:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T15:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T16:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T17:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T18:00:00.000+02:00",
"cost": null,
"consumption": null
},
{
"from": "2022-09-18T19:00:00.000+02:00",
"cost": null,
"consumption": null
}
]
}
EDIT:
This worked instead with my existing sensor
- entity: sensor.cumulative_active_import
type: column
show:
extremas: true
name: Usage P1
float_precision: 2
color: a4ddc6
opacity: 0.2
yaxis_id: kWh
group_by:
func: diff
duration: 60min
start_with_last: true
stroke_width: 4
Thanks for the ideas @p1ranha! I got it quite good. I get the usage from a local sensor (P1/HAN port on the meter, not connected to Tibber).
The red and purple lines are not straight… And the current energy consumption are not shown, because I use a cumulative-sensor. I have a momentary sensor: sensor.electricity_meter_momentary_active_import where I get currently measured kW. Can I include it in some way?
And, I still don’t get the tomorrow prices. I checked the sensor sensor.tibber_prices and both today and tomorrow are present!
type: custom:apexcharts-card
apex_config:
chart:
height: 500px
header:
show: true
title: Energy stats
show_states: true
colorize_states: true
now:
show: true
color: white
label: NOW
hours_12: false
graph_span: 36h
span:
start: day
yaxis:
- id: kWh
decimals: 0
opposite: true
apex_config:
tickAmount: 4
- id: SEK
series:
- entity: sensor.electricity_meter_cumulative_active_import
type: column
show:
extremas: true
name: Usage
stroke_width: 2
color: '#64511c'
opacity: 0.3
yaxis_id: kWh
group_by:
func: diff
duration: 60min
start_with_last: true
- entity: sensor.tibber_prices
stroke_width: 2
color: blue
curve: smooth
show:
legend_value: false
extremas: true
in_header: false
extend_to: now
yaxis_id: SEK
name: Predicted all
data_generator: |
return entity.attributes.today.map((entry) => {
return [new Date(entry.startsAt), entry.total];
});
return entity.attributes.tomorrow.map((entry) => {
return [new Date(entry.startsAt), entry.total];
});
- entity: sensor.electricity_price_home
extend_to: now
show:
extremas: true
color: pink
stroke_width: 5
yaxis_id: SEK
name: price
- entity: sensor.electricity_price_home
stroke_width: 2
show:
legend_value: false
extremas: true
curve: smooth
attribute: min_price
name: MIN
color: green
yaxis_id: SEK
type: line
group_by:
duration: 24hours
func: min
- entity: sensor.electricity_price_home
stroke_width: 2
yaxis_id: SEK
name: AVG
attribute: avg_price
color: violet
curve: smooth
type: line
show:
legend_value: false
extremas: true
group_by:
duration: 24hours
func: avg
- entity: sensor.electricity_price_home
attribute: max_price
stroke_width: 2
curve: smooth
show:
legend_value: false
extremas: true
name: MAX
color: red
yaxis_id: SEK
type: line
group_by:
duration: 24hours
func: max
I did this to get mine working
data_generator: |
var today = entity.attributes.today.map((record, index) => {
return [record.startsAt, record.total];
});
var tomorrow = entity.attributes.tomorrow.map((record, index) => {
return [record.startsAt, record.total];
});
return today.concat(tomorrow);
Holy shit. I totally missed this. Sorry.
But I reworked it a little so there’s only one function node to manage everything.
You have to fix the correct API endpoint in the Tibber nodes.
You have to create these helper entities.
input_number.elpris_gransvarde_low
input_number.elpris_gransvarde_hog
input_number.elpris_granspris_lag
input_number.elpris_granspris_hog
This is the Node-RED code.
[{"id":"1896f74a3f62ef44","type":"tibber-data","z":"ce6c5295294be6b3","name":"Get Todays Prices","active":true,"apiEndpointRef":"70b33fa87d346e0c","queryName":"getTodaysEnergyPrices","homeId":"","energyResolution":"HOURLY","lastCount":10,"x":950,"y":540,"wires":[["b290b2d2ee300d33"]]},{"id":"2ea2b8506beee228","type":"tibber-data","z":"ce6c5295294be6b3","name":"Get Tomorrows Prices","active":true,"apiEndpointRef":"70b33fa87d346e0c","queryName":"getTomorrowsEnergyPrices","homeId":"","energyResolution":"HOURLY","lastCount":10,"x":960,"y":600,"wires":[["099fc427156bf2d1"]]},{"id":"0f8b7329bdb2bcc6","type":"inject","z":"ce6c5295294be6b3","name":"Every hour","props":[],"repeat":"","crontab":"0 0-23 * * *","once":true,"onceDelay":"0.1","topic":"","x":110,"y":360,"wires":[["8b372d2c150e7d33","fe70b9021c349192"]]},{"id":"5a111d474a21d572","type":"time-range-switch","z":"ce6c5295294be6b3","name":"","lat":"","lon":"","startTime":"00:00","endTime":"12:59","startOffset":0,"endOffset":0,"x":690,"y":600,"wires":[[],["2ea2b8506beee228"]]},{"id":"384c206d221964a6","type":"inject","z":"ce6c5295294be6b3","name":"00:00","props":[],"repeat":"","crontab":"00 00 * * *","once":true,"onceDelay":"1","topic":"","x":100,"y":80,"wires":[["5c262db773ec0f5e"]]},{"id":"5c262db773ec0f5e","type":"tibber-data","z":"ce6c5295294be6b3","name":"getHomes","active":true,"apiEndpointRef":"70b33fa87d346e0c","queryName":"getHomes","homeId":"{ payload.[0] }","energyResolution":"DAILY","lastCount":10,"x":330,"y":80,"wires":[["60835a8a05d9df00"]]},{"id":"6adc76948391f8f2","type":"debug","z":"ce6c5295294be6b3","name":"HomeID","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":760,"y":80,"wires":[]},{"id":"60835a8a05d9df00","type":"function","z":"ce6c5295294be6b3","name":"set Home ID","func":"flow.set(\"tibberHome\", msg.payload[0].id)\n\nmsg.payload = msg.payload[0].id;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":80,"wires":[["6adc76948391f8f2"]]},{"id":"71e52704cbeaf3d2","type":"function","z":"ce6c5295294be6b3","name":"get Home ID","func":"msg.payload = { \"homeId\": flow.get(\"tibberHome\") };\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":540,"wires":[["1896f74a3f62ef44","5a111d474a21d572"]]},{"id":"eb5dceff17e2034a","type":"catch","z":"ce6c5295294be6b3","name":"","scope":null,"uncaught":false,"x":1200,"y":80,"wires":[["534fac41780628d8"]]},{"id":"534fac41780628d8","type":"debug","z":"ce6c5295294be6b3","name":"Errors","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1390,"y":80,"wires":[]},{"id":"9f4b345dd3f5ce67","type":"function","z":"ce6c5295294be6b3","name":"Set Price Thresholds","func":"const ha = global.get('homeassistant').homeAssistant.states;\nconst priceThresholdLow = ha[\"input_number.elpris_gransvarde_low\"].state;\nconst priceThresholdHigh = ha[\"input_number.elpris_gransvarde_hog\"].state;\nconst priceLow = ha[\"input_number.elpris_granspris_lag\"].state;\nconst priceHigh = ha[\"input_number.elpris_granspris_hog\"].state;\n\nflow.set(\"priceThresholdLow\", priceThresholdLow);\nflow.set(\"priceThresholdHigh\", priceThresholdHigh);\nflow.set(\"priceLow\", priceLow);\nflow.set(\"priceHigh\", priceHigh);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":200,"wires":[[]]},{"id":"fe70b9021c349192","type":"delay","z":"ce6c5295294be6b3","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":340,"y":360,"wires":[["9f4b345dd3f5ce67"]]},{"id":"8d212665da1bf70e","type":"comment","z":"ce6c5295294be6b3","name":"Hämta och sätt Home ID från Tibber i flow-variabel varje dag klockan 00:00.","info":"Home ID hämtas från Tibber \nvid start av Home Assistant\noch klockan 00:00 varje dygn","x":300,"y":40,"wires":[]},{"id":"411ce4dc63667929","type":"comment","z":"ce6c5295294be6b3","name":"Uppdatera priser, vid ändring av gränsvärde. Processa nya värden för drift.","info":"","x":260,"y":160,"wires":[]},{"id":"0585b5d20bee526d","type":"comment","z":"ce6c5295294be6b3","name":"Hämta priser varje timme och uppdatera drift (under gränsvärde = drift, ovan gränsvärde = stopp).","info":"","x":630,"y":500,"wires":[]},{"id":"f8eab22e0b97916a","type":"comment","z":"ce6c5295294be6b3","name":"Tjonga fast en massa states i olika noder som nyttjas av HA.","info":"","x":1940,"y":500,"wires":[]},{"id":"9c05e6a076cfc05f","type":"comment","z":"ce6c5295294be6b3","name":"Fånga märkliga errors.","info":"","x":1240,"y":40,"wires":[]},{"id":"48d9c102110176cb","type":"comment","z":"ce6c5295294be6b3","name":"Node Red ska först koppla upp sig till HA","info":"","x":440,"y":320,"wires":[]},{"id":"6c9aa1bc149d09bf","type":"comment","z":"ce6c5295294be6b3","name":"I denna funktion sprakar magi.","info":"","x":1560,"y":500,"wires":[]},{"id":"8b372d2c150e7d33","type":"delay","z":"ce6c5295294be6b3","name":"","pauseType":"queue","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"20","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":400,"y":540,"wires":[["71e52704cbeaf3d2"]]},{"id":"27213fa4bc540a8b","type":"ha-button","z":"ce6c5295294be6b3","name":"Update Prices","version":0,"debugenabled":false,"outputs":1,"entityConfig":"0a9777e75cdf4f2e","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"x":110,"y":200,"wires":[["9f4b345dd3f5ce67","8b372d2c150e7d33"]]},{"id":"1852ad800b07db13","type":"comment","z":"ce6c5295294be6b3","name":"Kör en gång i timmen.","info":"","x":140,"y":320,"wires":[]},{"id":"24fff71dd1ed6384","type":"debug","z":"ce6c5295294be6b3","name":"Process Data","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1800,"y":1380,"wires":[]},{"id":"b290b2d2ee300d33","type":"change","z":"ce6c5295294be6b3","name":"Change payload to today","rules":[{"t":"move","p":"payload","pt":"msg","to":"today","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1230,"y":540,"wires":[["3f60206f132695f8"]]},{"id":"099fc427156bf2d1","type":"change","z":"ce6c5295294be6b3","name":"Change payload to tomorrow","rules":[{"t":"move","p":"payload","pt":"msg","to":"tomorrow","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1240,"y":600,"wires":[["3f60206f132695f8"]]},{"id":"3f60206f132695f8","type":"function","z":"ce6c5295294be6b3","name":"Process Data","func":"// FUNCTION NODE FOR FETCHING PRICES NOW AND TOMORROW.\n// CALCULATING MIN, MAX, THRESHOLDS.\n// SETTING RUNAPPLIANCE LOW AND HIGH ACCORDINGLY.\n\n// TODAY\n\nif (msg.today != null) {\n\n //Variables\n const data = msg.today;\n\n const now = new Date();\n\n const onehour = new Date();\n onehour.setHours(onehour.getHours() + 1);\n\n const twohour = new Date();\n twohour.setHours(twohour.getHours() + 2);\n\n const threehour = new Date();\n threehour.setHours(threehour.getHours() + 3);\n\n const fourhour = new Date();\n fourhour.setHours(fourhour.getHours() + 4);\n\n const fivehour = new Date();\n fivehour.setHours(fivehour.getHours() + 5);\n\n const sixhour = new Date();\n sixhour.setHours(sixhour.getHours() + 6);\n\n const findTimestampnow = now.setMinutes(0, 0, 0);\n const findTimestamponehour = onehour.setMinutes(0, 0, 0);\n const findTimestamptwohour = twohour.setMinutes(0, 0, 0);\n const findTimestampthreehour = threehour.setMinutes(0, 0, 0);\n const findTimestampfourhour = fourhour.setMinutes(0, 0, 0);\n const findTimestampfivehour = fivehour.setMinutes(0, 0, 0);\n const findTimestampsixhour = sixhour.setMinutes(0, 0, 0);\n\n //find price now\n let priceNow = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestampnow;\n });\n\n //find price in one hour\n let price1hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestamponehour;\n });\n\n //find price in two hours\n let price2hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestamptwohour;\n });\n\n //find price in three hours\n let price3hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestampthreehour;\n });\n\n //find price in four hours\n let price4hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestampfourhour;\n });\n\n //find price in five hours\n let price5hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestampfivehour;\n });\n\n //find price in six hours\n let price6hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestampsixhour;\n });\n\n //Now lets parse the days min and max prices\n let prices = msg.today\n let minTotal = prices[0].total\n let maxTotal = prices[0].total\n\n prices.forEach(el => {\n if (el.total < minTotal) minTotal = el.total\n })\n\n prices.forEach(el => {\n if (el.total > maxTotal) maxTotal = el.total\n })\n\n //Price threshold, are we ok to run whatever needs to be run?\n let runApplianceLow = false;\n let runApplianceHigh = false; \n let thresholdLow = minTotal + ((maxTotal - minTotal) * (flow.get(\"priceThresholdLow\") / 100)) \n let thresholdHigh = minTotal + ((maxTotal - minTotal) * (flow.get(\"priceThresholdHigh\") / 100))\n\n //Run appliance? Either from threshold or set price levels\n if (priceNow.total <= thresholdLow) {\n runApplianceLow = true;\n } else if (priceNow.total <= flow.get(\"priceLow\")) {\n runApplianceLow = true;\n }\n\n if (priceNow.total <= thresholdHigh) {\n runApplianceHigh = true;\n } else if (priceNow.total <= flow.get(\"priceHigh\")) {\n runApplianceHigh = true;\n }\n \n //Null old payloads\n msg.payload = null;\n msg.today = null;\n\n //Build our payload\n msg.payload = {\n priceNow,\n minTotal,\n maxTotal,\n runApplianceLow,\n runApplianceHigh,\n thresholdLow,\n thresholdHigh\n }\n\n if (typeof price1hour != \"undefined\") {\n msg.payload[\"price1hour\"] = price1hour;\n }\n\n if (typeof price2hour != \"undefined\") {\n msg.payload[\"price2hour\"] = price2hour;\n }\n\n if (typeof price3hour != \"undefined\") {\n msg.payload[\"price3hour\"] = price3hour;\n }\n\n if (typeof price4hour != \"undefined\") {\n msg.payload[\"price4hour\"] = price4hour;\n }\n\n if (typeof price5hour != \"undefined\") {\n msg.payload[\"price5hour\"] = price5hour;\n }\n\n if (typeof price6hour != \"undefined\") {\n msg.payload[\"price6hour\"] = price6hour;\n } \n\n //Jalla let go\n return msg;\n}\n\n//TOMORROW\n\nif (msg.tomorrow != null) {\n\n //Variables\n const data = msg.tomorrow;\n\n const tom = new Date();\n tom.setHours(tom.getHours() + 24);\n\n const onehour = new Date();\n onehour.setHours(onehour.getHours() + 1);\n\n const twohour = new Date();\n twohour.setHours(twohour.getHours() + 2);\n\n const threehour = new Date();\n threehour.setHours(threehour.getHours() + 3);\n\n const fourhour = new Date();\n fourhour.setHours(fourhour.getHours() + 4);\n\n const fivehour = new Date();\n fivehour.setHours(fivehour.getHours() + 5);\n\n const sixhour = new Date();\n sixhour.setHours(sixhour.getHours() + 6); \n\n const findTimestamptom = tom.setMinutes(0, 0, 0);\n const findTimestamponehour = onehour.setMinutes(0, 0, 0);\n const findTimestamptwohour = twohour.setMinutes(0, 0, 0);\n const findTimestampthreehour = threehour.setMinutes(0, 0, 0);\n const findTimestampfourhour = fourhour.setMinutes(0, 0, 0);\n const findTimestampfivehour = fivehour.setMinutes(0, 0, 0);\n const findTimestampsixhour = sixhour.setMinutes(0, 0, 0);\n\n //find price tomorrow\n let priceTomorrow = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestamptom;\n });\n\n //find price in one hour\n let price1hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestamponehour;\n });\n\n //find price in two hours\n let price2hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestamptwohour;\n });\n\n //find price in three hours\n let price3hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestampthreehour;\n });\n\n //find price in four hours\n let price4hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestampfourhour;\n });\n\n //find price in five hours\n let price5hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestampfivehour;\n });\n\n //find price in six hours\n let price6hour = data.find(e => {\n return (new Date(e.startsAt)).valueOf() == findTimestampsixhour;\n });\n\n //Min max prices tomorrow\n let prices = msg.tomorrow\n let minTotalTom = prices[0].total\n let maxTotalTom = prices[0].total\n\n prices.forEach(el => {\n if (el.total < minTotalTom) minTotalTom = el.total\n })\n\n prices.forEach(el => {\n if (el.total > maxTotalTom) maxTotalTom = el.total\n })\n\n //Thresholds tomorrow\n let thresholdLowTom = minTotalTom + ((maxTotalTom - minTotalTom) * (flow.get(\"priceThresholdLow\") / 100))\n let thresholdHighTom = minTotalTom + ((maxTotalTom - minTotalTom) * (flow.get(\"priceThresholdHigh\") / 100))\n\n //Null the old payloads\n msg.payload = null;\n msg.tomorrow = null;\n\n //Build our payload\n if (typeof priceTomorrow != \"undefined\") {\n msg.payload = {\n priceTomorrow,\n minTotalTom,\n maxTotalTom,\n thresholdLowTom,\n thresholdHighTom\n }\n }\n\n if (typeof price1hour != \"undefined\") {\n msg.payload[\"price1hour\"] = price1hour;\n }\n\n if (typeof price2hour != \"undefined\") {\n msg.payload[\"price2hour\"] = price2hour;\n }\n\n if (typeof price3hour != \"undefined\") {\n msg.payload[\"price3hour\"] = price3hour;\n }\n\n if (typeof price4hour != \"undefined\") {\n msg.payload[\"price4hour\"] = price4hour;\n }\n\n if (typeof price5hour != \"undefined\") {\n msg.payload[\"price5hour\"] = price5hour;\n }\n\n if (typeof price6hour != \"undefined\") {\n msg.payload[\"price6hour\"] = price6hour;\n } \n\n //Jalla let go\n return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1520,"y":540,"wires":[["24fff71dd1ed6384","d21bf43301a97314","1ac7b8b302c16ca4","d466832b2120c5b0","2b9e6563bb1d5dab","cc5856cc6cc7f1a7","df0bab559e91b51d","1bf278cc13af329a","e5463d982916c28e","b03b5120dff8cca0","b8c28a61f66732f1","26ed89da0bdfb31e","c00365d6c09f6ffd","3fe5772dda3c2605","00d1ffcc148e9b9d"]]},{"id":"d21bf43301a97314","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Price now","entityConfig":"8930b7772c84df5f","version":0,"state":"payload.priceNow.total","stateType":"msg","attributes":[{"property":"Mintotal","value":"payload.minTotal","valueType":"msg"},{"property":"Maxtotal","value":"payload.maxTotal","valueType":"msg"},{"property":"level","value":"payload.level","valueType":"str"}],"inputOverride":"allow","outputProperties":[],"x":1790,"y":540,"wires":[[]]},{"id":"1ac7b8b302c16ca4","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Price in 1 hour","entityConfig":"887f061916c54562","version":0,"state":"payload.price1hour.total","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1800,"y":660,"wires":[[]]},{"id":"d466832b2120c5b0","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Price in 2 hours","entityConfig":"375aa345a1202971","version":0,"state":"payload.price2hour.total","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1800,"y":720,"wires":[[]]},{"id":"2b9e6563bb1d5dab","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Price in 3 hours","entityConfig":"eb0d4cb5d9d5e7bd","version":0,"state":"payload.price3hour.total","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1800,"y":780,"wires":[[]]},{"id":"cc5856cc6cc7f1a7","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Price in 4 hours","entityConfig":"e1956e8443b7732b","version":0,"state":"payload.price4hour.total","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1800,"y":840,"wires":[[]]},{"id":"df0bab559e91b51d","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Price in 5 hours","entityConfig":"cb2721b09234eda7","version":0,"state":"payload.price5hour.total","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1800,"y":900,"wires":[[]]},{"id":"1bf278cc13af329a","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Price in 6 hours","entityConfig":"10d5cb062d73c8b2","version":0,"state":"payload.price6hour.total","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1800,"y":960,"wires":[[]]},{"id":"e5463d982916c28e","type":"ha-binary-sensor","z":"ce6c5295294be6b3","name":"runApplianceLow","entityConfig":"d789d71f44158785","version":0,"state":"payload.runApplianceLow","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1810,"y":1260,"wires":[[]]},{"id":"b03b5120dff8cca0","type":"ha-binary-sensor","z":"ce6c5295294be6b3","name":"runApplianceHigh","entityConfig":"8f4fb67ec1f422eb","version":0,"state":"payload.runApplianceHigh","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1810,"y":1320,"wires":[[]]},{"id":"b8c28a61f66732f1","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Threshold Low","entityConfig":"3b106120266b6db9","version":0,"state":"payload.thresholdLow","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1800,"y":1020,"wires":[[]]},{"id":"26ed89da0bdfb31e","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Threshold High","entityConfig":"c10f0321b04d4245","version":0,"state":"payload.thresholdHigh","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1800,"y":1080,"wires":[[]]},{"id":"c00365d6c09f6ffd","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Threshold Low Tomorrow","entityConfig":"264e4dee52fefabe","version":0,"state":"payload.thresholdLowTom","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1830,"y":1140,"wires":[[]]},{"id":"3fe5772dda3c2605","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Threshold High Tomorrow","entityConfig":"dd2e464f7101f4e2","version":0,"state":"payload.thresholdHighTom","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1830,"y":1200,"wires":[[]]},{"id":"00d1ffcc148e9b9d","type":"ha-sensor","z":"ce6c5295294be6b3","name":"Price tomorrow","entityConfig":"1d4fcf6095bc6e5b","version":0,"state":"payload.priceTomorrow.total","stateType":"msg","attributes":[{"property":"Mintotal","value":"payload.minTotalTom","valueType":"msg"},{"property":"Maxtotal","value":"payload.maxTotalTom","valueType":"msg"},{"property":"level","value":"payload.priceTomorrow.level","valueType":"msg"}],"inputOverride":"allow","outputProperties":[],"x":1800,"y":600,"wires":[[]]},{"id":"70b33fa87d346e0c","type":"tibber-api-endpoint","feedUrl":"wss://api.tibber.com/v1-beta/gql/subscriptions","queryUrl":"https://api.tibber.com/v1-beta/gql","feedTimeout":"60","name":"Tibber Baby"},{"id":"0a9777e75cdf4f2e","type":"ha-entity-config","server":"1101e9cb.075866","name":"Update Prices","version":6,"entityType":"button","haConfig":[{"property":"name","value":""},{"property":"icon","value":""},{"property":"device_class","value":""}]},{"id":"8930b7772c84df5f","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Price now","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Price now"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"887f061916c54562","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Price in 1 hour","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Price +1 hour"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"375aa345a1202971","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Price in 2 hours","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Price +2 hours"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"eb0d4cb5d9d5e7bd","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Price in 3 hours","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Price +3 hours"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"e1956e8443b7732b","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Price in 4 hours","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Price +4 hours"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"cb2721b09234eda7","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Price in 5 hours","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Price +5 hours"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"10d5cb062d73c8b2","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Price in 6 hours","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Price +6 hours"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"d789d71f44158785","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"binary sensor config for runApplianceLow","version":6,"entityType":"binary_sensor","haConfig":[{"property":"name","value":"runApplianceLow"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"8f4fb67ec1f422eb","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"binary sensor config for runApplianceHigh","version":6,"entityType":"binary_sensor","haConfig":[{"property":"name","value":"runApplianceHigh"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"3b106120266b6db9","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Threshold Low","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Threshold Low SEK"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"c10f0321b04d4245","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Threshold High","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Threshold High SEK"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"264e4dee52fefabe","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Threshold Low Tomorrow","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Threshold Low Tomorrow SEK "},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"dd2e464f7101f4e2","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Threshold High Tomorrow","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Threshold High Tomorrow SEK"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"1d4fcf6095bc6e5b","type":"ha-entity-config","server":"1101e9cb.075866","deviceConfig":"","name":"sensor config for Price tomorrow","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Price +24 hours"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:currency-usd"},{"property":"unit_of_measurement","value":"SEK/kWh"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"1101e9cb.075866","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]
And this is my lovelace-panel for controlling it. There’s a bunch of entities that derives from my Tibber Pulse. It uses stack-in-card (from HACS) and vertical-stack.
views:
- title: Home
cards:
- type: custom:stack-in-card
cards:
- type: vertical-stack
cards:
- type: entities
title: Inställningar
entities:
- entity: input_boolean.visa_elpris_installningar
name: Visa
- type: vertical-stack
cards:
- type: conditional
conditions:
- entity: input_boolean.visa_elpris_installningar
state: 'on'
card:
type: entities
title: Gränsvärden
entities:
- entity: button.nodered_0a9777e75cdf4f2e
name: Uppdatera Priser
- entity: input_number.elpris_gransvarde_low
secondary_info: last-changed
name: Gränsvärde låg
- entity: input_number.elpris_gransvarde_hog
secondary_info: last-changed
name: Gränsvärde hög
- entity: input_number.elpris_granspris_lag
name: Gränspris låg
secondary_info: last-changed
- entity: input_number.elpris_granspris_hog
name: Gränspris hög
secondary_info: last-changed
- type: vertical-stack
cards:
- type: conditional
conditions:
- entity: input_boolean.visa_elpris_installningar
state: 'on'
card:
type: entities
title: Info
entities:
- entity: sensor.thresholdprices
secondary_info: last-changed
name: GV idag låg
- entity: sensor.threshold_high_sek
secondary_info: last-changed
name: GV idag hög
- entity: sensor.threshold_low_tomorrow_sek
secondary_info: last-changed
name: GV imorgon låg
- entity: sensor.threshold_high_tomorrow_sek
secondary_info: last-changed
name: GV imorgon hög
- entity: binary_sensor.nodered_d789d71f44158785
secondary_info: last-changed
name: Lågdrift
- entity: binary_sensor.runappliancehigh
secondary_info: last-changed
name: Högdrift
- type: custom:stack-in-card
cards:
- type: vertical-stack
cards:
- type: entities
title: Drift
entities:
- entity: input_boolean.visa_drift
name: Visa
- type: vertical-stack
cards:
- type: conditional
conditions:
- entity: input_boolean.visa_drift
state: 'on'
card:
type: entities
title: Låg
entities:
- entity: switch.shelly_elpanna_1
name: Elpanna
secondary_info: last-updated
- type: vertical-stack
cards:
- type: conditional
conditions:
- entity: input_boolean.visa_drift
state: 'on'
card:
type: entities
title: Hög
entities:
- entity: switch.shp1
secondary_info: last-updated
name: Luftavfuktare
- entity: sensor.shp1_power
name: Effekt
- entity: sensor.shp1_energy
name: Förbrukning
- type: custom:stack-in-card
cards:
- type: vertical-stack
cards:
- type: entities
title: Mätare
entities:
- entity: input_boolean.visa_matare
name: Visa
- type: vertical-stack
cards:
- type: conditional
conditions:
- entity: input_boolean.visa_matare
state: 'on'
card:
type: entities
entities:
- entity: sensor.power_morarpsvagen_14
name: Effektuttag nu
- entity: sensor.average_power_morarpsvagen_14
name: Genomsnittligt effektuttag
- entity: sensor.accumulated_cost_morarpsvagen_14
name: Kostnad idag
- entity: sensor.monthly_cost_morarpsvagen_14
name: Kostnad denna månad
- entity: sensor.monthly_net_consumption_morarpsvagen_14
name: Förbrukning denna månad
- entity: sensor.monthly_peak_hour_consumption_morarpsvagen_14
name: Högsta effektuttag denna månad
- entity: sensor.last_meter_consumption_morarpsvagen_14
name: Mätarställning
- entity: sensor.current_l1_morarpsvagen_14
name: Ström L1
- entity: sensor.current_l2_morarpsvagen_14
name: Ström L2
- entity: sensor.current_l3_morarpsvagen_14
name: Ström L3
- type: custom:stack-in-card
cards:
- type: vertical-stack
cards:
- type: entities
title: Priser
entities:
- entity: input_boolean.visa_priser
name: Visa
- type: vertical-stack
cards:
- type: conditional
conditions:
- entity: input_boolean.visa_priser
state: 'on'
card:
type: entities
title: Idag
entities:
- entity: sensor.nodered_8930b7772c84df5f
secondary_info: last-changed
name: Pris just nu
- type: attribute
entity: sensor.electricity_price_morarpsvagen_14
attribute: price_level
secondary_info: last-changed
name: Tibber prisnivå
- type: attribute
entity: sensor.nodered_8930b7772c84df5f
attribute: mintotal
suffix: SEK/kWh
name: Lägsta
- type: attribute
entity: sensor.nodered_8930b7772c84df5f
attribute: maxtotal
suffix: SEK/kWh
name: Högsta
- entity: sensor.thresholdprices
secondary_info: last-changed
name: Gränsvärde lågdrift
- entity: sensor.threshold_high_sek
secondary_info: last-changed
name: Gränsvärde högdrift
- type: vertical-stack
cards:
- type: conditional
conditions:
- entity: binary_sensor.tibber_morgondagens_priser
state: 'on'
- entity: input_boolean.visa_priser
state: 'on'
card:
type: entities
title: Imorgon
entities:
- entity: sensor.price_24_hours
name: Pris om 24h
secondary_info: none
- type: attribute
entity: sensor.price_24_hours
attribute: level
secondary_info: last-changed
name: Tibber prisnivå
- type: attribute
entity: sensor.price_24_hours
attribute: mintotal
suffix: SEK/kWh
name: Lägsta
- type: attribute
entity: sensor.price_24_hours
attribute: maxtotal
suffix: SEK/kWh
name: Högsta
- entity: sensor.threshold_low_tomorrow_sek
secondary_info: last-changed
name: Gränsvärde lågdrift
- entity: sensor.threshold_high_tomorrow_sek
secondary_info: last-changed
name: Gränsvärde högdrift
- type: vertical-stack
cards:
- type: conditional
conditions:
- entity: input_boolean.visa_priser
state: 'on'
card:
type: entities
title: Kommande timmar
entities:
- entity: sensor.nodered_887f061916c54562
name: +1 timme
- entity: sensor.nodered_375aa345a1202971
name: +2 timmar
- entity: sensor.nodered_eb0d4cb5d9d5e7bd
name: +3 timmar
- entity: sensor.nodered_e1956e8443b7732b
name: +4 timmar
- entity: sensor.nodered_cb2721b09234eda7
name: +5 timmar
- entity: sensor.nodered_10d5cb062d73c8b2
name: +6 timmar
- chart_type: line
period: 5minute
days_to_show: 0.5
type: statistics-graph
entities:
- entity: sensor.power_morarpsvagen_14
name: Effekt
stat_types:
- mean
- sum
- max
- min
title: Elpris
Might have missed something, just ask.
Nothing wrong, it’s by design:
value_template: Ok
The data it fetches (prices) is in the attributes of the sensor Tibber prices.
So if I want the forecast for price, is this the right kind of sensor?
I’m trying to keep up in the discussion…
Yes it is. I believe the state is just hardcoded to OK since state is limited to 255 characters or something like that. The data is kept in the attributes instead.
This is what mine looks like:
Then you can create other template sensors based on those attributes (today, tomorrow), with min, max, average etc. depending on your use case.
Or create a price chart for future prices with apex charts. That is what the data generator does, takes the data from the attributes of Tibber Prices and generates a chart from it.
So I guess there is something wrong with my sensor then…
Is there something wrong with this:
- platform: rest
name: Tibber prices
resource: https://api.tibber.com/v1-beta/gql
method: POST
scan_interval: 60
payload: ‘{ “query”: “{ viewer { homes { currentSubscription { priceInfo { today { total startsAt } tomorrow { total startsAt }}}}}}” }’
json_attributes_path: “$.data.viewer.homes[0].currentSubscription.priceInfo”
json_attributes:- today
- tomorrow
value_template: Ok
headers:
Authorization: “[XXXXX]”
Content-Type: application/json
User-Agent: REST
It seems so yes, not sure if it a formatting issue when pasting in the forum or if your actual yaml has the same. Here is how mine look:
value_template and headers should not have indentation as in your example.
json_attributes:
- today
- tomorrow
value_template: 'OK'
headers:
Authorization: "Bearer *****************************************"
User-Agent: Home Assistant
Content-Type: application/json
Now the sensor works great.
Now I just want to have the predicted price in a simple apex chart but can’t get it to show properly.
This only show todays historical prizes: (copy/paste so maybe code seems wrong but it works, not just showing tomorrow’s prize)
type: custom:apexcharts-card
header:
show: true
title: ApexCharts-Card
show_states: true
colorize_states: true
series:
-
entity: sensor.tibber_prices
data_generator: |return entity.attributes.today.map((entry) => {
return [new Date(entry.startsAt), entry.total];
});
return entity.attributes.tomorrow.map((entry) => {
return [new Date(entry.startsAt), entry.total];
});