Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Spotify in SingleRoom mode #4

Open
TimNN opened this issue Feb 28, 2021 · 27 comments
Open

Feature Request: Spotify in SingleRoom mode #4

TimNN opened this issue Feb 28, 2021 · 27 comments
Labels
enhancement New feature or request

Comments

@TimNN
Copy link

TimNN commented Feb 28, 2021

Hi!

First of all, thank you for this! I've been experimenting a bit with this and found that Spotify does not appear to be supported in SingleRoom mode.

To recap: Raumfeld supports two modes for Spotify: SingleRoom and MultiRoom. In SingleRoom mode, each room is separately available as a Device in Spotify. In MultiRoom mode, a single Device is available in Spotify, and the Teufel App can be used to configure which speakers actually play the music from Spotify.

Using Spotify in MultiRoom mode seems to mostly work (though I haven't experimented long with it).

Spotify in SingleRoom mode does not work: The Room shows as not active / playing. I suspect that this is because of this:

$ curl -L speaker-wohnzimmer:47365/getZones
<?xml version='1.0' encoding='UTF-8'?>
<zoneConfig numRooms='2' spotifyMode='singleRoom'>
 <zones>
  <zone udn='uuid:36C2A43C-B31C-4572-9EC1-0F43CFA40BB5'>
   <room name='Schlafzimmer' udn='uuid:b8f30d11-9a37-40c0-a9d5-fb334955de66' powerState='ACTIVE'>
    <renderer udn='uuid:1225735b-aec8-4058-892e-01018aa7d420' name='Speaker Schlafzimmer'></renderer>
   </room>
  </zone>
 </zones>
 <unassignedRooms>
  <room name='Wohnzimmer' udn='uuid:9b46f7f7-94e7-45f4-9e4f-49a45a7d2fbb' powerState='ACTIVE'>
   <renderer udn='uuid:666d35e9-f74f-4c0d-a59e-270f39e20a15' name='Speaker Wohnzimmer' spotifyConnect='active'></renderer>
  </room>
 </unassignedRooms>
</zoneConfig>

Note that the room where Spotify is active is listed as in unassignedRooms.

I don't understand enough about the data model here to determine if there's an ~easy fix for this or not. I'd be happy to test potential patches or even to try and write a patch myself if you can point me in the correct direction.

(Note: I totally understand if this is not a priority for you, but wanted to open this so that there's at least a central place for tracking this).

@TimNN
Copy link
Author

TimNN commented Feb 28, 2021

(Btw, I suspect that it would be possibly to control Spotify playing on Raumfeld devices using the Spotify Integegration, however what I'm looking for is basic controls (e.g. play/pause, next, volume) irrespective of what is currently playing, so this wouldn't help me much).

@B5r1oJ0A9G
Copy link
Owner

I guess you're pointing in the right direction. Spotify in singleRoom mode is likely using the device renderer directly. To prevent conflicts it would also make sense to ensure the respective speakers are not member of a zone - what finally gives unassignedRooms a reason to exist.

When you look at a current response of speaker-wohnzimmer:47365/getZones, do you find the Unique Device Name (UDN) of a room listed in unassingedRooms with spotifyConnect='active' again in the response of speaker-wohnzimmer:47365/listDevices?
In the getZones reponse shared above it would have been the UDN uuid:666d35e9-f74f-4c0d-a59e-270f39e20a15.

@TimNN
Copy link
Author

TimNN commented Feb 28, 2021

The room does not show up, but the renderer does:

$ curl -L speaker-wohnzimmer:47365/listDevices
<?xml version='1.0' encoding='UTF-8'?>
<devices>
 <device udn='uuid:1225735b-aec8-4058-892e-01018aa7d420' type='urn:schemas-upnp-org:device:MediaRenderer:1' location='http://192.168.3.116:54421/1225735b-aec8-4058-892e-01018aa7d420.xml'>Speaker Schlafzimmer</device>
 <device udn='uuid:1f63dfb3-f96c-49b6-85fe-4807a5470fd1' type='urn:schemas-raumfeld-com:device:ConfigDevice:1' location='http://192.168.3.115:60751/1f63dfb3-f96c-49b6-85fe-4807a5470fd1.xml'>Raumfeld ConfigDevice</device>
 <device udn='uuid:666d35e9-f74f-4c0d-a59e-270f39e20a15' type='urn:schemas-upnp-org:device:MediaRenderer:1' location='http://192.168.3.115:49957/666d35e9-f74f-4c0d-a59e-270f39e20a15.xml'>Speaker Wohnzimmer</device>
 <device udn='uuid:6daa3668-9a53-4ea2-bd2e-2dbe0c5ea8c5' type='urn:schemas-raumfeld-com:device:RaumfeldDevice:1' location='http://192.168.3.116:51146/6daa3668-9a53-4ea2-bd2e-2dbe0c5ea8c5.xml'>Teufel Raumfeld Device</device>
 <device udn='uuid:84064897-c811-4c8a-b79d-ff8f5280321b' type='urn:schemas-upnp-org:device:MediaServer:1' location='http://192.168.3.115:59198/84064897-c811-4c8a-b79d-ff8f5280321b.xml'>Raumfeld MediaServer</device>
 <device udn='uuid:9E67F123-86B5-4137-BDE3-569F56E05BF9' type='urn:schemas-upnp-org:device:MediaRenderer:1' location='http://192.168.3.115:59852/9E67F123-86B5-4137-BDE3-569F56E05BF9.xml'>Schlafzimmer</device>
 <device udn='uuid:b3516060-b8b2-49b1-ab64-0903f6261421' type='urn:schemas-raumfeld-com:device:RaumfeldDevice:1' location='http://192.168.3.115:55659/b3516060-b8b2-49b1-ab64-0903f6261421.xml'>Teufel Raumfeld Device</device>
</devices>

@B5r1oJ0A9G B5r1oJ0A9G added the enhancement New feature or request label Feb 28, 2021
@B5r1oJ0A9G
Copy link
Owner

Would have been too easy, I guess :)
Can you test whether you can play/pause with the following code against the renderer location (under same conditions as the previous test)?

from hassfeld.upnp import pause, play

location = "http://192.168.3.115:49957/666d35e9-f74f-4c0d-a59e-270f39e20a15.xml"
play(location)
#pause(location)

@TimNN
Copy link
Author

TimNN commented Feb 28, 2021

play and pause work. So do {set,get}_volume, {next,previous}_track and get_position_info.

upnp.get_media_info(location) does not work: Unexpected error with get_media_info: <class 'AttributeError'>No attribute or action found with name 'GetMediaInfo'.

I haven't tested any of the other methods.

@B5r1oJ0A9G
Copy link
Owner

Great! With this we can work.

@B5r1oJ0A9G B5r1oJ0A9G self-assigned this Feb 28, 2021
@B5r1oJ0A9G
Copy link
Owner

Can you please provide me the content of the sites /rendercontrol.xml and /avtransport.xml from the location of a renderer device having spotifyConnect='ACTIVE'?
I'd like to see whether there is any difference to a regular/room render device.

@TimNN
Copy link
Author

TimNN commented Mar 2, 2021

$ curl -sL http://192.168.3.115:55517/rendercontrol.xml (click to expand)
<?xml version="1.0" encoding="UTF-8"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
  <specVersion>
    <major>1</major>
    <minor>0</minor>
  </specVersion>
  <actionList>
    <action>
      <name>PlaySystemSound</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>Sound</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_SystemSound</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <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_Channel</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_Channel</relatedStateVariable>
        </argument>
        <argument>
          <name>DesiredMute</name>
          <direction>in</direction>
          <relatedStateVariable>Mute</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>ChangeVolume</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>Amount</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_VolumeDifference</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>GetBalance</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>CurrentBalance</name>
          <direction>out</direction>
          <relatedStateVariable>Balance</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>SetBalance</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>DesiredBalance</name>
          <direction>in</direction>
          <relatedStateVariable>Balance</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>GetLineInStreamURL</name>
      <argumentList>
        <argument>
          <name>URL</name>
          <direction>out</direction>
          <relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
        </argument>
        <argument>
          <name>Mimetype</name>
          <direction>out</direction>
          <relatedStateVariable>A_ARG_TYPE_String</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>SetFilter</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>LowDB</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_Filter</relatedStateVariable>
        </argument>
        <argument>
          <name>MidDB</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_Filter</relatedStateVariable>
        </argument>
        <argument>
          <name>HighDB</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_Filter</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>GetFilter</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>LowDB</name>
          <direction>out</direction>
          <relatedStateVariable>A_ARG_TYPE_Filter</relatedStateVariable>
        </argument>
        <argument>
          <name>MidDB</name>
          <direction>out</direction>
          <relatedStateVariable>A_ARG_TYPE_Filter</relatedStateVariable>
        </argument>
        <argument>
          <name>HighDB</name>
          <direction>out</direction>
          <relatedStateVariable>A_ARG_TYPE_Filter</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>ToggleFilter</name>
      <argumentList>
	<argument>
	  <name>InstanceID</name>
	  <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
	</argument>
	<argument>
	  <name>FilterName</name>
	  <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_FilterName</relatedStateVariable>
	</argument>
	<argument>
	  <name>Enable</name>
	  <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_Boolean</relatedStateVariable>
	</argument>
      </argumentList>
    </action>
    <action>
      <name>QueryFilter</name>
      <argumentList>
	<argument>
	  <name>InstanceID</name>
	  <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
	</argument>
	<argument>
	  <name>FilterName</name>
	  <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_FilterName</relatedStateVariable>
	</argument>
	<argument>
	  <name>Enabled</name>
	  <direction>out</direction>
	  <relatedStateVariable>A_ARG_TYPE_Boolean</relatedStateVariable>
	</argument>
      </argumentList>
    </action>

    <action>
      <name>SetDeviceSetting</name>
      <argumentList>
	<argument>
	  <name>InstanceID</name>
	  <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
	</argument>
	<argument>
	  <name>Name</name>
	  <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_SettingName</relatedStateVariable>
	</argument>
	<argument>
	  <name>Value</name>
	  <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_SettingValue</relatedStateVariable>
	</argument>
      </argumentList>
    </action>

    <action>
      <name>GetDeviceSetting</name>
      <argumentList>
	<argument>
	  <name>InstanceID</name>
	  <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
	</argument>
	<argument>
	  <name>Name</name>
	  <direction>in</direction>
	  <relatedStateVariable>A_ARG_TYPE_SettingName</relatedStateVariable>
	</argument>
	<argument>
	  <name>Value</name>
	  <direction>out</direction>
	  <relatedStateVariable>A_ARG_TYPE_SettingValue</relatedStateVariable>
	</argument>
      </argumentList>
    </action>

  </actionList>
  <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>VolumeDB</name>
      <dataType>i2</dataType>
    </stateVariable>
    <stateVariable sendEvents="yes">
      <name>Balance</name>
      <dataType>i2</dataType>
      <allowedValueRange>
        <minimum>-3072</minimum>
        <maximum>3072</maximum>
        <step>128</step>
      </allowedValueRange>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_Channel</name>
      <dataType>string</dataType>
      <allowedValueList>
        <allowedValue>Master</allowedValue>
        <allowedValue>Input</allowedValue>
      </allowedValueList>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_SystemSound</name>
      <dataType>string</dataType>
      <allowedValueList>
        <allowedValue>Success</allowedValue>
        <allowedValue>Failure</allowedValue>
      </allowedValueList>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_InstanceID</name>
      <dataType>ui4</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_String</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_Filter</name>
      <dataType>i4</dataType>
      <allowedValueRange>
        <minimum>-1536</minimum>
        <maximum>1536</maximum>
      </allowedValueRange>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_FilterName</name>
      <dataType>string</dataType>
      <allowedValueList>
        <allowedValue>stereo-widening</allowedValue>
      </allowedValueList>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_SettingName</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_SettingValue</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_VolumeDifference</name>
      <dataType>i1</dataType>
      <allowedValueRange>
        <minimum>-100</minimum>
        <maximum>100</maximum>
        <step>1</step>
      </allowedValueRange>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_Boolean</name>
      <dataType>boolean</dataType>
    </stateVariable>
  </serviceStateTable>
</scpd>
$ curl -sL http://192.168.3.115:55517/avtransport.xml (click to expand)
<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
  <specVersion>
    <major>1</major>
    <minor>0</minor>
  </specVersion>
  <actionList>
    <action>
      <name>SetAVTransportURI</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>CurrentURI</name>
          <direction>in</direction>
          <relatedStateVariable>AVTransportURI</relatedStateVariable>
        </argument>
        <argument>
          <name>CurrentURIMetaData</name>
          <direction>in</direction>
          <relatedStateVariable>AVTransportURIMetaData</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>SetNextAVTransportURI</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>NextURI</name>
          <direction>in</direction>
          <relatedStateVariable>AVTransportURI</relatedStateVariable>
        </argument>
        <argument>
          <name>NextURIMetaData</name>
          <direction>in</direction>
          <relatedStateVariable>AVTransportURIMetaData</relatedStateVariable>
          </argument>
      </argumentList>
    </action>
    <action>
      <name>SetNextStartTriggerTime</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>TimeService</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_WallClockService</relatedStateVariable>
        </argument>
        <argument>
          <name>StartTime</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_WallClockTime</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>GetPositionInfo</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>TrackDuration</name>
          <direction>out</direction>
          <relatedStateVariable>CurrentTrackDuration</relatedStateVariable>
        </argument>
        <argument>
          <name>RelTime</name>
          <direction>out</direction>
          <relatedStateVariable>RelativeTimePosition</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>GetTransportInfo</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>CurrentTransportState</name>
          <direction>out</direction>
          <relatedStateVariable>TransportState</relatedStateVariable>
        </argument>
        <argument>
          <name>CurrentTransportStatus</name>
          <direction>out</direction>
          <relatedStateVariable>TransportStatus</relatedStateVariable>
        </argument>
        <argument>
          <name>CurrentSpeed</name>
          <direction>out</direction>
          <relatedStateVariable>TransportPlaySpeed</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>GetTransportSettings</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>PlayMode</name>
          <direction>out</direction>
          <relatedStateVariable>CurrentPlayMode</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>Stop</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>Rewind</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>Position</name>
          <direction>out</direction>
          <relatedStateVariable>RelativeTimePosition</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>FastForward</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>Position</name>
          <direction>out</direction>
          <relatedStateVariable>RelativeTimePosition</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>Pause</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>Play</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>Speed</name>
          <direction>in</direction>
          <relatedStateVariable>TransportPlaySpeed</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>Next</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>Previous</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>Seek</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>Unit</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_SeekMode</relatedStateVariable>
        </argument>
        <argument>
          <name>Target</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_SeekTarget</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>SetPlayMode</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>NewPlayMode</name>
          <direction>in</direction>
          <relatedStateVariable>CurrentPlayMode</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>EnterManualStandby</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>EnterAutomaticStandby</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>LeaveStandby</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
    <action>
      <name>GetSpotifyPreset</name>
      <argumentList>
        <argument>
          <name>InstanceID</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
        </argument>
        <argument>
          <name>Button</name>
          <direction>in</direction>
          <relatedStateVariable>A_ARG_TYPE_ButtonNumber</relatedStateVariable>
        </argument>
        <argument>
          <name>Preset</name>
          <direction>out</direction>
          <relatedStateVariable>AVTransportURI</relatedStateVariable>
        </argument>
        <argument>
          <name>Metadata</name>
          <direction>out</direction>
          <relatedStateVariable>A_ARG_TYPE_JsonObject</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
  </actionList>
  <serviceStateTable>
    <stateVariable sendEvents="no">
      <name>TransportState</name>
      <dataType>string</dataType>
      <allowedValueList>
        <allowedValue>STOPPED</allowedValue>
        <allowedValue>PLAYING</allowedValue>
        <allowedValue>TRANSITIONING</allowedValue>
        <allowedValue>NO_MEDIA_PRESENT</allowedValue>
      </allowedValueList>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>TransportStatus</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>AVTransportURI</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>AVTransportURIMetaData</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>CurrentPlayMode</name>
      <dataType>string</dataType>
      <allowedValueList>
        <allowedValue>NORMAL</allowedValue>
        <allowedValue>SHUFFLE</allowedValue>
        <allowedValue>REPEAT_ALL</allowedValue>
        <allowedValue>REPEAT_ONE</allowedValue>
        <allowedValue>RANDOM</allowedValue>
      </allowedValueList>
      <defaultValue>NORMAL</defaultValue>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>CurrentTrackDuration</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>PowerState</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>RelativeTimePosition</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="yes">
      <name>BufferFilled</name>
      <dataType>ui4</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>OwnsAudioResource</name>
      <dataType>boolean</dataType>
    </stateVariable>
    <stateVariable sendEvents="yes">
      <name>LastChange</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_InstanceID</name>
      <dataType>ui4</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_SeekMode</name>
      <dataType>string</dataType>
      <allowedValueList>
        <allowedValue>ABS_TIME</allowedValue>
      </allowedValueList>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_SeekTarget</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>TransportPlaySpeed</name>
      <dataType>string</dataType>
      <allowedValueList>
        <allowedValue>1</allowedValue>
      </allowedValueList>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_WallClockTime</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_WallClockService</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_Boolean</name>
      <dataType>boolean</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_ButtonNumber</name>
      <dataType>ui4</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>A_ARG_TYPE_JsonObject</name>
      <dataType>string</dataType>
    </stateVariable>
  </serviceStateTable>
</scpd>

@B5r1oJ0A9G
Copy link
Owner

B5r1oJ0A9G commented Mar 2, 2021

Thanks for sharing! I just applied for the Spotify Premium plan for better testing. Unfortunately only to find out that it doesn't work over different networks.
You already spotted the branch where i dumped my first tests. Perhaps you can test it on your side. In case it is already working, the rest should be just a finger exercise :)

@TimNN
Copy link
Author

TimNN commented Mar 3, 2021

Spotify was simply not on my list (of interest) :)

Then even more so, thanks for looking into this.

Perhaps you can test it on your side.

Done.

One issue:

if room["renderer"]["@spotifyConnect"] == "ACTIVE":

needs to compare against lowercase "active". After fixing that, all the new methods (room_play, room_pause, room_is_spotify_single_room, get_room_transport_info) work from what I can tell.

get_room_transport_info returns {'CurrentTransportState': 'PLAYING', 'CurrentTransportStatus': 'OK', 'CurrentSpeed': '1'} if that is of interest to you.

@B5r1oJ0A9G
Copy link
Owner

B5r1oJ0A9G commented Mar 6, 2021

Thanks for the feedback! Did your test cover only hassfeld or teufel_raumfeld as well?

@TimNN
Copy link
Author

TimNN commented Mar 6, 2021

Ah, I didn't realize that teufel_raumfeld also got updated. Let me try that now.

@TimNN
Copy link
Author

TimNN commented Mar 6, 2021

Alright, I did some tests:

The room is recognized as "active" when Spotify is playing. However the play state does not appear to be correctly detected: A "Play" (instead of "Pause") button is shown, and attempting to click it fails with Action Play is currently not allowed.

If I manually pause Spotify, and then click the play button, the music starts playing but the action still produces an error:

Error: unhashable type: 'list' (click to expand)
Mar 06 10:50:28 ctrl hass[262080]: 2021-03-06 10:50:28 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [281472900019296] unhashable type: 'list'
Mar 06 10:50:28 ctrl hass[262080]: Traceback (most recent call last):
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/venv/lib/python3.8/site-packages/homeassistant/components/websocket_api/commands.py", line 136, in handle_call_service
Mar 06 10:50:28 ctrl hass[262080]:     await hass.services.async_call(
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/venv/lib/python3.8/site-packages/homeassistant/core.py", line 1455, in async_call
Mar 06 10:50:28 ctrl hass[262080]:     task.result()
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/venv/lib/python3.8/site-packages/homeassistant/core.py", line 1490, in _execute_service
Mar 06 10:50:28 ctrl hass[262080]:     await handler.job.target(service_call)
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/venv/lib/python3.8/site-packages/homeassistant/helpers/entity_component.py", line 204, in handle_service
Mar 06 10:50:28 ctrl hass[262080]:     await self.hass.helpers.service.entity_service_call(
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/venv/lib/python3.8/site-packages/homeassistant/helpers/service.py", line 595, in entity_service_call
Mar 06 10:50:28 ctrl hass[262080]:     future.result()  # pop exception if have
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/venv/lib/python3.8/site-packages/homeassistant/helpers/entity.py", line 664, in async_request_call
Mar 06 10:50:28 ctrl hass[262080]:     await coro
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/venv/lib/python3.8/site-packages/homeassistant/helpers/service.py", line 632, in _handle_entity_call
Mar 06 10:50:28 ctrl hass[262080]:     await result
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/venv/lib/python3.8/site-packages/homeassistant/components/media_player/__init__.py", line 788, in async_media_play_pause
Mar 06 10:50:28 ctrl hass[262080]:     await self.async_media_play()
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/config/custom_components/teufel_raumfeld/media_player.py", line 349, in async_media_play
Mar 06 10:50:28 ctrl hass[262080]:     await self.async_update_transport_state()
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/config/custom_components/teufel_raumfeld/media_player.py", line 557, in async_update_transport_state
Mar 06 10:50:28 ctrl hass[262080]:     info = await self._raumfeld.async_get_room_transport_info(self._rooms)
Mar 06 10:50:28 ctrl hass[262080]:   File "/home/homeassistant/venv/lib/python3.8/site-packages/hassfeld/__init__.py", line 892, in async_get_room_transport_info
Mar 06 10:50:28 ctrl hass[262080]:     room_udn = self.resolve["room_to_udn"][room]
Mar 06 10:50:28 ctrl hass[262080]: TypeError: unhashable type: 'list'

@TimNN
Copy link
Author

TimNN commented Mar 6, 2021

The error during play can be fixed by passing self._room to async_get_room_transport_info in async_update_transport_state.

Though that does not fix the "play state" detection.

@TimNN
Copy link
Author

TimNN commented Mar 6, 2021

Logging the result of async_get_room_transport_info:

Mar 06 11:04:10 ctrl hass[262646]: 2021-03-06 11:04:10 DEBUG (MainThread) [custom_components.teufel_raumfeld]
media_player.py->async_update_transport_state:
Transport Info: {'CurrentTransportState': 'PLAYING', 'CurrentTransportStatus': 'OK', 'CurrentSpeed': '1'}

@TimNN
Copy link
Author

TimNN commented Mar 6, 2021

Alright, I've been experimenting some more:

  1. async_media_pause also uses _rooms as an argument instead of _room in one place.
  2. async_update unconditionally setting the _state seems to part of the issue with the state not being correctly detected.

If I

  • Change (2) to only set _state if it is not None and
  • HomeAssistant and Spotify are in the same state (that is, both think Music is playing, or both think music is paused)

then the play / pause button in HomeAssistant works.

If HomeAssistant and Spotify disagree on the state, then button in HomeAssistant does not work (because it attempts to do the incorrect action).

@B5r1oJ0A9G
Copy link
Owner

I merged the changes to master for easier testing (starting from 65947ef). However, I fear I depend on external feedback/support to progress here due to the inability to test on my side.

@TimNN
Copy link
Author

TimNN commented Mar 20, 2021

Thanks a lot for your work on this!

If just tested this and found the following issue: room_is_spotify_single_room(...) no longer returns the correct result.

With hassfeld master:

>>> import hassfeld
>>> h = hassfeld.RaumfeldHost("speaker-wohnzimmer.lan"); h.start_update_thread()
>>> h.room_is_spotify_single_room('Wohnzimmer')
False

Downgrading back to the dev branch:

>>> import hassfeld
>>> h = hassfeld.RaumfeldHost("speaker-wohnzimmer.lan"); h.start_update_thread()
>>> h.room_is_spotify_single_room('Wohnzimmer')
True

It looks like the "Spotify active" check uses the wrong case again, changing SPOTIFY_ACTIVE = "ACTIVE" to SPOTIFY_ACTIVE = "active" resolves the issue.

Play / Pause from the Home Assistant UI seems to work reliably now! 🎉 🎊 🥳

I'll test this more over the next few days, and will report back with any issues.

@B5r1oJ0A9G
Copy link
Owner

B5r1oJ0A9G commented Mar 21, 2021

Thanks for the feedback! The failing "Spotify active" check was indeed a regression. It's fixed again with B5r1oJ0A9G/hassfeld@de86cc9.

What other controls are missing for single-room support?

Edit:
Probably:

{set,get}_volume, {next,previous}_track and get_position_info, resp. get_track_info.

@B5r1oJ0A9G
Copy link
Owner

In 840a4b1 support for {set,get}_volume, {next,previous}_track is ready for testing.

@B5r1oJ0A9G B5r1oJ0A9G removed their assignment May 9, 2021
@B5r1oJ0A9G B5r1oJ0A9G mentioned this issue May 19, 2021
@MaxSchuck
Copy link

I really appreciate the effort that went into this application, and it does work great with local files.
But I still experience the exact same issues discussed by Tim, so i wonder, where you solutions commited to the master branch (or whatever I get in HACS with the raumfeld download, or do I have to pick together a working version myself, and if thats the case, how do I do that? I am not savy with this slightly more advanced HA stuff

@B5r1oJ0A9G
Copy link
Owner

Hello @MaxSchuck ,

@TimNN and me worked on several aspects together. Can you please clarify what exactly you're referring to. Also, some information about your setup can be helpful too.
In case it is not about single room mode with Spotify, it would make sense to create a dedicated issue.

@MaxSchuck
Copy link

I have trouble using your extension in HA with my Raumfeldspeaker if spotify plays media in Single-Room modus. The speaker is playing via spotify, but in HA it is viewed as off. If i turn it on to change volume for example, spotify gets stopped. Everthing works as expected. If i use the multiroom modus after brief testing. To me, this sounds as if i might just have an outdated version, but i installed via the HACS extension, that should take care of updates for me. Update pollingn is activated

@B5r1oJ0A9G
Copy link
Owner

@MaxSchuck,
There was a regression identified and fiex by c-mellueh (#29 (comment)). Could it be caused by this or do you still face the problem with th current release v0.1.12-alpha

@MaxSchuck
Copy link

am on 0.1.12-alpha4 but I still face the same issue sadly.

@MaxSchuck
Copy link

allright, now it partly works for me, I don't know what exactly changed, I did a ton of restarting, reinstalling and so on concerning other problems. HA still does not realize if music is playing via spotify multiroom. If I hit play though, it starts playing from the multiroom speaker. Background-image still does not appear, but who cares. What bothers me is that i cant skip or replay songs. Imma just dump the log report here, can't make out what is of relevance and what not

` [140228859544000] 'HassRaumfeldHost' object has no attribute 'async_room_next_track'

Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 193, in handle_call_service
await hass.services.async_call(
File "/usr/src/homeassistant/homeassistant/core.py", line 1704, in async_call
task.result()
File "/usr/src/homeassistant/homeassistant/core.py", line 1741, in _execute_service
await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
await service.entity_service_call(
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 680, in entity_service_call
future.result() # pop exception if have
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 964, in async_request_call
await coro
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 717, in _handle_entity_call
await result
File "/config/custom_components/teufel_raumfeld/media_player.py", line 419, in async_media_next_track
await self._raumfeld.async_room_next_track(self._room)
AttributeError: 'HassRaumfeldHost' object has no attribute 'async_room_next_track'
`

@ulilicht
Copy link

Hi there, commenting on this old issue again, it seems I experience the same problem.

using v0.1.12-alpha4 installed through HACS 1.30 on Home Assistant version 2023.1.7

I have Teufel Raumfeld devices from the second generation. (Stereo M)

Steps to reproduce:

  • Raumfeld devices in Spotify SingleRoom mode
  • Play Spotify content through Spotify Connect (e.g. Playlist)
  • In HomeAssistant, observe:
    • Spotify Content is not displayed within the Raumfeld Widget. Instead, previously played radio station is shown.
  • Click on next
  • The exception stated below occurs.

In addition, I cannot play any media on the device until I use the Raumfeld app to choose anything without Spotify.

What does work:

  • Play/Pause works
  • Volume Control works

Happy to help debugging or fixing the issue if you point me in the right direction.

Best
Uli

Exception when clicking "next" while Spotify is being played:

Logger: homeassistant.components.websocket_api.http.connection
Source: custom_components/teufel_raumfeld/media_player.py:419 
Integration: Home Assistant WebSocket API (documentation, issues) 
First occurred: 09:15:46 (3 occurrences) 
Last logged: 09:51:39

[547763051328] Error handling message: Unknown error (unknown_error) from fe80::4f9:4b73:e16b:2f7b (Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Safari/605.1.15)
[547795794288] 'HassRaumfeldHost' object has no attribute 'async_room_next_track'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 27, in _handle_async_response
    await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 646, in handle_execute_script
    await script_obj.async_run(msg.get("variables"), context=context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1524, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 409, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 453, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 451, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 923, in _async_if_step
    await self._async_run_script(if_data["if_then"])
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1029, in _async_run_script
    await self._async_run_long_action(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 648, in _async_run_long_action
    long_task.result()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1524, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 409, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 453, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 451, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 684, in _async_call_service_step
    await service_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1755, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1792, in _execute_service
    await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 213, in handle_service
    await service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 678, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 958, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 715, in _handle_entity_call
    await result
  File "/config/custom_components/teufel_raumfeld/media_player.py", line 419, in async_media_next_track
    await self._raumfeld.async_room_next_track(self._room)
AttributeError: 'HassRaumfeldHost' object has no attribute 'async_room_next_track'

Exception when trying to choose media through a Service after Spotify has been used:

Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/connection.py:150 
Integration: Home Assistant WebSocket API ([documentation](https://www.home-assistant.io/integrations/websocket_api), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+websocket_api%22)) 
First occurred: 10:01:54 (1 occurrences) 
Last logged: 10:01:54

[547795794288] Error handling message: Entity media_player.room_wohnzimmer does not support this service. (unknown_error) from fe80::4f9:4b73:e16b:2f7b (Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Safari/605.1.15)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants