How to use the Riemann Sum Persistence Extension?

Hi,

just upgraded to OH5.0M2 (Docker image on X86) to explore the new Riemann Sum persistence extension (Persistence Extensions: Riemann Sums by mherwege · Pull Request #4461 · openhab/openhab-core · GitHub). Upgrade went smooth, all Items are up and working - great job!

Now what do I need to do to calculate the Riemann Sum for my Solar generator? I do capture and persist the current energy generated. Is it like the sumBetween persistence function? There is currently nothing to be found in the latest documentation about this.

Thanks!

There is documentation in the ‘next’ version of the documentation: Persistence | openHAB

1 Like

… ahh, very cool - that works:

val Riemann = (PV_Power.riemannSumBetween(now.with(LocalTime.MIDNIGHT),now())

But this does not:

val Riemann = (PV_Power.riemannSumBetween(now.with(LocalTime.MIDNIGHT),now(),RiemannType.TRAPEZOIDAL,"rrd4j")
2025-05-01 17:37:40.574 [ERROR] [.handler.AbstractScriptModuleHandler] - Script execution of rule with UID 'test-1' failed: The name 'RiemannType' cannot be resolved to an item or type; line 16, column 79, length 11 in test

Any idea? Thanks!!

Which language do you use? JS, rules DSL?
That’s unclear in both, in your post as well as in the example from the docs.
FWIW in the docs it’s even tagged as being ‘java’ which I think is plain wrong.
@Mherwege maybe you can rework the docs a little and give examples in both languages.

… oh, sorry - I’m (still) using rule DSL. Isn’t that what the documentation is for?

It looks like Rules DSL does not see the static Enum.

I was able to make it work by importing the enum, or refering to it explicitly for a DSL rule defined in the UI:

val Riemann = PV_Power.riemannSumBetween(now.with(LocalTime.MIDNIGHT),now(),org.openhab.core.persistence.extensions.PersistenceExtensions.RiemannType.TRAPEZOIDAL,"rrd4j")

I was expecting it to work for a file based rule with an import as well:

import org.openhab.core.persistence.extensions.PersistenceExtensions.RiemannType

PV_Power.riemannSumBetween(now.with(LocalTime.MIDNIGHT),now(),RiemannType.TRAPEZOIDAL,"rrd4j")

This is clearly not what I intended and I am looking into it. This should already be better when using javascript, jruby or even Blockly.

So far, all the extensions only have been documented with DSL syntax in the persistence documentation. The specific parts of the other language documentations have their specific syntax documented. I agree it would be nice to have it documented for all languages everywhere, but that is a more structural change to the documentation and beyond what was done here. As far as I know there is no specific format tagging for dsl and java tagging is used throughout the documentation for that. It is not something I have touched.

Haven’t tried myself but I believe there must be. There’s various places in the docs that have tabs in the examples sections to show the code in at least JS, DSL and sometimes other languages.

Unless I miss it, I don’t see it show dsl anywhere, it is all tagged as java (or not at all) when it is showing DSL code: Textual Rules | openHAB. Correct for js or yaml though.
And yes, there are places in the docs with tabs. That is in itself very incomplete and I didn’t do anything on that or on any of the code examples on this page.

See the “When the sun …” paragraph of the link I gave. It even has an ‘UI’ tab.
I’d think that even if you don’t have code handy in all languages, you should at least use this template format to name the language you’re giving the example in.

Then again seems there is a bug right with the default, DSL that apparently is … it shows java instead in the upper right when you select the upper left ‘DSL’ tag but rightly shows js and rb when you select JS or JRuby there.
cc: @stefan.hoehn

Fair enough. But then again, I added exactly one code block on that entire persistence page. And also in what you show, under the DSL tab, the code is tagged as java. It would be useful to go through the documentation and change it to do show tabs everywhere, but that is off topic for this discussion.

I can confirm the following javascript (even generated from Blockly code) works as expected:

console.info((items.getItem('Aussentemperatur').persistence.riemannSumBetween(time.ZonedDateTime.now().minusYears(1), time.ZonedDateTime.now().plusHours(1), items.RiemannType.TRAPEZOIDAL, 'rrd4j')?.quantityState));

This is a pure DSL issue. I haven’t figured out yet how to solve this.

I have created an issue: RiemannType file based DSL not working · Issue #4784 · openhab/openhab-core · GitHub. Hopefully someone has an idea.

Just a general remark regarding the naming: While the name of this extension is technically correct, it was putting me off initially, as it sounds more complicated than necessary. Grafana calls similar functionality ‘integral’, which conveys the intention more clearly, even though it’s only an approximation.

1 Like

If it’s a suitable replacement, maybe we can still rename this now, since it was only introduced in 5.0, wdyt @Mherwege ?

I have no objection in principe to change the name, although the chosen name is mathematically more correct. I understand integral is easier to understand. The original request came from @dandjo. What’s your view?

An integral is a mathematical concept that represents the area under a curve, while a Riemann sum is a method used to approximate that area by dividing it into smaller shapes, like rectangles, and summing their areas. The Riemann sum approaches the actual value of the integral as the number of shapes increases and their size decreases. So calling a Riemann sum an integral is not only inaccurate, but strictly speaking, actually wrong.

So let’s stick with the name it has right now. I agree Riemann sum is the right name for it. But I also know it will be used in practice to approximate the integral value, although it will never be the real integral (as the real curve is undefined from the measurements). But that doesn’t mean it should be given a name it is not.

@jimtng The issue about it not working in file based DSL’s is more pressing I believe (see github issue linked above), and should be solved before release. Do you have idea about this?

I’m not sure if it’s the same, but this is how I added some variables to DSL: Add sharedCache and privateCache to file-based RulesDSL by jimtng · Pull Request #4525 · openhab/openhab-core · GitHub. IIRC, ScriptJvmModelInferrer applies to UI DSL and RulesJvmModelInferrer applies to file-based DSL.

I think this one may be closer to what you’re looking for: openhab-core/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/scoping at main · openhab/openhab-core · GitHub

Thank you for the link. I already saw that, but I am not sure that solves it. RiemannType is not a parameter to the rule or script, but a parameter to one of the called actions. Defining it in implicit imports makes it available in the UI, but when used in a file based script, it can’t find the PersistenceExtensions class (although RiemannType is an enum member of it), stating it is null. It looks like something is going on with OSGI not liking (and making available) static members.

Also, ScriptJvmModelInferrer should apply to file based rules as well (but just the script part of the rule).

We might have to put RiemannType into a separate class / file?

@jimtng I tried that, but without result. It still works for UI defined rules, but now also gives a warning when initially loading the file based rule.