Hi, I have some rules that count the time some items were on.
I want to know is he rounding the minutes, or what is the default behavior?
When I inspect the item value in cli, there is never any decimals, just whole numbers, so if he says 4, does it mean it might have been 4 minutes and 29 seconds, and then those 29 seconds are lost in the overall counter?
I know I can use seconds, but I want to simplify my rules and not have proxy items to seconds, then /60 to get minutes.
rule "Daily AC runtime Bedrooms started"
when
Item ACRooms1 received update 26 or
Item ACRooms1 received update 33
then
if(DebounceACRooms.state != ON){
postUpdate(ACRooms1_LastOnState, new DateTimeType())
DebounceACRooms.sendCommand(ON)}
end
rule "Daily AC runtime Bedrooms stopped"
when
Item ACRooms1 changed to 0
then
if(DebounceACRooms.state != ON && ACRooms1.averageSince(now.minusMinutes(2)) > 0.1) {
var DateTimeType prevOnState = (ACRooms1_LastOnState.state as DateTimeType).getZonedDateTime()
var Number execDuration = Duration.between(prevOnState, ZonedDateTime.now()).toMinutes()
var Number dailyTotalMinutes = execDuration + ACRooms1_Today_Runtime_Min.state as Number
postUpdate(ACRooms1_Today_Runtime_Min, dailyTotalMinutes)
DebounceACRooms.sendCommand(ON)}
end
so you are saying that if I write “Duration.between(prevOnState, ZonedDateTime.now()).toMinutes()” to a Number item, it will have somehow hidden seconds inside, and when I run it next time, he will take into consideration the seconds while adding more time to the duration?
I don’t care for seeing the actual seconds, just want the sum of runtime in minutes, but calculated with taking seconds in consideration
or you are saying it returns only integer number of minutes, if I requested it to give me minutes.
in that case, if 3 minutes and 59 seconds elapsed, he will write 3 minutes? or 4 minutes? no rounding is happening?
so in that case i have to use seconds to get accurate calculation
something like
var DateTimeType prevOnState = (ACRooms1_LastOnState.state as DateTimeType).getZonedDateTime()
var Number execDuration = Duration.between(prevOnState, ZonedDateTime.now()).toSeconds()
var Number todaySeconds = ACRooms1_Today_Runtime_Min.state as Number * 60
var Number dailyTotalSeconds = execDuration + todaySeconds
var Number dailyTotalMinutes = dailyTotalSeconds / 60
postUpdate(ACRooms1_Today_Runtime_Min, dailyTotalMinutes)
should I drop “as Number” from line 3?
So I want to permanently store only minutes in an Item, but since I need seconds for more accurate calculation, then I “unpack” stored minutes to seconds to add more seconds to it, then convert it back to minutes. while doing these conversions, I’ll probably end up with decimal values, but thats ok as I can hide them on the sitemap
sorry for overcomplicating stuff, I already had a working rule with 2 items, one storing seconds, one storing minutes, just trying to reduce the number of my items, and persisted items.
OK, I went back to seconds but without storing the seconds in any item
here is my final rule
var DateTimeType prevOnState = (ACRooms1_LastOnState.state as DateTimeType).getZonedDateTime()
var Number execDuration = Duration.between(prevOnState, ZonedDateTime.now()).toSeconds()
var Number todaySeconds = ACRooms1_Today_Runtime_Min.state as Number * 60
var Number dailyTotalMinutes = (execDuration + todaySeconds) / 60
postUpdate(ACRooms1_Today_Runtime_Min, dailyTotalMinutes)
and now I’m getting values like 22.2 stored in minutes item, so I am not losing any time. sorry if you lost some time on this
I just want to add that Java ZonedDateTimes and Durations maintain values down to nanoseconds.
Also, if you set your ACRooms1_Today_Runtime_Min Item to be a Number:Time you can avoid some work in the time and let OH do the conversations for you.
For example, if you accept the default unit of “seconds” or “s” you can postUpdate dailyTotalSeconds + ' s' to the Item and use 1$tH:%1$tM:%1$tS (for example) in the sitemap/item label or state description patterns to get hours:minutes:seconds on the UIs.
Note that a hack (the duration was added to a date time and then formatted as such) was used to evaluate this prior to OH 4.2 that had limitations so this may not meet your needs in those versions. In 4.2 there are no such limitations.
thanks for suggestions. I’m still on 4.02. But definitely I should create some order in my time items, as they are not all unified, I should probably accept the default of 4.2 once I upgrade and move all items to seconds
The only problem I see is that some of these items are being persisted for years, with nice graphs based on influxdb data, so it will be a pain to lose all that and start from scratch
set the unit metadata of the Item to be what ever you are saving now (minutes I presume)
then change the type of the Item to Number:Time
then set the State Description pattern to what ever you want to see
Follow that procedure and you should not lose your persisted data and the saved values will make sense. If you do it is some other order your charts might get messed up. As long as you keep the same Item name and don’t change to some wholly different type (e.g. from Number to String) your data will still be there.
ah right, I was under the impression that default of Number:Time is seconds and that it cannot be changed, so in that case whatever items I have that were in minutes, would have to become seconds, so the graphs would not make sense…But if I can configure them to remain minutes, then all good.
Bigger problem is that I have some other persisted counters that I stupidly made in hours, so now I cannot easily move them to minutes to make it unified across all time items. If I convert them, the graphs won’t make sense. I would have to retroactively rewrite all values in influxdb
Yep, that’s what the unit metadata is for. The system default isn’t always what you want so it’s configurable though Item metadata.
I can’t help with that. Unfortunately you’ll have to update the old values but you should be able to figure out how to do it with a script or something.