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

Cool! :wink:

1 Like

Nice, can you share your code?

Which code? The code for the chart is pretty much the same Stikstof shared. The code for the battery charging strategy is a big mess under constant development. :grin:

Well yes, I mean the code for the battery charging strategy.
I have (optimised) working code (homeyscript) for all known prices for coming hours. I would like to know how you add the “charging strategy” knowledge in the graph.
Maybe you can tell in words how you accomplished that?

The code for the visualisation is pretty straight forward. The major part is that:

	let values=[],labels=[],backgrounds=[],datalabels=[];
	lastSimulatedSOC=-1;
	for (i=0;i<simulatedHours.length;i++)
	{
		hour=simulatedHours[i];
		values.push(hour.price);
		labels.push(((currentHour+i)%24).toFixed(0).padStart(2,"0"));
		
		simulatedSOC=Math.round(100.0*(MIN_SOC+hour.simulatedBatteryAtEnd/batteryNetCapacity*(1-MIN_SOC)));
		if (simulatedSOC!=lastSimulatedSOC) datalabels.push(simulatedSOC.toFixed(0)+"%");
		else datalabels.push([]);
		lastSimulatedSOC=simulatedSOC;
		
		let color;
		if (hour.batteryMode.prioritiseBattery) color="rgb(255,0,0)";
		else if (!hour.batteryMode.allowDischarging) color="rgb(255,255,0)";
		else if (hour.pvYield>=hour.consumption) color="rgb(192,255,64)";
		else color="rgb(0,255,0)";		
		backgrounds.push(color);
	}

The optimiser just returns for every hour if either (i) battery discharging should be prevented, (ii) battery charging should be prioritised, i.e. no self consumption until battery is full, or (iii) no optimisation necessary, just use prices to decide what to do. Those three I use to choose a color, in addition to the estimated PV yield being higher than the estimated consumption (which I haven’t seen for quite some time :grin:)

I also add the estimated battery level as data label, but only if it has changed compared to the last hour.

The four arrays values, labels, backgrounds and datalabels then just go straight into the “settings” for the chart.

	const settings=
	{ 
		type: "bar",
		data: 
		{
			labels,
			datasets: [
				{
					label: "Optimierung",
					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: -10,
					padding: 0,
					backgroundColor: 'white',
					color: 'black',
					font: { size: 7 }
				}
			},
			datalabels
		}
	}

Looks really good and might try it out.

I was looking for a function: Getting a push notification around 21.00 with the cheapest two coherent hours during the night and what the prices would be. This way I would easily know when to start e.g. dishwasher. Seems it would be possible to reuse some of the functions above.

Anyone have suggestions for it? :slight_smile:

Not sure if you need it to be in Hscript, but you could use a flow like this for inspiration

You can import it as well:

Thank you Peter. That looks quite interesting. I’ll take a deeper look at that one.

1 Like

Hi Gruiter,
How can I activate this image graph?
I only see this:

It is automatically generated when you have prices. But you dont have prices, so probably the source data is down. If in a few days you still dont see anything send an app diagnostics report.

Hi @Stikstof and @CaptainVoni,

I followed the directive from scratch and have a flow for the purpose of test. If you see the image, the error I got is similar for both scripts, so the original but also the @CaptainVoni script.

EDIT, just got the default script working, so the @CaptainVoni script still returns the error.

The error occurs when running the script manually with the test data (yellow). Today the flow did not respond to the data received by PBTH.

Any any what’s wrong? Suppose its a simple solution, but I just don’t know.

Thanks!

Hi Phil, maybe you can share your code?

The error you are seeing seems helpful.

Probably you are using the await within a function. That is only allowed in an async function.

e.g.

async function() {
  await tag('ChartUrl', fullUrl);
}

It seems you are missing a closing bracket } at the end.

Try this:

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

function buildChartUrl(simulatedHours)
{
	// Set base url
	const chartWidth = 1200;
	const chartHeight = 600;
	const baseUrl = `https://image-charts.com/chart.js/2.8.0?bkg=white&height=${chartHeight}&width=${chartWidth}&c=`;


	let values=[],labels=[],backgrounds=[],datalabels=[];
	lastSimulatedSOC=-1;
	for (i=0;i<simulatedHours.length;i++)
	{
		hour=simulatedHours[i];
		values.push(hour.price);
		labels.push(((currentHour+i)%24).toFixed(0).padStart(2,"0"));
		
		simulatedSOC=Math.round(100.0*hour.simulatedBatteryAtEnd/batteryCapacity);
		if (simulatedSOC!=lastSimulatedSOC) datalabels.push(simulatedSOC.toFixed(0)+"%");
		else datalabels.push([]);
		lastSimulatedSOC=simulatedSOC;
		
		let color;
		if (hour.chargingMode==CHARGING_GRID) color="rgb(255,0,0)";
		else if (hour.chargingMode==CHARGING_PRIORITISE) color="rgb(255,160,0)";
		else if (hour.dischargingMode==DISCHARGING_OFF) color="rgb(255,255,0)";
		else if (hour.pvYield>=hour.consumption) color="rgb(192,255,64)";
		else color="rgb(0,255,0)";		
		backgrounds.push(color);
	}


	// Build configuration for the chart
	const settings=
	{ 
		type: "bar",
		data: 
		{
			labels,
			datasets: [
				{
					label: "Optimierung",
					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: -10,
					padding: 0,
					backgroundColor: 'white',
					color: 'black',
					font: { size: 7 }
				}
			},
			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;

it now says : error, settings not defined (copy paste your script).

In the script line 36 settings is grayed out.

EDIT; taking a closer look it says;
‘settings’ is declared but its value is never read.(6133)

Seems the extra bracket at the end is causing this trouble, but I don’t know. Everything further than old school VB is like chinese for me, but learning here.

I’m sorry. I’ll send you a personal message, because think I am missing some context.

Hi,

I tried to copy paste the script info but it does not function. Is this the full script?

Just not possible for me to implement, for that I regret the scripting part since your output is very nice!

P

Torch1969

would you be so kind to share the code to adjust the defaults like you did?

Yes, somewhere in the coming days. I need to use my computer to be able to copy the code :smirk:

1 Like

Perfect! Take it easy, wait for you.