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?

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.

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