Convert script to jython for squeezebox

hello together,
until now i use the squeezebox binding with dsl-rules and now i want to convert them to jython.
my items file contains:

String iSbPlayer_Favorit "Senderliste[%s]" <none> { channel="squeezebox:squeezeboxplayer:squeezeboxServer:squeezeboxPlayer:playFavorite"
}

and this is the script that i cannot manage to move to jython:

var Number iFavoritenGesamt = 0

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

background:
with this script i count the number of favorites that are existend in squeezebox. i need this number because i use a simple switch in bathroom to power squeezebox on and off. wenn it is already powered on and i press on again then i jump to the next favorite. when last favorite is reached it jumps to first favorite.

this item is a string, but it contains a list of more or less favorites, depending how much i have in squeezebox. every time if i jump to next favorite this script is called to check if there is a next one or start from beginning.

this is the iSbPlayer_Favorit item in paperui:
grafik

can somebody please tell me if/how it is possible to run this in jython?

thanks in advance, stefan

You need to provide more context because what you posted is not a Rule. At best it’s a Rule fragment. you probably need to post what is calling this script for better context.

Anything you can do in Rules DSL can be done in Jython, but you need to provide far more information.

Try this…

from core.actions import LogAction

iFavoritenGesamt = 0

for option in ir.getItem("iSbPlayer_Favorit").getStateDescription().getOptions():
    #LogAction.logInfo("Squeezebox", "Favorit {}: {}", option.getValue(), option.getLabel())
    iFavoritenGesamt += 1
LogAction.logInfo("Squeezebox", "Anzahl Favoriten = {}", iFavoritenGesamt)

There are other options for the logging (see the docs). You could also use forEach, but you’d need to create a Consumer to use it, so it is much easier to just iterate through the results, as in my example.

1 Like

thanks a lot @5iver, that is what i couldn´t find out! now my squeezebox rule is migrated to jython and works fine - i´m so happy.

sorry @rlkoshak, i never wanted to keep anything secret, but i thought if i post the whole rule it will be much more confusing.
i have a bticino bus-system in my house installed and so i have the openwebnet-binding installed. but this binding supports only few basic commands and because of that i created a little python-programm that can monitor my bticino bus and send commands to it (thats what i do with “iJython_Busbefehl”).
i´m not a programmer at all and i´m afraid people will laugh about my dirty coding - but for me it works and i can manage nearly all of my house with openhab now what makes me very happy.
but if interested, this is the final jython-file with the funcion included to update number of favorites that are stored in logitech media server:

from core.rules import rule
from core.triggers import when
from core.utils import sendCommand, postUpdate
from core.actions import PersistenceExtensions, ScriptExecution
from core.date import DateTime
from core.actions import LogAction

@rule("updateFavoritenliste",\
    description="Favoritenliste wurde aktualisiert, Anzahl der vorhandenen Favoriten ermitteln")
@when("System started")
@when("Item iSbServer_FavListe received update")
def updateFavoritenliste(event):
    iFavoriteCount = 0

    for option in ir.getItem("iSbPlayer_Favorit").getStateDescription().getOptions():
        LogAction.logInfo("updateFavoritenliste", "Favorit {}: {}", option.getValue(), option.getLabel())
        iFavoriteCount += 1

    LogAction.logInfo("updateFavoritenliste", "Anzahl Favoriten = {}", iFavoriteCount)
    postUpdate("iFavoritenGesamt", iFavoriteCount)

@rule("musicInit",\
    description="Beim Systemstart Status von allen Verstärkern abfragen und Squeezebox einschalten falls mindestens ein Verstärker eingeschaltet ist")
@when("System started")
def musicInit(event):
    sendCommand("iJython_Busbefehl", "*#16*11*5##") # Statusabfrage Verstärker 1 EWoK (OFF/ON)
    sendCommand("iJython_Busbefehl", "*#16*21*5##") # Statusabfrage Verstärker 2 WC (OFF/ON)
    sendCommand("iJython_Busbefehl", "*#16*31*5##") # Statusabfrage Verstärker 3 Bad (OFF/ON)

    if len([item for item in itemRegistry.getItem("iG_Verstaerker").members if item.state == ON]) >= 1:
        sendCommand("iSbPlayer_AusEin", "ON")
    else:
        sendCommand("iSbPlayer_AusEin", "OFF")

def musik_AusEinLauterLeiser(location, parameter, state):
    # Musik aus, ein, lauter, leiser - nur nötig damit Steuerung vom Touchscreen möglich (über CEN)
    LogAction.logInfo(u"musik_AusEinLauterLeiser", "Funktion aufgerufen: sendCommand({}_Musik, {})".format(location, parameter))
    sendCommand(location + "_Musik", parameter)

def musik_Verstaerker(location, parameter, state):
    ownCommand = "*16*"

    if state == "OFF":
        ownCommand = ownCommand + "13"
    else:
        ownCommand = ownCommand + "3"

    if location == "iEWoK":
        ownCommand = ownCommand + "*11##"
    elif location == "iWC":
        ownCommand = ownCommand + "*21##"
    else:   # location == "iBad":
        ownCommand = ownCommand + "*31##"

    LogAction.logInfo(u"musik_Verstaerker", "Funktion aufgerufen: sendCommand({}, {})".format(parameter, ownCommand))
    sendCommand(parameter, ownCommand)

def musik_Steuerung(location, parameter, state):
    if state == "2":
        return      # wenn nur der Status des Buttons zurĂĽckgesetzt wird Funktion beenden

    itemVerstaerker = location + "_Verstaerker"
    itemMusik = location + "_Musik"

    ownSetAmbient = "*16*3*"
    ownSetVolume = "*16*"
    ownVolumeUp = "*16*1003*"
    ownVolumeDown = "*16*1103*"

    if location == "iEWoK":
        ownSetAmbient = ownSetAmbient + "111##"     # ein Stereo-Kanal Ambiente 1 Source 1
        ownSetVolume = ownSetVolume + "11*#1*7*##"  # Verstärker 1 Lautstärke auf 23% (0-31)
        ownVolumeUp = ownVolumeUp + "11##"          # Verstärker 1 um 10% lauter
        ownVolumeDown = ownVolumeDown + "11##"      # Verstärker 1 um 10% leiser
    elif location == "iWC":
        ownSetAmbient = ownSetAmbient + "121##"     # ein Stereo-Kanal Ambiente 2 Source 1
        ownSetVolume = ownSetVolume + "21*#1*3*##"  # Verstärker 2 Lautstärke auf 10% (0-31)
        ownVolumeUp = ownVolumeUp + "21##"          # Verstärker 2 um 10% lauter
        ownVolumeDown = ownVolumeDown + "21##"      # Verstärker 2 um 10% leiser
    else:   # location == "iBad":
        ownSetAmbient = ownSetAmbient + "131##"     # ein Stereo-Kanal Ambiente 3 Source 1
        ownSetVolume = ownSetVolume + "31*#1*5*##"  # Verstärker 3 Lautstärke auf 17% (0-31)
        ownVolumeUp = ownVolumeUp + "31##"          # Verstärker 3 um 10% lauter
        ownVolumeDown = ownVolumeDown + "31##"      # Verstärker 3 um 10% leiser

    if state == "0":
        # zählt wie viele Verstärker eingeschaltet sind
        if len([item for item in itemRegistry.getItem("iG_Verstaerker").members if item.state == ON]) == 1:
            sendCommand("iSbPlayer_AusEin", "OFF")
        sendCommand(itemVerstaerker, "OFF")
        ScriptExecution.createTimer(DateTime.now().plusSeconds(2), lambda: postUpdate(itemMusik, "2"))
    elif state == "1":
        ScriptExecution.createTimer(DateTime.now().plusSeconds(2), lambda: postUpdate(itemMusik, "2"))
        # lastUpdate weil manchmal Verstärker = ON schon im Log steht vor dem iBad_Musik.state
        if PersistenceExtensions.lastUpdate(ir.getItem(itemVerstaerker)).isBefore(DateTime.now().minusSeconds(3)) and items[itemVerstaerker] == ON:
            favorit_weiter()
            return
        # sendCommand("iSbPlayer_AusEin", "ON")
        sendCommand("iJython_Busbefehl", ownSetAmbient)
        sendCommand(itemVerstaerker, "ON")
        sendCommand("iJython_Busbefehl", ownSetVolume)
        sendCommand("iSbPlayer_Funktionen", "PLAY")
        sendCommand("iSbPlayer_Laut", "90")
    elif state == "3":
        sendCommand("iJython_Busbefehl", ownVolumeUp)
        # LogAction.logInfo(u"musik_Steuerung", "iJython_Busbefehl: %s" % ownVolumeUp)
        ScriptExecution.createTimer(DateTime.now().plusMillis(150), lambda: postUpdate(itemMusik, "2"))
    elif state == "4":
        sendCommand("iJython_Busbefehl", ownVolumeDown)
        # LogAction.logInfo(u"musik_Steuerung", "iJython_Busbefehl: %s" % ownVolumeDown)
        ScriptExecution.createTimer(DateTime.now().plusMillis(150), lambda: postUpdate(itemMusik, "2"))
    else:
        return

def favorit_weiter():
    # Schalte auf nächsten Favoriten, beginne am Anfang der Liste falls aktueller Favorit nicht bekannt
    iNextFavorite = 0

    if not isinstance(items["iSbPlayer_Favorit"], UnDefType):
        iNextFavorite = int(str(items["iSbPlayer_Favorit"]))
        iNextFavorite += 1
    if iNextFavorite >= items["iFavoritenGesamt"].intValue():
        iNextFavorite = 0
    LogAction.logInfo(u"favorit_weiter", "Squeezebox schaltet auf Favorit Nr %s" % iNextFavorite)
    sendCommand("iSbPlayer_Favorit", iNextFavorite)

musicDict = {
    # Musik aus, nur nötig damit Steuerung vom Touchscreen möglich
    "CenMH_Musik_Aus":\
        {"function": musik_AusEinLauterLeiser,\
        "parameter": 0},
    # Musik ein (Favorit weiter schalten wenn schon ein), nur nötig damit Steuerung vom Touchscreen möglich
    "CenMH_Musik_Ein":\
        {"function": musik_AusEinLauterLeiser,\
        "parameter": 1},
    # Musik lauter, nur nötig damit Steuerung vom Touchscreen möglich
    "CenMH_Musik_VP":\
        {"function": musik_AusEinLauterLeiser,\
        "parameter": 3},
    # Musik leiser, nur nötig damit Steuerung vom Touchscreen möglich
    "CenMH_Musik_VM":\
        {"function": musik_AusEinLauterLeiser,\
        "parameter": 4},
    # Leistungsverstärker aus / ein
    "Verstaerker":\
        {"function": musik_Verstaerker,\
        "parameter": "iJython_Busbefehl"},
    "Musik":\
        {"function": musik_Steuerung,\
        "parameter": "Null"}
}

@rule("musicControl",\
    description="Steuerung der Squeezebox fĂĽr WC, EWoK und Bad")
@when("Member of iG_Musik changed")
def musicControl(event):
    item = event.itemName
    location = item.split("_")[0]
    dictKey = item.split("_", 1)[1]
    state = str(event.itemState)

    # LogAction.logInfo(u"musicControl", "item = %s" % item)
    # LogAction.logInfo(u"musicControl", "location = %s" % location)
    # LogAction.logInfo(u"musicControl", "ictKey = %s" % dictKey)
    # LogAction.logInfo(u"musicControl", "state = %s" % state)

    if dictKey in musicDict:
        musicDict[dictKey]["function"](location, musicDict[dictKey]["parameter"], state)
1 Like

Often, seeing the whole Rule helps to avoid the XY Problem and it almost always provides clarity about the question being asked instead of confusion. For example, above you posted a fragment of Rules DSL. Well, there is a way to have an isolated chunk of Rules DSL code, and those isolated chunks of code are in fact called “scripts”. But your code as posted wouldn’t be appropriate for that sort of script so it was not obvious whether you are using Rules DSL Scripts incorrectly or using the term “script” incorrectly. Seeing the code in contex would have made that clear.