How to change LMS Favorite List with a rule?

I am using on a Win PC the OH4.1. Here I do installed the squeezebox where I can select a favorite and play it. Now I would like to change the favorite with a trigger with following rule:

rule "RadiosenderUp"

when
    Item Raumthermostat_Taster_Bad_Radiosender___Taste_4_links received command
then
	var Integer sendernummer = Integer::parseInt(SqueezeBox_Player_Play_a_Favorite.state.toString)
	
	if ((receivedCommand == ON) || (receivedCommand == OFF)) {
		
		logInfo("RADIO Log", "Letzte Sendernummer: " + (SqueezeBox_Player_Play_a_Favorite.state))
		var Number sendernummer = Integer::parseInt(SqueezeBox_Player_Play_a_Favorite.state.toString)


		if ( (sendernummer > 9)|| (sendernummer == 0) || (sendernummer == 1) )
		{
			sendernummer = 2
			SqueezeBox_Player_Play_a_Favorite.sendCommand(sendernummer.toString())
			logInfo("RADIO Log-", "Aktuelle Sendernummer: " + (sendernummer.toString))
		}
		else 
		{
			sendernummer = sendernummer + 1
			SqueezeBox_Player_Play_a_Favorite.sendCommand(sendernummer.toString())
			logInfo("RADIO Log+", "Aktuelle Sendernummer: " + (sendernummer.toString))
		}
	}

end

The trigger is working and reacting to ON or OFF. When the favorite number is 9 it goes to the next favorite with the number 10 (current + 1). But when I trigger again the current favorite is STILL 9 and goes again to 10. Actually I would expect it goes to favorite number 2 as stated in the rule.

What I am doing wrong here?

2024-01-09 18:14:16.606 [INFO ] [.openhab.core.model.script.RADIO Log] - Letzte Sendernummer: 9
2024-01-09 18:14:16.608 [INFO ] [openhab.core.model.script.RADIO Log+] - Aktuelle Sendernummer: 10
2024-01-09 18:15:08.504 [INFO ] [.openhab.core.model.script.RADIO Log] - Letzte Sendernummer: 9
2024-01-09 18:15:08.505 [INFO ] [openhab.core.model.script.RADIO Log+] - Aktuelle Sendernummer: 10

Some comments:

  • Never force the type of variables in Rules DSL unless and until you absolutely have to (you’ll know when you need to, you’ll get an error).

  • Assuming Raumthermostat_Taster_Bad_Radiosender___Taste_4_links is a switch Item, it can only receive ON or OFF as a command so if ((receivedCommand == ON) || (receivedCommand == OFF)) { is pointless. If the rule runs at all with the given trigger receivedCommand can only be ON or OFF. That’s the only possibility.

  • SqueezeBox_Player_Play_a_Favorite if this is a Number Item don’t convert it to a String and then parse it. Keep it as a number. var sendernummer = SqueezeBox_Player_Play_a_Favorite.state as Number.

  • There is an operation that is very useful to use in cases where you want to loop through some numbers and start over when you get to the end called modulo. That could be used to simplify this rule.

Putting it all together:

rule "RadiosenderUp"

when
    Item Raumthermostat_Taster_Bad_Radiosender___Taste_4_links received command
then

    // Get and log the current number
    const currNumber = SqueezeBox_Player_Play_a_Favorite.state as Number
    logInfo("RADIO Log", "Letzte Sendernummer: " + currNumber)

    // Calculate the next number, skipping 0 and 1 if we cycled
    var nextNumber = currNumber % 11 // Modulo operator, or remainder operator, 10 % 11 = 10, 11 % 11 = 0, 12 % 11 = 1
    if(nextNumber <= 1) nextNumber = 2 // skip 0 and 1

    // Command the Item and log.
    SqueezeBox_Player_Play_a_Favorite.sendCommand(nextNumber)
    logInfo("RADIO Log", "Aktuelle Sendernummer: " + nextNumber)

end

As for what was wrong with the original? :man_shrugging: There was so much unnecessary code in it that it’s really hard to follow and analyze. Try this and if it doesn’t work come back with the logs (include relevant events.log entries).

Note, I just typed this in, there may be typos.

Thanks a lot for your input - it helped at lot to understand the rule much better now!!!

When I run your new rule I get this error:

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'RadiosenderUp-1' failed: The name 'const' cannot be resolved to an item or type; line 8, column 5, length 5 in RadiosenderUp

Do I need a constant here?

and the event log is:

2024-01-12 06:58:08.029 [INFO ] [openhab.event.ItemStateUpdatedEvent ] - Item 'SqueezeBox_Player_Current_Playing_Time' updated to 173
2024-01-12 06:58:08.029 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'SqueezeBox_Player_Current_Playing_Time' changed from 172 to 173

I did say I just typed this in and I guess my Rules DSL has gotten rusty over the years. There is no such thing as const in Rules DSL (there is in JS). Need to use val instead.

val currNumber = ...

with that I get following error:

'RadiosenderUp-1' failed: Could not cast 9 to java.lang.Number; line 8, column 22, length 49 in RadiosenderUp

although I checked other docu I could not find the right solution. hmmmm??

ist long time ago when i switched to habapp, before i used dsl rules and there i (dont remember why) used this script for switching favourites:

// **************************************************************************************************************
// Schalte auf nächsten Favoriten
// - beginnt am Anfang der Liste falls aktueller Favorit nicht bekannt
//
// issues:
// - erkennt nicht wenn direkt in LMS ein anderer Favorit gewählt wird
// **************************************************************************************************************

var Number iFavoritenGesamt = 0
var Number iFavoritAktuell = 0

iSbPlayer_Favorit.getStateDescription.getOptions.forEach [ option |
    // logInfo("Squeezebox", "Favorit {}: {}", option.getValue, option.getLabel)
    iFavoritenGesamt = iFavoritenGesamt + 1
]
logInfo("Squeezebox", "Anzahl Favoriten = {}", iFavoritenGesamt)

if (!(iSbPlayer_Favorit.state == NULL)){
    logInfo("Squeezebox", "schalte auf nächsten Favoriten")
    iFavoritAktuell = Integer::parseInt(iSbPlayer_Favorit.state.toString())
    iFavoritAktuell = iFavoritAktuell + 1
}
if (iFavoritAktuell >= iFavoritenGesamt){
    iFavoritAktuell = 0
}

iSbPlayer_Favorit.sendCommand(iFavoritAktuell)

but this had the issue that it did not recognize when i switched to another favourite direct in the lms website.

in rules dsl i called the scrpit with:

callScript("favorit_weiter")

and this dsl rule i used to count the actual number of favourites:

var Number iFavoriteCount = 0

// Favoritenliste wurde aktualisiert, Anzahl der vorhandenen Favoriten ermitteln
rule "Squeezebox Favoriten geändert"
    when
        System started or
        Item iSbServer_FavListe received update
    then
        // logInfo("Squeezebox Favoriten geändert", "Squeezebox Favoriten geändert, Liste: " + iSbServer_FavListe.state.toString)
        iSbPlayer_Favorit.getStateDescription.getOptions.forEach [ option |
            // logInfo("Squeezebox", "Favorit {}: {}", option.getValue, option.getLabel)
            iFavoriteCount = iFavoriteCount + 1
        ]
        logInfo("Squeezebox", "Anzahl Favoriten = {}", iFavoriteCount)
        iFavoritenGesamt.postUpdate(iFavoriteCount)
    end

perhaps this might help you

SqueezeBox_Player_Play_a_Favorite is a Number Item and it’s state is not NULL or UNDEF?

no it is a string item in my setup.

Hi, my item is also a string. But I have rules which sends numbers to the item.

if (now.getDayOfWeek.getValue == 7) SqueezerKueche_PlayaFavorite.sendCommand (0)
		else SqueezerKueche_PlayaFavorite.sendCommand (7)
	

For switching the favorite I use

var favorite = Integer::parseInt(SqueezerKueche_PlayaFavorite.state.toString)
. 
. 
. 
favorite = favorite + 1
. 
. 
. 
SqueezerKueche_PlayaFavorite.sendCommand (favorite.toString)

Greets

Thanks to all!! Now it works perfectly…!