Accumulator has downward steps
-
Calculating kWh (using the simple formula given as an example in the forum) and finding drops in the chart, which makes no sense. I have verified that the additive is positive, yet I still see a pattern I cannot explain.
The formula is simple:
return my.value + (power.past(MINUTE,1).average/60);
But the result is unexpectedly jagged:
I expect this is due to the formula looking back too far for the previous (current) value, but I haven't had any luck calculating a better window. As an example, here is some of what I have been attempting:
var prev = my.lastValue(0); var lastVal = (null === prev) ? my.value : prev.value; return lastVal + (power.value/60);
FWIW, the data point is not set to update the context; instead, it's set to update every minute.
Any clarification is greatly appreciated.
Thanks,
Aldo
-
Hi Aldo,
The first thing that comes to mind is that in a history generation
my.lastValue(0)
isn't going to be the last value before the time of the historical execution - it's always going to query the database for that value. You could add the cache control argument likemy.lastValue(0, true);
but I think you would get the current value of the point.Instead, simply use
my.value
. If you must, usemy.pointValueBefore(CONTEXT.getTimestamp())
I do tend to agree that in the first snippet you posted the last minute's average must seemingly be negative to get those drops. Or, perhaps you generated the history more than once and something was slightly different on the calculation? Are you purging value in between regenerating them? Perhaps the logging type of the Meta point isn't something simple like All data or Point value changes?
-
Thanks @phildunlap
I did consider that
my.lastValue
would be returning current values, not historical. I have been working on a more complex function to work with that, but wasn't ready to post it, yet.However, the graph I posted was from data created in real-time (not history generation). And I explicitly purged all data before that run executed. I also typically purge and check the "Delete existing data in range" when generating history, to avoid the chance of running into such values.
Here is the more complex time-traveler version (possibly buggy; I was just throwing stuff together, and haven't gone through with a fine-t0othed comb and debugged yet):
//LOG.debug(my); //var lv = my.lastValue(); LOG.debug("my.time:\t" + my.time); var lv = my.pointValueBefore(my.time); LOG.debug("lv:\t" + lv.value); var lastValue = ((null === lv) ? 0 : lv.value); LOG.debug("lastValue:\t" + lastValue); //var stats = power.past(MINUTE,1); var stats = power.getStats(my.time-60000, my.time); LOG.debug("stats:\t" + stats); if ((null === stats)) { LOG.debug("stats:\tnull"); return lastValue; } else if ((0 === stats.length) || (0 === stats.count)) { LOG.debug("stats:\tempty"); LOG.debug("power:\t" + power.pointValueAt(my.time)); return lastValue + ((power.pointValueAt(my.time)/60)/1000); } else { LOG.debug("stats.average:\t" + stats.average); return lastValue + ((stats.average/60)/1000); }
While I would like having a function I can use for generating history as well as runtime, I would expect at least the simple formula to work, and it would go a long way to helping debug the more complex version.
-
I could see how on
my.pointValueBefore(my.time)
could run into issues in a history generation without use of the cache control, somy.pointValueBefore(my.time, true)
If the logic you want is
return my.value + (power.past(MINUTE,1).average/60);
I think we should approach from why this would not be working. Have you tried generating history forreturn (power.past(MINUTE,1).average/60);
to ensure you're getting the positive values? That simple form is what I think would be the right way to write it.