[APP][Pro] Insight Trends Reloaded

That an Issue on your flow.

What is the output for NettoP of the caluclate trend?
What does the app settings show on NettoP

NettoP is the result of PeakP minus actual power usage. PeakP is the maximum allowed power value (3600W) I would use for load balancing. If I have power of my solar panels, PeakP can be more than 3600W. With the Insight trend calculation, I would determine the average value of NettoP for the last minute…. On the graph it is clear - NettoP works fine. Only the calculation of average value is not working.

There is somehow an error, but I can’t say where. You would take a look why and where the data is wrongly passed. I don’t think it’s inside my app since I haven’t changed anything for a long time

How could I check where the data is struggling?

See if the trend is correctly calculated inside the app settings.
See if the outs of the flow are correct and not 0
Change time range of the caluclation etc…

Thanks for your help!

Is there a problem with negative values during comparison?

Flow says it’s not smaller than -0.000416

Test on configuration page says different (correct value) - and -0.000067xxx is defnitely smaller than -0.0000416

I’m experiencing something similar. The card which is checking “if trend is larger then”, doesn’t work anymore since the update in July. Before it was working just fine, but now it is always false no matter the value. Is this a bug? It worked before and I didn’t change anything. Checked the values, either I’m using it wrong or the card is not able to do proper comparisons anymore.

As you can see, the card is false, but the actual values suggest the oposite.

Also if the values are actually smaller than 0.003 the card is still false, which then would be correct.

Thank you

Lenny

Strange Issue, since I didnt changed anything at the code itself. I just updated dependency. I’ll take a look at this issue.

Nerd stuff:

    public static compare(a: number, b: number, operator: string): boolean {
        if (operator === "smaller") return a < b;
        if (operator === "smaller_equal") return a <= b;
        if (operator === "equal") return a === b;
        if (operator === "not_equal") return a !== b;
        if (operator === "greater") return a > b;
        if (operator === "greater_equal") return a >= b;
        return false;
    }

I mean this should work. I’ll need to debug this issue

Could it be a localisation issue?

, instead of .

I tried both, but it always changes back to , as I’m in Germany and the German localisation uses , and not .

Hey @L3nny and @m.plo.b

I’ve put together a test build with some extra debug logging for the flow card that’s been acting up.
If you’ve got a minute, please give it a try and help me figure out what’s going on:

  1. Install the test version of the app.
  2. Run the flow manually once (just to trigger the card).
  3. Right after running it, go to the app settings and send a diagnostic report.

Please do that immediately after running the flow, the report only includes the most recent logs, and they get overwritten pretty fast.

That should give me the full picture in the logs so I can finally nail down what’s happening here.

1 Like

Hey @spkesDE
Done: 11260a3a-9e00-4f1d-90c3-08a0807d9aa6

Thank you
Lenny

Got your log, thanks! :folded_hands:

The card itself is working correctly:

trend slope: 2.566790501511337e-7
trend (token output): 0.0002566790501511337
trend (token output): 0.0000002566790501511337
args.value: 0.00003

comparison: 0.0002566790501511337 >= 0.00003 → false

comparison: 0.0000002566790501511337 >= 0.00003 → false

data points: 119
min/max: 59.7 / 68.3

The issue isn’t with the comparison. So mathematically, everything matches up

Edit: issue explained here

But it isn’t mathematically correct, it should be true:

Oh, maybe i missed something.

2.566790501511337×10−7 should be 0.0000002566790501511337 and not 0.0002566790501511337

Edit:

I do on the “caluclate trend” a modification on the trend (* 1000)

trend: app.significantFigures ? FlowUtils.toSignificantDigits(Trend.createTrend(logs).slope * 1000, app.significantFiguresValue) : Trend.createTrend(logs).slope * 1000,

So, should I rework the Trend Slope to make it more readable or keep it as low as it its? This is a question to everyone that uses the trend

Edit 2:

New test version is online where I removed the * 1000 modification.

1 Like

No idea if I’m doing something wrong or if I don’t unterstand it correctly, but now I’m getting different numbers depending on where I’m looking for them.

Trend: 7,61….

Trend -1.0065…

Before these two values were about the same

Diagnostic Report c29771e3-24f7-41c3-86fc-f2e6e54eb335

my opnion(s):

  • remove the factor 1000 (why 1000 at all?)
  • the value you enter in the flow card should be the same “unit” as when checking values on the app configuration page
  • with no factor 1000 it’s also easier to calculate the value on his own (value change divided by time in seconds)

Breaking Change: Trend Calculation Changes

I’ve reworked the trend calculation to make it more consistent and easier to understand.
Before, one of the flow cards multiplied the trend result by 1000, while others didn’t, which made things confusing. That factor is now removed. The trend number will now feel much more natural (no huge or tiny numbers that depend on arbitrary scaling).

:brain: Nerd Corner

Old method:
Used millisecond-based time differences

static createTrend(data: any, xKey: string = "x", yKey: string = "y") {
        const xData = data.map((value: any) => value[xKey]);
        const yData = data.map((value: any) => value[yKey]);

        // average of X values and Y values
        const xMean: number = this.getAverage(xData);
        const yMean: number = this.getAverage(yData);

        // Subtract X or Y mean from corresponding axis value
        const xMinusYMean = xData.map((val: any) => val - xMean);
        const yMenusXMean = yData.map((val: any) => val - yMean);

        const xMinusXMeanSq = xMinusYMean.map((val: any) => Math.pow(val, 2));

        const xy = [];
        for (let x = 0; x < data.length; x++) {
            xy.push(xMinusYMean[x] * yMenusXMean[x]);
        }

        const xySum = this.getSum(xy);

        // b1 is the slope
        const b1 = xySum / this.getSum(xMinusXMeanSq);
        // b0 is the start of the slope on the Y axis
        const b0 = yMean - b1 * xMean;

        return {
            slope: b1,
            yStart: b0,
            calcY: (x: number) => b0 + b1 * x,
        };
    }

New method (humanized):

Now uses seconds for time differences and normalizes the slope to show change per hour for easier interpretation.

    static createTrendHumanized(data: { x: number; y: number }[]) {
        if (!data || data.length < 2) return { slope: 0, direction: 'flat', calcY: () => 0 };

        // Convert timestamps to seconds (so time differences aren’t huge)
        const firstX = data[0].x;
        const x = data.map(p => (p.x - firstX) / 1000);
        const y = data.map(p => p.y);

        const n = x.length;
        const meanX = x.reduce((a, b) => a + b, 0) / n;
        const meanY = y.reduce((a, b) => a + b, 0) / n;

        // Calculate slope (Δy / Δx using least squares)
        let num = 0, den = 0;
        for (let i = 0; i < n; i++) {
            num += (x[i] - meanX) * (y[i] - meanY);
            den += (x[i] - meanX) ** 2;
        }

        const b1 = num / den; // slope
        const b0 = meanY - b1 * meanX; // intercept (where line crosses Y-axis)

        // Optional: normalize slope for readability (e.g. % change per hour)
        let slope = b1 * 3600;

        return {
            slope,
            direction: slope > 0 ? 'up' : slope < 0 ? 'down' : 'flat',
            calcY: (xVal: number) => b0 + b1 * ((xVal - firstX) / 1000),
            intercept: b0,
        };
    }

Yeah, I actually removed the *1000 factor, but as you can see in @L3nny’s post, the resulting trend values get super tiny (like 0.000000...).

and maybe even in general “per hour”?" I guess it’s very unrealistic in home automatiion context to even monitor “changes per second”.

I think important is that values are identical throughout the app (claculated values vs. shown value on configuration page)

actually e.g. my threshold is something like 0.3 °C / hour

For trend I don’t need seconds, but I need it in minutes. I need a detection, that someone used the shower. Which I use the trend for. If humidity trend is higher as …
This way I can use the very steep change of the humidity in the bathroom to identify that someone showered. Just using a percentage value would also work, but would create false positives on very humid sommer days.

The newest test version works for me now. Need to figure out the correct trend number, but that is no issue. Also the settings card delivers the same number as the flow card.

Numbers in screenshot are different, because it took me some time to get the second output :sweat_smile:
But it is working correctly now!

Thank you!