If AND Statement formatting

Greetings NodeRed Community,

I cannot say that I am exactly new to using NodeRed, however while attempting to create this flow, i sure do feel like a noobie.

  • My Goal:
    Create a flow within my Home Assistant instance, which dims a light (after being turned on) to a certain amount depending on sun position. So, after sunset, you flight a light on and you are not blinded by 100% brightness.

I have been working through the logic of this function, and it is where I am still working... :-/

I have included the code from within my function node below. As with many things, there are probably five other ways I can accomplish this, however I am trying my best to become more proficient in JavaScript. So using the Function node is something I would like to do more of.

Thus far I have broken it down into the individual components that are working...

Read in Sun Position via BigTimer and Output based on Sunrise or Sunset:

[{"id":"701405d8143b2762","type":"tab","label":"Brilliant Light Controls","disabled":false,"info":"","env":[]},{"id":"bf94cdbbd26df0f8","type":"server-state-changed","z":"701405d8143b2762","name":"Downstairs Bathroom","server":"59c431be.e53a8","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.downstairs_bathroom_switch","entityidfiltertype":"exact","outputinitially":true,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"seconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"light_status","propertyType":"msg","value":"","valueType":"entityState"}],"x":120,"y":320,"wires":[["982fc76b14bf46a7","92f0363b22df3b5d"]]},{"id":"cab4ba365b14fa7b","type":"api-call-service","z":"701405d8143b2762","name":"Set Daytime Brightnesss","server":"59c431be.e53a8","version":5,"debugenabled":false,"domain":"homeassistant","service":"turn_on","areaId":[],"deviceId":[],"entityId":["light.downstairs_bathroom_switch"],"data":"{ \"brightness_pct\": \"50\" }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1190,"y":80,"wires":[[]]},{"id":"50301ce323ba786c","type":"api-call-service","z":"701405d8143b2762","name":"Set Nighttime Brightnesss","server":"59c431be.e53a8","version":5,"debugenabled":false,"domain":"homeassistant","service":"turn_on","areaId":[],"deviceId":[],"entityId":["light.downstairs_bathroom_switch"],"data":"{ \"brightness_pct\": \"10\" }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1190,"y":340,"wires":[[]]},{"id":"47ce4b10332a2b46","type":"inject","z":"701405d8143b2762","name":"Force true","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"on","payloadType":"str","x":140,"y":140,"wires":[["e90ddad364b8a5bd"]]},{"id":"6a4a279c982edb3f","type":"inject","z":"701405d8143b2762","name":"Force False","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"off","payloadType":"str","x":130,"y":220,"wires":[["e90ddad364b8a5bd"]]},{"id":"334ef63c81b5f888","type":"inject","z":"701405d8143b2762","name":"Sunbased Auto","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"auto","payloadType":"str","x":120,"y":180,"wires":[["e90ddad364b8a5bd"]]},{"id":"e90ddad364b8a5bd","type":"bigtimer","z":"701405d8143b2762","outtopic":"","outpayload1":"sunrise","outpayload2":"sunset","name":"Sunrise","comment":"","lat":"38.87105","lon":"-77.05639","starttime":"5003","endtime":"5004","starttime2":0,"endtime2":0,"startoff":0,"endoff":0,"startoff2":0,"endoff2":0,"offs":0,"outtext1":"Sunrise","outtext2":"Sunset","timeout":1440,"sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"day6":0,"month6":0,"day7":0,"month7":0,"day8":0,"month8":0,"day9":0,"month9":0,"day10":0,"month10":0,"day11":0,"month11":0,"day12":0,"month12":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"d6":0,"w6":0,"xday1":0,"xmonth1":0,"xday2":0,"xmonth2":0,"xday3":0,"xmonth3":0,"xday4":0,"xmonth4":0,"xday5":0,"xmonth5":0,"xday6":0,"xmonth6":0,"xday7":0,"xmonth7":0,"xday8":0,"xmonth8":0,"xday9":0,"xmonth9":0,"xday10":0,"xmonth10":0,"xday11":0,"xmonth11":0,"xday12":0,"xmonth12":0,"xd1":0,"xw1":0,"xd2":0,"xw2":0,"xd3":0,"xw3":0,"xd4":0,"xw4":0,"xd5":0,"xw5":0,"xd6":0,"xw6":0,"suspend":false,"random":false,"randon1":false,"randoff1":false,"randon2":false,"randoff2":false,"repeat":false,"atstart":true,"odd":false,"even":false,"x":320,"y":180,"wires":[["9c9ea542489be6aa"],[],[]]},{"id":"672b4125788c91d4","type":"debug","z":"701405d8143b2762","name":"debug A","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"dimmer_setting","targetType":"msg","statusVal":"","statusType":"auto","x":620,"y":280,"wires":[]},{"id":"982fc76b14bf46a7","type":"function","z":"701405d8143b2762","name":"If Statment","func":"if (msg.sun_position == \"sunrise\") {\n    msg.dimmer_setting = \"bright\";\n    return [msg, null];\n}\n\n\nif (msg.sun_position == \"sunset\") {\n    msg.dimmer_setting = \"dim\";\n    return [null, msg];\n}\n\nreturn msg;","outputs":2,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\n","finalize":"","libs":[],"x":410,"y":320,"wires":[["672b4125788c91d4"],["21d1e9f3a69a0217"]]},{"id":"fecc26849400f1be","type":"server-state-changed","z":"701405d8143b2762","name":"Downstairs Bathroom","server":"59c431be.e53a8","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.downstairs_bathroom_switch","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"seconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":200,"y":700,"wires":[[],[]]},{"id":"21d1e9f3a69a0217","type":"debug","z":"701405d8143b2762","name":"debug B","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"dimmer_setting","targetType":"msg","statusVal":"","statusType":"auto","x":620,"y":360,"wires":[]},{"id":"c1fec89af89bef7e","type":"debug","z":"701405d8143b2762","name":"debug sun_position","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"sun_position","targetType":"msg","statusVal":"","statusType":"auto","x":570,"y":100,"wires":[]},{"id":"92f0363b22df3b5d","type":"debug","z":"701405d8143b2762","name":"debug light_status","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"light_status","targetType":"msg","statusVal":"","statusType":"auto","x":190,"y":460,"wires":[]},{"id":"9c9ea542489be6aa","type":"change","z":"701405d8143b2762","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"sun_position","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":120,"wires":[["c1fec89af89bef7e","982fc76b14bf46a7"]]},{"id":"59c431be.e53a8","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

Read in the status of the light switch, this could easily be a bool or a string value. So long as it works.

[{"id":"701405d8143b2762","type":"tab","label":"Brilliant Light Controls","disabled":false,"info":"","env":[]},{"id":"bf94cdbbd26df0f8","type":"server-state-changed","z":"701405d8143b2762","name":"Downstairs Bathroom","server":"59c431be.e53a8","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.downstairs_bathroom_switch","entityidfiltertype":"exact","outputinitially":true,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"seconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"light_status","propertyType":"msg","value":"","valueType":"entityState"}],"x":120,"y":320,"wires":[["982fc76b14bf46a7","92f0363b22df3b5d"]]},{"id":"cab4ba365b14fa7b","type":"api-call-service","z":"701405d8143b2762","name":"Set Daytime Brightnesss","server":"59c431be.e53a8","version":5,"debugenabled":false,"domain":"homeassistant","service":"turn_on","areaId":[],"deviceId":[],"entityId":["light.downstairs_bathroom_switch"],"data":"{ \"brightness_pct\": \"50\" }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1190,"y":80,"wires":[[]]},{"id":"50301ce323ba786c","type":"api-call-service","z":"701405d8143b2762","name":"Set Nighttime Brightnesss","server":"59c431be.e53a8","version":5,"debugenabled":false,"domain":"homeassistant","service":"turn_on","areaId":[],"deviceId":[],"entityId":["light.downstairs_bathroom_switch"],"data":"{ \"brightness_pct\": \"10\" }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1190,"y":340,"wires":[[]]},{"id":"47ce4b10332a2b46","type":"inject","z":"701405d8143b2762","name":"Force true","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"on","payloadType":"str","x":140,"y":140,"wires":[["e90ddad364b8a5bd"]]},{"id":"6a4a279c982edb3f","type":"inject","z":"701405d8143b2762","name":"Force False","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"off","payloadType":"str","x":130,"y":220,"wires":[["e90ddad364b8a5bd"]]},{"id":"334ef63c81b5f888","type":"inject","z":"701405d8143b2762","name":"Sunbased Auto","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"auto","payloadType":"str","x":120,"y":180,"wires":[["e90ddad364b8a5bd"]]},{"id":"e90ddad364b8a5bd","type":"bigtimer","z":"701405d8143b2762","outtopic":"","outpayload1":"sunrise","outpayload2":"sunset","name":"Sunrise","comment":"","lat":"38.87105","lon":"-77.05639","starttime":"5003","endtime":"5004","starttime2":0,"endtime2":0,"startoff":0,"endoff":0,"startoff2":0,"endoff2":0,"offs":0,"outtext1":"Sunrise","outtext2":"Sunset","timeout":1440,"sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"day6":0,"month6":0,"day7":0,"month7":0,"day8":0,"month8":0,"day9":0,"month9":0,"day10":0,"month10":0,"day11":0,"month11":0,"day12":0,"month12":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"d6":0,"w6":0,"xday1":0,"xmonth1":0,"xday2":0,"xmonth2":0,"xday3":0,"xmonth3":0,"xday4":0,"xmonth4":0,"xday5":0,"xmonth5":0,"xday6":0,"xmonth6":0,"xday7":0,"xmonth7":0,"xday8":0,"xmonth8":0,"xday9":0,"xmonth9":0,"xday10":0,"xmonth10":0,"xday11":0,"xmonth11":0,"xday12":0,"xmonth12":0,"xd1":0,"xw1":0,"xd2":0,"xw2":0,"xd3":0,"xw3":0,"xd4":0,"xw4":0,"xd5":0,"xw5":0,"xd6":0,"xw6":0,"suspend":false,"random":false,"randon1":false,"randoff1":false,"randon2":false,"randoff2":false,"repeat":false,"atstart":true,"odd":false,"even":false,"x":320,"y":180,"wires":[["9c9ea542489be6aa"],[],[]]},{"id":"672b4125788c91d4","type":"debug","z":"701405d8143b2762","name":"debug A","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"dimmer_setting","targetType":"msg","statusVal":"","statusType":"auto","x":620,"y":280,"wires":[]},{"id":"982fc76b14bf46a7","type":"function","z":"701405d8143b2762","name":"If Statment","func":"if (msg.light_status == \"on\") {\n    msg.dimmer_setting = \"continue\";\n    return [msg, null];\n}\n\n\nif (msg.light_status == \"off\") {\n    msg.dimmer_setting = \"wait\";\n    return [null, msg];\n}\n\nreturn msg;","outputs":2,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\n","finalize":"","libs":[],"x":410,"y":320,"wires":[["672b4125788c91d4"],["21d1e9f3a69a0217"]]},{"id":"fecc26849400f1be","type":"server-state-changed","z":"701405d8143b2762","name":"Downstairs Bathroom","server":"59c431be.e53a8","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.downstairs_bathroom_switch","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"seconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":200,"y":700,"wires":[[],[]]},{"id":"21d1e9f3a69a0217","type":"debug","z":"701405d8143b2762","name":"debug B","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"dimmer_setting","targetType":"msg","statusVal":"","statusType":"auto","x":620,"y":360,"wires":[]},{"id":"c1fec89af89bef7e","type":"debug","z":"701405d8143b2762","name":"debug sun_position","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"sun_position","targetType":"msg","statusVal":"","statusType":"auto","x":570,"y":100,"wires":[]},{"id":"92f0363b22df3b5d","type":"debug","z":"701405d8143b2762","name":"debug light_status","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"light_status","targetType":"msg","statusVal":"","statusType":"auto","x":190,"y":460,"wires":[]},{"id":"9c9ea542489be6aa","type":"change","z":"701405d8143b2762","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"sun_position","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":120,"wires":[["c1fec89af89bef7e","982fc76b14bf46a7"]]},{"id":"59c431be.e53a8","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

I am stuck, when I try to combine the two:

if (msg.light_status == "on" && msg.sun_position == "sunrise") {
    msg.dimmer_setting = "bright";
    return [msg, null];
}


if (msg.light_status == "on" && msg.sun_position == "sunset") {
    msg.dimmer_setting = "dim";
    return [null, msg];
}

return msg;

I cannot get that "msg.dimmer_setting" message to pass through to a debug node.
I assume, it is a syntax or formatting issue with the double ampersand? shrugs

Let me know your thoughts, or if I should provide more information.
Thank you in advance for any input or suggestion.

Best,
Bigrob55

Just at a casual glance in your if statement you have a two message output and right below that a return msg which indicates one output. How many outputs are you working with?

[Edit] your second comparison in the if statement should have two"="

Hey gerry,

Thank you for your reply.

I will go take another look at my code, is this the section you are speaking of?

msg.sun_position == "sunrise"

in the function node did you set it to have two outputs?
function

In a situation like this you should create a small flow with data that will demonstrate your issue. Then export it and add it to a reply.

Oops, sorry statement about two "=" was wrong. Just looked at post on big screen.

I think that msg.light_status and msg.sun_position are in different messages?

Like any node, your function can only process one message at a time, and it has no "memory" of previous messages.

There are two ways around this common problem:

  1. Combine the two messages into one using the Join node.
    To do this the two messages should each have a msg.topic, and the Join is "manual mode"

    Now you can test eg msg.payload.sun and msg.payload.state.

2, When a server state message arrives, store it's payload in a context variable. When a sun event message arrives, you have the context variable to compare it with.

ps I really dislike the return [null, msg] or return [msg, null] idiom, it makes the flow less easy to understand. A single output and a switch node testing msg.dimmer_setting "dim" or "bright" seems better to me

Funny I really like it :wink:
If I'm going to use a function node it may as well do as much as possible at that point in the flow.
You can always label the outputs as well.

I think it overcomplicates things.

2 Likes

No worries at all.
As you said, it was a casual glance and I appreciated you taking the time to offer input.

It's hard to disagree with you bakman2.

Your proposed flow does seem alot less complex. I might just go this route to have something that is functional and on the side keep exploring the increased use of the function node; so that I may learn more JavaScript code.

Once i am able to get this flow working, I will come back and mark your post as a solution

Best,
Bigrob55

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