Conditionally add message to payload in msg.topic

I am working with some messages related to notifications. I currently have the following working just fine (with the exception of the Function nodes, which is what I need help with):

[{"id":"72f054d31130bd9a","type":"change","z":"647eafda.c7cfa","name":"Set Message","rules":[{"t":"set","p":"person","pt":"msg","to":"payload.data.event.old_state.attributes.friendly_name","tot":"msg"},{"t":"set","p":"zone","pt":"msg","to":"payload.data.event.old_state.state","tot":"msg"},{"t":"set","p":"direction","pt":"msg","to":"left","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1850,"y":700,"wires":[["8018062759696e7e","93adb26a8fbc6b9f"]]},{"id":"6ede69fea6cb4679","type":"trigger-state","z":"647eafda.c7cfa","name":"Person Left a Zone","server":"296c0678.b5f9ca","version":4,"inputs":0,"outputs":2,"exposeAsEntityConfig":"","entityId":"^person\\..*$","entityIdType":"regex","debugEnabled":false,"constraints":[{"targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"not_home"},{"targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is_not","comparatorValueDatatype":"str","comparatorValue":"not_home"}],"customOutputs":[],"outputInitially":true,"stateType":"str","enableInput":false,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":1430,"y":700,"wires":[["6e6e1be63b852e38"],[]]},{"id":"8c4e62426ed94bce","type":"trigger-state","z":"647eafda.c7cfa","name":"Person Arrived at a Zone","server":"296c0678.b5f9ca","version":4,"inputs":0,"outputs":2,"exposeAsEntityConfig":"","entityId":"^person\\..*$","entityIdType":"regex","debugEnabled":false,"constraints":[{"targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is_not","comparatorValueDatatype":"str","comparatorValue":"not_home"},{"targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is_not","comparatorValueDatatype":"str","comparatorValue":"not_home"}],"customOutputs":[],"outputInitially":true,"stateType":"str","enableInput":false,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":1450,"y":820,"wires":[["ccfbbde4f1209703"],[]]},{"id":"99a2450d0a1fe749","type":"change","z":"647eafda.c7cfa","name":"Set Message","rules":[{"t":"set","p":"person","pt":"msg","to":"data.event.new_state.attributes.friendly_name","tot":"msg"},{"t":"set","p":"zone","pt":"msg","to":"data.event.new_state.state","tot":"msg"},{"t":"set","p":"direction","pt":"msg","to":"arrived at","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1850,"y":820,"wires":[["8018062759696e7e","65d8af957668f71b"]]},{"id":"6e6e1be63b852e38","type":"function","z":"647eafda.c7cfa","name":"Set Topic","func":"var oldstate = msg.payload.data.event.old_state.state;\nvar newstate = msg.payload.data.event.new_state.state;\nvar id = msg.data.event.new_state.attributes.id;\n\nif (oldstate == \"home\")\n    msg.topic = 'input_datetime.time_left_home_${id}';\nif (newstate == \"home\")\n    msg.topic = 'input_datetime.time_arrived_home${id}';\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1680,"y":700,"wires":[["72f054d31130bd9a"]]},{"id":"ccfbbde4f1209703","type":"function","z":"647eafda.c7cfa","name":"Set Topic","func":"var oldstate = msg.payload.data.event.old_state.state;\nvar newstate = msg.payload.data.event.new_state.state;\nvar id = msg.data.event.new_state.attributes.id;\n\nif (oldstate == \"home\")\n    msg.topic = 'input_datetime.time_left_home_${id}';\nif (newstate == \"home\")\n    msg.topic = 'input_datetime.time_arrived_home${id}';\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1680,"y":820,"wires":[["99a2450d0a1fe749"]]},{"id":"8018062759696e7e","type":"template","z":"647eafda.c7cfa","name":"Format Message","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{{person}}} has just {{{direction}}} {{{zone}}}.","output":"str","x":2110,"y":760,"wires":[["d002dcb3716f8a90"]]},{"id":"296c0678.b5f9ca","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’m sure there’s a way I can do this with a single state trigger node, but it’s taken me a bit to get here…

The “Set Topic” function nodes are meant to conditionally add a msg.topic based on some criteria:

  • if the value of msg.payload.data.event.old_state.state is home, then set msg.topic to input_datetime.time_left_home_${id}, where “id” is msg.data.event.new_state.attributes.id.
  • if the value of msg.payload.data.event.new_state.state is home, then set msg.topic to input_datetime.time_left_home_${id}, where “id” is also msg.data.event.new_state.attributes.id.

So, adding this msg.topic to the payload is failing, and I’m sure it’s because my syntax is bad in “input_datetime.time_left_home_${id},” or maybe some assignment thereof. Can anyone provide me with a solution?

TIA!

If you use an event state you can use the $entity() variable and get everything in one node. idk where the input date time landed in the text message but that value can be accessed in the event state with

$entities('input_datetime.time_left_home_' & $entity().attributes.id).state
[{"id":"067c7bf7e3c3fb1e","type":"server-state-changed","z":"0a325c35fc29f44e","name":"","server":"","version":5,"outputs":1,"exposeAsEntityConfig":"","entityId":"^person\\..*$","entityIdType":"regex","outputInitially":true,"stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"{\t   \"title\": $entities('person.' & $entity().attributes.id).state,\t   \"message\": $entity().attributes.friendly_name & \" has just left \" & $prevEntity().state,\t   \"data\":{\t       \"ttl\":0,\t       \"priority\":\"high\"        \t   } \t}","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"}],"x":360,"y":6440,"wires":[["dd5b10fc694382ce"]]}]
1 Like

I forgot all about that. I’ve used it in other flows… thanks for the reminder, I appreciate it!

1 Like

Alright, I just came back to implement this, and… wow! It really cuts down on the nodes, and simplifies things greatly if I add zones or persons.

However, that input datetime is still causing me problems…

The purpose of topic was to capture the time left/entering the home zone. I needed two events: state nodes, one for leaving zones and one for entering zones. I added topic here, though I’ve changed the key to timestore for clarity:

[{"id":"067c7bf7e3c3fb1e","type":"server-state-changed","z":"647eafda.c7cfa","name":"Person Left a Zone","server":"296c0678.b5f9ca","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"^person\\..*$","entityIdType":"regex","outputInitially":false,"stateType":"str","ifState":"not_home","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"{\t   \"title\": $entities('person.' & $entity().attributes.id).state,\t   \"message\": $entity().attributes.friendly_name & \" has just left \" & $prevEntity().state & \".\",\t   \"timestore\": $entities('input_datetime.time_left_home_' & $entity().attributes.id).state,   \"data\":{\t       \"ttl\":0,\t       \"priority\":\"high\"        \t   } \t}","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"}],"x":1450,"y":1100,"wires":[["060dfd804a346f8f","2d824db0d1a4030c","dd87af01bbab545a"],[]]},{"id":"060dfd804a346f8f","type":"debug","z":"647eafda.c7cfa","name":"EVENT STATE","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1820,"y":1000,"wires":[]},{"id":"54f4d95457220465","type":"server-state-changed","z":"647eafda.c7cfa","name":"Person Arrived at a Zone","server":"296c0678.b5f9ca","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"^person\\..*$","entityIdType":"regex","outputInitially":true,"stateType":"str","ifState":"not_home","ifStateType":"str","ifStateOperator":"is_not","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"{\t   \"title\": $entities('person.' & $entity().attributes.id).state,\t   \"message\": $entity().attributes.friendly_name & \" has just arrived at \" & $prevEntity().state & \".\",\t   \"timestore\": $entities('input_datetime.time_arrived_home_' & $entity().attributes.id).state,      \"data\":{\t       \"ttl\":0,\t       \"priority\":\"high\"        \t   } \t}","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"}],"x":1470,"y":1140,"wires":[["060dfd804a346f8f","2d824db0d1a4030c","dd87af01bbab545a"],[]]},{"id":"2d824db0d1a4030c","type":"api-call-service","z":"647eafda.c7cfa","name":"Store Time","server":"296c0678.b5f9ca","version":5,"debugenabled":false,"domain":"input_datetime","service":"set_datetime","areaId":[],"deviceId":[],"entityId":["{{ time }}"],"data":"{\"timestamp\": $millis() / 1000 }\t","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1830,"y":1180,"wires":[[]]},{"id":"dd87af01bbab545a","type":"change","z":"647eafda.c7cfa","name":"Set Message","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.message","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1830,"y":1120,"wires":[["d002dcb3716f8a90"]]},{"id":"296c0678.b5f9ca","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}]

Here’s my flow and the messages. You can see timestore is capturing a timestamp for some reason…?

I would expect timestore to contain the value input_datetime.time_arrived_home_[whatever the id is]… any thoughts on this?

EDIT: I suspect I could use a single events:state node and then set what is now timestore afterwards, but this is easier to get my head around at the moment.

Ohh, shucks… I know what I did wrong. I’m trying to pass the entity_id to set, and you’ve set me up to pass the actual datetime value. What’s weird is that this isn’t working, though:

{	   "title": $entities('person.' & $entity().attributes.id).state,	   "message": $entity().attributes.friendly_name & " has just arrived at " & $prevEntity().state & ".",	   "timestore": "input_datetime.time_arrived_home_" & $entity().attributes.id,      "data":{	       "ttl":0,	       "priority":"high"        	   } 	}

…previously, when I passed the datetime entity_id into this node, it would set the current timestamp:

OK… the issue was the layered message under payload. This works:

[{"id":"067c7bf7e3c3fb1e","type":"server-state-changed","z":"647eafda.c7cfa","g":"1661f8dc4b8b3f99","name":"Person Left a Zone","server":"296c0678.b5f9ca","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"^person\\..*$","entityIdType":"regex","outputInitially":false,"stateType":"str","ifState":"not_home","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"{\t   \"title\": $entities('person.' & $entity().attributes.id).state,\t   \"message\": $entity().attributes.friendly_name & \" has just left \" & $prevEntity().state & \".\",\t   \"topic\": $entities('input_datetime.time_left_home_' & $entity().attributes.id).state,   \"data\":{\t       \"ttl\":0,\t       \"priority\":\"high\"        \t   } \t}","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"}],"x":150,"y":880,"wires":[["060dfd804a346f8f","dd87af01bbab545a"],[]]},{"id":"54f4d95457220465","type":"server-state-changed","z":"647eafda.c7cfa","g":"1661f8dc4b8b3f99","name":"Person Arrived at a Zone","server":"296c0678.b5f9ca","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"^person\\..*$","entityIdType":"regex","outputInitially":true,"stateType":"str","ifState":"not_home","ifStateType":"str","ifStateOperator":"does_not_include","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"{\t   \"title\": $entities('person.' & $entity().attributes.id).state,\t   \"message\": $entity().attributes.friendly_name & \" has just arrived at \" & $prevEntity().state & \".\",\t   \"topic\": \"input_datetime.time_arrived_home_\" & $entity().attributes.id,      \"data\":{\t       \"ttl\":0,\t       \"priority\":\"high\"        \t   } \t}","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"}],"x":170,"y":920,"wires":[["060dfd804a346f8f","dd87af01bbab545a"],[]]},{"id":"dd87af01bbab545a","type":"change","z":"647eafda.c7cfa","g":"1661f8dc4b8b3f99","name":"Set Message","rules":[{"t":"set","p":"topic","pt":"msg","to":"payload.topic","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"payload.message","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":900,"wires":[["d002dcb3716f8a90","2d824db0d1a4030c","44b3d5ef30781345"]]},{"id":"2d824db0d1a4030c","type":"api-call-service","z":"647eafda.c7cfa","g":"1661f8dc4b8b3f99","name":"Store Time","server":"296c0678.b5f9ca","version":5,"debugenabled":false,"domain":"input_datetime","service":"set_datetime","areaId":[],"deviceId":[],"entityId":["{{ topic }}"],"data":"{\"timestamp\": $millis() / 1000 }\t","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":790,"y":900,"wires":[[]]},{"id":"296c0678.b5f9ca","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}]

!