One shot/repeating 'filter'

Good afternoon node-red'ers!

First time posting here, I've got a scenario I'm trying to iron out.

First off, I'm running Home Assistant, Room assistant and Node RED (among other items but I don't think they are pertinent here). Room assistant monitors my Galaxy S10 phone's connection status (connected or not connected) to a Raspberry Pi 4's bluetooth. I have a simple automation that when the phone connects to the bluetooth aka "I'm home", it turns my entrance lights on. When the phone disconnects from the the bluetooth aka "I'm NOT home", it turns the lights off. This automation works just fine with the lights coming on either before I open the front door or in a worst case connection scenario, the light turns on right when I'm opening the door. The problem however, lies below...

Randomly throughout the evening (particularly while charging the phone) the bluetooth connection randomly disconnects and reconnects, sometimes not at all, sometimes flickering on and off in roughly 3 second intervals thus turning my place into a poor man's disco. Not cool when you're trying to sleep.

What I have right now:

  • events: state to check when the phone connects, this triggers a call service to turn lights on
  • events: state to check when the phone disconnects, this triggers another call service to turn lights off. I also have within the call service, a 'if state is true for 5 minutes' (in an attempt to limit the lights flickering) which works...sort of. I can't repeat the same logic on the 'lights on' portion because then the light won't turn on for 5 minutes of the phone being connected.

The way I have been thinking of solving this issue (through NodeRED) is to:

  • have the events: state trigger the lights:on AND a timer (say 5 minutes) to start. If another lights:on call is sent and the timer is still running, do not trigger the lights AND restart the timer. The same logic could then be used for the lights:off timer.

I can't seem to wrap my head around having the sequence run straight through the first time but check if the timer is running each concurrent time. If the timer successfully times out (which would happen if I truly wasn't home) then allow the sequence to run straight through again.

Any thoughts on making this work OR have a better solution to this problem? In case someone's going to ask "why don't you use HA's location service to detect your location", I could do that however I don't have nabu casa/similar setup and I thought that doing this through NodeRED would be fun.

Thanks in advance!
Adam

Welcome to the community btw.. heaps of good people here willing to help!

have you considered using a ping on the wifi to your phone rather then bluetooth?

You could even use arp detection but that would be slower to change state.

Have a look at the Trigger node, it should be able to do something for you you. Come back if you can't work out the right way to configure it.

Good afternoon Colin, thanks for the response.

I like you're approach to 'helping along' rather than outright answering, it made me think although it's still stumping me. As an electrician I am very familiar with logic/logic gate flow but I am unfortunately not as familiar with the code logic.

I have tried various versions of trigger and switch nodes and I can achieve the result that you mentioned above EXCEPT for the 'if the timer is running, do not trigger the lights'. The problem is that I once a lights:on OR lights:off call is made, all subsequent requests from BOTH on/off need to be ignored during the duration of the timer. I can't seem to find a way to block the payloads while the timer is running (via the trigger node) yet allow the payload through once the timer is done. I would imagine I'm looking for some version of an AND gate (in electronics terminology) so when the 3 scenarios happen:

Constants:
"DenPi4" (room assistant's designation for "I'm home")
"not_home" (room assistant's designation for "I'm not home")
"DenPi4Timer" (5 minutes for example)
"not_homeTimer" (5 minutes for example)

Scenario 1 - I get home:

  • DenPi4 = true AND
  • DenPi4Timer is <1 (seconds) AND
  • not_homeTimer is <1 (seconds) THEN
  • turn hall lights on AND
  • reset DenPi4Timer AND
  • reset not_homeTimer

Scenario 2 - I leave home:

  • not_home = true AND
  • DenPi4Timer is <1 (seconds) AND
  • not_homeTimer is <1 (seconds) THEN
  • turn hall lights off AND
  • reset DenPi4Timer AND
  • reset not_homeTimer

Random disconnects happen while I'm home which cause both "not_home" AND "DenPi4" events to happen thus if EITHER of these events happen within 5 minutes the timers:

Scenario 3 - [Either DenPi4 OR not_home events are true BUT EITHER Timer is >1 second]

  • reset DenPi4 timer AND
  • reset not_home timer

The only reason that I have 2 timers is that if I use only 1 timer (trigger), the output cannot distinguish between the 2 inputs and the result is that the lights turn on then immediately off as they are tied to the same output.

I have some code that I've been working with but I don't know if it's acceptable to post it here

Thanks!

As a fellow in the art of electrickery. i would like to say hi.

here is my thought you have a random on/off of about 3 seconds. So you just need to filter the 3 second off and on. A combination of trigger and rbe should do the trick.

have a play with this flow. Turn home to 1 , is should pass the 1.
now turn on and off at 3 second intervals, no message will pass till the gap is greater than delay, set in trigger node. The rbe will only allow a message to pass if it is different than the last.

Hope this help you discover they way forward.

[{"id":"7e012f65.3d5428","type":"inject","z":"5a245aa1.510164","name":"home 0","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":120,"y":1520,"wires":[["890b804b.d2b9e"]]},{"id":"890b804b.d2b9e","type":"switch","z":"5a245aa1.510164","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"0","vt":"num"}],"checkall":"false","repair":false,"outputs":2,"x":260,"y":1500,"wires":[["85168508.41ddf","19461bb5.56522c"],["85168508.41ddf"]]},{"id":"54bed1fb.22783","type":"inject","z":"5a245aa1.510164","name":"home 1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":120,"y":1480,"wires":[["890b804b.d2b9e"]]},{"id":"85168508.41ddf","type":"trigger","z":"5a245aa1.510164","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"10","extend":true,"overrideDelay":false,"units":"s","reset":"1","bytopic":"all","topic":"topic","outputs":1,"x":440,"y":1520,"wires":[["19461bb5.56522c"]]},{"id":"19461bb5.56522c","type":"rbe","z":"5a245aa1.510164","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":470,"y":1480,"wires":[["b5d6be0a.40b5b8"]]},{"id":"b5d6be0a.40b5b8","type":"debug","z":"5a245aa1.510164","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":630,"y":1480,"wires":[]}]

Hello E1cid,

That my friend is simple and brilliant, thank you very much! It solves the random disconnecting issue as well as retaining the 'instant on' function that's desired when the device initially connects and you want the lights to come on right away! I'm also not a fan of relying on timers for "smart automation", that's not the best practice.

I had seen the RBE node but obviously did not linger on it long enough haha!

It does however (well, MY situation at least) have one flaw that is still an issue but the inherent design is at the root of it. While your solution is great and it IS what I'm looking for, there is still the midnight scenario when the lights are already OFF and the phone disconnects and reconnects which turns the lights on in the middle of the night. I've solved this by another bit of automation I had in place: When by bedroom door is closed (when we are sleeping) the bathroom light is turned off. If the bedroom door is opened for a bio-break, the bathroom lights turn on at 10% brightness as to not burn your retinas out when your half-zombied. I've simply halted the code if the bedroom door is closed. Here's the code if it helps anyone else out.

Thanks again, you were a great help!

[{"id":"193d36ed.bfa9d9","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"4b248457.5fe50c","type":"trigger","z":"193d36ed.bfa9d9","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"5","extend":true,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":610,"y":388,"wires":[["e1570bd1.795b48"]]},{"id":"e1570bd1.795b48","type":"rbe","z":"193d36ed.bfa9d9","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":790,"y":348,"wires":[["a65d8983.7eb7b8"]]},{"id":"6de9878f.c6d088","type":"debug","z":"193d36ed.bfa9d9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1490,"y":260,"wires":[]},{"id":"a7c6f857.489d98","type":"server-state-changed","z":"193d36ed.bfa9d9","name":"S10 connects to Room assistant","server":"474016b8.573908","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.adam_s_galaxy_s10_room_presence","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"DenPi4","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":190,"y":348,"wires":[["e8159790.0272a8"],[]]},{"id":"69601347.34b32c","type":"server-state-changed","z":"193d36ed.bfa9d9","name":"S10 not_home for 5 minutes","server":"474016b8.573908","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.adam_s_galaxy_s10_room_presence","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"not_home","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"5","forType":"num","forUnits":"seconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":200,"y":428,"wires":[["ccfb0089.a9b18"],[]]},{"id":"eaf2381.04b08c8","type":"api-current-state","z":"193d36ed.bfa9d9","name":"","server":"474016b8.573908","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"binary_sensor.test_door","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":1190,"y":328,"wires":[["de9f3eec.fce23","6de9878f.c6d088"],[]]},{"id":"a65d8983.7eb7b8","type":"switch","z":"193d36ed.bfa9d9","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"DenPi4","vt":"str"},{"t":"eq","v":"not_home","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":930,"y":348,"wires":[["eaf2381.04b08c8","6b5bd634.b62e48"],["e31bc4e5.4c9798"]]},{"id":"de9f3eec.fce23","type":"api-call-service","z":"193d36ed.bfa9d9","name":"Light On","server":"474016b8.573908","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.hall_switch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1480,"y":300,"wires":[[]]},{"id":"265a68be.0b6c98","type":"api-call-service","z":"193d36ed.bfa9d9","name":"Bathroom Light Off","server":"474016b8.573908","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.mj_dimmer_1","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1510,"y":420,"wires":[[]]},{"id":"aece8aac.687298","type":"api-call-service","z":"193d36ed.bfa9d9","name":"Hall Light Off","server":"474016b8.573908","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.hall_switch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1490,"y":380,"wires":[[]]},{"id":"8b9ca806.848038","type":"inject","z":"193d36ed.bfa9d9","name":"Inject (for testing)","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"DenPi4","payloadType":"str","x":240,"y":288,"wires":[["e1570bd1.795b48","e8159790.0272a8"]]},{"id":"fad783bf.108fb","type":"inject","z":"193d36ed.bfa9d9","name":"Inject (for testing)","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"not_home","payloadType":"str","x":240,"y":488,"wires":[["ccfb0089.a9b18"]]},{"id":"6b5bd634.b62e48","type":"debug","z":"193d36ed.bfa9d9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1110,"y":268,"wires":[]},{"id":"e31bc4e5.4c9798","type":"api-current-state","z":"193d36ed.bfa9d9","name":"","server":"474016b8.573908","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"binary_sensor.test_door","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":1190,"y":388,"wires":[["aece8aac.687298","265a68be.0b6c98"],[]]},{"id":"ccfb0089.a9b18","type":"switch","z":"193d36ed.bfa9d9","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"not_home","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":430,"y":448,"wires":[["4b248457.5fe50c"]]},{"id":"e8159790.0272a8","type":"switch","z":"193d36ed.bfa9d9","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"DenPi4","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":430,"y":348,"wires":[["4b248457.5fe50c"]]},{"id":"2eb39595.54f7aa","type":"comment","z":"193d36ed.bfa9d9","name":"Bedroom door closed sensor","info":"","x":1160,"y":360,"wires":[]},{"id":"4d79f895.310e38","type":"comment","z":"193d36ed.bfa9d9","name":"","info":"The Switches are simply to revert the payloads back to my HA naming convention for my ease of troubleshooting","x":440,"y":480,"wires":[]},{"id":"f12488d6.b81568","type":"comment","z":"193d36ed.bfa9d9","name":"","info":"The Switches are simply to revert the payloads back to my HA naming convention for my ease of troubleshooting","x":440,"y":380,"wires":[]},{"id":"f9a77a72.43b178","type":"comment","z":"193d36ed.bfa9d9","name":"","info":"The Switches are simply to revert the payloads back to my HA naming convention for my ease of troubleshooting","x":940,"y":380,"wires":[]},{"id":"474016b8.573908","type":"server","name":"Home Assistant","addon":true}]

This may work for you it has a 10 second spam check in the switch node. You will get instant on's only if the phone BT has not been spamming for 10 seconds.

[{"id":"fbc6147d.a0e04","type":"change","z":"5a245aa1.510164","name":"","rules":[{"t":"set","p":"time","pt":"flow","to":"","tot":"date"}],"action":"","property":"","from":"","to":"","reg":false,"x":410,"y":1560,"wires":[["85168508.41ddf"]]},{"id":"890b804b.d2b9e","type":"switch","z":"5a245aa1.510164","name":"","property":"payload","propertyType":"msg","rules":[{"t":"jsonata_exp","v":"$flowContext(\"time\")+10000 < $millis() and payload = 1","vt":"jsonata"},{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"0","vt":"num"}],"checkall":"true","repair":false,"outputs":3,"x":260,"y":1480,"wires":[["19461bb5.56522c"],["fbc6147d.a0e04"],["fbc6147d.a0e04"]]},{"id":"85168508.41ddf","type":"trigger","z":"5a245aa1.510164","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"10","extend":true,"overrideDelay":false,"units":"s","reset":"1","bytopic":"all","topic":"topic","outputs":1,"x":620,"y":1560,"wires":[["19461bb5.56522c"]]},{"id":"54bed1fb.22783","type":"inject","z":"5a245aa1.510164","name":"home 1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":120,"y":1480,"wires":[["890b804b.d2b9e"]]},{"id":"7e012f65.3d5428","type":"inject","z":"5a245aa1.510164","name":"home 0","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":120,"y":1520,"wires":[["890b804b.d2b9e"]]},{"id":"19461bb5.56522c","type":"rbe","z":"5a245aa1.510164","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":530,"y":1480,"wires":[["b5d6be0a.40b5b8"]]},{"id":"b5d6be0a.40b5b8","type":"debug","z":"5a245aa1.510164","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":710,"y":1480,"wires":[]}]

Once again you came through with a great solution, thanks!