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
- Power by the Hour App signals about new prices and returns “Prijzen” tag.
- The HomeyScript converts the prices object into an encoded URL for the chart and returns “ChartUrl” tag.
- Fetch the image using the Image Grabber App
- 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 )
Final words
That’s it! I hope this gives some inspiration. Feedback, suggestions or improvement ideas are more than welcome!