[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:

23 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

5 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