Sonos binding possible race condition on executing standalone before play commands

In a rule, following code seems to not be working. I expect the code to drop the zone from all groups. It keeps the zone in a group though.

sendCommand(SonosBadezimmer_Standalone, "ON") 

Is there anywhere where I can see what commands are currently working or not?

If SonosBadezimmer_Standalone ist a switch-item it sould work. It would be easyer knowing your definition.
You can use the RestAPI for checking a item-state.
Alternate SonosBadezimmer_Standalone.sendCommand(ON)

It is set to on, but the expected action, which I would believe is to drop from the zone player group, is not happening. It doesn’t change on a grouping change either. When I add the zone to a zone group, the switch remains “ON”.

  {
    "link": "https://myopenhab.org/rest/items/SonosBadezimmer_Standalone",
    "state": "ON",
    "type": "Switch",
    "name": "SonosBadezimmer_Standalone",
    "label": "Stand Alone",
    "tags": [],
    "groupNames": []
  },

I understand that not all of the Sonos commands are working right now. Is there a list of commands which are not working with the current Sonos firmware somewhere?

SonosBadezimmer_Standalone should be a switch item and then this should work:

sendCommand(SonosBadezimmer_Standalone, ON)

Yes, it is defined as a switch item, but no, it doesn’t work. I can change the switch and nothing happens. Somewhere in these forums I read that some Sonos binding commands that relied on undocumented status pages were broken at some point due to changes in firmware. The current status is a bit unclear to me.

Switch   SonosBadezimmer_Standalone            "Stand Alone"                   {channel="sonos:CONNECTAMP:RINCON_000E5810648001400:standalone"}

At my knowledge, the binding is not relying on any undocumented status pages but only on UPnP actions. Of course Sonos could decide at any time to suppress some UPnP actions with any new firmware.

Will try to test again the standalone command when I find time.

My experience with Sonos API after several years is that they never break it. So I will be very surprised if they decided to break it suddenly.

Do you get some interesting logs when the command is failing ?

Just tested it quickly with a UI switch linked to the channel and it works well as expected.

Have any command working ?

Hi, The UI switch (Paper UI) works for me as well. I am calling the switch in a rule though. I think the problem is, that when you group a zone, it is no longer “Stand Alone” and the switch should change to “OFF”. However it doesn’t. After my first usage of the sendCommand(SonosBadezimmer_Standalone, “ON”), the switch will stay on indefinitely no matter what. So in Paper UI, I first had to set the switch to “OFF” manually, although the zone was grouped. Then switching it to “ON” would ungroup as expected.

After grouping, the switch stays “ON”, although the player is not really “stand alone”. So any subsequent command “ON” will not register any change on the switch and thus no action. This would be no problem as long as the zone still is standalone. But because after grouping the zone, the switch will not change, sending the “ON” command won’t cause it to ungroup as expected any more.

For now, my work-around is to first send “OFF” then “ON” in order to invoke the ungrouping.

This switch is only a kind of trigger or command if you prefer. It does not show if the player is in standalone mode or not, a change of its state will just start the action.
Note that you can send either ON or OFF to trigger the action.

As you can see in the documentation, this channel is marked as W for access mode, not as RW.

http://docs.openhab.org/addons/bindings/sonos/readme.html

That is not the issue. I am not trying to read the switch!

I want to invoke the switch. The problem is, that in order to invoke the switch, you need to change its status from whatever it was. It would be logical that the switch would either revert to “OFF” as soon as the player is joining a group (thus no longer standalone) or that it would revert to “OFF” as soon as it has executed the command, i.e. a momentary switch action.

The way it is now, you have to know what the last command to the switch was to effect the “stand alone” command. If you send “ON”, while its value was “ON” already, then nothing happens. So now I have to send both values, only to be sure that an action is triggered. Or I would have to first poll for the switch position and then reverse it, which would also be two operations to invoke one command.

So the bug is “This switch invokes a momentary action, but does not have a momentary operation”. It sticks in the last position without this having any logic, meaning or predictability.

What you say is not stupid but this was not implemented like that in the Sonos binding and it concerns many channels, in fact probably all channels with access mode “W” in the documentation. As another example, you can use the channel to play a playlist. This channel remains with the value you set.

Are you sure that sending a ON command to a switch inside a rule does nothing if the switch is already in an ON state ?

I have done some testing, and actually you are right. I can send either command and it still works no matter what the status was.

Then I must have some other problem. My rule logic is that whenever there is motion in the bathroom and Sonos is not already on, that it will either play nature sounds or in case my playbar is playing TV sound, group with the playbar. I always send the “stand alone” command right before I set the volume, playmode and trigger the nature playlist. They always go together in that order.

My symptom is: after watching tv (and having triggered the grouping with the playbar), I go into the bathroom and I get nature sounds on both the bathroom and the playbar. That should not be possible as I always issue the standalone command before playing back nature sounds. There is no manual control of Sonos in between. So I was figuring the standalone command fails. Maybe some kind of race condition between the zone dropping and playlist start?

Or maybe some kind of race condition between the zone status saving and the grouping, causing it to restore the grouping later?

var Timer music_bath_timer = null
var Boolean music_bath_motion = false

rule "TV Sound Automation"
//Rules when TV is producing sound

when
    Item SonosFernseher_State changed 
then
    if (SonosFernseher_Currenttrackuri.state.toString.contains(":spdif") && (SonosFernseher_State.state == "PLAYING")){
        //As the playbar is in the same room as the hifi sonos system, we pause the hifi system on TV sound
        sendCommand(SonosWohnzimmer_Control, PAUSE)
    }
end

rule "Start playback on movement"
//rules for movement in the bathroom 
when
    Item BewegungssensorBadezimmer_SensorOccupancy changed
then
    if (BewegungssensorBadezimmer_SensorOccupancy.state == ON){
        if ( SonosBadezimmer_State.state != "PLAYING" ){
            //Sonos in in Bathroom not in use, save state, adjust volume, and set variable to indicate playback is caused by motion
            sendCommand(SonosBadezimmer_Save, "ON")
            if (SonosFernseher_Currenttrackuri.state.toString.contains(":spdif") && (SonosFernseher_State.state == "PLAYING")){
                //TV is producing sound, link to Playbar
                sendCommand(SonosBadezimmer_Volume, 25)
                sendCommand(SonosFernseher_Add, "RINCON_000E5810648001400")               
            }
            else {
                //No TV, start nature sounds
                sendCommand(SonosBadezimmer_Standalone, "ON")      
                while (SonosBadezimmer_Localcoordinator.state == OFF){
                    Thread::sleep(200) //wait for zone to become (probably) standalone
                }          
                sendCommand(SonosBadezimmer_Volume, 25)
                sendCommand(SonosBadezimmer_Shuffle, "ON")
                sendCommand(SonosBadezimmer_Playlist, "nature sounds")
                sendCommand(SonosBadezimmer_Repeat, "ALL")
            }
            music_bath_motion = true        
        } else {
        //Someone in bathroom, music is playing, destroy timer to prevent sound stopping
        music_bath_timer.cancel
        music_bath_timer = null
        }
    }
    else if ( (BewegungssensorBadezimmer_SensorOccupancy.state == OFF) && (music_bath_motion == true) ){
            //no movement, playback was triggered by movement. Set timer to stop playback
            music_bath_timer = createTimer(now.plusMinutes(5)) [|
                sendCommand(SonosBadezimmer_Standalone, "ON")      
                while (SonosBadezimmer_Localcoordinator.state == OFF){
                    Thread::sleep(200) //wait for zone to become (probably) standalone
                }          
                sendCommand(SonosBadezimmer_Control, PAUSE)
                sendCommand(SonosBadezimmer_Restore, "ON")
                music_bath_motion = false
                music_bath_timer = null
            ]
    }
end

rule "Cancel autostop after manual control"
when
    Item SonosBadezimmer_Control received command or
    Item SonosBadezimmer_Volume received command
    //in case things are changed manually, assume no autostop is desired.
then
    if (music_bath_motion && ( SonosBadezimmer_State.state == "PLAYING" )) {
        music_bath_motion = false
        music_bath_timer.cancel
        music_bath_timer = null
    }
end


Changing groups generally takes a certain time so yes you could need some sleep commands somewhere in your complex rules.

You might rename the topic please, as stanbalone command is finally working ?

I have changed the thread title.

I added a little loop to wait with the playlist command until the bathroom is the local coordinator. That should take care of most situations. I’ll add in into the above code just in case anybody thinks nature sounds and TV in the bathroom is a nice idea, and wants to reuse the logic. It gets complicated quickly if you want to cover all eventualities. I’ll add some english comments as well.