The ability to control a Sonos Subwoofer’s volume (The actual Sonos self-powered version) was added in March of 22, but there is no control for the similarly named “Sub Audio Level” which is a control in the Sonos app which controls the audio level of the “Subwoofer” Audio output on the back of the Sonos Amp and Sonos Amp2. This level controls the volume of an “Add On”, wired (not Sonos Branded) powered subwoofer. This would be a HUGE win.
Don’t forget to vote for your own request!
This is likely straightforward to add, but I unfortunately do not have a device to test with. Would you be able to provide info and run scripts to help move this along?
@rosshenning If you can run this script and adjust the “Sub Audio Level” in the Sonos app to its min & max values, hopefully this will print out what we need to get started.
Make sure to change the IP address to the Amp before running. The script will listen for updates for 30 seconds and then exit.
sub_test.py
import asyncio
from datetime import datetime
from pprint import pformat
import soco
import soco.config
from soco import events_asyncio
soco.config.EVENTS_MODULE = events_asyncio
# SET ME
amp = soco.SoCo("10.6.9.224")
def print_event(event):
print(
"{} - {} [{}]:\n{}".format(
datetime.now(),
event.service.soco.ip_address,
event.service.service_type,
pformat(event.variables, indent=4, width=180, compact=True),
)
)
async def main():
sub = await amp.renderingControl.subscribe()
sub.callback = print_event
await asyncio.sleep(30)
await sub.unsubscribe()
await events_asyncio.event_listener.async_stop()
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Save the above in a file like sub_test.py
and run it with python sub_test.py
. You’ll need the soco
package installed. That can likely be installed with pip install soco
if it’s not already available.
Hi jjlawren,
My apologies for not seeing this sooner. My notifications must be going to spam or something. I just happened upon this answer. I’m not familiar with running a script like this. I’m an “old school” guy who learned Basic, Java, C# back in the day, but python is something I haven’t tackled. Would I run this on my HA Device, or would I need to install Python somewhere else?
Thanks
Hi jjlawren,
Okay…after I played with it a few minutes, I figured it out. Here’s the output you requested:
2023-03-01 12:51:39.037327 - 192.168.1.202 [RenderingControl]:
{ ‘audio_delay’: ‘0’,
‘audio_delay_left_rear’: ‘1’,
‘audio_delay_right_rear’: ‘1’,
‘bass’: ‘10’,
‘dialog_level’: ‘0’,
‘height_channel_level’: ‘0’,
‘loudness’: {‘Master’: ‘1’},
‘music_surround_level’: ‘0’,
‘mute’: {‘LF’: ‘0’, ‘Master’: ‘0’, ‘RF’: ‘0’},
‘night_mode’: ‘0’,
‘output_fixed’: ‘0’,
‘preset_name_list’: ‘FactoryDefaults’,
‘sonar_calibration_available’: ‘0’,
‘sonar_enabled’: ‘0’,
‘speaker_size’: ‘1’,
‘sub_crossover’: ‘80’,
‘sub_enabled’: ‘1’,
‘sub_gain’: ‘11’,
‘sub_polarity’: ‘0’,
‘surround_enabled’: ‘0’,
‘surround_level’: ‘3’,
‘surround_mode’: ‘0’,
‘treble’: ‘10’,
‘volume’: {‘LF’: ‘100’, ‘Master’: ‘19’, ‘RF’: ‘100’}}
2023-03-01 12:51:54.325275 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘11’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:54.624547 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘15’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:54.879164 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘15’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:55.558797 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘15’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:55.862212 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘5’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:56.078208 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-1’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:56.374836 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:56.612679 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-14’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:56.884506 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-15’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:57.138630 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-15’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:58.299701 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-14’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:58.553346 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-3’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:58.807031 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘1’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:59.059443 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘6’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:59.314020 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘8’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:59.570828 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:51:59.821469 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
Exception in callback _ProactorBasePipeTransport._call_connection_lost(None)
handle: <Handle _ProactorBasePipeTransport._call_connection_lost(None)>
Traceback (most recent call last):
File “C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2800.0_x64__qbz5n2kfra8p0\lib\asyncio\events.py”, line 80, in _run
self._context.run(self._callback, *self._args)
File “C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2800.0_x64__qbz5n2kfra8p0\lib\asyncio\proactor_events.py”, line 165, in _call_connection_lost
self._sock.shutdown(socket.SHUT_RDWR)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
2023-03-01 12:52:01.065528 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:01.324556 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘91’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:01.576634 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘97’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:01.829675 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘103’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:02.080524 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘106’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:02.336738 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘109’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:02.592335 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘110’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:02.846189 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘110’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:03.105013 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘105’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:03.357477 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘94’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:03.655515 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘84’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:03.911808 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘78’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:04.167277 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘75’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:04.374521 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘65’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:04.678006 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘59’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:04.890955 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘55’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:05.188887 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘50’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:05.419789 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘50’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:05.698839 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘50’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
C:\Users\rossh\Documents>python sonos-sub.py
2023-03-01 12:52:17.029124 - 192.168.1.202 [RenderingControl]:
{ ‘audio_delay’: ‘0’,
‘audio_delay_left_rear’: ‘1’,
‘audio_delay_right_rear’: ‘1’,
‘bass’: ‘10’,
‘dialog_level’: ‘0’,
‘height_channel_level’: ‘0’,
‘loudness’: {‘Master’: ‘1’},
‘music_surround_level’: ‘0’,
‘mute’: {‘LF’: ‘0’, ‘Master’: ‘0’, ‘RF’: ‘0’},
‘night_mode’: ‘0’,
‘output_fixed’: ‘0’,
‘preset_name_list’: ‘FactoryDefaults’,
‘sonar_calibration_available’: ‘0’,
‘sonar_enabled’: ‘0’,
‘speaker_size’: ‘1’,
‘sub_crossover’: ‘95’,
‘sub_enabled’: ‘1’,
‘sub_gain’: ‘10’,
‘sub_polarity’: ‘0’,
‘surround_enabled’: ‘0’,
‘surround_level’: ‘3’,
‘surround_mode’: ‘0’,
‘treble’: ‘10’,
‘volume’: {‘LF’: ‘100’, ‘Master’: ‘19’, ‘RF’: ‘100’}}
2023-03-01 12:52:18.973951 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘1’}
2023-03-01 12:52:21.964114 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:25.794801 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:26.048878 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘15’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:26.261905 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘15’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:26.793480 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘15’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:27.086520 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘11’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:27.295550 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘9’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:27.551072 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:27.805638 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-14’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:28.060370 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-15’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:29.017947 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:29.274485 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-9’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:29.529782 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-5’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:29.781808 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-3’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:30.031332 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘-2’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:30.283859 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘0’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:30.539264 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘1’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:30.796132 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘3’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:31.050946 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘6’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:31.308725 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘8’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:31.560934 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘10’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:31.815462 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘11’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:32.069480 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:32.322667 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘95’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:32.834669 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘92’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:33.090243 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘69’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:33.346762 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘55’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:33.643817 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘50’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:34.349140 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘50’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:34.583028 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘64’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:34.856703 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘84’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:35.111268 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘87’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:35.321827 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘90’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:36.574960 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘79’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:36.848766 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘78’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:37.772350 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘78’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:38.030373 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘66’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:40.020075 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘68’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:40.271670 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘88’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:40.525694 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘92’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:41.318764 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘90’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:41.575790 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘82’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:41.831825 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘81’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:42.082745 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘81’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:42.337053 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:42.588712 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘1’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
2023-03-01 12:52:44.471534 - 192.168.1.202 [RenderingControl]:
{‘speaker_size’: ‘1’, ‘sub_crossover’: ‘80’, ‘sub_enabled’: ‘0’, ‘sub_gain’: ‘12’, ‘sub_polarity’: ‘0’}
C:\Users\rossh\Documents>
Can you explain what you were adjusting in the Sonos app during these tests? I see both sub_crossover
and sub_gain
changing at different times.
Also if you’re able to share a screenshot of the adjustment slider it would be interesting to see.
Sure thing. There’s actually two sliders for the subwoofer output. Gain and Crossover point. I thought you’d probably want to see values for both being generated, so I moved both sliders.
Okay, that wasn’t clear from the original post and I don’t have a sub myself to test with. Thanks for the explanation and screenshot, those make things much clearer.
What are the upper and lower limits for each slider in the Sonos app? Is it 50-110Hz on the crossover and -15 to +15 on the gain?
You have the limits correct on both…I just double-checked.
Now that I’ve had a chance to sit down and look/remember, “sub gain” controls were added to the underlying library and HA integration about a year ago. Is this different from what you’re looking for?
The crossover controls can still be added.
@rosshenning can you see if this script changes the subwoofer crossover level? It’s a guess so I’ll need a tester.
import soco
# SET ME
amp = soco.SoCo("10.6.9.224")
frequency = 110
amp.renderingControl.SetEQ(
[
("InstanceID", 0),
("EQType", "SubCrossover"),
("DesiredValue", int(frequency)),
]
)
Run a couple times with different frequency
values and see if it changes as expected in the native Sonos app.
Also, if would be interesting if you could attach the XML returned by the Amp which has a paired sub: http://<AMP_IP_HERE>:1400/xml/RenderingControl1.xml
Sub gain isn’t showing up as entities for any of my Sonos units and all of mine have third party subs. I have a feeling the sub gain that is published is for Sonos branded subs, which seem to be addressed differently than third party.
The new script works correctly. I am able to change the subwoofer crossover frequency with no errors.
Here is the output from the render:
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<serviceStateTable>
<stateVariable sendEvents="yes">
<name>LastChange</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Mute</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Volume</name>
<dataType>ui2</dataType>
<allowedValueRange>
<minimum>0</minimum>
<maximum>100</maximum>
<step>1</step>
</allowedValueRange>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_LeftVolume</name>
<dataType>ui2</dataType>
<allowedValueRange>
<minimum>0</minimum>
<maximum>100</maximum>
<step>1</step>
</allowedValueRange>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_RightVolume</name>
<dataType>ui2</dataType>
<allowedValueRange>
<minimum>0</minimum>
<maximum>100</maximum>
<step>1</step>
</allowedValueRange>
</stateVariable>
<stateVariable sendEvents="no">
<name>VolumeDB</name>
<dataType>i2</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Bass</name>
<dataType>i2</dataType>
<allowedValueRange>
<minimum>-10</minimum>
<maximum>10</maximum>
<step>1</step>
</allowedValueRange>
</stateVariable>
<stateVariable sendEvents="no">
<name>Treble</name>
<dataType>i2</dataType>
<allowedValueRange>
<minimum>-10</minimum>
<maximum>10</maximum>
<step>1</step>
</allowedValueRange>
</stateVariable>
<stateVariable sendEvents="no">
<name>EQValue</name>
<dataType>i2</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_EQType</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>Loudness</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SupportsOutputFixed</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>OutputFixed</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>HeadphoneConnected</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_Channel</name>
<dataType>string</dataType>
<allowedValueList>
<allowedValue>Master</allowedValue>
<allowedValue>LF</allowedValue>
<allowedValue>RF</allowedValue>
</allowedValueList>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_MuteChannel</name>
<dataType>string</dataType>
<allowedValueList>
<allowedValue>Master</allowedValue>
<allowedValue>LF</allowedValue>
<allowedValue>RF</allowedValue>
</allowedValueList>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_InstanceID</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_VolumeAdjustment</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_RampType</name>
<dataType>string</dataType>
<allowedValueList>
<allowedValue>SLEEP_TIMER_RAMP_TYPE</allowedValue>
<allowedValue>ALARM_RAMP_TYPE</allowedValue>
<allowedValue>AUTOPLAY_RAMP_TYPE</allowedValue>
</allowedValueList>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_RampTimeSeconds</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_ResetVolumeAfter</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_ProgramURI</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_ChannelMap</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>AudioDelay</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>AudioDelayLeftRear</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>AudioDelayRightRear</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>DialogLevel</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SpeakerSize</name>
<dataType>ui4</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SubCrossover</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SubEnabled</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SubGain</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SubPolarity</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SurroundLevel</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>MusicSurroundLevel</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>NightMode</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SurroundEnabled</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SurroundMode</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>PresetNameList</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>RoomCalibrationID</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>RoomCalibrationCoefficients</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>RoomCalibrationCalibrationMode</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>RoomCalibrationEnabled</name>
<dataType>boolean</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>RoomCalibrationAvailable</name>
<dataType>boolean</dataType>
</stateVariable>
</serviceStateTable>
<actionList>
<action>
<name>GetMute</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_MuteChannel</relatedStateVariable>
</argument>
<argument>
<name>CurrentMute</name>
<direction>out</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetMute</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_MuteChannel</relatedStateVariable>
</argument>
<argument>
<name>DesiredMute</name>
<direction>in</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ResetBasicEQ</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Bass</name>
<direction>out</direction>
<relatedStateVariable>Bass</relatedStateVariable>
</argument>
<argument>
<name>Treble</name>
<direction>out</direction>
<relatedStateVariable>Treble</relatedStateVariable>
</argument>
<argument>
<name>Loudness</name>
<direction>out</direction>
<relatedStateVariable>Loudness</relatedStateVariable>
</argument>
<argument>
<name>LeftVolume</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_LeftVolume</relatedStateVariable>
</argument>
<argument>
<name>RightVolume</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_RightVolume</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>ResetExtEQ</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>EQType</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_EQType</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetVolume</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
<argument>
<name>CurrentVolume</name>
<direction>out</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetVolume</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
<argument>
<name>DesiredVolume</name>
<direction>in</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetRelativeVolume</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
<argument>
<name>Adjustment</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_VolumeAdjustment</relatedStateVariable>
</argument>
<argument>
<name>NewVolume</name>
<direction>out</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetVolumeDB</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
<argument>
<name>CurrentVolume</name>
<direction>out</direction>
<relatedStateVariable>VolumeDB</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetVolumeDB</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
<argument>
<name>DesiredVolume</name>
<direction>in</direction>
<relatedStateVariable>VolumeDB</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetVolumeDBRange</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
<argument>
<name>MinValue</name>
<direction>out</direction>
<relatedStateVariable>VolumeDB</relatedStateVariable>
</argument>
<argument>
<name>MaxValue</name>
<direction>out</direction>
<relatedStateVariable>VolumeDB</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetBass</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>CurrentBass</name>
<direction>out</direction>
<relatedStateVariable>Bass</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetBass</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>DesiredBass</name>
<direction>in</direction>
<relatedStateVariable>Bass</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetTreble</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>CurrentTreble</name>
<direction>out</direction>
<relatedStateVariable>Treble</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetTreble</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>DesiredTreble</name>
<direction>in</direction>
<relatedStateVariable>Treble</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetEQ</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>EQType</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_EQType</relatedStateVariable>
</argument>
<argument>
<name>CurrentValue</name>
<direction>out</direction>
<relatedStateVariable>EQValue</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetEQ</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>EQType</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_EQType</relatedStateVariable>
</argument>
<argument>
<name>DesiredValue</name>
<direction>in</direction>
<relatedStateVariable>EQValue</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetLoudness</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
<argument>
<name>CurrentLoudness</name>
<direction>out</direction>
<relatedStateVariable>Loudness</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetLoudness</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
<argument>
<name>DesiredLoudness</name>
<direction>in</direction>
<relatedStateVariable>Loudness</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetSupportsOutputFixed</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>CurrentSupportsFixed</name>
<direction>out</direction>
<relatedStateVariable>SupportsOutputFixed</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetOutputFixed</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>CurrentFixed</name>
<direction>out</direction>
<relatedStateVariable>OutputFixed</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetOutputFixed</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>DesiredFixed</name>
<direction>in</direction>
<relatedStateVariable>OutputFixed</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetHeadphoneConnected</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>CurrentHeadphoneConnected</name>
<direction>out</direction>
<relatedStateVariable>HeadphoneConnected</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>RampToVolume</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
<argument>
<name>RampType</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_RampType</relatedStateVariable>
</argument>
<argument>
<name>DesiredVolume</name>
<direction>in</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
<argument>
<name>ResetVolumeAfter</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_ResetVolumeAfter</relatedStateVariable>
</argument>
<argument>
<name>ProgramURI</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_ProgramURI</relatedStateVariable>
</argument>
<argument>
<name>RampTime</name>
<direction>out</direction>
<relatedStateVariable>A_ARG_TYPE_RampTimeSeconds</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>RestoreVolumePriorToRamp</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetChannelMap</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>ChannelMap</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_ChannelMap</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetRoomCalibrationStatus</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>RoomCalibrationEnabled</name>
<direction>out</direction>
<relatedStateVariable>RoomCalibrationEnabled</relatedStateVariable>
</argument>
<argument>
<name>RoomCalibrationAvailable</name>
<direction>out</direction>
<relatedStateVariable>RoomCalibrationAvailable</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>SetRoomCalibrationStatus</name>
<argumentList>
<argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
<argument>
<name>RoomCalibrationEnabled</name>
<direction>in</direction>
<relatedStateVariable>RoomCalibrationEnabled</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
</scpd>
You’re not going to believe this, but I played with it and found a way to adjust the subwoofer level. Here’s your original code with my copy/change. This works:
import soco
SET ME
amp = soco.SoCo(“192.168.1.139”)
frequency = 80
level = 10
amp.renderingControl.SetEQ(
[
(“InstanceID”, 0),
(“EQType”, “SubGain”),
(“DesiredValue”, int(level)),
]
)
amp.renderingControl.SetEQ(
[
(“InstanceID”, 0),
(“EQType”, “SubCrossover”),
(“DesiredValue”, int(frequency)),
]
)
amp.renderingControl.SetEQ(
[
(“InstanceID”, 0),
(“EQType”, “SubPolarity”),
(“DesiredValue”, ‘0’), # Set to 0 or 180
]
)
I’ve not been able to get “SubEnabled” to work the same way.
It appears that the API to control the sub is identical, but we probably just need to detect 3rd party external subs in a different way.
Thanks for confirming that the proposed API calls work. Lucky guess.
@rosshenning are you able to attach a diagnostics dump from the Sonos integration? It should contain the info we would need to understand how mark your system as containing a subwoofer.
Happy to attach a diagnostics dump, but I’m not sure how to obtain that?
Three dots on the Sonos card in Settings > Devices & Services > Download diagnostics
.
There’s a lot of non Sonos stuff in the file that I don’t want to post out to the world, but here’s a section for one of the units:
"RINCON_B8E937AB5E2E01400": {
"available": true,
"battery_info": {},
"hardware_version": "1.17.3.1-1.1",
"household_id": "Sonos_6l1WB964izNxwxoBYJajfV0sJC",
"is_coordinator": true,
"model_name": "Sonos Connect:Amp",
"model_number": "ZP120",
"software_version": "71.1-38080",
"sonos_group_entities": [
"media_player.master_bath_sonos"
],
"subscription_address": "192.168.1.21:1400",
"subscriptions_failed": false,
"version": "15.1",
"zone_name": "Master Bath",
"_group_members_missing": [],
"_last_activity": 507662.736595229,
"_last_event_cache": {
"DeviceProperties": {
"zone_name": "Master Bath",
"icon": null,
"configuration": "1",
"invisible": "0",
"is_zone_bridge": "0",
"wireless_mode": "0",
"wireless_leaf_only": "0",
"channel_freq": "2437",
"behind_wifi_extender": "0",
"wifi_enabled": "0",
"eth_link": "1",
"settings_replication_state": "RINCON_B8E937AB5E2E01400,23,RINCON_FFFFFFFFFFFF99999,0,RINCON_B8E937AB5E2E01400,24,RINCON_B8E9379D29D601400,1,RINCON_C438755A444E01400,361,RINCON_C438755A442A01400,4,RINCON_B8E937AB5E2E01400,449,RINCON_FFFFFFFFFFFF99999,0,RINCON_000E582CAE7E01400,8,RINCON_B8E937AB5E2E01400,0,RINCON_B8E937AB5E2E01400,102,RINCON_C438755A445101400,299,RINCON_C438755A442A01400,5,RINCON_C438755A445101400,6,RINCON_C438755A43BE01400,2,RINCON_B8E937AB5E2E01400,103,RINCON_B8E937AB5E2E01400,26",
"secure_reg_state": "3",
"is_idle": "1",
"more_info": "TargetRoomName:Master Bath",
"channel_map_set": null,
"ht_sat_chan_map_set": null,
"ht_bonded_zone_commit_state": "0",
"orientation": "0",
"last_changed_play_state": "STOPPED,,,",
"available_room_calibration": null,
"room_calibration_state": "4",
"config_mode": null,
"supports_audio_in": "1",
"supports_audio_clip": "1"
},
"ContentDirectory": {
"system_update_id": "4",
"container_update_i_ds": "R:,1",
"radio_location_update_id": "RINCON_C438755A444E01400,361"
},
"AVTransport": {
"transport_state": "STOPPED",
"current_play_mode": "REPEAT_ALL",
"current_crossfade_mode": "1",
"number_of_tracks": "9",
"current_track": "1",
"current_section": "0",
"current_track_uri": "x-sonos-http:track%2f3003206.flac?sid=174&flags=24616&sn=10",
"current_track_duration": "0:04:19",
"current_track_meta_data": {
"title": "Amie (Remastered January 1992)",
"parent_id": "-1",
"item_id": "-1",
"restricted": true,
"resources": [
{
"__type": "<class 'soco.data_structures.DidlResource'>",
"repr": "<DidlResource 'x-sonos-http:track%2f3003206.flac?sid=174&flags=24616&sn=10' at 0x7fbd5ade6530>"
}
],
"desc": null,
"creator": "Pure Prairie League",
"stream_content": "",
"radio_show": "",
"album_art_uri": "/getaa?s=1&u=x-sonos-http%3atrack%252f3003206.flac%3fsid%3d174%26flags%3d24616%26sn%3d10",
"album": "Aimee And Other Hits"
},
"next_track_uri": "x-sonos-http:track%2f68709636.flac?sid=174&flags=24616&sn=10",
"next_track_meta_data": {
"title": "The Best of My Love (2013 Remaster)",
"parent_id": "-1",
"item_id": "-1",
"restricted": true,
"resources": [
{
"__type": "<class 'soco.data_structures.DidlResource'>",
"repr": "<DidlResource 'x-sonos-http:track%2f68709636.flac?sid=174&flags=24616&sn=10' at 0x7fbd5ade42b0>"
}
],
"desc": null,
"creator": "Eagles",
"album_art_uri": "/getaa?s=1&u=x-sonos-http%3atrack%252f68709636.flac%3fsid%3d174%26flags%3d24616%26sn%3d10",
"album": "On the Border (2013 Remaster)"
},
"enqueued_transport_uri": "file:///jffs/settings/trackqueue.rsq#0",
"enqueued_transport_uri_meta_data": "",
"playback_storage_medium": "NETWORK",
"av_transport_uri": "x-rincon-queue:RINCON_B8E937AB5E2E01400#0",
"av_transport_uri_meta_data": "",
"next_av_transport_uri": "",
"next_av_transport_uri_meta_data": "",
"current_transport_actions": "Set, Stop, Pause, Play, X_DLNA_SeekTime, Next, Previous, X_DLNA_SeekTrackNr",
"current_valid_play_modes": "SHUFFLE,REPEAT,REPEATONE,CROSSFADE",
"direct_control_client_id": "",
"direct_control_is_suspended": "0",
"direct_control_account_id": "",
"transport_status": "OK",
"sleep_timer_generation": "0",
"alarm_running": "0",
"snooze_running": "0",
"restart_pending": "0",
"transport_play_speed": "NOT_IMPLEMENTED",
"current_media_duration": "NOT_IMPLEMENTED",
"record_storage_medium": "NOT_IMPLEMENTED",
"possible_playback_storage_media": "NONE, NETWORK",
"possible_record_storage_media": "NOT_IMPLEMENTED",
"record_medium_write_status": "NOT_IMPLEMENTED",
"current_record_quality_mode": "NOT_IMPLEMENTED",
"possible_record_quality_modes": "NOT_IMPLEMENTED"
},
"AlarmClock": {
"time_zone": "012c0b000102000003000202ffc4",
"time_server": "0.sonostime.pool.ntp.org,1.sonostime.pool.ntp.org,2.sonostime.pool.ntp.org,3.sonostime.pool.ntp.org",
"time_generation": "20000001",
"alarm_list_version": "RINCON_000E58AF974601400:0",
"time_format": "INV",
"date_format": "INV",
"daily_index_refresh_time": null
},
"ZoneGroupTopology": {
"third_party_media_servers_x": "2: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"
},
"RenderingControl": {
"volume": {
"Master": "20",
"LF": "100",
"RF": "100"
},
"mute": {
"Master": "0",
"LF": "0",
"RF": "0"
},
"bass": "3",
"treble": "10",
"loudness": {
"Master": "0"
},
"output_fixed": "0",
"speaker_size": "-1",
"sub_gain": "0",
"sub_crossover": "0",
"sub_polarity": "0",
"sub_enabled": "1",
"sonar_enabled": "0",
"sonar_calibration_available": "0",
"preset_name_list": "FactoryDefaults"
}
},
"enabled_entities": [
"media_player.master_bath_sonos",
"switch.master_bath_sonos_crossfade",
"switch.master_bath_sonos_loudness",
"number.master_bath_sonos_bass",
"number.master_bath_sonos_treble"
],
"media": {
"album_name": "Aimee And Other Hits",
"artist": "Pure Prairie League",
"channel": null,
"duration": 259,
"image_url": "http://192.168.1.234:1400/getaa?s=1&u=x-sonos-http%3atrack%252f3003206.flac%3fsid%3d174%26flags%3d24616%26sn%3d10",
"queue_position": 1,
"playlist_name": null,
"source_name": null,
"title": "Amie (Remastered January 1992)",
"uri": "x-sonos-http:track%2f3003206.flac?sid=174&flags=24616&sn=10",
"current_track_poll": {
"Track": "1",
"TrackDuration": "0:04:19",
"TrackMetaData": "<DIDL-Lite xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" xmlns:r=\"urn:schemas-rinconnetworks-com:metadata-1-0/\" xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"><item id=\"-1\" parentID=\"-1\" restricted=\"true\"><res protocolInfo=\"sonos.com-http:*:audio/flac:*\" duration=\"0:04:19\">x-sonos-http:track%2f3003206.flac?sid=174&flags=24616&sn=10</res><r:streamContent></r:streamContent><upnp:albumArtURI>/getaa?s=1&u=x-sonos-http%3atrack%252f3003206.flac%3fsid%3d174%26flags%3d24616%26sn%3d10</upnp:albumArtURI><dc:title>Amie (Remastered January 1992)</dc:title><upnp:class>object.item.audioItem.musicTrack</upnp:class><dc:creator>Pure Prairie League</dc:creator><upnp:album>Aimee And Other Hits</upnp:album></item></DIDL-Lite>",
"TrackURI": "x-sonos-http:track%2f3003206.flac?sid=174&flags=24616&sn=10",
"RelTime": "0:00:00",
"AbsTime": "NOT_IMPLEMENTED",
"RelCount": "2147483647",
"AbsCount": "2147483647"
}
},
"activity_stats": {
"DeviceProperties subscription": {
"count": 9,
"last_seen": 505156.822676048
},
"ContentDirectory subscription": {
"count": 4,
"last_seen": 505156.845502008
},
"AVTransport subscription": {
"count": 2,
"last_seen": 489062.255595483
},
"SonosMedia.poll_track_info": {
"count": 2,
"last_seen": 489062.276172919
},
"AlarmClock subscription": {
"count": 2,
"last_seen": 489062.263354354
},
"ZoneGroupTopology subscription": {
"count": 12,
"last_seen": 489642.151554212
},
"RenderingControl subscription": {
"count": 2,
"last_seen": 489062.298646543
},
"discovery": {
"count": 641,
"last_seen": 507662.736595229
}
},
"event_stats": {
"DeviceProperties": {
"received": 9,
"duplicates": 0,
"processed": 9
},
"ContentDirectory": {
"received": 4,
"duplicates": 0,
"processed": 0
},
"AVTransport": {
"received": 2,
"duplicates": 0,
"processed": 2
},
"AlarmClock": {
"received": 2,
"duplicates": 1,
"processed": 0
},
"ZoneGroupTopology": {
"received": 12,
"duplicates": 0,
"processed": 2
},
"RenderingControl": {
"received": 2,
"duplicates": 1,
"processed": 1
},
"soco:from_didl_string": [
19,
22,
128,
22
],
"soco:parse_event_xml": [
113,
284,
128,
128
]
},
"zone_group_state_stats": {
"processed": 30,
"total_requests": 178
}
}