Notify Message Call Service Problem

Hi All,

I have a flow that will notify any family member that enters our home, via Alexa, who is currently away, and who is also home. (Credit to Tom Schneider for creating the original flow Let Alexa welcome you home ).

In the flow, there is a function node that does a lot of stuff to prep and create a dynamic message based on who is home and not home. This function successfully creates the message, passes it off to to the Alexa Call Service Node, and Alexa successfully announces the message. No issues on this side. The Alexa notification works like a charm!

My issue is when attempting to pass the same message from the same function to a Call Service Node as a message to my cellphone (My alteration/addition to the original flow from Tom Schneider).

Instead of getting the actual same message that Alex announces, I get a cellphone notification that just says “object object, object object, object object”.

For the life of me I am unable to figure out why, and was hoping someone could assist me in a solution?

I have added my flow for anyone to review.

Any help in getting me back on track would be greatly appreciated.

Thanks in advance :slight_smile:

[{"id":"6e393969.673f5","type":"server-state-changed","z":"aea0d0f9624c9c25","name":"Someone comes 🏠","server":"e3c3c875.5a6578","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person\\..*","entityidfiltertype":"regex","outputinitially":false,"state_type":"str","haltifstate":"home","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,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":110,"y":300,"wires":[["49d067bc.f7f448"],[]]},{"id":"49d067bc.f7f448","type":"delay","z":"aea0d0f9624c9c25","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":235,"y":300,"wires":[["9dff5589.c12218"]],"l":false},{"id":"e01bf48d.d8b98","type":"function","z":"aea0d0f9624c9c25","name":"Filter family","func":"let family = ['person.john', 'person.mary', 'person.bob'];\n\nif(family.includes(msg.topic)) {\n    node.status({fill:\"green\",shape:\"dot\",text:\"Family\"});\n    return [msg, null];\n}\nnode.status({fill:\"green\",shape:\"dot\",text:\"Guest\"});\nreturn [null, msg];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":300,"wires":[["caef02e7.7fe64"],[]],"outputLabels":["Familie","Gäste"]},{"id":"9dff5589.c12218","type":"ha-wait-until","z":"aea0d0f9624c9c25","name":"Front door opened","server":"e3c3c875.5a6578","version":0,"outputs":2,"entityId":"binary_sensor.downstairs_front_door_on_off","entityIdFilterType":"exact","property":"state","comparator":"is","value":"on","valueType":"str","timeout":"20","timeoutType":"num","timeoutUnits":"minutes","entityLocation":"","entityLocationType":"none","checkCurrentState":true,"blockInputOverrides":true,"x":370,"y":300,"wires":[["e01bf48d.d8b98"],[]]},{"id":"caef02e7.7fe64","type":"ha-get-entities","z":"aea0d0f9624c9c25","name":"🔎 Get all persons","server":"e3c3c875.5a6578","version":0,"rules":[{"property":"entity_id","logic":"is","value":"person\\..*","valueType":"re"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":730,"y":300,"wires":[["43b98a51.b5e6e4"]]},{"id":"43b98a51.b5e6e4","type":"deduplicate","z":"aea0d0f9624c9c25","name":"","keyproperty":"payload","expiry":"120","x":295,"y":400,"wires":[["f2c5ca0e.349a7"],[]],"l":false},{"id":"f2c5ca0e.349a7","type":"function","z":"aea0d0f9624c9c25","name":"Create message","func":"/** CONFIGURATION **/\n\n// These are the persons you want to include in the greeting.\nlet persons_whitelist = ['person.john', 'person.mary', 'person.bob'];\n\n// A random greeting will be played every time.\nlet r_greet = [\"Welcome home, \", \"It's nice to see you, \", \"Welcome back, \", \"Hey \", \"Hi, \"];\n\n/** Optional: Localization\n *  If you create a new localization, you can share it in the comments! **/\nlet l10n = {\n  \"is\": \"is\",\n  \"are\": \"are\",\n  \"and\": \"and\",\n  \"xyz_is_also_home\": (others, is_are) => others + \" \" + is_are + \" also at home. \",\n  \"since\": \"since\",\n  \"just_now\": \"just now\",\n  \"one_minute\": \"one minute\",\n  \"x_minutes\": (minutes) => minutes + \" minutes\",\n  \"one_hour\": \"one hour\",\n  \"x_hours\": (hours) => hours + \" hours\",\n  \"one_day\": \"one day\",\n  \"x_days\": (days) => days + \" days\",\n  \"away_text\": (persons_with_time) => smart_join(persons_with_time.map(pwt => pwt[0] + \" left \" + pwt[1]  + \" ago\")),\n  \"final_text\": (text) => hour >= 0 && hour < 6 ? \"<amazon:effect name='whispered'>\" + text + \"</amazon:effect>\" : text  \n}\n\n// // Below you find my template for German.\n// // You may also like my r_greet: let r_greet = [\"Willkommen zu Hause, \", \"Schön, dass du da bist, \", \"Willkommen zurück, \", \"Hallo \", \"Moin, \"];\n// let l10n = {\n//     \"is\": \"ist\",\n//     \"are\": \"sind\",\n//     \"and\": \"und\",\n//     \"xyz_is_also_home\": (others, is_are) => others + \" \" + is_are + \" auch zu Hause. \",\n//     \"since\": \"seit\",\n//     \"just_now\": \"gerade eben\",\n//     \"one_minute\": \"einer Minute\",\n//     \"x_minutes\": (minutes) => minutes + \" Minuten\",\n//     \"one_hour\": \"einer Stunde\",\n//     \"x_hours\": (hours) => hours + \" Stunden\",\n//     \"one_day\": \"einem Tag\",\n//     \"x_days\": (days) => days + \" Tagen\",\n//     \"away_text\": (persons_with_time) => smart_join(persons_with_time.map(pwt => pwt[0] + \" ist seit \" + pwt[1])) + \" unterwegs.\",\n//     \"final_text\": (text) => hour >= 0 && hour < 6 ? \"<amazon:effect name='whispered'>\" + text + \"</amazon:effect>\" : text  \n// }\n\n/** Optional: Relations. Replace a name for a person. E.g.: Call Peter \"Dad\" for the kids */\nlet relations = {\n  \"person.john\": {\n    \"person.mary\": \"Mom\",\n  },\n  \"person.bob\": {\n    \"person.john\": \"Dad\",\n    \"person.mary\": \"Mom\",\n  }\n}\n\n/** END CONFIGURATION.\n *  You don't have to change anything below, but if you have a great idea on\n *  how to improve this, please write a comment to share it with us! */\n\n// Join the array to a string separated by commas except the last, which gets replaced by \"and\".\nfunction smart_join(arr) { return arr.join(', ').replace(/, ([^,]*)$/, ' ' + l10n[\"and\"] + ' $1'); }\n\n// convert a Date object into a relative time\nfunction relative_time(time_value) {\n  var parsed_date = Date.parse(time_value);\n  var relative_to = (arguments.length > 1) ? arguments[1] : new Date();\n  var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);\n\n  if (delta < 60) {\n    return l10n[\"just_now\"];\n  } else if(delta < 120) {\n    return l10n[\"one_minute\"];\n  } else if(delta < (60*60)) {\n    return l10n[\"x_minutes\"](parseInt(delta / 60).toString());\n  } else if(delta < (120*60)) {\n    return l10n[\"one_hour\"];\n  } else if(delta < (24*60*60)) {\n    return l10n[\"x_hours\"](parseInt(delta / 3600).toString());\n  } else if(delta < (48*60*60)) {\n    return l10n[\"one_day\"]\n  } else {\n    return l10n[\"x_days\"](parseInt(delta / 86400).toString());\n  }\n}\n\n// The arriver is the person that just came home\nlet arriver = msg.data.entity_id;\nlet arriver_name = msg.data.new_state.attributes.friendly_name;\n\nlet hour = new Date().getHours();\nlet home = [];\nlet away = [];\n\n// Get all persons that are home excluding the arriver\nfor(var i=0; i<msg.payload.length; i++) {\n    let current = msg.payload[i];\n    if(current.entity_id != arriver) {\n\n        // Rewrite names for special relations\n        var other_name = (relations[arriver] || {})[current.entity_id] || current.attributes.friendly_name;\n\n        if(current.state == \"home\") {\n            home.push(other_name);\n        } else if(persons_whitelist.includes(current.entity_id)) {\n            away.push([other_name, relative_time(current.last_changed), current.last_changed]);\n        }\n    }\n}\n\n// Sort by away time (untested)\naway = away.sort(a => a[2]);\n\n// Create the message\n\n// Get a random greeting from r_greet\nlet greet = r_greet[Math.floor(Math.random()*r_greet.length)];\nlet is_are = home.length == 1 ? l10n[\"is\"] : l10n[\"are\"];\nlet others = smart_join(home);\n\nlet text = greet + arriver_name + \". \";\n\n// Just tell who is home when there is actually someone home\nif(home.length > 0) {\n    text += l10n[\"xyz_is_also_home\"](others, is_are);\n}\n\n// Just tell who is away when there is actually someone away\nif(away.length > 0) {\n    text += l10n[\"away_text\"](away);\n}\n\nmsg.payload.data = {\n  message: l10n[\"final_text\"](text)  \n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":400,"wires":[["5f00952f.0a657c","f82a557ea2bd1c32"]]},{"id":"5f00952f.0a657c","type":"api-call-service","z":"aea0d0f9624c9c25","name":"📢 Alexa","server":"e3c3c875.5a6578","version":3,"debugenabled":false,"service_domain":"notify","service":"alexa_media","entityId":"","data":"{\"data\":{\"type\":\"announce\",\"method\":\"all\"},\"target\":\"media_player.living_room_echo\"}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":620,"y":380,"wires":[[]]},{"id":"f82a557ea2bd1c32","type":"api-call-service","z":"aea0d0f9624c9c25","name":"Send notification to John's phone","server":"e3c3c875.5a6578","version":3,"debugenabled":false,"service_domain":"notify","service":"mobile_app_john_iphone","entityId":"","data":"{\"message\":\"{{payload}}\"}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":700,"y":440,"wires":[[]]},{"id":"e3c3c875.5a6578","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]

Is this a Home Assistant flow?

Sorry. Forgot to mention that in the post. Yes it is :slight_smile:

You might want to have a look at this node / flow, in case you want to receive the notification on whatsapp; if's quite simple, easy to use and setting it up is quick:

Without loading your flow (I don't have/use HA nodes) I suspect the properties you use to build the message are objects instead of strings.

In your function, use node.warn(xxx) as many times as you need to determine what you are actually concatenating.

Also...

There’s a great page in the docs that will explain how to use the debug panel to find the right path to any data item.

Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

BX00Cy7yHi

https://nodered.org/docs/user-guide/messages