When this switch is “on”, Sonos should start playing. When the switch is “off”, Sonos should pause.
This is my Sonos item:
Player Sonos_GV_Keuken "Radio keuken" <soundvolume> (gGV_Keuken, gSonos) {channel="sonos:PLAY5:RINCON_000E58834E6A01400:control"}
I have connected these items using the following rules:
rule "Play/Pause Sonos Keuken"
when
Item KNX_GV_Keuken_Sonos_10_1_0 received update
then
if (KNX_GV_Keuken_Sonos_10_1_0.state==ON) {
sendCommand(Sonos_GV_Keuken, PLAY)
} else {
sendCommand(Sonos_GV_Keuken, PAUSE)
}
end
This rule is working fine. Using my switch I can now play/pause my Sonos. However, it is only working fine when I would control my Sonos using only this switch (e.g. not via the Sonos app). When the KNX-switch is “off” and I start my Sonos using the Sonos-app, the KNX-switch remains off.
I would like to have a feedback from Sonos to update the switch-status.
I tried adding this rule:
rule "Play/Pause Sonos Keuken - reverse"
when
Item Sonos_GV_Keuken received update
then
if (Sonos_GV_Keuken.state==PLAY) {
sendCommand(KNX_GV_Keuken_Sonos_10_1_0, ON)
} else {
sendCommand(KNX_GV_Keuken_Sonos_10_1_0, OFF)
}
end
But together with the first rule, it creates obviously an infinite loop.
I think if you replace:
sendCommand
with:
sendUpdate
in your second rule, it would do just that: update the items status,but don’t trigger any command.
@Oli: If I use “sendUpdate” I see errors in my log (2017-04-01 11:13:44.864 [ERROR] [.script.engine.ScriptExecutionThread] - Rule ‘Play/Pause Sonos Keuken - reverse’: An error occured during the script execution: The name ‘sendUpdate(,)’ cannot be resolved to an item or type.)
Also “postupdate” is not an option. I really want the new value to be transmitted to the KNX bus, so I think I have to use the sendcommand. Otherwise nothing is send over the KNX binding. Correct?
I tried adding an additional check in my rule.
In fact, if both variables (KNX and Sonos) are having the same state (“ON”, “PLAYING”), nothing should happen. This could avoid the loop.
But since this is my first rule in OpenHAB, I don’t succeed in getting there. I’m not sure I’m doing this in an elegant way:
// Play or pause Sonos Keuken
rule "Play/Pause Sonos Keuken - part 1"
when
Item KNX_GV_Keuken_Sonos_10_1_0 changed from OFF to ON
then
if (Sonos_GV_Keuken_State.state != "PLAYING") {
sendCommand(Sonos_GV_Keuken, PLAY)
} else {
/* Do Nothing */
}
end
rule "Play/Pause Sonos Keuken - part 2"
when
Item KNX_GV_Keuken_Sonos_10_1_0 changed from ON to OFF
then
if (Sonos_GV_Keuken_State.state == "PLAYING") {
sendCommand(Sonos_GV_Keuken, PAUSE)
} else {
/* Do Nothing */
}
end
rule "Play/Pause Sonos Keuken - part 3"
when
Item Sonos_GV_Keuken changed to PLAYING
then
if (KNX_GV_Keuken_Sonos_10_1_0 == OFF) {
sendCommand(KNX_GV_Keuken_Sonos_10_1_0, ON)
} else {
/* Do Nothing */
}
end
rule "Play/Pause Sonos Keuken - part 4"
when
Item Sonos_GV_Keuken changed to SOMETHINGELSETHANPLAYING (PAUSED_PLAYBACK / STOPPED / ...)
then
if (KNX_GV_Keuken_Sonos_10_1_0 == ON) {
sendCommand(KNX_GV_Keuken_Sonos_10_1_0, OFF)
} else {
/* Do Nothing */
}
end
I just don’t know how to changed this line into something that acctually works:
Item Sonos_GV_Keuken changed to SOMETHINGELSETHANPLAYING (PAUSED_PLAYBACK / STOPPED / ...)
Is there a “not equal” statement that you can use in this when-statement? How? I couldn’t find anything.
Not that I’m aware of.You could do an or and include all you’re interested in:
Item Sonos_GV_Keuken changed to PAUSED or
Item Sonos_GV_Keuken changed to STOPPED or
Item Sonos_GV_Keuken changed to OFF or
Hi,
Thanks again Oli. I was hoping a “not” was available, because your approach assumes I know all states. I think they are limited to PLAYING, PAUSED_PLAYBACK and STOPPED.
Below my final rule. It is working well. I’m not sure it is the most elegant way to go. This is my first Openhab rule, so any suggestions to improve/optimize are welcome.
// Play or pause Sonos Keuken
rule "Play/Pause Sonos Keuken - part 1"
when
Item KNX_GV_Keuken_Sonos_10_1_0 changed from OFF to ON
then
if (Sonos_GV_Keuken_State.state != "PLAYING") {
sendCommand(Sonos_GV_Keuken, PLAY)
logInfo("Debug","Sonos Debug1")
} else {
/* Do Nothing */
logInfo("Debug","Sonos Debug2")
}
end
rule "Play/Pause Sonos Keuken - part 2"
when
Item KNX_GV_Keuken_Sonos_10_1_0 changed from ON to OFF
then
if (Sonos_GV_Keuken_State.state == "PLAYING") {
sendCommand(Sonos_GV_Keuken, PAUSE)
logInfo("Debug","Sonos Debug3")
} else {
/* Do Nothing */
logInfo("Debug","Sonos Debug4")
}
end
rule "Play/Pause Sonos Keuken - part 3"
when
Item Sonos_GV_Keuken_State changed to PLAYING
then
if (KNX_GV_Keuken_Sonos_10_1_0.state == OFF) {
sendCommand(KNX_GV_Keuken_Sonos_10_1_0, ON)
logInfo("Debug","Sonos Debug5")
} else {
/* Do Nothing */
logInfo("Debug","Sonos Debug6")
}
end
rule "Play/Pause Sonos Keuken - part 4"
when
Item Sonos_GV_Keuken_State changed to PAUSED_PLAYBACK or
Item Sonos_GV_Keuken_State changed to STOPPED
then
if (KNX_GV_Keuken_Sonos_10_1_0.state == ON) {
sendCommand(KNX_GV_Keuken_Sonos_10_1_0, OFF)
logInfo("Debug","Sonos Debug7")
} else {
/* Do Nothing */
logInfo("Debug","Sonos Debug8")
}
end
Elegance is overrated as long as it works.
But you could reduce that to just two rules. In your part 2 rules you basically do stuff you could put in the else-part of rules part 1:
rule "Play/Pause Sonos Keuken - part 1"
when
Item KNX_GV_Keuken_Sonos_10_1_0 changed
then
if (Sonos_GV_Keuken_State.state != "PLAYING") {
sendCommand(Sonos_GV_Keuken, PLAY)
logInfo("Debug","Sonos Debug1")
} else {
sendCommand(Sonos_GV_Keuken, PAUSE)
logInfo("Debug","Sonos Debug3")
}
end
rule "Play/Pause Sonos Keuken - part 3"
when
Item Sonos_GV_Keuken_State changed
then
//
if (KNX_GV_Keuken_Sonos_10_1_0.state == OFF) {
sendCommand(KNX_GV_Keuken_Sonos_10_1_0, ON)
logInfo("Debug","Sonos Debug5")
} else {
sendCommand(KNX_GV_Keuken_Sonos_10_1_0, OFF)
logInfo("Debug","Sonos Debug7")
}
end
I think that will work the same. But make a backup of your current 4 rules just to be save
Thanks.
I’m afraid using this approach, I will create an infinite loop again.
The first rule says "When “KNX_GV_Keuken_Sonos_10_1_0” changes, change “Sonos_GV_Keuken_State”. The second rule says exactly the opposite. I’m afraid these rules will keep each other busy for quite a while.