Arithmetic mean vs average linear/step interpolation

I did not file issues yet but implemented a pretty accurate calculation for power consumptions in a JS rule. This could be a nice gimmick for openHAB core and the rule API (JS and DSL). Input is an Item with a series of power consumptions. It will calculate the Riemann Sum with Midpoint strategy.

https://www.statisticshowto.com/calculus-problem-solving/riemann-sums/

  const calcRiemannSumMidpoint = function(item) {
    const PersistenceExtensions = Java.type('org.openhab.core.persistence.extensions.PersistenceExtensions');
    const Duration = Java.type('java.time.Duration');
    const ZonedDateTime = Java.type('java.time.ZonedDateTime');
    const LocalTime = Java.type('java.time.LocalTime');
    const midnight = ZonedDateTime.now().with(LocalTime.MIDNIGHT);
    const now = ZonedDateTime.now();
    const states = PersistenceExtensions.getAllStatesBetween(items.getItem(item).rawItem, midnight, now);
    if (states.size() === 0) {
      return 0;
    }
    let dtPrev = Duration.between(midnight, states[0].getTimestamp()).toNanos() / 3600000000000;
    let dtNext = Duration.between(states[states.size() - 1].getTimestamp(), now).toNanos() / 3600000000000;
    let sum = 0;
    for (index = 0; index < states.size(); index++) {
      const curr = states[index];
      const prev = states[index - 1];
      const next = states[index + 1];
      if (prev) {
        dtPrev = Duration.between(prev.getTimestamp(), curr.getTimestamp()).toNanos() / 3600000000000 / 2;
      }
      if (next) {
        dtNext = Duration.between(curr.getTimestamp(), next.getTimestamp()).toNanos() / 3600000000000 / 2;
      }
      sum += (dtPrev * curr.getState().floatValue()) + (dtNext * curr.getState().floatValue());
    }
    return sum;
  };
1 Like