How to calculate appliance exact accumulated electricity cost

Hi, I need to calculate certain appliances exact accumulated electricity cost.
I’m persisting each hour electric price and each appliance kWh value.
While/do-while and for cycles are quite unfamiliar to me- I would ask some advice regarding the correct rule format.
This is what I have come up with (probably full of mistakes):

rule "Electricity hourly cost sum per device"
when
    Item RunRule changed or
	Time cron "0 0/1 * 1/1 * ? *"
then
    var i = 0
	var x = now.withTimeAtStartOfDay //here I need to get int which is equal to hours from beginning of day until now
	var A = appliance_ElectricMeterKWh
	var B = Electricity_price
	var Sum = 0
    while((i=i+1) < x) {
		product = [A.deltaSince(now.minusHours(i).minusHours(i-1))*B.historicState(now.minusHours(i))]
		Sum = Sum + product
    }
	Appliance_El_price_up_to_moment.postUpdate(Sum)
end

Is this how it is done or is there an easier way? Or is there just more elegant way to achieve it?

Here are a few of the mistakes I see.

  • now.withTimeAtStartOfDay gives you a DateTime Object for midnight today. If you want the number of hours since midnight use now.getHourOfDay.

  • Please use meaningful variable names.

  • Why not keep a running Sum instead of reacalculating it for every hour? You already have the sum for all the hours up to now in Appliance_El_price_up_to_moment. So just take the reading and price for the past hour and add them to Appliance_El_price_up_to_moment and you won’t have to have a loop. Just remember to reset it to zero at midnight.

Thanks

updated/changed somewhat

I wanted to create universal code which I could later use to calculate appliance daily, monthly etc electricity cost. I don’t want to persist appliances electricity cost- I prefer to calculate it every time based on historic hourly energy consumed and electricity price at that hour. Live sum can’t use historic data and would start over after system start/crash.

rule "Electricity hourly cost sum per device"
when
    Item RunRule changed or
	Time cron "0 0/1 * 1/1 * ? *"
then
    var i = 0
	var x = now.getHourOfDay //here I need to get int which is equal to hours from beginning of day until now
	var A = appliance_ElectricMeterKWh
	var B = Electricity_price
	var Total_Cost = 0
    while((i=i+1) < x) {
		Cost_per_hour = [A.deltaSince(now.minusHours(i).minusHours(i-1))*B.historicState(now.minusHours(i))]
		Total_Cost = Total_Cost + Cost_per_hour
    }
	Appliance_El_price_Total_Cost.postUpdate(Total_Cost)
end

Not if you persist Applicance_El_price_Total_Cost and use restoreOnStartup. That’s the whole reason restoreOnStartup exists.