Different behaviour passing the same message as JSON or Object?

I need some help, if possible, please?

I’m testing a TTS Notification from NodeRed to the HomeAssistant Android app and I’ve hit a brick wall, so thought I’d ask here and see if anyone else can see what I’m doing wrong… or if its a NodeRed bug? I’m really hoping that I did something wrong and someone can correct me?

The top flow works fine, passing a message into “notify” as JSON.
(see top “success” message in debug log. It does the TTS on phone fine)

The bottom flow fails, trying to pass the same message into “notify” as an object (from the JSON).
(see the other debug messages below it)

I’d assume that both should work the same… what am I missing / doing wrong?
…and how can I fix it?


The flow nodes:

[{"id":"1c6c87c31901de88","type":"inject","z":"e7f4496eefd20d50","name":"Send Object to Phone","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":200,"y":3700,"wires":[["f480831a0f4cb048"]]},{"id":"95994c3181675c81","type":"api-call-service","z":"e7f4496eefd20d50","name":"","server":"c4befa2f.dc8018","version":5,"debugenabled":false,"domain":"notify","service":"mobile_app_sm_g975f","areaId":[],"deviceId":[],"entityId":[],"data":"{{msg.paypload}}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":920,"y":3700,"wires":[["57f79fbf45ce78d1"]]},{"id":"57f79fbf45ce78d1","type":"debug","z":"e7f4496eefd20d50","name":"Debug:NMAO","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1180,"y":3700,"wires":[]},{"id":"f480831a0f4cb048","type":"function","z":"e7f4496eefd20d50","name":"Create JSON","func":"msg.payload = \"Your current position is test\";\nmsg.payload = \"{\\\"title\\\":\\\"\" + msg.payload + \"\\\",\\\"message\\\":\\\"TTS\\\",\\\"data\\\":{\\\"priority\\\":\\\"high\\\"}}\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":3700,"wires":[["1e3e7c6c4ddbdf7b","729ff3f37a906bae"]]},{"id":"1f6663d3accc1278","type":"debug","z":"e7f4496eefd20d50","name":"Debug:CTO","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":870,"y":3760,"wires":[]},{"id":"1e3e7c6c4ddbdf7b","type":"function","z":"e7f4496eefd20d50","name":"Convert to Object","func":"msg.payload = JSON.parse(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":650,"y":3700,"wires":[["95994c3181675c81","1f6663d3accc1278","58cf158ddfbdab0e"]]},{"id":"729ff3f37a906bae","type":"debug","z":"e7f4496eefd20d50","name":"Debug:CJ","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":620,"y":3760,"wires":[]},{"id":"5a1df2408ca6cf6d","type":"inject","z":"e7f4496eefd20d50","name":"Send JSON to Phone","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":200,"y":3560,"wires":[["bbb04e266d82e308"]]},{"id":"bbb04e266d82e308","type":"api-call-service","z":"e7f4496eefd20d50","name":"","server":"c4befa2f.dc8018","version":5,"debugenabled":false,"domain":"notify","service":"mobile_app_sm_g975f","areaId":[],"deviceId":[],"entityId":[],"data":"{\"title\":\"Your current position is test\",\"message\":\"TTS\",\"data\":{\"priority\":\"high\"}}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":920,"y":3560,"wires":[["9159a17de0b4743a"]]},{"id":"9159a17de0b4743a","type":"debug","z":"e7f4496eefd20d50","name":"Debug:NMAJ","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1170,"y":3560,"wires":[]},{"id":"58cf158ddfbdab0e","type":"function","z":"e7f4496eefd20d50","name":"Convert back to JSON (test)","func":"msg.payload = JSON.stringify(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":920,"y":3640,"wires":[["a4f506aa6cf49ef9"]]},{"id":"a4f506aa6cf49ef9","type":"debug","z":"e7f4496eefd20d50","name":"Debug:CBTJ","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1170,"y":3640,"wires":[]},{"id":"c4befa2f.dc8018","type":"server","name":"Home Assistant","version":4,"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"}]

Mustache templates don’t handle objects.

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/call-service.html#data-field

Same error using the other method J:msg.payload

[{"id":"95994c3181675c81","type":"api-call-service","z":"e7f4496eefd20d50","name":"","server":"c4befa2f.dc8018","version":5,"debugenabled":false,"domain":"notify","service":"mobile_app_sm_g975f","areaId":[],"deviceId":[],"entityId":[],"data":"msg.payload","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":920,"y":3700,"wires":[["57f79fbf45ce78d1"]]},{"id":"c4befa2f.dc8018","type":"server","name":"Home Assistant","version":4,"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"}]

msg.payload.data is being imported as a config override. If you turn on debug of the call-service node you’ll see that it’s being placed in the data field at the top level.

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/call-service.html#input

Turning on “Show debug information” of the Call Service node returns nothing. It just hangs at “Sending”.
Capture

The “static” JSON text works fine (the top flow)… but the “dynamic” text that I change to an object doesn’t (the one under it).

How would I make the “dynamic” text be sent the same as the “static” JSON string?
(with the accompanying “priority”?)

change the property it is in msg to anything other than payload

1 Like

Thanks :slight_smile:

I changed it to msg.fubar instead of msg.payload
…and it works fine.

I don’t understand why payload wouldn’t work… but fubar does.

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/call-service.html#input

The call-service node accepts config override via msg.payload. One of the accepted inputs is msg.payload.data. Anything in this property gets placed into the data field.

The payload you send the call-service node includes msg.payload.data.priority which gets copied to the top level in the data field.

1 Like

Oh… so I was attempting to reuse a special variable/object as my input variable/object?

I’ve been reusing msg.payload in other nodes without any errors, so didn’t know they were special config objects / variables :frowning:

I guess that I should start getting used to adding “custom” variables / objects instead of just clearing-down and/or reusing msg.payload then?

Thanks again for all the help and information :slight_smile:

Now that it works, I have made a simple notification that will use TTS on my mobile to say where I am (to test when I enter / leave zones).



The nodes:

[{"id":"d844bb4111ac1596","type":"server-state-changed","z":"e7f4496eefd20d50","name":"","server":"c4befa2f.dc8018","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person.daryl","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":"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":200,"y":3120,"wires":[["88b3a77ef62aa1ea"]]},{"id":"259b6cd144eaeec8","type":"debug","z":"e7f4496eefd20d50","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1030,"y":3120,"wires":[]},{"id":"88b3a77ef62aa1ea","type":"function","z":"e7f4496eefd20d50","name":"Create notification object","func":"msg.notification = \"Daryl is now \" + msg.payload;\nmsg.notification = \"{\\\"title\\\":\\\"\" + msg.notification + \"\\\",\\\"message\\\":\\\"TTS\\\",\\\"data\\\":{\\\"priority\\\":\\\"high\\\"}}\";\nmsg.notification = JSON.parse(msg.notification);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":3120,"wires":[["538d6f108b678637"]]},{"id":"538d6f108b678637","type":"api-call-service","z":"e7f4496eefd20d50","name":"","server":"c4befa2f.dc8018","version":5,"debugenabled":true,"domain":"notify","service":"mobile_app_sm_g975f","areaId":[],"deviceId":[],"entityId":[],"data":"msg.notification","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":780,"y":3120,"wires":[["259b6cd144eaeec8"]]},{"id":"c4befa2f.dc8018","type":"server","name":"Home Assistant","version":4,"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"}]

You don’t have a create a JSON string and then parse it to a js object. You can create the object from the start.

msg.notification = {
  title: `Daryl is now ${payload}`,
  message: 'TTS',
  data: {
    priority: 'high',
  }
};

return msg;

You can also do all this inside the call-service node. In the data field use

{
  "title": "Daryl is now " & payload,
  "message": "TTS",
  "data": {
    "priority": "high",
  }
}

I’ll probably use the top example going forward, thanks :slight_smile:

I don’t like the idea of putting it in the call-service node though, as I often just copy / paste the call-service nodes & drop them into anywhere I want the node (normally temporarily)… as I know the variables they’ll use & don’t need to edit the node.