DLNA / UPNP binding

No. Audiosinks are more at the system level, that can be used in audio Actions. I have Items that hold the UUIDs of all the sinks, an Item for each speaker representing the PlayURI, and play to the speakers using this. The important part is right above the ‘except’ in the third rule.

@rule("Alert: Advance House Shuffle")
@when("Item HouseShuffle_Advance received command")
def advanceHouseShuffle(event):
    advanceHouseShuffle.log.debug("Advancing House Shuffle")
    workingStreamList = str(items["Working_Stream_List"]).split(",")
    if len(workingStreamList) == 0:
        streamList = str(items["Stream_List"]).split(",")
        workingStreamList = refillList(None, streamList, "HA_Streams_{}".format(items["HouseShuffle_Genre"]))
    if len(workingStreamList) > 0:
        events.sendCommand("HouseShuffle_PlayURI", workingStreamList.pop())
        events.postUpdate("Working_Stream_List", ",".join(workingStreamList))
    else:
        advanceHouseShuffle.log.error("Advance House Shuffle: Reset workingStreamList failed")  

@rule("Alert: House Shuffle received command")
@when("Item HouseShuffle_PlayURI received command")
def houseShuffleChange(event):
    previousPlayURI = items["HouseShuffle_PlayURI"]
    houseShuffleChange.log.debug("House Shuffle changed: [{}]".format(event.itemCommand))
    for speaker in filter(lambda speaker: speaker.state == previousPlayURI and ir.getItem(speaker.name.replace("_PlayURI", "_Player")).state == PlayPauseType.PLAY, ir.getItem("gSpeakerPlayURI").getMembers()):
        speaker.sendCommand(str(event.itemCommand))

@rule("Alert: Speaker playURI received command")
@when("Member of gSpeakerPlayURI received command")
def speakerPlayURIReceivedCommand(event):
    speakerPlayURIReceivedCommand.log.debug("Speaker playURI received command [{}]: Starting rule: current state=[{}], command=[{}]".format(event.itemName,ir.getItem(event.itemName).state,event.itemCommand))
    try:
        if event.itemCommand == StringType("HouseShuffle"):
            newURI = str(items["HouseShuffle_PlayURI"])
            if not any(filter(lambda speaker: speaker.state == PLAY and items[speaker.name.replace("_Player","_PlayURI")] == StringType(newURI), ir.getItem("gSpeakerPlayer").getMembers())):
                speakerPlayURIReceivedCommand.log.debug("Speaker playURI received command [{}]: No other speaker is playing the house shuffle, so picking a new random one".format(event.itemName))
                workingStreamList = str(items["Working_Stream_List"]).split(",")
                if len(workingStreamList) > 0:
                    newURI = workingStreamList.pop()
                    if len(workingStreamList) > 0:
                        events.sendCommand("Working_Stream_List", ",".join(workingStreamList))
                    else:
                        events.sendCommand("HouseShuffle_Genre", str(items["HouseShuffle_Genre"]))
                    events.postUpdate("HouseShuffle_PlayURI", newURI)
            events.sendCommand(event.itemName, newURI)
        else:
            if items[event.itemName.replace("_PlayURI","_System")] == ON:
                audioSink = "upnpcontrol:upnprenderer:{}".format(items[event.itemName.replace("_PlayURI","_UUID")])
                playStream(audioSink, str(event.itemCommand))
            else:
                speakerPlayURIReceivedCommand.log.debug("Speaker playURI received command [{}]: canceling request since speaker is offline: [{}]".format(event.itemName, event.itemCommand))
    except Exception as e:
        import traceback
        message = "Alert: Speaker playURI received command [{}]: Exception: [{}]: [{}]".format(event.itemName, e, traceback.format_exc())
        speakerPlayURIReceivedCommand.log.error(message)
        NotificationAction.sendNotification(adminEmail,"{}".format(message))

While I’m at it, here is a rule to provide a online/offline state for the speakers. Every now and then mine will fall off the network.

@rule("Alert: Speaker system status update")
@when("Thing upnpcontrol:upnprenderer:5f9ec1b3-ed59-1900-4530-0007f521099e changed")
@when("Thing upnpcontrol:upnprenderer:5f9ec1b3-ed59-1900-4530-0007f521366d changed")
@when("Thing upnpcontrol:upnprenderer:5f9ec1b3-ed59-1900-4530-0007f522dcaf changed")
@when("Thing upnpcontrol:upnprenderer:5f9ec1b3-ed59-1900-4530-0007f5207868 changed")
@when("Thing upnpcontrol:upnprenderer:5f9ec1b3-ed59-1900-4530-0007f520f682 changed")
@when("Thing upnpcontrol:upnprenderer:5f9ec1b3-ed59-1900-4530-0007f5210909 changed")
@when("Thing upnpcontrol:upnprenderer:5f9ec1b3-ed59-1900-4530-0007f52220b3 changed")
@when("Thing upnpcontrol:upnprenderer:5f9ec1b3-ed59-1900-4530-0007f52109de changed")
def speakerSystemStatusUpdate(event):
    speakerName = filter(lambda item: str(item.state).replace("uuid:", "") == str(event.thingUID).split(":")[2], ir.getItem("gSpeakerUUID").members)[0].name.replace("UUID", "System")
    speakerSystemStatusUpdate.log.debug("Speaker system update [{}]: [{}]".format(speakerName, event.statusInfo))
    if items[speakerName] == OnOffType.OFF and str(event.statusInfo) == "ONLINE":
        events.sendCommand(speakerName, "ON")
        if items[speakerName.replace("System", "Player")] == PlayPauseType.PLAY:
            events.sendCommand(speakerName.replace("System", "Stop"), "OFF")
        else:
            events.sendCommand(speakerName.replace("System", "Stop"), "ON")
        speakerSystemStatusUpdate.log.info("Speaker system update [{}]: ON".format(speakerName))
    elif items[speakerName] == OnOffType.ON:
        events.sendCommand(speakerName, "OFF")
        speakerSystemStatusUpdate.log.info("Speaker system update [{}]: OFF".format(speakerName))
2 Likes