<item>.deltaSince(..) does not provide "delta" for rain counter for Homematic WeatherStation HmIP-SWO-PL

I am a little bit puzzled.
I have searched the WWW to get the job done with less work, but then I stumpled into trouble after few minutes.

SYSTEM / INSTALLATION

Homematic CCU3

Version:     3.2.0.M4 (Build)

User:        openhab (Active Process 18408)
User Groups: openhab tty dialout audio

Directories: Folder Name      | Path                        | User:Group
             -----------      | ----                        | ----------
             OPENHAB_HOME     | /usr/share/openhab          | openhab:openhab
             OPENHAB_RUNTIME  | /usr/share/openhab/runtime  | openhab:openhab
             OPENHAB_USERDATA | /var/lib/openhab            | openhab:openhab
             OPENHAB_CONF     | /etc/openhab                | openhab:openhab
             OPENHAB_LOGDIR   | /var/log/openhab            | openhab:openhab
             OPENHAB_BACKUPS  | /var/lib/openhab/backups    | root:root

INTRO

In most examples (not specific for the Homematic WeatherStation) the people just use deltaSince(..) (openHAB documentation Persistence | openHAB) to calculate the delta between two dates, e.g. from now to now.minusDays(1).

I tried this, and I already have logged data based on rrd4 stored in /var/lib/openhab/persistence/rrd4j. The file is recently refreshed during the writting of this post:
image
I have not done any additional setup, everything was already present with openHAB3. As far as I see, approx 99% of all tutorials in the WWW are about openHAB2 persistence for which additional setup is needed, but not for openHAB3.

The binding in openHAB looks like this:

And the item configuration in /var/lib/openhab/jsondb/org.openhab.core.items.Item.json as follows:

  "Wetterstation_RainCounter": {
    "class": "org.openhab.core.items.ManagedItemProvider$PersistedItem",
    "value": {
      "groupNames": [
        "Wetterstation"
      ],
      "itemType": "Number:Length",
      "tags": [
        "Point"
      ],
      "label": "Rain Counter",
      "category": "Rain"
    }
  },

In my CCU3 it looks like this (I do not why the amount of rain is approx 22 and not 29 as seen in the previous screenshot, that is not my question):
image

ISSUE

Few minutes (maybe a hour) ago I have put up to 1 liter of water into the sensor, the is raining switch signaled this immediatelly, fine.

Now, when I try to get the delta from yesterday to right now, I always get the full amout of rain since start of the measurement/device installation two weeks ago.

My log instructions:

logInfo("INFO", String::format("%s   Hour  1: %s", now.minusHours( 1), Wetterstation_RainCounter.deltaSince(now.minusHours( 1))))
logInfo("INFO", String::format("%s   Hour  2: %s", now.minusHours( 2), Wetterstation_RainCounter.deltaSince(now.minusHours( 2))))
logInfo("INFO", String::format("%s   Hour  3: %s", now.minusHours( 3), Wetterstation_RainCounter.deltaSince(now.minusHours( 3))))
logInfo("INFO", String::format("%s   Hour  4: %s", now.minusHours( 4), Wetterstation_RainCounter.deltaSince(now.minusHours( 4))))
logInfo("INFO", String::format("%s   Hour  5: %s", now.minusHours( 5), Wetterstation_RainCounter.deltaSince(now.minusHours( 5))))
logInfo("INFO", String::format("%s   Hour  6: %s", now.minusHours( 6), Wetterstation_RainCounter.deltaSince(now.minusHours( 6))))
logInfo("INFO", String::format("%s   Hour  7: %s", now.minusHours( 7), Wetterstation_RainCounter.deltaSince(now.minusHours( 7))))
logInfo("INFO", String::format("%s   Hour  8: %s", now.minusHours( 8), Wetterstation_RainCounter.deltaSince(now.minusHours( 8))))
logInfo("INFO", String::format("%s   Hour  9: %s", now.minusHours( 9), Wetterstation_RainCounter.deltaSince(now.minusHours( 9))))

logInfo("INFO", String::format("%s   Days  1: %s", now.minusDays( 1), Wetterstation_RainCounter.deltaSince(now.minusDays( 1))))
logInfo("INFO", String::format("%s   Days  2: %s", now.minusDays( 2), Wetterstation_RainCounter.deltaSince(now.minusDays( 2))))
logInfo("INFO", String::format("%s   Days  3: %s", now.minusDays( 3), Wetterstation_RainCounter.deltaSince(now.minusDays( 3))))
logInfo("INFO", String::format("%s   Days  4: %s", now.minusDays( 4), Wetterstation_RainCounter.deltaSince(now.minusDays( 4))))
logInfo("INFO", String::format("%s   Days  5: %s", now.minusDays( 5), Wetterstation_RainCounter.deltaSince(now.minusDays( 5))))
logInfo("INFO", String::format("%s   Days  6: %s", now.minusDays( 6), Wetterstation_RainCounter.deltaSince(now.minusDays( 6))))
logInfo("INFO", String::format("%s   Days  7: %s", now.minusDays( 7), Wetterstation_RainCounter.deltaSince(now.minusDays( 7))))

The output of this looks like:

2021-11-11 08:33:15.026- 2021-11-11T08:33+01:00[Europe/Berlin]
2021-11-11 08:33:15.031- 2021-11-11T07:33:15.027617+01:00[Europe/Berlin] Hour1: 29.1708
2021-11-11 08:33:15.036- 2021-11-11T06:33:15.032677+01:00[Europe/Berlin] Hour2: 29.172599999999999996
2021-11-11 08:33:15.041- 2021-11-11T05:33:15.037773+01:00[Europe/Berlin] Hour3: 29.172599999999999996
2021-11-11 08:33:15.044- 2021-11-11T04:33:15.042213+01:00[Europe/Berlin] Hour4: 29.172599999999999996
2021-11-11 08:33:15.047- 2021-11-11T03:33:15.045551+01:00[Europe/Berlin] Hour5: 29.172599999999999996
2021-11-11 08:33:15.051- 2021-11-11T02:33:15.048737+01:00[Europe/Berlin] Hour6: 29.172599999999999996
2021-11-11 08:33:15.053- 2021-11-11T01:33:15.051784+01:00[Europe/Berlin] Hour7: 29.172599999999999996
2021-11-11 08:33:15.056- 2021-11-11T00:33:15.054623+01:00[Europe/Berlin] Hour8: 29.172599999999999996
2021-11-11 08:33:15.059- 2021-11-10T23:33:15.057553+01:00[Europe/Berlin] Hour9: 29.172599999999999996
2021-11-11 08:33:15.062- 2021-11-10T08:33:15.060504+01:00[Europe/Berlin] Days1: 29.172599999999999996
2021-11-11 08:33:15.065- 2021-11-09T08:33:15.063243+01:00[Europe/Berlin] Days2: 29.172899999999999997
2021-11-11 08:33:15.068- 2021-11-08T08:33:15.065974+01:00[Europe/Berlin] Days3: 29.173399999999999998
2021-11-11 08:33:15.071- 2021-11-07T08:33:15.068801+01:00[Europe/Berlin] Days4: 29.1758
2021-11-11 08:33:15.074- 2021-11-06T08:33:15.072227+01:00[Europe/Berlin] Days5: 29.1791
2021-11-11 08:33:15.076- 2021-11-05T08:33:15.075063+01:00[Europe/Berlin] Days6: 29.1793
2021-11-11 08:33:15.079- 2021-11-04T08:33:15.077785+01:00[Europe/Berlin] Days7: 29.1829

As you can see, all calculations provide the total amount.

By the way… this diff looks interesting as well:
image

When I use historicState(..) it would be possible to calculate the delta on my own, but why should I when some functionality already exist ? :slight_smile:

Call of historicState(..):

logInfo("INFO", String::format("%s   Hour  1: %s", now.minusHours( 1), Wetterstation_RainCounter.historicState(now.minusHours( 1)).state.toString))
logInfo("INFO", String::format("%s   Hour  2: %s", now.minusHours( 2), Wetterstation_RainCounter.historicState(now.minusHours( 2)).state.toString))
logInfo("INFO", String::format("%s   Hour  3: %s", now.minusHours( 3), Wetterstation_RainCounter.historicState(now.minusHours( 3)).state.toString))
..
..

Output:

2021-11-11 08:33:15.087 [INFO ] 2021-11-11T06:33:15.084252+01:00[Europe/Berlin]   Hour  2: 0.027400000000000004 m
2021-11-11 08:33:15.089 [INFO ] 2021-11-11T05:33:15.087895+01:00[Europe/Berlin]   Hour  3: 0.027400000000000004 m
2021-11-11 08:33:15.092 [INFO ] 2021-11-11T04:33:15.090703+01:00[Europe/Berlin]   Hour  4: 0.027400000000000004 m

BUT, when I try to use the same approach for other values like the amount of power I produced with my solarplant everything looks fine:

logInfo("INFO", String::format("%s   Hour  1: %s", now.minusHours( 1), PV_Garage_ETotal.deltaSince(now.minusHours( 1))))
logInfo("INFO", String::format("%s   Hour  2: %s", now.minusHours( 2), PV_Garage_ETotal.deltaSince(now.minusHours( 2))))
logInfo("INFO", String::format("%s   Hour  3: %s", now.minusHours( 3), PV_Garage_ETotal.deltaSince(now.minusHours( 3))))

Output:

2021-11-11 08:33:15.132 [INFO ] 2021-11-11T07:33:15.131868+01:00[Europe/Berlin]   Hour  1: 0.055
2021-11-11 08:33:15.134 [INFO ] 2021-11-11T06:33:15.133515+01:00[Europe/Berlin]   Hour  2: 0.055
2021-11-11 08:33:15.135 [INFO ] 2021-11-11T05:33:15.135031+01:00[Europe/Berlin]   Hour  3: 0.055

This output seems to be correct as since August I have produced approx 248 kW and today the sun is rising in the moment, so the amount is very low.
image

Question

Do I have to change any setting for the persistance of the rain values?
Do you need more information for giving any suggestions?
What should I do to calculate the correct delta between two time values?

You might look into how rrd4j works. It compresses old data, by discarding and averaging data, the older the more compressed.

That’s to keep the database a fixed size, and it works great for graphing and charting, where we need less detail the more time the chart covers.

Also makes it useless for serious “maths”. Yesterday’s data is a bit “blurred”, last week’s data is blurrier. The archive structure gives weird effects too; yesterdays value may be one thing when looking in a “one-day” table and something different for the same moment when looking in a “one-month” table.

Not all the persistence services provide all the possible functions. I’m a bit surprised delataSince() is even implemented in rrd4j, but I suppose it can work under some circumstances.

It is possible to manually configure rrd4j to store data in different ways that may make it more suitable for your purpose.

Most users simply use a more conventional database like InfluxDB for this kind of data.

Alright, I switched over to InfluxDB by help of this nice tutorial:

I imported few datasets from rrd4j with this nice tool:

So far, I will give it a try.

Thanks.

I would have had a look into the (rrd4j) database before switching. That way WE would know what the culprit was that you observed.
Until now .deltaSince is working for me in rrd4j without problems!

Good point. So far as I know, persistence features may still stumble over ‘gaps’ (NaN) in rrd4j archives. The likelihood of encountering a NaN depends on individual use patterns, and decreases as you reach further back in time.

1 Like

Feel free to analyze. I do not have more time to spend for this, I need the job done otherwise I will have some trouble with my wife.

Remark: I had to add the extension .txt to get this uploaded. The original filename is Wetterstation_RainCounter.rrd.

Wetterstation_RainCounter.rrd.txt (738.0 KB)

1 Like

As far I remember classic rrd… you can have buckets of different kinds (avg, max, min) and different time (second, minute, day, year) and number of buckets (ie. 2*year).
Effectively it means that you could store an average values for a bucket which has high density and provide normal querying options. Not sure if rrd4j works same way, in practice all boils down to proper construction of rrd buckets.

I just like to give the feedback that it looks good with influxdb.
I have put water inside the sensor three times today.
As you see I got three measurements:
image

By the way, I recognized that the sensor increases the water amount all the time. On Homematic CCU3 WebGui is a reset button, but this button just resets “virtual” / “internal” system variables, and probably not the global counter.

These are the moments where I put the water:

Fri Nov 12 2021 09:08:46 GMT+0100 (Central European Standard Time)
1636704526572000000 Wetterstation_RainCounter 30.1

Fri Nov 12 2021 12:49:26 GMT+0100 (Central European Standard Time)
1636717766815000000 Wetterstation_RainCounter 31.3

Fri Nov 12 2021 13:16:52 GMT+0100 (Central European Standard Time)
1636719412560000000 Wetterstation_RainCounter 31.9

Tested with my previous mentioned rule file:

logInfo("INFO", String::format("%s   Minutes 10: %s", now.minusMinutes( 10), Wetterstation_RainCounter.deltaSince(now.minusMinutes(10))))
logInfo("INFO", String::format("%s   Minutes 20: %s", now.minusMinutes( 20), Wetterstation_RainCounter.deltaSince(now.minusMinutes(20))))
logInfo("INFO", String::format("%s   Minutes 30: %s", now.minusMinutes( 30), Wetterstation_RainCounter.deltaSince(now.minusMinutes(30))))
logInfo("INFO", String::format("%s   Minutes 40: %s", now.minusMinutes( 40), Wetterstation_RainCounter.deltaSince(now.minusMinutes(40))))
logInfo("INFO", String::format("%s   Minutes 50: %s", now.minusMinutes( 50), Wetterstation_RainCounter.deltaSince(now.minusMinutes(50))))

logInfo("INFO", String::format("%s   Hour  1: %s", now.minusHours( 1), Wetterstation_RainCounter.deltaSince(now.minusHours( 1))))
logInfo("INFO", String::format("%s   Hour  2: %s", now.minusHours( 2), Wetterstation_RainCounter.deltaSince(now.minusHours( 2))))
logInfo("INFO", String::format("%s   Hour  3: %s", now.minusHours( 3), Wetterstation_RainCounter.deltaSince(now.minusHours( 3))))
logInfo("INFO", String::format("%s   Hour  4: %s", now.minusHours( 4), Wetterstation_RainCounter.deltaSince(now.minusHours( 4))))
logInfo("INFO", String::format("%s   Hour  5: %s", now.minusHours( 5), Wetterstation_RainCounter.deltaSince(now.minusHours( 5))))
logInfo("INFO", String::format("%s   Hour  6: %s", now.minusHours( 6), Wetterstation_RainCounter.deltaSince(now.minusHours( 6))))
logInfo("INFO", String::format("%s   Hour  7: %s", now.minusHours( 7), Wetterstation_RainCounter.deltaSince(now.minusHours( 7))))
logInfo("INFO", String::format("%s   Hour  8: %s", now.minusHours( 8), Wetterstation_RainCounter.deltaSince(now.minusHours( 8))))
logInfo("INFO", String::format("%s   Hour  9: %s", now.minusHours( 9), Wetterstation_RainCounter.deltaSince(now.minusHours( 9))))

Looks good so far:

Now I can finally start to implement the rule for my irretation plant.

:smirk: Great statement for someone who is asking for help from others.

I gave all information I can give with the information I have and I can get by using several search engines, using this forum(search), using a lot of blog posts, etc. I already spend hours and days for simple things to get running. I am sorry that you are not happy about that statement, but simple things should just be run on simple ways. The combination of several different sensor technologies/approaches and a lot of different software components does not make it easy to establish a well working home automation infastructure. But yeah, as for all of us we do it as volunteers and as I already approved, the best statement was written by “rossko57” and his answer is accepted as solution – sooooo actually its done. But ok, try to blame me, its fine.

I was NOT able to open this .rrd file with the rrd4j-3.3.1-inspector.
No clue what was going on!

[Edit:]
Used the wrong .jar! With the 3.8 version the .rrd file is readable and the strored values do not give a clue why that function is not returning the correct value (IMHO).
I do see only increasing values (as stated).

Thanks for your feedback.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.