Injection missing at certain time

I've been trying to understand why my program is buggy but I'm not sure if this behavior is normal.

I have a Flow acquiring generated energy during the day. Inside a flow, I use an injection node to reset the total accumulated energy inside a function. The example flow is here.

The problem is: I set the inject to 00:00. It works well, but sometimes, it doesn't. First time in the morning I check and sometimes I have to manually inject to reset counting.

I've been searching and found node-red-contrib--cron-pkjq, but I'm not sure if this is the correct approach.

Is there a redundant approach or I'm doing something wrong?

Edit: Let me just quote inject node

Note: "interval between times" and "at a specific time" will use cron.
"interval" should be less than 596 hours.
See info box for details.

It is supposed to work.

(1) ?? there must be a semantics issue here. The function node and inject node are two different nodes and you can not put an inject node inside a function node.

Now if that is not what you meant, could you explain it again?

(2) the example flow you point to is part of a a node's description but there are two flows -

If you have an inject node that you think is not performing the inject, add a debug node showing the inject node output and set it to log to the console, then you can look in the log in the morning to see whether it is the inject node that is at fault or some other problem.

I edited the original post. Thank you.

Here is a picture.

@Colin Indeed I already did that. I just put a time inject 2 minutes ahead and it works. The problem is that it seems to fail sometimes.

Is there a way to check, inside the flow if the injects was received?

EDIT: I will put 2 inject nodes for redundancy.

Better to wait till it fails then look to see whether it was actually the inject node that failed or whether there is a flaw somewhere else.

Post the code of the Store kwh node so we can have a look.

Ok. I will follow your suggestion:

// Save payload
var inputVal = msg.payload;

// Create output variable
var outputVal;

// If receive a reset, save the last value as daily value
if (inputVal == "reset"){
    flow.set("DailyInv_energyVal", flow.get("Inv_energyVal")||0 ); 
}else{
    // Continually store the total energy to the flow
    flow.set("Inv_energyVal", inputVal);
    outputVal = inputVal - flow.get("DailyInv_energyVal")||0;
    
    msg = {payload: outputVal, "inputVal": inputVal, "Inv_energyVal": flow.get("Inv_energyVal"), "DailyInv_energyVal": flow.get("DailyInv_energyVal")};
    return msg;
}

Is there a reason you have used flow context rather than node context? Node context is safer if you only want to access the value inside that function node. Then there is no possibility of something else accidentally writing to it.
Other than that I can't see any reason why it might not reset.
Hopefully when it fails the log may tell you something useful.

Your pictures show 2 flows - each with a reset going into a function... If they are both resetting at the "same" time and writing to the same flow variable name then as Colin (sort of) suggests then the order those things happen could be an issue if one resets before the other and then sometimes (for some reason) the other resets first.

Just did follow the example presented by the package writer. I will look into it.
@dceejay Thank you! I will check that carefully as well.

I'm rushing at the moment, but a quick look at your function node code does not do what I think you want it to do.
Firstly, the readings from the watt2kwh node should form a running total, starting at zero at midnight, then every energy feed reading should be added to the context value, right up to midnight before being set to zero again.
In the example flow that I included in the watt2kwh contrib node, the function code was;

var inputVal = msg.payload;
if (inputVal == "reset"){
 flow.set("energyVal",0); 
 } else {
var savedVal = flow.get('energyVal')||0;
savedVal += inputVal;
flow.set("energyVal",savedVal);
msg.payload = savedVal;
return msg;
}

So as you can see, savedVal += inputVal; continually adds the values together so we have a running total, whilst flow.set("energyVal",0); resets the value back to zero.

In your flow, you have flow.set("DailyInv_energyVal", flow.get("Inv_energyVal")||0 ); which at midnight saves one context value to another context, but where is Inv_energyVal reset back to zero?

Hello @Paul-Reed, I have this variable that comes from the inverter that stores the total inverter energy since the day it was first power on.

I was concerned about power loss or even communication fault. If that happens, I lost info and variables and finally the total energy generated. Thus I added two functions.
First one is the one you've created (just copy and paste). By the way, nice job. Really handy.
The other one just retrieve the total energy from the inverter and store the last one from the last day (that is the expected behaviour from my function). With that, it is expected to get only daily energy.

outputVal = inputVal - flow.get("DailyInv_energyVal")||0;

If I get that working correctly, I can either manually reset to a value from a day before or store in a file.

...hmm, so you are not using the watt2kwh at all in this flow, and the energy accumulation is done by the inverter...

In that case, similar to what Colin has said, I would add some logging, to see what is happening. You could always add some node.log statements in your function node, like this;

// Save payload
var inputVal = msg.payload;

// Create output variable
var outputVal;

// If receive a reset, save the last value as daily value
if (inputVal == "reset"){
    flow.set("DailyInv_energyVal", flow.get("Inv_energyVal")||0 ); 

// Add some logging
       node.log("Reset msg received");
       node.log("Inv_energy = " + context.get(Inv_energyVal));
       node.log("DailyInv_energy = " + context.get(DailyInv_energyVal));
// End of logging

}else{
    // Continually store the total energy to the flow
    flow.set("Inv_energyVal", inputVal);
    outputVal = inputVal - flow.get("DailyInv_energyVal")||0;
    
    msg = {payload: outputVal, "inputVal": inputVal, "Inv_energyVal": flow.get("Inv_energyVal"), "DailyInv_energyVal": flow.get("DailyInv_energyVal")};
    return msg;
}

Then tomorrow, check your node-RED log, and you will see datestamped statements showing if a reset occured, and what the new context values are at that point in time.
Something like...

pi@raspberrypi:~ $ node-red-log
18 Feb 19:39:49 - [info] [function:Divertor node 10] Reset msg received
18 Feb 19:39:49 - [info] [function:Divertor node 10] Inv_energy = 1582054789186
18 Feb 19:39:49 - [info] [function:Divertor node 10] DailyInv_energy = 1582054789186
1 Like

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