[Inspiration] Daily energy prices chart (using Power by the Hour)

Hi all. I’ve been working on a set of flows to create a chart of the energy prices of the next day (using the Power by the Hour App). When the new prices come in, the chart is generated and sent to myself in a notification. As I think it might be useful for others, I’d like to share my work with you.

Chart

The chart itself looks like this (and is configurable), for which I use a free online tool called Image Charts. With this tool, I can send the chart configuration encoded in the URL and it will return an image file of the chart. To fetch the image for use within a Homey flow, I use the Image Grabber app.

How it works

  1. Power by the Hour App signals about new prices and returns “Prijzen” tag.
  2. The HomeyScript converts the prices object into an encoded URL for the chart and returns “ChartUrl” tag.
  3. Fetch the image using the Image Grabber App
  4. Send myself a notification with the fetched image.

Flows


(note: the flow preview is showing a grey question mark instead of the actual tag used. Here the “ChartUrl” tag should be selected, which is set by the HomeyScript card)

HomeyScript

// Check if args are set
if (!args[0]) return false;

// Set base url
const chartWidth = 540;
const chartHeight = 320;
const baseUrl = `https://image-charts.com/chart.js/2.8.0?bkg=white&height=${chartHeight}&width=${chartWidth}&c=`;

// Convert input data to prices, labels and values
const prices = JSON.parse(args[0].replaceAll("'", "\""));
const labels = Object.keys(prices).map((label) => {
  return label.padStart(2, "0");
});
const values = Object.values(prices);

// Map color of each bar based on value.
// You can play with the colors and values, if you like.
const backgrounds = values.map((value) => {
  if (value <= 0.15) {
    return 'rgb(189, 44, 188)'; // Purple (free energy)
  }

  if (value <= 0.25) {
    return 'rgb(0, 170, 101)'; // Green (relatively cheap)
  }

  if (value <= 0.3) {
     return 'rgb(53, 86, 81)'; // Dark green (normal price)
  }

  return 'rgb(237, 95, 23)'; // Orange (high price)
});

// Add a data label to the cheapest and most expensive hour
const cheapestIndex = values.indexOf(Math.min(...values));
const expensiveIndex = values.indexOf(Math.max(...values));

const datalabels = values.map((value, index) => {
  if (index === cheapestIndex || index === expensiveIndex) {
    return [`€${value.toFixed(2)}`];
  }
  return [];
});

// Build configuration for the chart
const settings = { 
	type: "bar",
	data: {
		labels,
		datasets: [
			{
				label: "Prijzen",
				backgroundColor: backgrounds,
				data: values
			}
		]
	},
	options: {
		responsive: true,
		legend: {
			position: "none"
		},
		layout: {
			padding: {
        top: 35,
        bottom: 0,
        left: 5,
        right: 5
      }
		},
		rectangleRadius: 6,
    plugins: {
      datalabels: {
        anchor: 'end',
        align: 'start',
        offset: -40,
        padding: 5,
        backgroundColor: backgrounds,
        color: 'white',
        borderWidth: 2,
        borderColor: 'white',
        borderRadius: 100,
        font: {
         size: 14
        }
	    }
    },
    datalabels
  }
}

// Build the final url and save as tag
const settingsUrl = encodeURIComponent(JSON.stringify(settings))
const fullUrl = baseUrl + settingsUrl;
await tag('ChartUrl', fullUrl);

log(fullUrl);
return true;

Result

On iOS, long-press the notification to see the entire image. (You can also click on the notification, but then you’ll be redirected to the Homey app showing the image, which takes a second longer :wink: )

Final words

That’s it! I hope this gives some inspiration. Feedback, suggestions or improvement ideas are more than welcome! :slight_smile:

27 Likes

Very nice work. Thank you!

Edit: maybe I could even add it as a native functionality within PBTH :thinking:

9 Likes

Nice idea. In that case you might want to use the chartjs library (which is used by image-chart.com) directly in the app to generate the charts. Feel free to contact me if you need any help (although I’ve never developed a Homey app before, I’m eager to learn)

3 Likes

This is really great, exactly what I was looking for!
However, one question. When I try running the script (your script including flows), it just shows a graph with two prices for all 24h. Is this because it will only work when the actual new prices come in at PBTH? Thanks!

Edit: it looks like the chart works perfectly, but that PBTH just not provides the actual prices within the ‘Prijzen’ tag

1 Like

At this moment PBTH only fills the prices tag when new prices arrive. That is always somewhere in the afternoon, and right after midnight. There is no way to easily test the flows, other then just wait for those moments.

1 Like

When testing the flow, you can input your own data for that tag. As the default is a bit weird, copy-paste the following into your test tag for a more realistic chart (desktop only, I think):

{'0':0.2747,'1':0.2678,'2':0.261,'3':0.2606,'4':0.2672,'5':0.2721,'6':0.272,'7':0.2678,'8':0.2625,'9':0.2516,'10':0.2409,'11':0.2317,'12':0.20,'13':0.15,'14':0.12,'15':0.11,'16':0.12,'17':0.20,'18':0.2772,'19':0.2927,'20':0.3052,'21':0.2944,'22':0.2856,'23':0.2725}

2 Likes

Thanks for the fast reply both, I indeed modified the data already in the tag to confirm that the graph was working. I’ll wait for PBTH to push the new prices :raised_hands:

2 Likes

Working with the web url at the moment, since I dont want to bloat PBTH too much with onboard libraries.

Edit: it is ready and implemented in v5.6.0 of Power By The Hour: [APP][Pro] Power by the Hour: Insights per hour, day, month and year - #1547 by Gruijter

6 Likes

Yes please!!! 🫶🏼

Done. See version 5.6.1 :hugs:

2 Likes

How to install 5.6.1? Is this a beta version?

Yes Power by the Hour | Homey

@Stikstof , thx for the inspiration. Despite @Gruijter added the image’s to PBTH, i wanted to learn from this for myself, and created my own image, based on your code, with some modifications

  • I’m using the “komende uren”/“coming hours” JSON from PBTH
  • i changed the labels on the x-axis, so it starts with current hour (@Gruijter i can share the solution with you… :wink: )
  • i changed the colours, they are dynamic, based on averega price. So purple is negative price, light green is price 10% under average, orange is price 10% above average and darkgreen is between them. (so it is aligned with my homey script with notification of new prices)
  • i added a title with average price.

I trigger this image from a flow and send it with push message like your tutorial. Thx for this :slight_smile:

1 Like

Thanks for this post. It does allow me to start to learn homey script. It did take me some time to get it to work as initially I was not able to select (and thus fill) the url tag. Simply could not find it as the flow needs an inital run to create this tag. And when I wanted to test-run the flow it appeared I missed a final bracket: namely the “}” at the end of the test string (as posted earlier in this topic). I also adapted the script to add the “}” to the end of the string via below change of the code.

// Check if args are set
var energiePrijzen = args[0] + “}”;
if (!energiePrijzen) return false;

Fixing these 2 things resulted in a succesfull test-run of the flow, and in an image being created…

Howewer: I now never get a trigger by PBTH for receiving new prices. So the script never runs and my graphs are never created. Also, when I created a very simple flow that sends a push message to myself when the PBTH trigger "new prizes"is recieved does not work.

I don’t know what I’m doing wrong. Does this PBTH trigger not work anymore? Note that triggers on hourly updates of prizes by PBTH does work just fine. Anybody?

@Torch1969 : can you share your code with me?

Correct, the trigger for new prices for tomorrow doesn’t work at this moment @Gruijter is working on it.

1 Like

Sure see private message

Thx for both replies Torch1969. I will try your script. I have it set up, so let’s see if I get a trigger sometime. Also thanks for the instructions within the script :slight_smile:

1 Like

@Archibaldus, the flow I send you is to update coming hours prices json in the variable. This is triggered every hour by pbth. I made a separate script that I start manually (or when I wake up) that executes the script and sends generated image with push message.

Thank you @Stikstof for that really great inspiration! Based on your code I visualized my battery charging strategy, which makes it way easier to see what it’s doing compared to digging through log files. :grin:

2 Likes