Current-state node - statement "for" issue

Hi there

happy 2024 to you all. Recently I installed a mailbox-sensor (GitHub - PricelessToolkit/MailBoxGuard: Lora Long Range Mailbox Sensor for Smart Homes or for Standalone use) which checks if I got mail. It works fantastic and avoids to walk to the mailbox when it is empty.

I use a template-sensor which displays “Post” when an input-number is greater than one. If the mailbox is empty, it displays “leer”.

  - platform: template
    sensors:
      mailbox_counter:
        friendly_name: "Mailbox Counter"
        value_template: >-
          {% if states('input_number.mailbox_count') | int >= 1 %}
            Post
          {% else %}
            leer
          {% endif %}
        icon_template: "mdi:mailbox"

In Node-Red I want to check daily at 3PM if the template-sensor’s state is “Post” for 12 hours. If so, I get a reminder to check the mailbox. However the condition for is not working. The sensor is in the state “Post” for more than 12 hours as you can see.



I would be glad to get help to solve the issue. Is it due to the fact that is a template-sensor maybe? I couldnt find answers in the forum nor from Chat-GPT. The template-sensors values are stored in the history and recorder.

all the best

Andrew

You trigger the flow at 15:00 and a few milliseconds later it hits the current state node which starts the timer for 12 hours at 3 in the night you should then get a notice that you got mail.

You might want to split your up so make a flow that sets a timestamp to the current time and store it in a flow variable.
And of course also a flow that clears that value when the state change to leer.

Now you will have a flow variable that you can retrieve in your flow and check if it is difference is more than 12 hours without having to wait.

thanks for the quick reply! Maybe I have problem of understanding. at 3PM the flow gets triggered by the inject-node. shouldnt it then check if the sensor has been in the state “Post” for at least 12 hours (in the past) and if so, send a message?

could you help me with an example of your suggestion? I have basic knowledge of Node-Red but never worked with variables or storing data/history.

on the other hand I could adjust the inject-node to trigger at 3AM and then I should get the message at 3PM?

The check first start when the node gets activated.

I always use a function node to set a flow variable, but I think a change can do it too.

It could look something like this.

flow.set("trigger_time", Date.now());
eeturn msg;

To retrieve it again and calculate the difference you could make a function node with something like this.

msg.trigger_diff = Date.now()-flow.get("trigger_time");
return msg;

This should make a value in msg.trigger, which is a number of either Milli seconds, microseconds or seconds. I can’t remember what the timestamps in Node Red is in, but it should be easy to see.

I am doing this from memory and I am a bit uncertain on the function to get the Now time, so Date.now(), might instead be Now() or something else.
If it does not work, then it will probably be Date.now() that is the cause.

1 Like

great, thanks. I try it with changing the time to 3AM and otherwise think about the function-node.

thanks for your help, I finally figured it out after HOURS of Chat-GPT, this community and Google. this is how the flow looks like.

the core is to save the timestamp when the sensors switches to “Post”. I use this node to store the data: node-red-persistent-values (node) - Node-RED this is crucial to survive a restart of HA or Node-RED.

in the function-node i use the following code. in this example for 1 minute but you can adjust that to your needs.

// Get the current time in milliseconds
const currentTime = new Date().getTime();

// Get the timestamp from the payload
const eventTime = msg.payload;

// Calculate the time difference in milliseconds
const timeDifference = currentTime - eventTime;

// Convert milliseconds to minutes
const timeDifferenceInMinutes = timeDifference / (1000 * 60);

// Check if the time difference is more than 1 minute
const isMoreThan1Minute = timeDifferenceInMinutes > 1;

// Create an object with a descriptive structure
msg.payload = {
    eventTime: eventTime,
    currentTime: currentTime,
    timeDifferenceInMinutes: timeDifferenceInMinutes,
    isMoreThan1Minute: isMoreThan1Minute
};

return msg;

the output is a boolean true. this can be used for further processing.

To answer your original post - there is nothing wrong with how the current state node is working with the ‘for’ condition.

The node triggers on a state change for your ‘mailbox counter’ sensor, either changing to ‘Post’ or to ‘leer’ (or unavailable…)

As you are checking for State is ‘Post’ it will ignore ‘leer’

Then, as you have For 12 hours, it will check the time since the last state change. If the last state change was 12 hours or more in the past, then the message will exit the node at the top output.

Looking very closely at your screenshot and I can see that your sensor has only been in the state ‘Post’ for 31 minutes. There is a very faint line in the history state bar, just under the last ‘e’ in anzeigen. You are hovering over the middle part of the history - the state was Post from 5th Jan 13:54 to 6th Jan 10:25 (which was indeed 20h31). Had you tested this anytime after 01:54 to 10:24 it would have worked as expected.

The state must have changed at 10:25:43, and yes as you were looking at this at 10:56, that makes 31 minutes.

The question remains - what happened at 10:25:43 on the 6th? Did you reset the counter? Did you restart Node-RED?

If you are going to test at 15:00 every day, clearly if the sensor, even for just a second, goes from Post to leer and back to Post, then looking at the Post duration time will not count more than the recent period.

yeah, everything is fine with the current state node :wink: I try to describe the issue I ran into and thanks for your comment, appreciate that!

Initially I wanted to check if the sensor is “Post” via the current state-node. lets say It must be 12 hours. When the state “Post” is lets say 10 hours, then gets unknown (due to a restart) and then is 2 hours again “Post” it wont count 12 hours due to the interruption of the unknown state.

to answer your question regarding the history: yes, I restarted HA and then the sensor reported “unknown” for a couple of seconds, thats the faint grey line.

From a technical point nothing is wrong that unknown will be taken into account and then i dont get the consecutive 12 hours.

I had to deal with the fact to ignore the unknown state as well as a flow that survives a HA-restart. This is why I came up with the new flow.

out of curiosity: how would you have designed the flow, taking unknown and a HA-restart into account? I would be glad to get another perspective on this specific usecase.

I have several (usually WiFi) sensors and integrations that go off line from time to time.

I can think of three ways to get around the ‘unknown / unavailable’ issue.

  • Use HA automation rather than template to manage your Mailbox Post sensor
  • Use a flow to write the state change time to context, but not when the state is unknown
  • Use history and JSONata to pick out historical state, removing the unwanted state periods

HA automations include an option ‘For’ to deal with skipping over unwanted short term state changes. There is also a great ‘not_from’ option.

  • create an automation that runs when input_number.mailbox_count changes.
  • if the count >0, then action a service call to set your ‘Mailbox Counter’ to ‘Post’
  • use the ‘for’ and / or the ‘not_from’ to stop the automation from running when the state is unavailable for a short period like this

This should remove the opportunity for any unavailable state periods from actually changing your Mailbox counter sensor.

If you do as Wally suggested and write a record to context memory, you should be able to use the settings in the all events node to filter out unavailable. You can also use the output settings to directly write something to context.

This effectively writes ‘last changed to open’ to memory, but you could also add a bit of code to either write “POST @ timestamp” or write “EMPTY @ timestamp”, and then your context variable would always be telling you what you need to know.

Here I am using the state node ‘ignore current state is unknown / unavailable’ to do the work for me.

Lastly, since HA actually keeps a copy of history for 10 days, I try to use that if I can. This one is a bit more complicated. ,For example, my ‘person’ states in HA track when my smartphone is around, and I can tell if I am ‘at home’ or ‘away’. There are, however, a lot of periods when the phone goes offline for a few minutes, so the aim is to look back over the last day and ignore any periods less than 10 minutes. Your post inspired me to try and create this as an example - it is a bit tricky so I am still working on it.

1 Like

thanks for the detailed guide, I have to check that in a quiet minute. I wanted to move as many automations as possible from HA to Node-Red in order to have like one central application with all its pros and cons.