Add Volume Attribute to Service Call

I’ve set up an alert for my sump pump using Node-Red and service calls to Sonos Cloud integration (Sonos Cloud Volume Example). I’ve figured out everything except how to set volume for the integration. Referring to instruction for the integration, there should be “extra:” and “volume: xx” attributes added to data. The yaml code looks like;

service: media_player.play_media
data:
  entity_id: media_player.kitchen
  media_content_id: https://<unique_cloud_id>.ui.nabu.casa/local/sound_files/doorbell.mp3
  media_content_type: music
  extra:
    volume: 35  # Can be provided as 0-100 or 0.0-0.99
    play_on_bonded: true

I’ve been able to configure the service nodes to work with everything except “volume: 35”. I don’t wish to use the “play_on_bonded:” attribute so I’m not concerned about how to pass that atribute.

Here’s my node-red flow thus far;

[{"id":"d0731a83c27702f1","type":"ha-get-entities","z":"03e200a6de65cb92","name":"Get List of Sonos Speakers for Announcement","server":"fcf9b76b.256a88","version":0,"rules":[{"property":"entity_id","logic":"is","value":"_announce","valueType":"re"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"announce_to","output_results_count":1,"x":920,"y":500,"wires":[["b2470f6e3396ca28"]]},{"id":"624ff75936f16499","type":"inject","z":"03e200a6de65cb92","name":"Test - Alarm Active","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"on","payloadType":"str","x":290,"y":500,"wires":[["8a0be39fa7341bdd"]]},{"id":"ceadb35ee5740e03","type":"inject","z":"03e200a6de65cb92","name":"Test - Alarm Error","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"str","x":300,"y":560,"wires":[["8a0be39fa7341bdd"]]},{"id":"e7596274a2f6e065","type":"inject","z":"03e200a6de65cb92","name":"Test Alarm - Clear","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"off","payloadType":"str","x":290,"y":620,"wires":[["8a0be39fa7341bdd"]]},{"id":"8a0be39fa7341bdd","type":"function","z":"03e200a6de65cb92","name":"Formulate Message","func":"var dateNow = new Date();\nvar timeAsString = dateNow.toLocaleTimeString();\n\nif (msg.payload === \"on\") {\n    msg.topic = 'Alarm On';\n    msg.payload = 'Check immediately.';\n    msg.announcement = 'Check immediately.';\n    msg.criticality_level = 1;\n    msg.alert_volume_level = 1;\n} else {\n    if (msg.payload === \"off\") {\n    msg.topic = 'Alarm Off';\n    msg.payload = 'Check late.r';\n    msg.criticality_level = 0;\n    msg.alert_volume_level = 0.5;\n    } else {\n        msg.topic = 'Unkown Status';\n        msg.payload = 'Check Soon.';\n    msg.criticality_level = 1;\n    msg.alert_volume_level = 1;\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":560,"y":500,"wires":[["d0731a83c27702f1"]]},{"id":"c3db28364f858f09","type":"api-call-service","z":"03e200a6de65cb92","name":"Make Announcement","server":"fcf9b76b.256a88","version":3,"debugenabled":false,"service_domain":"tts","service":"cloud_say","entityId":"{{payload.entity_id}}","data":"{\"message\":\"{{announcement}}\"}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1360,"y":580,"wires":[["3d429cabef4dbe91","3ee13a4cd512541d"]]},{"id":"b2470f6e3396ca28","type":"array-loop","z":"03e200a6de65cb92","name":"","key":"al171b66887045a526","keyType":"msg","reset":false,"resetValue":"value-null","array":"announce_to","arrayType":"msg","x":830,"y":580,"wires":[[],["c4f32314113145ef"]]},{"id":"e1399478db850301","type":"function","z":"03e200a6de65cb92","name":"return msg","func":"\nreturn msg;","outputs":1,"noerr":0,"x":1690,"y":580,"wires":[["b2470f6e3396ca28"]]},{"id":"3d429cabef4dbe91","type":"delay","z":"03e200a6de65cb92","name":"","pauseType":"delay","timeout":"6","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"2","randomLast":"3","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1540,"y":580,"wires":[["e1399478db850301"]]},{"id":"c4f32314113145ef","type":"api-call-service","z":"03e200a6de65cb92","name":"Sound Chime","server":"fcf9b76b.256a88","version":3,"debugenabled":false,"service_domain":"media_player","service":"play_media","entityId":"{{payload.entity_id}}","data":"{\t  \"media_content_id\": \"CHIME\",\t  \"media_content_type\": \"music\"\t}","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1020,"y":580,"wires":[["72c57acfe039ba4f"]]},{"id":"72c57acfe039ba4f","type":"delay","z":"03e200a6de65cb92","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"2","randomLast":"3","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1180,"y":580,"wires":[["c3db28364f858f09"]]},{"id":"3ee13a4cd512541d","type":"debug","z":"03e200a6de65cb92","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1570,"y":720,"wires":[]},{"id":"fcf9b76b.256a88","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"}]

How do I add the extra/volume attributes to the “Sound Chime” and “Make Announcement” service nodes?

Note: you may wish/need to add the node-red-contrib-loop-processing node to make the flow work as laid out.

In the data element of the call service node you’d have something like:

{"media_content_id": "https://<unique_cloud_id>.ui.nabu.casa/local/sound_files/doorbell.mp3", "media_content_type": "music", "extra": {"volume": 35, "play_on_bound": true}}

This works perfect for the “CHIME” node;

{
   "media_content_id": "CHIME",
   "media_content_type": "music",
   "extra":{
      "volume": 40
    }
}

But adding this to the “Make Announcement” node results in and error - “Call-service error. extra keys not allowed @ data[‘extra’]”

{
    "message": "{{announcement}}",
    "extra": {
        "volume": 40
    }
}

Can’t figure out why it works for one and not the other!

Presumably that is a different service call with a different structure. Work out what the parameters are using the services call in the Developer Tools menu, and then replicate the structure to Node Red. Sorry, I didn’t load your nodes and you didn’t provide the yaml equivalent for your announcement node. It should be a simple translation of the yaml structure for the data attribute to a json structure.

Assuming you are using the Google TTS service, then there is no volume control. Just message and language (on top of the entity).

Using tts cloud_say and the Sonos Cloud integration allows for volume to be set via Sonos Cloud integration.

The call service node can do whatever you can do in the services dialogue of the Developer Tools menu. If you can do it in one call there, you can do it in Node Red. Just follow the structure that you should be able to see from the example I gave.

This shows how to use it, doesn’t look like there is a volume control on the TTS service. So set the volume first, send the message, then set the volume back.

I’ve read through that a few times. Perhaps I’ve set up the service call incorrectly. I’m try to use the Sono Cloud integration for the output [https://github.com/jjlawren/sonos_cloud/#examples](https://Sonos cloud integration). Have you looked at that integration to see how it works?

I don’t use this so I can’t say what the correct format is. When I run into this message removing the key before the indentation sometimes works.

{
    "message": "{{announcement}}",
    "volume": 40
}

I don’t use Nabu cloud at all, so haven’t used the integration. Have you done what I suggested and tried the call in the services tab of Developer Tools, otherwise you are just guessing.

Just to add, you can’t mix the parameters used for play_media, with those for tts_say. The examples that page clearly show the only parameter you can send to tts_say is message.

Yes, tried what you suggested. I’ve figured out the problem…

Despite the fact that Sonos Cloud supports volume control, tts doesn’t pass the required attribute (volume) along. There was an HA PR submitted by the author of the integration in 2021 but is was rejected (Sonos Cloud PR).

Since tts doesn’t support volume I’ll need to find a different means of adjusting message volume.

Thanks for your help on sorting out volume on the “Chime” node.

media_player.volume_up/volume_down/set_volume are the set of services. I forget which Sonos supports. Use a current state node, to get and store the current volume for the relevant entity.

The point of the Sonos Cloud integration is elimination of the need to capture then reset Sonos settings when sending a message. The integration manages that for you. I need to reflect on both methods prior to moving forward.

TTSultimate seems to support volume for sonos

image

@Mikefila , thanks for this. I give it a try!

Jumping in here on this topic, I’ve been trying to do a message out to my google home speakers using “tts.cloud_say” with Nabu Casa and the volume on the speakers for some reason will drop to 40% does the set message as expected and then resumes volume back to what it was set to prior. Here is my flow:

[{"id":"364527aca23436fa","type":"change","z":"222807841272ebfa","name":"Message Info","rules":[{"t":"delete","p":"payload.data.title","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"payload.target","pt":"msg","to":"{\"entity_id\":\"media_player.googlehome1850\"}","tot":"json"},{"t":"set","p":"payload.data.message","pt":"msg","to":"Test message","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":1400,"wires":[["816ff106322aa13d"]]},{"id":"816ff106322aa13d","type":"api-call-service","z":"222807841272ebfa","name":"","server":"541ade28.b4a62","version":5,"debugenabled":true,"domain":"tts","service":"cloud_say","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":730,"y":1400,"wires":[[]]},{"id":"d8dd05d31b20c004","type":"inject","z":"222807841272ebfa","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":390,"y":1400,"wires":[["364527aca23436fa"]]},{"id":"541ade28.b4a62","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"","connectionDelay":false,"cacheJson":false,"heartbeat":false,"heartbeatInterval":"","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":false}] `